From 06ba6a1aceb8dd2c6df3b243bddb15ef8a8af27d Mon Sep 17 00:00:00 2001 From: ZhaoBo Date: Tue, 23 Oct 2018 15:18:11 +0800 Subject: [PATCH] Only store segmenthostmapping when enable segment plugin This patch adds a check to determine if the 'segments' service plugin is enabled. The segment-host mapping db table should only be saved and updated to the db table if the users configure the 'segments' service plugin in the config file. The data should be available only in a routed network resource situation. Change-Id: I65a42aa2129bef696906a18d82575461dc02ba21 Closes-Bug: #1799328 --- neutron/services/segments/db.py | 27 ++++++++++++- neutron/tests/unit/extensions/test_segment.py | 38 +++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/neutron/services/segments/db.py b/neutron/services/segments/db.py index 8c844fbcc04..af8f1489276 100644 --- a/neutron/services/segments/db.py +++ b/neutron/services/segments/db.py @@ -23,6 +23,7 @@ from neutron_lib.db import utils as db_utils from neutron_lib import exceptions as n_exc from neutron_lib.plugins import directory from oslo_concurrency import lockutils +from oslo_config import cfg from oslo_db import exception as db_exc from oslo_log import helpers as log_helpers from oslo_utils import uuidutils @@ -37,6 +38,26 @@ from neutron.objects import network from neutron.services.segments import exceptions +_USER_CONFIGURED_SEGMENT_PLUGIN = None + + +def check_user_configured_segment_plugin(): + global _USER_CONFIGURED_SEGMENT_PLUGIN + # _USER_CONFIGURED_SEGMENT_PLUGIN will contain 3 possible values: + # 1. None, this just happens during neutron-server startup. + # 2. True, this means that users configure the 'segments' + # service plugin in neutron config file. + # 3. False, this means that can not find 'segments' service + # plugin in neutron config file. + # This function just load once to store the result + # into _USER_CONFIGURED_SEGMENT_PLUGIN during neutron-server startup. + if _USER_CONFIGURED_SEGMENT_PLUGIN is None: + segment_class = 'neutron.services.segments.plugin.Plugin' + _USER_CONFIGURED_SEGMENT_PLUGIN = any( + p in cfg.CONF.service_plugins for p in ['segments', segment_class]) + return _USER_CONFIGURED_SEGMENT_PLUGIN + + class SegmentDbMixin(common_db_mixin.CommonDbMixin): """Mixin class to add segment.""" @@ -258,7 +279,8 @@ def _update_segment_host_mapping_for_agent(resource, event, trigger, context, host, plugin, agent, status): check_segment_for_agent = getattr(plugin, 'check_segment_for_agent', None) - if not check_segment_for_agent: + if (not check_user_configured_segment_plugin() or + not check_segment_for_agent): return phys_nets = _get_phys_nets(agent) if not phys_nets: @@ -289,7 +311,8 @@ def _add_segment_host_mapping_for_segment(resource, event, trigger, return cp = directory.get_plugin() check_segment_for_agent = getattr(cp, 'check_segment_for_agent', None) - if not hasattr(cp, 'get_agents') or not check_segment_for_agent: + if not check_user_configured_segment_plugin() or not hasattr( + cp, 'get_agents') or not check_segment_for_agent: # not an agent-supporting plugin registry.unsubscribe(_add_segment_host_mapping_for_segment, resources.SEGMENT, events.PRECOMMIT_CREATE) diff --git a/neutron/tests/unit/extensions/test_segment.py b/neutron/tests/unit/extensions/test_segment.py index c56e9ba8bc4..49f13153e94 100644 --- a/neutron/tests/unit/extensions/test_segment.py +++ b/neutron/tests/unit/extensions/test_segment.py @@ -84,6 +84,7 @@ class SegmentTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase): if not plugin: plugin = TEST_PLUGIN_KLASS service_plugins = {'segments_plugin_name': SERVICE_PLUGIN_KLASS} + cfg.CONF.set_override('service_plugins', [SERVICE_PLUGIN_KLASS]) ext_mgr = SegmentTestExtensionManager() super(SegmentTestCase, self).setUp(plugin=plugin, ext_mgr=ext_mgr, service_plugins=service_plugins) @@ -2661,3 +2662,40 @@ class TestSegmentHostRoutes(TestSegmentML2): self.assertIn(sub_res['gateway_ip'], gateway_ips) self.assertEqual(len(sub_res['host_routes']), 1) self.assertIn(sub_res['host_routes'][0], host_routes) + + +class TestSegmentHostMappingNoStore( + test_db_base_plugin_v2.NeutronDbPluginV2TestCase): + + def setUp(self): + driver_type.register_ml2_drivers_vlan_opts() + cfg.CONF.set_override('network_vlan_ranges', ['phys_net1'], + group='ml2_type_vlan') + cfg.CONF.set_override('service_plugins', []) + super(TestSegmentHostMappingNoStore, self).setUp( + plugin='neutron.plugins.ml2.plugin.Ml2Plugin') + # set to None for simulating server start + db._USER_CONFIGURED_SEGMENT_PLUGIN = None + db.subscribe() + + @mock.patch('neutron.services.segments.db.update_segment_host_mapping') + @mock.patch('neutron.services.segments.db.map_segment_to_hosts') + def test_no_segmenthostmapping_when_disable_segment( + self, mock_map_segment_to_hosts, mock_update_segment_mapping): + with self.network( + arg_list=('provider:network_type', + 'provider:physical_network', + 'provider:segmentation_id'), + **{'provider:network_type': 'vlan', + 'provider:physical_network': 'phys_net1', + 'provider:segmentation_id': '400'}) as network: + network['network'] + mock_map_segment_to_hosts.assert_not_called() + + host1 = 'test_host' + physical_network = 'phys_net1' + helpers.register_ovs_agent( + host=host1, + bridge_mappings={physical_network: 'br-eth-1'}, + plugin=self.plugin) + mock_update_segment_mapping.assert_not_called()