Merge "Add the ability to load a set of service plugins on startup"
This commit is contained in:
commit
92dcc59aa4
@ -30,6 +30,7 @@ from neutron._i18n import _, _LE, _LI, _LW
|
||||
from neutron.common import exceptions
|
||||
import neutron.extensions
|
||||
from neutron import manager
|
||||
from neutron.plugins.common import constants as const
|
||||
from neutron.services import provider_configuration
|
||||
from neutron import wsgi
|
||||
|
||||
@ -440,11 +441,18 @@ class ExtensionManager(object):
|
||||
# Exit loop as no progress was made
|
||||
break
|
||||
if exts_to_process:
|
||||
LOG.error(_LE("It was impossible to process the following "
|
||||
"extensions: %s because of missing requirements."),
|
||||
','.join(exts_to_process.keys()))
|
||||
raise exceptions.ExtensionsNotFound(
|
||||
extensions=list(exts_to_process.keys()))
|
||||
unloadable_extensions = set(exts_to_process.keys())
|
||||
LOG.error(_LE("Unable to process extensions (%s) because "
|
||||
"the configured plugins do not satisfy "
|
||||
"their requirements. Some features will not "
|
||||
"work as expected."),
|
||||
', '.join(unloadable_extensions))
|
||||
# Fail gracefully for default extensions, just in case some out
|
||||
# of tree plugins are not entirely up to speed
|
||||
default_extensions = set(const.DEFAULT_SERVICE_PLUGINS.values())
|
||||
if not unloadable_extensions <= default_extensions:
|
||||
raise exceptions.ExtensionsNotFound(
|
||||
extensions=list(unloadable_extensions))
|
||||
|
||||
# Extending extensions' attributes map.
|
||||
for ext in processed_exts.values():
|
||||
|
@ -161,6 +161,10 @@ class NeutronManager(object):
|
||||
LOG.info(_LI("Service %s is supported by the core plugin"),
|
||||
service_type)
|
||||
|
||||
def _get_default_service_plugins(self):
|
||||
"""Get default service plugins to be loaded."""
|
||||
return constants.DEFAULT_SERVICE_PLUGINS.keys()
|
||||
|
||||
def _load_service_plugins(self):
|
||||
"""Loads service plugins.
|
||||
|
||||
@ -171,6 +175,7 @@ class NeutronManager(object):
|
||||
self._load_services_from_core_plugin()
|
||||
|
||||
plugin_providers = cfg.CONF.service_plugins
|
||||
plugin_providers.extend(self._get_default_service_plugins())
|
||||
LOG.debug("Loading service plugins: %s", plugin_providers)
|
||||
for provider in plugin_providers:
|
||||
if provider == '':
|
||||
|
@ -38,6 +38,11 @@ EXT_TO_SERVICE_MAPPING = {
|
||||
'qos': QOS,
|
||||
}
|
||||
|
||||
# Maps default service plugins entry points to their extension aliases
|
||||
DEFAULT_SERVICE_PLUGINS = {
|
||||
'auto_allocate': 'auto-allocated-topology',
|
||||
}
|
||||
|
||||
# Service operation status constants
|
||||
ACTIVE = "ACTIVE"
|
||||
DOWN = "DOWN"
|
||||
|
@ -350,6 +350,7 @@ class BaseTestCase(DietTestCase):
|
||||
cp = PluginFixture(core_plugin)
|
||||
self.useFixture(cp)
|
||||
self.patched_dhcp_periodic = cp.patched_dhcp_periodic
|
||||
self.patched_default_svc_plugins = cp.patched_default_svc_plugins
|
||||
|
||||
def setup_notification_driver(self, notification_driver=None):
|
||||
self.addCleanup(fake_notifier.reset)
|
||||
@ -365,6 +366,11 @@ class PluginFixture(fixtures.Fixture):
|
||||
self.core_plugin = core_plugin
|
||||
|
||||
def _setUp(self):
|
||||
# Do not load default service plugins in the testing framework
|
||||
# as all the mocking involved can cause havoc.
|
||||
self.default_svc_plugins_p = mock.patch(
|
||||
'neutron.manager.NeutronManager._get_default_service_plugins')
|
||||
self.patched_default_svc_plugins = self.default_svc_plugins_p.start()
|
||||
self.dhcp_periodic_p = mock.patch(
|
||||
'neutron.db.agentschedulers_db.DhcpAgentSchedulerDbMixin.'
|
||||
'start_periodic_dhcp_agent_status_check')
|
||||
|
@ -502,13 +502,21 @@ class RequestExtensionTest(base.BaseTestCase):
|
||||
|
||||
class ExtensionManagerTest(base.BaseTestCase):
|
||||
|
||||
def test_missing_required_extensions(self):
|
||||
def test_missing_required_extensions_raise_error(self):
|
||||
ext_mgr = extensions.ExtensionManager('')
|
||||
attr_map = {}
|
||||
ext_mgr.add_extension(ext_stubs.StubExtensionWithReqs('foo_alias'))
|
||||
self.assertRaises(exceptions.ExtensionsNotFound,
|
||||
ext_mgr.extend_resources, "2.0", attr_map)
|
||||
|
||||
def test_missing_required_extensions_gracefully_error(self):
|
||||
ext_mgr = extensions.ExtensionManager('')
|
||||
attr_map = {}
|
||||
default_ext = list(constants.DEFAULT_SERVICE_PLUGINS.values())[0]
|
||||
ext_mgr.add_extension(ext_stubs.StubExtensionWithReqs(default_ext))
|
||||
ext_mgr.extend_resources("2.0", attr_map)
|
||||
self.assertIn(default_ext, ext_mgr.extensions)
|
||||
|
||||
def test_invalid_extensions_are_not_registered(self):
|
||||
|
||||
class InvalidExtension(object):
|
||||
|
@ -111,6 +111,15 @@ class NeutronManagerTestCase(base.BaseTestCase):
|
||||
self.assertIn(constants.LOADBALANCER, svc_plugins.keys())
|
||||
self.assertIn(constants.DUMMY, svc_plugins.keys())
|
||||
|
||||
def test_load_default_service_plugins(self):
|
||||
self.patched_default_svc_plugins.return_value = {
|
||||
'neutron.tests.unit.dummy_plugin.DummyServicePlugin': 'DUMMY'
|
||||
}
|
||||
cfg.CONF.set_override("core_plugin", DB_PLUGIN_KLASS)
|
||||
mgr = manager.NeutronManager.get_instance()
|
||||
svc_plugins = mgr.get_service_plugins()
|
||||
self.assertIn('DUMMY', svc_plugins)
|
||||
|
||||
def test_post_plugin_validation(self):
|
||||
cfg.CONF.import_opt('dhcp_agents_per_network',
|
||||
'neutron.db.agentschedulers_db')
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
prelude: >
|
||||
The "get-me-a-network" feature simplifies the process
|
||||
for launching an instance with basic network connectivity
|
||||
(via an externally connected private tenant network).
|
||||
features:
|
||||
- Once Nova takes advantage of this feature, a user can
|
||||
launch an instance without explicitly provisioning
|
||||
network resources.
|
@ -76,6 +76,7 @@ neutron.service_plugins =
|
||||
neutron.services.vpn.plugin.VPNDriverPlugin = neutron_vpnaas.services.vpn.plugin:VPNDriverPlugin
|
||||
qos = neutron.services.qos.qos_plugin:QoSPlugin
|
||||
flavors = neutron.services.flavors.flavors_plugin:FlavorsPlugin
|
||||
auto_allocate = neutron.services.auto_allocate.plugin:Plugin
|
||||
neutron.qos.notification_drivers =
|
||||
message_queue = neutron.services.qos.notification_drivers.message_queue:RpcQosServiceNotificationDriver
|
||||
neutron.ml2.type_drivers =
|
||||
|
Loading…
Reference in New Issue
Block a user