[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
This commit is contained in:
Abhishek Raut 2016-05-11 15:24:56 -07:00
parent 03eea64ef9
commit ecbed5d940
6 changed files with 69 additions and 129 deletions

View File

@ -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=

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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")