From ecbed5d94068939712bd5ddf8b22efb7d60b4d32 Mon Sep 17 00:00:00 2001 From: Abhishek Raut Date: Wed, 11 May 2016 15:24:56 -0700 Subject: [PATCH] [NSX|V|V3]: Refactor NSX-V L2 Gateway driver Commit Ib56ee8bfd182c031e468c503acb0cd75daea8c40 refactored code in L2 gateway base plugin. This patch removes unused NSX plugin code and makes appropriate changes to NSX-V driver. This patch also adds a couple of update_l2_gateway methods to both NSX|V and NSX|V3 L2GW drivers. These methods are added since the base plugin expects the driver to define them. Change-Id: Ifda5401ec5134268b8a9c3276ed7abf4cf8874aa Partial-Bug: #1591413 --- vmware_nsx/services/l2gateway/README.rst | 9 ++- .../services/l2gateway/common/__init__.py | 0 .../services/l2gateway/common/plugin.py | 79 ------------------- vmware_nsx/services/l2gateway/nsx_v/driver.py | 76 ++++++++++++------ .../services/l2gateway/nsx_v3/driver.py | 16 ++-- .../services/l2gateway/test_nsxv_driver.py | 18 +---- 6 files changed, 69 insertions(+), 129 deletions(-) delete mode 100644 vmware_nsx/services/l2gateway/common/__init__.py delete mode 100644 vmware_nsx/services/l2gateway/common/plugin.py diff --git a/vmware_nsx/services/l2gateway/README.rst b/vmware_nsx/services/l2gateway/README.rst index 79dccec632..3483d5c6c9 100644 --- a/vmware_nsx/services/l2gateway/README.rst +++ b/vmware_nsx/services/l2gateway/README.rst @@ -12,16 +12,21 @@ Following steps are meant for L2GW service in neutron for stable/mitaka* release enable_plugin networking-l2gw https://github.com/openstack/networking-l2gw ENABLED_SERVICES=l2gw-plugin -3. For NSXv3 include the following additional flags in ``local.conf``:: +3.1 For NSX|v3 include the following additional flags in ``local.conf``:: [[local|localrc]] NETWORKING_L2GW_SERVICE_DRIVER=L2GW:vmware-nsx-l2gw:vmware_nsx.services.l2gateway.nsx_v3.driver.NsxV3Driver:default DEFAULT_BRIDGE_CLUSTER_UUID= +3.2 For NSX|V include the following additional flags in ``local.conf``:: + [[local|localrc]] + NETWORKING_L2GW_SERVICE_DRIVER=L2GW:vmware-nsx-l2gw:vmware_nsx.services.l2gateway.nsx_v.driver.NsxvL2GatewayDriver:default + 4. run ``stack.sh`` * Configuration for stable/liberty release in ``local.conf``:: [[local|localrc]] enable_plugin networking-l2gw https://github.com/openstack/networking-l2gw - NSX_L2GW_DRIVER='vmware_nsx.services.l2gateway.nsx_v3.driver.NsxV3Driver' + NSX_L2GW_DRIVER='vmware_nsx.services.l2gateway.nsx_v3.driver.NsxV3Driver' # NSXv3 driver + NSX_L2GW_DRIVER='vmware_nsx.services.l2gateway.nsx_v.driver.NsxvL2GatewayDriver' # NSX|V driver Q_SERVICE_PLUGIN_CLASSES=vmware_nsx_l2gw DEFAULT_BRIDGE_CLUSTER_UUID= diff --git a/vmware_nsx/services/l2gateway/common/__init__.py b/vmware_nsx/services/l2gateway/common/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/vmware_nsx/services/l2gateway/common/plugin.py b/vmware_nsx/services/l2gateway/common/plugin.py deleted file mode 100644 index fb3a96f689..0000000000 --- a/vmware_nsx/services/l2gateway/common/plugin.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright 2015 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 networking_l2gw.db.l2gateway import l2gateway_db -from networking_l2gw.services.l2gateway.common import constants as l2gw_const - -from oslo_config import cfg -from oslo_log import log as logging -from oslo_utils import importutils - -from vmware_nsx.common import config # noqa - -LOG = logging.getLogger(__name__) - - -class NsxL2GatewayPlugin(l2gateway_db.L2GatewayMixin): - - """Service plugin for VMware NSX to implement Neutron's L2 gateway API.""" - - supported_extension_aliases = ["l2-gateway", "l2-gateway-connection"] - _methods_to_delegate = ["create_l2_gateway", "get_l2_gateway", - "delete_l2_gateway", "get_l2_gateways", - "update_l2_gateway", - "create_l2_gateway_precommit", - "create_l2_gateway_postcommit", - "delete_l2_gateway_precommit", - "delete_l2_gateway_postcommit", - "create_l2_gateway_connection", - "create_l2_gateway_connection_precommit", - "create_l2_gateway_connection_postcommit", - "get_l2_gateway_connection", - "get_l2_gateway_connections", - "update_l2_gateway_connection", - "delete_l2_gateway_connection_precommit", - "delete_l2_gateway_connection_postcommit", - "delete_l2_gateway_connection"] - - def __init__(self, plugin): - """Initialize service plugin and load backend driver.""" - super(NsxL2GatewayPlugin, self).__init__() - self._plugin = plugin - LOG.debug("Starting service plugin for NSX L2Gateway") - self._nsx_l2gw_driver = cfg.CONF.nsx_l2gw_driver - if not getattr(self, "_nsx_l2gw_driver"): - raise cfg.RequiredOptError("nsx_l2gw_driver") - self._driver = importutils.import_object(self._nsx_l2gw_driver) - - @staticmethod - def get_plugin_type(): - """Get type of the plugin.""" - return l2gw_const.L2GW - - @staticmethod - def get_plugin_description(): - """Get description of the plugin.""" - return l2gw_const.L2_GATEWAY_SERVICE_PLUGIN - - def __getattribute__(self, name): - """Delegate L2GW API calls to the driver class.""" - methods = object.__getattribute__(self, "_methods_to_delegate") - if name in methods: - # If method is delegated, return the driver class method. - return getattr(object.__getattribute__(self, "_driver"), name) - else: - # Else return our own method. - return object.__getattribute__(self, name) diff --git a/vmware_nsx/services/l2gateway/nsx_v/driver.py b/vmware_nsx/services/l2gateway/nsx_v/driver.py index 8cc8dae2fa..29c147e9d9 100644 --- a/vmware_nsx/services/l2gateway/nsx_v/driver.py +++ b/vmware_nsx/services/l2gateway/nsx_v/driver.py @@ -21,7 +21,6 @@ from neutron import manager from neutron_lib import exceptions as n_exc from oslo_config import cfg from oslo_log import log as logging -from oslo_utils import excutils from oslo_utils import uuidutils from vmware_nsx._i18n import _, _LE @@ -37,6 +36,11 @@ LOG = logging.getLogger(__name__) class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): """Class to handle API calls for L2 gateway and NSXv backend.""" + + def __init__(self, plugin): + super(NsxvL2GatewayDriver, self).__init__() + self._plugin = plugin + @property def _core_plugin(self): return manager.NeutronManager.get_plugin() @@ -67,6 +71,12 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): msg = _("Configured interface not found") raise n_exc.InvalidInput(error_message=msg) + def create_l2_gateway_precommit(self, context, l2_gateway): + pass + + def create_l2_gateway_postcommit(self, context, l2_gateway): + pass + def create_l2_gateway(self, context, l2_gateway): """Create a logical L2 gateway.""" self._admin_check(context, 'CREATE') @@ -85,8 +95,13 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): devices[0]['device_name'] = edge_id l2_gateway[self.gateway_resource]['devices'] = devices - return super(NsxvL2GatewayDriver, self).create_l2_gateway(context, - l2_gateway) + return + + def update_l2_gateway_precommit(self, context, l2_gateway): + pass + + def update_l2_gateway_postcommit(self, context, l2_gateway): + pass def _create_l2_gateway_edge(self, context): # Create a dedicated DLR @@ -108,22 +123,16 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): devices = self._get_l2_gateway_devices(context, l2gw_id) return devices[0] - def create_l2_gateway_connection(self, context, l2_gateway_connection): - """Create a L2 gateway connection.""" - gw_connection = l2_gateway_connection.get(l2gw_const. - CONNECTION_RESOURCE_NAME) - l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) - gw_db = self._get_l2_gateway(context, l2gw_id) - if gw_db.network_connections: - raise nsx_exc.NsxL2GWInUse(gateway_id=l2gw_id) - l2gw_connection = super( - NsxvL2GatewayDriver, self).create_l2_gateway_connection( - context, l2_gateway_connection) + def create_l2_gateway_connection_precommit(self, contex, gw_connection): + pass + + def create_l2_gateway_connection_postcommit(self, context, gw_connection): network_id = gw_connection.get('network_id') virtual_wire = nsx_db.get_nsx_switch_ids(context.session, network_id) # In NSX-v, there will be only one device configured per L2 gateway. # The name of the device shall carry the backend DLR. + l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) device = self._get_device(context, l2gw_id) device_name = device.get('device_name') device_id = device.get('id') @@ -138,12 +147,29 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): try: self._nsxv.create_bridge(device_name, bridge_dict) except exceptions.VcnsApiException: - with excutils.save_and_reraise_exception(): - super(NsxvL2GatewayDriver, self).delete_l2_gateway_connection( - context, l2gw_connection['id']) - LOG.exception(_LE("Failed to update NSX, " - "rolling back changes on neutron")) - return l2gw_connection + LOG.exception(_LE("Failed to update NSX, " + "rolling back changes on neutron.")) + raise l2gw_exc.L2GatewayServiceDriverError( + method='create_l2_gateway_connection_postcommit') + return + + def create_l2_gateway_connection(self, context, l2_gateway_connection): + """Create a L2 gateway connection.""" + gw_connection = l2_gateway_connection.get(l2gw_const. + CONNECTION_RESOURCE_NAME) + l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID) + gw_db = self._get_l2_gateway(context, l2gw_id) + if gw_db.network_connections: + raise nsx_exc.NsxL2GWInUse(gateway_id=l2gw_id) + return + + def delete_l2_gateway_connection_precommit(self, context, + l2_gateway_connection): + pass + + def delete_l2_gateway_connection_postcommit(self, context, + l2_gateway_connection): + pass def delete_l2_gateway_connection(self, context, l2_gateway_connection): """Delete a L2 gateway connection.""" @@ -157,18 +183,20 @@ class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin): device = self._get_device(context, l2gw_id) device_name = device.get('device_name') self._nsxv.delete_bridge(device_name) - return super(NsxvL2GatewayDriver, - self).delete_l2_gateway_connection(context, - l2_gateway_connection) def delete_l2_gateway(self, context, l2_gateway): """Delete a L2 gateway.""" self._admin_check(context, 'DELETE') device = self._get_device(context, l2_gateway) - super(NsxvL2GatewayDriver, self).delete_l2_gateway(context, l2_gateway) edge_id = device.get('device_name') rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge( context.session, edge_id) if rtr_binding: self._edge_manager.delete_lrouter(context, rtr_binding['router_id']) + + def delete_l2_gateway_precommit(self, context, l2_gateway): + pass + + def delete_l2_gateway_postcommit(self, context, l2_gateway): + pass diff --git a/vmware_nsx/services/l2gateway/nsx_v3/driver.py b/vmware_nsx/services/l2gateway/nsx_v3/driver.py index 0449d84c44..d41be8f62b 100644 --- a/vmware_nsx/services/l2gateway/nsx_v3/driver.py +++ b/vmware_nsx/services/l2gateway/nsx_v3/driver.py @@ -59,16 +59,6 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): LOG.debug("Initialization complete for NSXv3 driver for " "L2 gateway service plugin.") - @staticmethod - def get_plugin_type(): - """Get type of the plugin.""" - return l2gw_const.L2GW - - @staticmethod - def get_plugin_description(): - """Get description of the plugin.""" - return l2gw_const.L2_GATEWAY_SERVICE_PLUGIN - @property def _core_plugin(self): return manager.NeutronManager.get_plugin() @@ -167,6 +157,12 @@ class NsxV3Driver(l2gateway_db.L2GatewayMixin): def create_l2_gateway_postcommit(self, context, l2_gateway): pass + def update_l2_gateway_precommit(self, context, l2_gateway): + pass + + def update_l2_gateway_postcommit(self, context, l2_gateway): + pass + def delete_l2_gateway(self, context, l2_gateway_id): pass diff --git a/vmware_nsx/tests/unit/services/l2gateway/test_nsxv_driver.py b/vmware_nsx/tests/unit/services/l2gateway/test_nsxv_driver.py index 28d046a007..6527f3746a 100644 --- a/vmware_nsx/tests/unit/services/l2gateway/test_nsxv_driver.py +++ b/vmware_nsx/tests/unit/services/l2gateway/test_nsxv_driver.py @@ -29,7 +29,7 @@ class TestL2gatewayDriver(base.BaseTestCase): def setUp(self): super(TestL2gatewayDriver, self).setUp() self.context = context.get_admin_context() - self.plugin = nsx_v_driver.NsxvL2GatewayDriver() + self.plugin = nsx_v_driver.NsxvL2GatewayDriver(mock.MagicMock()) def test_validate_device_with_multi_devices(self): fake_l2gw_dict = {"l2_gateway": @@ -109,12 +109,9 @@ class TestL2gatewayDriver(base.BaseTestCase): 'nsx_v.driver.NsxvL2GatewayDriver._validate_interface_list') @mock.patch('vmware_nsx.services.l2gateway.' 'nsx_v.driver.NsxvL2GatewayDriver._create_l2_gateway_edge') - @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' - 'L2GatewayMixin.create_l2_gateway') @mock.patch('vmware_nsx.services.l2gateway.' 'nsx_v.driver.NsxvL2GatewayDriver._edge_manager') - def test_create_l2_gateway(self, edge_manager, create_l2gw, - _create_l2gw_edge, + def test_create_l2_gateway(self, edge_manager, _create_l2gw_edge, val_inter, val_dev, _admin_check): fake_l2gw_dict = {"l2_gateway": {"tenant_id": "fake_teannt_id", @@ -130,19 +127,16 @@ class TestL2gatewayDriver(base.BaseTestCase): _admin_check.assert_called_with(self.context, 'CREATE') val_dev.assert_called_with(fake_devices) val_inter.assert_called_with(fake_interfaces) - create_l2gw.assert_called_with(self.context, fake_l2gw_dict) @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' 'L2GatewayMixin._admin_check') @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' 'L2GatewayMixin.get_l2_gateway_connection') - @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' - 'L2GatewayMixin.delete_l2_gateway_connection') @mock.patch('vmware_nsx.services.l2gateway.' 'nsx_v.driver.NsxvL2GatewayDriver._get_device') @mock.patch('vmware_nsx.services.l2gateway.' 'nsx_v.driver.NsxvL2GatewayDriver._nsxv') - def test_delete_l2_gateway_connection(self, nsxv, get_devices, del_conn, + def test_delete_l2_gateway_connection(self, nsxv, get_devices, get_conn, admin_check): fake_conn_dict = {'l2_gateway_id': 'fake_l2gw_id'} fake_device_dict = {'id': 'fake_dev_id', @@ -154,7 +148,6 @@ class TestL2gatewayDriver(base.BaseTestCase): get_conn.assert_called_with(self.context, fake_conn_dict) get_devices.assert_called_with(self.context, 'fake_l2gw_id') self.plugin._nsxv().del_bridge.asert_called_with('fake_dev_name') - del_conn.assert_called_with(self.context, fake_conn_dict) @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' 'L2GatewayMixin._admin_check') @@ -162,11 +155,9 @@ class TestL2gatewayDriver(base.BaseTestCase): 'nsx_v.driver.NsxvL2GatewayDriver._get_device') @mock.patch('vmware_nsx.db.' 'nsxv_db.get_nsxv_router_binding_by_edge') - @mock.patch('networking_l2gw.db.l2gateway.l2gateway_db.' - 'L2GatewayMixin.delete_l2_gateway') @mock.patch('vmware_nsx.services.l2gateway.' 'nsx_v.driver.NsxvL2GatewayDriver._edge_manager') - def test_delete_l2_gateway(self, edge_manager, del_l2gw, get_nsxv_router, + def test_delete_l2_gateway(self, edge_manager, get_nsxv_router, get_devices, admin_check): fake_device_dict = {"id": "fake_dev_id", "device_name": "fake_edge_name", @@ -177,6 +168,5 @@ class TestL2gatewayDriver(base.BaseTestCase): self.plugin.delete_l2_gateway(self.context, 'fake_l2gw_id') admin_check.assert_called_with(self.context, 'DELETE') get_devices.assert_called_with(self.context, 'fake_l2gw_id') - del_l2gw.assert_called_with(self.context, 'fake_l2gw_id') get_nsxv_router.assert_called_with(self.context.session, "fake_edge_name")