diff --git a/doc/source/devstack.rst b/doc/source/devstack.rst index 21877c70db..f8f8ee6d9c 100644 --- a/doc/source/devstack.rst +++ b/doc/source/devstack.rst @@ -232,6 +232,11 @@ Add neutron-vpnaas repo as an external repository and configure following flags [[local|localrc]] enable_plugin neutron-vpnaas https://git.openstack.org/openstack/neutron-vpnaas NEUTRON_VPNAAS_SERVICE_PROVIDER=VPN:vmware:vmware_nsx.services.vpnaas.nsxv3.ipsec_driver.NSXv3IPsecVpnDriver:default + Q_SERVICE_PLUGIN_CLASSES+=,vmware_nsx_vpnaas + + [[post-config|$NEUTRON_CONF]] + [DEFAULT] + api_extensions_path = $DEST/neutron-vpnaas/neutron_vpnaas/extensions NSX-TVD diff --git a/setup.cfg b/setup.cfg index 183b124b4a..0f5f19b4f8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -50,6 +50,7 @@ neutron.service_plugins = vmware_nsxtvd_l2gw = vmware_nsx.services.l2gateway.nsx_tvd.plugin:L2GatewayPlugin vmware_nsxtvd_qos = vmware_nsx.services.qos.nsx_tvd.plugin:QoSPlugin vmware_nsxtvd_vpnaas = vmware_nsx.services.vpnaas.nsx_tvd.plugin:VPNPlugin + vmware_nsx_vpnaas = vmware_nsx.services.vpnaas.nsx_plugin:NsxVPNPlugin neutron.qos.notification_drivers = vmware_nsxv3_message_queue = vmware_nsx.services.qos.nsx_v3.message_queue:NsxV3QosNotificationDriver neutron.ipam_drivers = diff --git a/vmware_nsx/services/vpnaas/nsx_plugin.py b/vmware_nsx/services/vpnaas/nsx_plugin.py new file mode 100644 index 0000000000..dbd5d21bfe --- /dev/null +++ b/vmware_nsx/services/vpnaas/nsx_plugin.py @@ -0,0 +1,65 @@ +# Copyright 2018 VMware, Inc. +# All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_log import log as logging + +from neutron_vpnaas.services.vpn import plugin + +LOG = logging.getLogger(__name__) + + +class NsxVPNPlugin(plugin.VPNDriverPlugin): + """NSX plugin for VPNaaS. + + This plugin overrides get connection/s calls to issue a status update + before them, and make sure the connections status is up to date + """ + def _update_nsx_connection_status(self, context, ipsec_site_conn_id): + driver = self.drivers[self.default_provider] + if hasattr(driver, 'get_ipsec_site_connection_status'): + status = driver.get_ipsec_site_connection_status( + context, ipsec_site_conn_id) + if status: + self._update_connection_status(context, ipsec_site_conn_id, + status, False) + + def update_all_connection_status(self, context): + connections = super(NsxVPNPlugin, self).get_ipsec_site_connections( + context) + if not connections: + return + # TODO(asarfaty): This will not scale well. Should use a bulk action + # instead for the NSX api + for connection in connections: + self._update_nsx_connection_status(context, connection['id']) + + def get_ipsec_site_connection(self, context, + ipsec_site_conn_id, fields=None): + # update connection status + if not fields or 'status' in fields: + self._update_nsx_connection_status(context, ipsec_site_conn_id) + + # call super + return super(NsxVPNPlugin, self).get_ipsec_site_connection( + context, ipsec_site_conn_id, fields=fields) + + def get_ipsec_site_connections(self, context, filters=None, fields=None): + # update connection status + if not fields or 'status' in fields: + self.update_all_connection_status(context) + + # call super + return super(NsxVPNPlugin, self).get_ipsec_site_connections( + context, filters=filters, fields=fields) diff --git a/vmware_nsx/services/vpnaas/nsx_tvd/ipsec_driver.py b/vmware_nsx/services/vpnaas/nsx_tvd/ipsec_driver.py index 917b9b7db8..b96aa86f14 100644 --- a/vmware_nsx/services/vpnaas/nsx_tvd/ipsec_driver.py +++ b/vmware_nsx/services/vpnaas/nsx_tvd/ipsec_driver.py @@ -98,3 +98,11 @@ class NSXIPsecVpnDriver(service_drivers.VpnDriver): return d._generate_ipsecvpn_firewall_rules( plugin_type, context, **kargs) return [] + + def get_ipsec_site_connection_status(self, context, ipsec_site_conn_id): + # Currently only NSX-T supports it. In the future we will need to + # decide on the driver by the tenant + driver = self.drivers.get(projectpluginmap.NsxPlugins.NSX_T) + if driver and hasattr(driver, 'get_ipsec_site_connection_status'): + return driver.get_ipsec_site_connection_status( + context, ipsec_site_conn_id) diff --git a/vmware_nsx/services/vpnaas/nsx_tvd/plugin.py b/vmware_nsx/services/vpnaas/nsx_tvd/plugin.py index 448009b9a4..dd91bcc74f 100644 --- a/vmware_nsx/services/vpnaas/nsx_tvd/plugin.py +++ b/vmware_nsx/services/vpnaas/nsx_tvd/plugin.py @@ -13,14 +13,13 @@ # License for the specific language governing permissions and limitations # under the License. -from neutron_vpnaas.services.vpn import plugin - from vmware_nsx.plugins.nsx import utils as tvd_utils +from vmware_nsx.services.vpnaas import nsx_plugin @tvd_utils.filter_plugins -class VPNPlugin(plugin.VPNDriverPlugin): - """NSX-TV plugin for QoS. +class VPNPlugin(nsx_plugin.NsxVPNPlugin): + """NSX-TV plugin for VPNaaS. This plugin adds separation between T/V instances """ diff --git a/vmware_nsx/services/vpnaas/nsxv3/ipsec_driver.py b/vmware_nsx/services/vpnaas/nsxv3/ipsec_driver.py index aa9fbfcb3a..7b86446d9d 100644 --- a/vmware_nsx/services/vpnaas/nsxv3/ipsec_driver.py +++ b/vmware_nsx/services/vpnaas/nsxv3/ipsec_driver.py @@ -493,6 +493,24 @@ class NSXv3IPsecVpnDriver(service_drivers.VpnDriver): policy_rules=rules, enabled=enabled) + def get_ipsec_site_connection_status(self, context, ipsec_site_conn_id): + mapping = db.get_nsx_vpn_connection_mapping( + context.session, ipsec_site_conn_id) + if not mapping or not mapping['session_id']: + LOG.info("Couldn't find NSX session for VPN connection %s", + ipsec_site_conn_id) + return + + status_result = self._nsx_vpn.session.get_status(mapping['session_id']) + if status_result and 'session_status' in status_result: + status = status_result['session_status'] + # NSX statuses are UP, DOWN, DEGRADE + # VPNaaS connection status should be ACTIVE or DOWN + if status == 'UP': + return 'ACTIVE' + elif status == 'DOWN' or status == 'DEGRADED': + return 'DOWN' + def _delete_session(self, session_id): self._nsx_vpn.session.delete(session_id)