]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
ML2: verify if required extension drivers are loaded
authorSławek Kapłoński <slawek@kaplonski.pl>
Sat, 5 Dec 2015 23:11:46 +0000 (00:11 +0100)
committerSławek Kapłoński <slawek@kaplonski.pl>
Wed, 13 Jan 2016 23:18:50 +0000 (00:18 +0100)
This change ensures extension drivers required by service plugins are loaded
when using ML2 plugin: we check that ML2 loads QoS extension driver when QoS
service plugin is enabled.

Change-Id: Ibf19e77b88ce34c58519ae157c852c9e2b30e31f
Closes-bug: #1496787

neutron/plugins/ml2/common/exceptions.py
neutron/plugins/ml2/extensions/qos.py
neutron/plugins/ml2/plugin.py
neutron/tests/fullstack/resources/config.py
neutron/tests/unit/plugins/ml2/test_plugin.py

index ae75c8c5c171daa7dba92477bb2996489a7f5e92..349a80e674fc2bff61e6b7b0eea4f2ad6e16c0f7 100644 (file)
@@ -27,3 +27,9 @@ class MechanismDriverError(exceptions.NeutronException):
 class ExtensionDriverError(exceptions.InvalidInput):
     """Extension driver call failed."""
     message = _("Extension %(driver)s failed.")
+
+
+class ExtensionDriverNotFound(exceptions.InvalidConfigurationOption):
+    """Required extension driver not found in ML2 config."""
+    message = _("Extension driver %(driver)s required for "
+                "service plugin %(service_plugin)s not found.")
index 4de7cf653a7b805c2895f7a18f7f17d288d34987..62c69a001b300928760f579a15c04567cc061c29 100644 (file)
@@ -21,6 +21,8 @@ from neutron.plugins.ml2 import driver_api as api
 
 LOG = logging.getLogger(__name__)
 
+QOS_EXT_DRIVER_ALIAS = 'qos'
+
 
 class QosExtensionDriver(api.ExtensionDriver):
 
index 3648deb8404100611ae20821374c69ebeee88093..f9efdf636a63201ec6cbdedc51f99278333b9437 100644 (file)
@@ -74,6 +74,7 @@ from neutron.plugins.ml2 import config  # noqa
 from neutron.plugins.ml2 import db
 from neutron.plugins.ml2 import driver_api as api
 from neutron.plugins.ml2 import driver_context
+from neutron.plugins.ml2.extensions import qos as qos_ext
 from neutron.plugins.ml2 import managers
 from neutron.plugins.ml2 import models
 from neutron.plugins.ml2 import rpc
@@ -85,6 +86,11 @@ LOG = log.getLogger(__name__)
 MAX_BIND_TRIES = 10
 
 
+SERVICE_PLUGINS_REQUIRED_DRIVERS = {
+    'qos': [qos_ext.QOS_EXT_DRIVER_ALIAS]
+}
+
+
 class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
                 dvr_mac_db.DVRDbMixin,
                 external_net_db.External_net_db_mixin,
@@ -152,6 +158,7 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
         self._setup_dhcp()
         self._start_rpc_notifiers()
         self.add_agent_status_check(self.agent_health_check)
+        self._verify_service_plugins_requirements()
         LOG.info(_LI("Modular L2 Plugin initialization complete"))
 
     def _setup_rpc(self):
@@ -173,6 +180,17 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
         )
         self.start_periodic_dhcp_agent_status_check()
 
+    def _verify_service_plugins_requirements(self):
+        for service_plugin in cfg.CONF.service_plugins:
+            extension_drivers = SERVICE_PLUGINS_REQUIRED_DRIVERS.get(
+                service_plugin, []
+            )
+            for extension_driver in extension_drivers:
+                if extension_driver not in self.extension_manager.names():
+                    raise ml2_exc.ExtensionDriverNotFound(
+                        driver=extension_driver, service_plugin=service_plugin
+                    )
+
     @property
     def supported_qos_rule_types(self):
         return self.mechanism_manager.supported_qos_rule_types
index 6384f0703e3d4d586c350e4439a75a9d6764a110..94d95e032ab9f42ac2596035d4e9dded5ee3ad85 100644 (file)
@@ -17,6 +17,7 @@ import tempfile
 import fixtures
 
 from neutron.common import constants
+from neutron.plugins.ml2.extensions import qos as qos_ext
 from neutron.tests import base
 from neutron.tests.common import config_fixtures
 from neutron.tests.common import helpers as c_helpers
@@ -134,7 +135,8 @@ class ML2ConfigFixture(ConfigFixture):
         })
 
         if env_desc.qos:
-            self.config['ml2']['extension_drivers'] = 'qos'
+            self.config['ml2']['extension_drivers'] =\
+                    qos_ext.QOS_EXT_DRIVER_ALIAS
 
 
 class OVSConfigFixture(ConfigFixture):
index 2d13438acd455586d31ad9c72b4af9bbb68c552d..d9bb281db95fdeeb60a5936ae6b056ffb3e84245 100644 (file)
@@ -759,6 +759,29 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
 class TestMl2PluginOnly(Ml2PluginV2TestCase):
     """For testing methods that don't call drivers"""
 
+    def test__verify_service_plugins_requirements(self):
+        plugin = manager.NeutronManager.get_plugin()
+        with mock.patch.dict(ml2_plugin.SERVICE_PLUGINS_REQUIRED_DRIVERS,
+                             {self.l3_plugin: self._mechanism_drivers}),\
+                mock.patch.object(plugin.extension_manager,
+                                  'names',
+                                  return_value=self._mechanism_drivers):
+
+            plugin._verify_service_plugins_requirements()
+
+    def test__verify_service_plugins_requirements_missing_driver(self):
+        plugin = manager.NeutronManager.get_plugin()
+        with mock.patch.dict(ml2_plugin.SERVICE_PLUGINS_REQUIRED_DRIVERS,
+                             {self.l3_plugin: ['test_required_driver']}),\
+                mock.patch.object(plugin.extension_manager,
+                                  'names',
+                                  return_value=self._mechanism_drivers):
+
+            self.assertRaises(
+                ml2_exc.ExtensionDriverNotFound,
+                plugin._verify_service_plugins_requirements
+            )
+
     def _test_check_mac_update_allowed(self, vif_type, expect_change=True):
         plugin = manager.NeutronManager.get_plugin()
         port = {'mac_address': "fake_mac", 'id': "fake_id"}