From 4757ccfc8eb10bee756deb36c72d7a7ca37bdbff Mon Sep 17 00:00:00 2001 From: armando-migliaccio Date: Fri, 13 Sep 2013 13:34:00 -0700 Subject: [PATCH] Redefine behavior for NvpAdvancedPlugin during network creation When using the NvpAdvancedPlugin, *all* logical switches should be created through VCNS. VCNS will then proxy the requests to NVP. This patch implements such a behavior. This is achieved by replacing the use of nvplib.create_lswitch with the one of the vcns driver, as the remaining logic can be left as it is. Fixes bug #1225011 Change-Id: I6c276f747d02ac0d4934c38bf2858cf9b73c5e24 --- .../plugins/nicira/NeutronServicePlugin.py | 34 ++++++++ .../nicira/vshield/edge_appliance_driver.py | 11 ++- neutron/tests/unit/nicira/test_edge_router.py | 85 +++++++++++++++++++ 3 files changed, 126 insertions(+), 4 deletions(-) diff --git a/neutron/plugins/nicira/NeutronServicePlugin.py b/neutron/plugins/nicira/NeutronServicePlugin.py index 576e04730..2480bb15a 100644 --- a/neutron/plugins/nicira/NeutronServicePlugin.py +++ b/neutron/plugins/nicira/NeutronServicePlugin.py @@ -107,6 +107,21 @@ class NvpAdvancedPlugin(sr_db.ServiceRouter_mixin, # load the vCNS driver self._load_vcns_drivers() + # nvplib's create_lswitch needs to be replaced in order to proxy + # logical switch create requests to vcns + self._set_create_lswitch_proxy() + + def _set_create_lswitch_proxy(self): + NeutronPlugin.nvplib.create_lswitch = self._proxy_create_lswitch + + def _proxy_create_lswitch(self, *args, **kwargs): + name, tz_config, tags = ( + _process_base_create_lswitch_args(*args, **kwargs) + ) + return self.vcns_driver.create_lswitch( + name, tz_config, tags=tags, + port_isolation=None, replication_mode=None) + def _load_vcns_drivers(self): self.vcns_driver = vcns_driver.VcnsDriver(self.callbacks) @@ -1578,3 +1593,22 @@ class VcnsCallbacks(object): def nat_update_result(self, task): LOG.debug(_("nat_update_result %d"), task.status) + + +def _process_base_create_lswitch_args(*args, **kwargs): + tags = [{"tag": nvplib.NEUTRON_VERSION, "scope": "quantum"}] + if args[1]: + tags.append({"tag": args[1], "scope": "os_tid"}) + switch_name = args[2] + tz_config = args[3] + if "neutron_net_id" in kwargs or len(args) >= 5: + neutron_net_id = kwargs.get('neutron_net_id') + if neutron_net_id is None: + neutron_net_id = args[4] + tags.append({"tag": neutron_net_id, + "scope": "quantum_net_id"}) + if kwargs.get("shared", False) or len(args) >= 6: + tags.append({"tag": "true", "scope": "shared"}) + if kwargs.get("tags"): + tags.extend(kwargs["tags"]) + return switch_name, tz_config, tags diff --git a/neutron/plugins/nicira/vshield/edge_appliance_driver.py b/neutron/plugins/nicira/vshield/edge_appliance_driver.py index fe3128133..54ad0033f 100644 --- a/neutron/plugins/nicira/vshield/edge_appliance_driver.py +++ b/neutron/plugins/nicira/vshield/edge_appliance_driver.py @@ -624,16 +624,19 @@ class EdgeApplianceDriver(object): self.task_manager.add(task) return task - def create_lswitch(self, name, tz_config): + def create_lswitch(self, name, tz_config, tags=None, + port_isolation=False, replication_mode="service"): lsconfig = { 'display_name': utils.check_and_truncate(name), - "tags": [], + "tags": tags or [], "type": "LogicalSwitchConfig", "_schema": "/ws.v1/schema/LogicalSwitchConfig", - "port_isolation_enabled": False, - "replication_mode": "service", "transport_zones": tz_config } + if port_isolation is bool: + lsconfig["port_isolation_enabled"] = port_isolation + if replication_mode: + lsconfig["replication_mode"] = replication_mode response = self.vcns.create_lswitch(lsconfig)[1] return response diff --git a/neutron/tests/unit/nicira/test_edge_router.py b/neutron/tests/unit/nicira/test_edge_router.py index ad772d77a..d7659c25d 100644 --- a/neutron/tests/unit/nicira/test_edge_router.py +++ b/neutron/tests/unit/nicira/test_edge_router.py @@ -26,6 +26,9 @@ from neutron import context from neutron.extensions import l3 from neutron.manager import NeutronManager from neutron.openstack.common import uuidutils +from neutron.plugins.nicira import NeutronServicePlugin as nsp +from neutron.plugins.nicira import nvplib +from neutron.tests import base from neutron.tests.unit.nicira import NVPEXT_PATH from neutron.tests.unit.nicira import SERVICE_PLUGIN_NAME from neutron.tests.unit.nicira import test_nicira_plugin @@ -64,6 +67,11 @@ class NvpRouterTestCase(test_nicira_plugin.TestNiciraL3NatTestCase): def setUp(self, plugin=None, ext_mgr=None, service_plugins=None): plugin = plugin or SERVICE_PLUGIN_NAME + # Disable the proxying in the tests but functionality will + # be covered separately + mock_proxy = mock.patch( + "%s.%s" % (SERVICE_PLUGIN_NAME, '_set_create_lswitch_proxy')) + mock_proxy.start() super(NvpRouterTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins) @@ -110,6 +118,9 @@ class ServiceRouterTest(test_nicira_plugin.NiciraL3NatTest, self.fc2 = fake_vcns.FakeVcns(unique_router_name=False) self.mock_vcns = mock.patch(VCNS_NAME, autospec=True) self.vcns_patch() + mock_proxy = mock.patch( + "%s.%s" % (SERVICE_PLUGIN_NAME, '_set_create_lswitch_proxy')) + mock_proxy.start() ext_mgr = ext_mgr or ServiceRouterTestExtensionManager() super(ServiceRouterTest, self).setUp( @@ -219,3 +230,77 @@ class ServiceRouterTestCase(ServiceRouterTest, NvpRouterTestCase): super(ServiceRouterTestCase, self)._test_router_update_gateway_on_l3_ext_net( vlan_id, validate_ext_gw=False) + + +class TestProxyCreateLswitch(base.BaseTestCase): + def setUp(self): + super(TestProxyCreateLswitch, self).setUp() + self.tenant_id = "foo_tenant" + self.display_name = "foo_network" + self.tz_config = [ + {'zone_uuid': 'foo_zone', + 'transport_type': 'stt'} + ] + self.tags = [ + {'scope': 'quantum', 'tag': nvplib.NEUTRON_VERSION}, + {'scope': 'os_tid', 'tag': self.tenant_id} + ] + self.cluster = None + + def test_create_lswitch_with_basic_args(self): + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config) + self.assertEqual(self.display_name, result[0]) + self.assertEqual(self.tz_config, result[1]) + self.assertEqual(self.tags, result[2]) + + def test_create_lswitch_with_neutron_net_id_as_kwarg(self): + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config, + neutron_net_id='foo') + expected = self.tags + [{'scope': 'quantum_net_id', 'tag': 'foo'}] + self.assertEqual(expected, result[2]) + + def test_create_lswitch_with_neutron_net_id_as_arg(self): + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config, + 'foo') + expected = self.tags + [{'scope': 'quantum_net_id', 'tag': 'foo'}] + self.assertEqual(expected, result[2]) + + def test_create_lswitch_with_shared_as_kwarg(self): + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config, + shared=True) + expected = self.tags + [{'scope': 'shared', 'tag': 'true'}] + self.assertEqual(expected, result[2]) + + def test_create_lswitch_with_shared_as_arg(self): + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config, + 'foo', + True) + additional_tags = [{'scope': 'quantum_net_id', 'tag': 'foo'}, + {'scope': 'shared', 'tag': 'true'}] + expected = self.tags + additional_tags + self.assertEqual(expected, result[2]) + + def test_create_lswitch_with_additional_tags(self): + more_tags = [{'scope': 'foo_scope', 'tag': 'foo_tag'}] + result = nsp._process_base_create_lswitch_args(self.cluster, + self.tenant_id, + self.display_name, + self.tz_config, + tags=more_tags) + expected = self.tags + more_tags + self.assertEqual(expected, result[2]) -- 2.45.2