Decentralize the managemement of service providers

After the service split, some of the configuration, parsing and
validation was kept in the neutron core; ultimately this needs to
get closer to the services where it belongs.

This patch starts from ProviderConfiguration and ServiceTypeManager
classes, and aims at removing the hard-coded elements, like the list
of known advanced services, so that in the long run we can make
Neutron easier to plug with external services.

Partial-bug: #1473110

Depends-on: I44edcceba37ac58efcc0a53c9d1f835d9530344a
Depends-on: I8924234aadf786801ffc100d7daa27acc145a195
Change-Id: Ia4cad678e6c722ca05821dbdbf05d61523246a86
This commit is contained in:
armando-migliaccio 2015-07-08 13:48:11 -07:00 committed by Armando Migliaccio
parent 43c00a9f65
commit 61121c5f2a
7 changed files with 262 additions and 261 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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']],