From: Sławek Kapłoński Date: Sat, 5 Dec 2015 23:11:46 +0000 (+0100) Subject: ML2: verify if required extension drivers are loaded X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=c615c6f3a7a05dac8684366dde78080f347964dd;p=openstack-build%2Fneutron-build.git ML2: verify if required extension drivers are loaded 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 --- diff --git a/neutron/plugins/ml2/common/exceptions.py b/neutron/plugins/ml2/common/exceptions.py index ae75c8c5c..349a80e67 100644 --- a/neutron/plugins/ml2/common/exceptions.py +++ b/neutron/plugins/ml2/common/exceptions.py @@ -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.") diff --git a/neutron/plugins/ml2/extensions/qos.py b/neutron/plugins/ml2/extensions/qos.py index 4de7cf653..62c69a001 100644 --- a/neutron/plugins/ml2/extensions/qos.py +++ b/neutron/plugins/ml2/extensions/qos.py @@ -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): diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 3648deb84..f9efdf636 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -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 diff --git a/neutron/tests/fullstack/resources/config.py b/neutron/tests/fullstack/resources/config.py index 6384f0703..94d95e032 100644 --- a/neutron/tests/fullstack/resources/config.py +++ b/neutron/tests/fullstack/resources/config.py @@ -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): diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index 2d13438ac..d9bb281db 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -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"}