diff --git a/neutron/api/extensions.py b/neutron/api/extensions.py index 1246087f90d..cc4074b705c 100644 --- a/neutron/api/extensions.py +++ b/neutron/api/extensions.py @@ -27,10 +27,10 @@ import webob.dec import webob.exc from neutron.common import exceptions -from neutron.common import repos import neutron.extensions from neutron.i18n import _LE, _LI, _LW from neutron import manager +from neutron.services import provider_configuration from neutron import wsgi @@ -579,8 +579,9 @@ class PluginAwareExtensionManager(ExtensionManager): @classmethod def get_instance(cls): if cls._instance is None: - cls._instance = cls(get_extensions_path(), - manager.NeutronManager.get_service_plugins()) + service_plugins = manager.NeutronManager.get_service_plugins() + cls._instance = cls(get_extensions_path(service_plugins), + service_plugins) return cls._instance def get_supported_extension_aliases(self): @@ -647,31 +648,30 @@ class ResourceExtension(object): # Returns the extension paths from a config entry and the __path__ # of neutron.extensions -def get_extensions_path(): - paths = neutron.extensions.__path__ +def get_extensions_path(service_plugins=None): + paths = collections.OrderedDict() - neutron_mods = repos.NeutronModules() - for x in neutron_mods.installed_list(): - try: - paths += neutron_mods.module(x).extensions.__path__ - except AttributeError: - # Occurs normally if module has no extensions sub-module - pass + # Add Neutron core extensions + paths[neutron.extensions.__path__[0]] = 1 + if service_plugins: + # Add Neutron *-aas extensions + for plugin in service_plugins.values(): + neutron_mod = provider_configuration.NeutronModule( + plugin.__module__.split('.')[0]) + try: + paths[neutron_mod.module().extensions.__path__[0]] = 1 + except AttributeError: + # Occurs normally if module has no extensions sub-module + pass + # Add external/other plugins extensions if cfg.CONF.api_extensions_path: - paths.append(cfg.CONF.api_extensions_path) - - # If the path has dups in it, from discovery + conf file, the duplicate - # import of the same module and super() do not play nicely, so weed - # out the duplicates, preserving search order. - - z = collections.OrderedDict() - for x in paths: - z[x] = 1 - paths = z.keys() + for path in cfg.CONF.api_extensions_path.split(":"): + paths[path] = 1 LOG.debug("get_extension_paths = %s", paths) + # Re-build the extension string path = ':'.join(paths) return path diff --git a/neutron/common/repos.py b/neutron/common/repos.py deleted file mode 100644 index 2bd15737e56..00000000000 --- a/neutron/common/repos.py +++ /dev/null @@ -1,99 +0,0 @@ -# Copyright (c) 2015, A10 Networks -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import importlib -import os - -from oslo_config import cfg -from oslo_log import log as logging -from six.moves import configparser as ConfigParser - -LOG = logging.getLogger(__name__) - - -class NeutronModules(object): - - MODULES = { - 'neutron_fwaas': { - 'alembic-name': 'fwaas', - }, - 'neutron_lbaas': { - 'alembic-name': 'lbaas', - }, - 'neutron_vpnaas': { - 'alembic-name': 'vpnaas', - }, - } - - def __init__(self): - self.repos = {} - for repo in self.MODULES: - self.repos[repo] = {} - self.repos[repo]['mod'] = self._import_or_none(repo) - self.repos[repo]['ini'] = None - - def _import_or_none(self, module): - try: - return importlib.import_module(module) - except ImportError: - return None - - def installed_list(self): - z = filter(lambda k: self.repos[k]['mod'] is not None, self.repos) - LOG.debug("NeutronModules related repos installed = %s", z) - return z - - def module(self, module): - return self.repos[module]['mod'] - - def alembic_name(self, module): - return self.MODULES[module]['alembic-name'] - - # Return an INI parser for the child module. oslo.config is a bit too - # magical in its INI loading, and in one notable case, we need to merge - # together the [service_providers] section across at least four - # repositories. - def ini(self, module): - if self.repos[module]['ini'] is None: - neutron_dir = None - try: - neutron_dir = cfg.CONF.config_dir - except cfg.NoSuchOptError: - pass - - if neutron_dir is None: - neutron_dir = '/etc/neutron' - - ini = ConfigParser.SafeConfigParser() - ini_path = os.path.join(neutron_dir, '%s.conf' % module) - if os.path.exists(ini_path): - ini.read(ini_path) - - self.repos[module]['ini'] = ini - - return self.repos[module]['ini'] - - def service_providers(self, module): - ini = self.ini(module) - - sp = [] - try: - for name, value in ini.items('service_providers'): - if name == 'service_provider': - sp.append(value) - except ConfigParser.NoSectionError: - pass - - return sp diff --git a/neutron/db/servicetype_db.py b/neutron/db/servicetype_db.py index 46a9a944817..0ef4f409a4a 100644 --- a/neutron/db/servicetype_db.py +++ b/neutron/db/servicetype_db.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +from itertools import chain + from oslo_log import log as logging import sqlalchemy as sa @@ -42,14 +44,36 @@ class ServiceTypeManager(object): return cls._instance def __init__(self): - self._load_conf() + self.config = {} + # TODO(armax): remove these as soon as *-aaS start using + # the newly introduced add_provider_configuration API + self.config['LOADBALANCER'] = ( + pconf.ProviderConfiguration('neutron_lbaas')) + self.config['LOADBALANCERV2'] = ( + pconf.ProviderConfiguration('neutron_lbaas')) + self.config['FIREWALL'] = ( + pconf.ProviderConfiguration('neutron_fwaas')) + self.config['VPN'] = ( + pconf.ProviderConfiguration('neutron_vpnaas')) - def _load_conf(self): - self.conf = pconf.ProviderConfiguration( - pconf.parse_service_provider_opt()) + def add_provider_configuration(self, service_type, configuration): + """Add or update the provider configuration for the service type.""" + LOG.debug('Adding provider configuration for service %s', service_type) + self.config.update({service_type: configuration}) def get_service_providers(self, context, filters=None, fields=None): - return self.conf.get_service_providers(filters, fields) + if filters and 'service_type' in filters: + return list( + chain.from_iterable(self.config[svc_type]. + get_service_providers(filters, fields) + for svc_type in filters['service_type'] + if svc_type in self.config) + ) + return list( + chain.from_iterable( + self.config[p].get_service_providers(filters, fields) + for p in self.config) + ) def get_default_service_provider(self, context, service_type): """Return the default provider for a given service type.""" @@ -65,7 +89,7 @@ class ServiceTypeManager(object): def add_resource_association(self, context, service_type, provider_name, resource_id): - r = self.conf.get_service_providers( + r = self.get_service_providers(context, filters={'service_type': [service_type], 'name': [provider_name]}) if not r: raise pconf.ServiceProviderNotFound(provider=provider_name, diff --git a/neutron/services/provider_configuration.py b/neutron/services/provider_configuration.py index 938644f8c47..b4c03cbada6 100644 --- a/neutron/services/provider_configuration.py +++ b/neutron/services/provider_configuration.py @@ -13,14 +13,16 @@ # License for the specific language governing permissions and limitations # under the License. +import importlib +import os + from oslo_config import cfg from oslo_log import log as logging +from six.moves import configparser as ConfigParser import stevedore from neutron.common import exceptions as n_exc -from neutron.common import repos from neutron.i18n import _LW -from neutron.plugins.common import constants LOG = logging.getLogger(__name__) @@ -36,6 +38,67 @@ serviceprovider_opts = [ cfg.CONF.register_opts(serviceprovider_opts, 'service_providers') +class NeutronModule(object): + """A Neutron extension module.""" + + def __init__(self, service_module): + self.module_name = service_module + self.repo = { + 'mod': self._import_or_none(), + 'ini': None + } + + def _import_or_none(self): + try: + return importlib.import_module(self.module_name) + except ImportError: + return None + + def installed(self): + LOG.debug("NeutronModule installed = %s", self.module_name) + return self.module_name + + def module(self): + return self.repo['mod'] + + # Return an INI parser for the child module. oslo.config is a bit too + # magical in its INI loading, and in one notable case, we need to merge + # together the [service_providers] section across at least four + # repositories. + def ini(self): + if self.repo['ini'] is None: + neutron_dir = None + try: + neutron_dir = cfg.CONF.config_dir + except cfg.NoSuchOptError: + pass + + if neutron_dir is None: + neutron_dir = '/etc/neutron' + + ini = ConfigParser.SafeConfigParser() + ini_path = os.path.join(neutron_dir, '%s.conf' % self.module_name) + if os.path.exists(ini_path): + ini.read(ini_path) + + self.repo['ini'] = ini + + return self.repo['ini'] + + def service_providers(self): + ini = self.ini() + + sp = [] + try: + for name, value in ini.items('service_providers'): + if name == 'service_provider': + sp.append(value) + except ConfigParser.NoSectionError: + pass + + return sp + + #global scope function that should be used in service APIs def normalize_provider_name(name): return name.lower() @@ -65,32 +128,16 @@ def get_provider_driver_class(driver, namespace=SERVICE_PROVIDERS): return new_driver -def parse_service_provider_opt(): +def parse_service_provider_opt(service_module='neutron'): + """Parse service definition opts and returns result.""" def validate_name(name): if len(name) > 255: raise n_exc.Invalid( _("Provider name is limited by 255 characters: %s") % name) - # TODO(dougwig) - phase out the neutron.conf location for service - # providers a cycle or two after Kilo. - - # Look in neutron.conf for service providers first (legacy mode) - try: - svc_providers_opt = cfg.CONF.service_providers.service_provider - except cfg.NoSuchOptError: - svc_providers_opt = [] - - # Look in neutron-*aas.conf files for service provider configs - if svc_providers_opt: - LOG.warning(_LW("Reading service_providers from legacy location in " - "neutron.conf, and ignoring values in " - "neutron_*aas.conf files; this override will be " - "going away soon.")) - else: - neutron_mods = repos.NeutronModules() - for x in neutron_mods.installed_list(): - svc_providers_opt += neutron_mods.service_providers(x) + neutron_mod = NeutronModule(service_module) + svc_providers_opt = neutron_mod.service_providers() LOG.debug("Service providers = %s", svc_providers_opt) @@ -113,14 +160,7 @@ def parse_service_provider_opt(): prov_def) LOG.error(msg) raise n_exc.Invalid(msg) - ALLOWED_SERVICES = constants.EXT_TO_SERVICE_MAPPING.values() - if svc_type not in ALLOWED_SERVICES: - msg = (_("Service type '%(svc_type)s' is not allowed, " - "allowed types: %(allowed)s") % - {'svc_type': svc_type, - 'allowed': ALLOWED_SERVICES}) - LOG.error(msg) - raise n_exc.Invalid(msg) + driver = get_provider_driver_class(driver) res.append({'service_type': svc_type, 'name': name, @@ -145,9 +185,10 @@ class ServiceProviderAlreadyAssociated(n_exc.Conflict): class ProviderConfiguration(object): - def __init__(self, prov_data): + + def __init__(self, svc_module='neutron'): self.providers = {} - for prov in prov_data: + for prov in parse_service_provider_opt(svc_module): self.add_provider(prov) def _ensure_driver_unique(self, driver): diff --git a/neutron/tests/unit/api/test_extensions.py b/neutron/tests/unit/api/test_extensions.py index 0aacc316ba8..69093f2bf8d 100644 --- a/neutron/tests/unit/api/test_extensions.py +++ b/neutron/tests/unit/api/test_extensions.py @@ -67,6 +67,40 @@ class FakePluginWithExtension(object): self._log("method_to_support_foxnsox_extension", context) +class ExtensionPathTest(base.BaseTestCase): + + def setUp(self): + self.base_path = extensions.get_extensions_path() + super(ExtensionPathTest, self).setUp() + + def test_get_extensions_path_with_plugins(self): + path = extensions.get_extensions_path( + {constants.CORE: FakePluginWithExtension()}) + self.assertEqual(path, + '%s:neutron/tests/unit/extensions' % self.base_path) + + def test_get_extensions_path_no_extensions(self): + # Reset to default value, as it's overriden by base class + cfg.CONF.set_override('api_extensions_path', '') + path = extensions.get_extensions_path() + self.assertEqual(path, self.base_path) + + def test_get_extensions_path_single_extension(self): + cfg.CONF.set_override('api_extensions_path', 'path1') + path = extensions.get_extensions_path() + self.assertEqual(path, '%s:path1' % self.base_path) + + def test_get_extensions_path_multiple_extensions(self): + cfg.CONF.set_override('api_extensions_path', 'path1:path2') + path = extensions.get_extensions_path() + self.assertEqual(path, '%s:path1:path2' % self.base_path) + + def test_get_extensions_path_duplicate_extensions(self): + cfg.CONF.set_override('api_extensions_path', 'path1:path1') + path = extensions.get_extensions_path() + self.assertEqual(path, '%s:path1' % self.base_path) + + class PluginInterfaceTest(base.BaseTestCase): def test_issubclass_hook(self): class A(object): diff --git a/neutron/tests/unit/extensions/test_servicetype.py b/neutron/tests/unit/extensions/test_servicetype.py index 13eab8fa2e6..53e23dfaec2 100644 --- a/neutron/tests/unit/extensions/test_servicetype.py +++ b/neutron/tests/unit/extensions/test_servicetype.py @@ -38,65 +38,63 @@ _get_path = test_base._get_path class ServiceTypeManagerTestCase(testlib_api.SqlTestCase): def setUp(self): + self.service_providers = mock.patch.object( + provconf.NeutronModule, 'service_providers').start() super(ServiceTypeManagerTestCase, self).setUp() - st_db.ServiceTypeManager._instance = None - self.manager = st_db.ServiceTypeManager.get_instance() self.ctx = context.get_admin_context() + def _set_override(self, service_providers): + self.service_providers.return_value = service_providers + st_db.ServiceTypeManager._instance = None + self.manager = st_db.ServiceTypeManager.get_instance() + for provider in service_providers: + self.manager.add_provider_configuration( + provider.split(':')[0], provconf.ProviderConfiguration()) + def test_service_provider_driver_not_unique(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver'], - 'service_providers') + self._set_override([constants.LOADBALANCER + ':lbaas:driver']) prov = {'service_type': constants.LOADBALANCER, 'name': 'name2', 'driver': 'driver', 'default': False} - self.manager._load_conf() self.assertRaises( - n_exc.Invalid, self.manager.conf.add_provider, prov) + n_exc.Invalid, + self.manager.config['LOADBALANCER'].add_provider, prov) def test_get_service_providers(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.DUMMY + ':dummy:dummy_dr'], - 'service_providers') + """Test that get_service_providers filters correctly.""" + self._set_override( + [constants.LOADBALANCER + + ':lbaas:driver_path1', + constants.FIREWALL + + ':fwaas:driver_path2']) ctx = context.get_admin_context() - provconf.parse_service_provider_opt() - self.manager._load_conf() - res = self.manager.get_service_providers(ctx) - self.assertEqual(len(res), 2) - - res = self.manager.get_service_providers( - ctx, - filters=dict(service_type=[constants.DUMMY]) - ) - self.assertEqual(len(res), 1) - res = self.manager.get_service_providers( ctx, filters=dict(service_type=[constants.LOADBALANCER]) ) self.assertEqual(len(res), 1) + res = self.manager.get_service_providers( + ctx, + filters=dict(service_type=[constants.FIREWALL]) + ) + self.assertEqual(len(res), 1) + def test_multiple_default_providers_specified_for_service(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.LOADBALANCER + - ':lbaas2:driver_path:default'], - 'service_providers') - self.assertRaises(n_exc.Invalid, self.manager._load_conf) + self.assertRaises( + n_exc.Invalid, + self._set_override, + [constants.LOADBALANCER + + ':lbaas1:driver_path:default', + constants.LOADBALANCER + + ':lbaas2:driver_path:default']) def test_get_default_provider(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() + self._set_override([constants.LOADBALANCER + + ':lbaas1:driver_path:default', + constants.DUMMY + + ':lbaas2:driver_path2']) # can pass None as a context p = self.manager.get_default_service_provider(None, constants.LOADBALANCER) @@ -112,13 +110,10 @@ class ServiceTypeManagerTestCase(testlib_api.SqlTestCase): ) def test_add_resource_association(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() + self._set_override([constants.LOADBALANCER + + ':lbaas1:driver_path:default', + constants.DUMMY + + ':lbaas2:driver_path2']) ctx = context.get_admin_context() self.manager.add_resource_association(ctx, constants.LOADBALANCER, @@ -130,13 +125,10 @@ class ServiceTypeManagerTestCase(testlib_api.SqlTestCase): ctx.session.delete(assoc) def test_invalid_resource_association(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas1:driver_path:default', - constants.DUMMY + - ':lbaas2:driver_path2'], - 'service_providers') - self.manager._load_conf() + self._set_override([constants.LOADBALANCER + + ':lbaas1:driver_path:default', + constants.DUMMY + + ':lbaas2:driver_path2']) ctx = context.get_admin_context() self.assertRaises(provconf.ServiceProviderNotFound, self.manager.add_resource_association, @@ -200,13 +192,19 @@ class ServiceTypeExtensionTestCase(ServiceTypeExtensionTestCaseBase): class ServiceTypeManagerExtTestCase(ServiceTypeExtensionTestCaseBase): """Tests ServiceTypemanager as a public API.""" def setUp(self): + self.service_providers = mock.patch.object( + provconf.NeutronModule, 'service_providers').start() + service_providers = [ + constants.LOADBALANCER + ':lbaas:driver_path', + constants.DUMMY + ':dummy:dummy_dr' + ] + self.service_providers.return_value = service_providers # Blank out service type manager instance st_db.ServiceTypeManager._instance = None - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.DUMMY + ':dummy:dummy_dr'], - 'service_providers') + self.manager = st_db.ServiceTypeManager.get_instance() + for provider in service_providers: + self.manager.add_provider_configuration( + provider.split(':')[0], provconf.ProviderConfiguration()) super(ServiceTypeManagerExtTestCase, self).setUp() def _list_service_providers(self): @@ -217,4 +215,4 @@ class ServiceTypeManagerExtTestCase(ServiceTypeExtensionTestCaseBase): self.assertEqual(res.status_int, webexc.HTTPOk.code) data = self.deserialize(res) self.assertIn('service_providers', data) - self.assertEqual(len(data['service_providers']), 2) + self.assertGreaterEqual(len(data['service_providers']), 2) diff --git a/neutron/tests/unit/services/test_provider_configuration.py b/neutron/tests/unit/services/test_provider_configuration.py index a10b6f783a9..1930c278bef 100644 --- a/neutron/tests/unit/services/test_provider_configuration.py +++ b/neutron/tests/unit/services/test_provider_configuration.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import mock + from oslo_config import cfg from neutron.common import exceptions as n_exc @@ -22,15 +24,22 @@ from neutron.tests import base class ParseServiceProviderConfigurationTestCase(base.BaseTestCase): + + def setUp(self): + super(ParseServiceProviderConfigurationTestCase, self).setUp() + self.service_providers = mock.patch.object( + provconf.NeutronModule, 'service_providers').start() + + def _set_override(self, service_providers): + self.service_providers.return_value = service_providers + def test_default_service_provider_configuration(self): providers = cfg.CONF.service_providers.service_provider self.assertEqual(providers, []) def test_parse_single_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':lbaas:driver_path']) expected = {'service_type': constants.LOADBALANCER, 'name': 'lbaas', 'driver': 'driver_path', @@ -40,10 +49,8 @@ class ParseServiceProviderConfigurationTestCase(base.BaseTestCase): self.assertEqual(res, [expected]) def test_parse_single_default_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path:default'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':lbaas:driver_path:default']) expected = {'service_type': constants.LOADBALANCER, 'name': 'lbaas', 'driver': 'driver_path', @@ -53,56 +60,46 @@ class ParseServiceProviderConfigurationTestCase(base.BaseTestCase): self.assertEqual(res, [expected]) def test_parse_multi_service_provider_opt(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - constants.LOADBALANCER + ':name1:path1', - constants.LOADBALANCER + - ':name2:path2:default'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':lbaas:driver_path', + constants.LOADBALANCER + ':name1:path1', + constants.LOADBALANCER + + ':name2:path2:default']) res = provconf.parse_service_provider_opt() # This parsing crosses repos if additional projects are installed, # so check that at least what we expect is there; there may be more. self.assertTrue(len(res) >= 3) - def test_parse_service_provider_opt_not_allowed_raises(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - 'svc_type:name1:path1'], - 'service_providers') - self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - def test_parse_service_provider_invalid_format(self): - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':lbaas:driver_path', - 'svc_type:name1:path1:def'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':lbaas:driver_path', + 'svc_type:name1:path1:def']) self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':', - 'svc_type:name1:path1:def'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':', + 'svc_type:name1:path1:def']) self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) def test_parse_service_provider_name_too_long(self): name = 'a' * 256 - cfg.CONF.set_override('service_provider', - [constants.LOADBALANCER + - ':' + name + ':driver_path', - 'svc_type:name1:path1:def'], - 'service_providers') + self._set_override([constants.LOADBALANCER + + ':' + name + ':driver_path', + 'svc_type:name1:path1:def']) self.assertRaises(n_exc.Invalid, provconf.parse_service_provider_opt) class ProviderConfigurationTestCase(base.BaseTestCase): + def setUp(self): super(ProviderConfigurationTestCase, self).setUp() + self.service_providers = mock.patch.object( + provconf.NeutronModule, 'service_providers').start() + + def _set_override(self, service_providers): + self.service_providers.return_value = service_providers def test_ensure_driver_unique(self): - pconf = provconf.ProviderConfiguration([]) + pconf = provconf.ProviderConfiguration() pconf.providers[('svctype', 'name')] = {'driver': 'driver', 'default': True} self.assertRaises(n_exc.Invalid, @@ -110,7 +107,7 @@ class ProviderConfigurationTestCase(base.BaseTestCase): self.assertIsNone(pconf._ensure_driver_unique('another_driver1')) def test_ensure_default_unique(self): - pconf = provconf.ProviderConfiguration([]) + pconf = provconf.ProviderConfiguration() pconf.providers[('svctype', 'name')] = {'driver': 'driver', 'default': True} self.assertRaises(n_exc.Invalid, @@ -121,7 +118,7 @@ class ProviderConfigurationTestCase(base.BaseTestCase): self.assertIsNone(pconf._ensure_default_unique('svctype1', False)) def test_add_provider(self): - pconf = provconf.ProviderConfiguration([]) + pconf = provconf.ProviderConfiguration() prov = {'service_type': constants.LOADBALANCER, 'name': 'name', 'driver': 'path', @@ -134,7 +131,7 @@ class ProviderConfigurationTestCase(base.BaseTestCase): [{'driver': 'path', 'default': False}]) def test_add_duplicate_provider(self): - pconf = provconf.ProviderConfiguration([]) + pconf = provconf.ProviderConfiguration() prov = {'service_type': constants.LOADBALANCER, 'name': 'name', 'driver': 'path', @@ -144,6 +141,10 @@ class ProviderConfigurationTestCase(base.BaseTestCase): self.assertEqual(len(pconf.providers), 1) def test_get_service_providers(self): + self._set_override([constants.LOADBALANCER + ':name:path', + constants.LOADBALANCER + ':name2:path2', + 'st2:name:driver:default', + 'st3:name2:driver2:default']) provs = [{'service_type': constants.LOADBALANCER, 'name': 'name', 'driver': 'path', @@ -161,7 +162,7 @@ class ProviderConfigurationTestCase(base.BaseTestCase): 'name': 'name2', 'driver': 'driver2', 'default': True}] - pconf = provconf.ProviderConfiguration(provs) + pconf = provconf.ProviderConfiguration() for prov in provs: p = pconf.get_service_providers( filters={'name': [prov['name']], @@ -170,6 +171,8 @@ class ProviderConfigurationTestCase(base.BaseTestCase): self.assertEqual(p, [prov]) def test_get_service_providers_with_fields(self): + self._set_override([constants.LOADBALANCER + ":name:path", + constants.LOADBALANCER + ":name2:path2"]) provs = [{'service_type': constants.LOADBALANCER, 'name': 'name', 'driver': 'path', @@ -178,7 +181,7 @@ class ProviderConfigurationTestCase(base.BaseTestCase): 'name': 'name2', 'driver': 'path2', 'default': False}] - pconf = provconf.ProviderConfiguration(provs) + pconf = provconf.ProviderConfiguration() for prov in provs: p = pconf.get_service_providers( filters={'name': [prov['name']],