Split Provider configuration into files
Change-Id: Ie88895ceda3a620aa33999a980e04e144d8f32e6
This commit is contained in:
parent
e90c2356d1
commit
7b24765f4a
9
etc/providers.d/openstack-infra.conf
Normal file
9
etc/providers.d/openstack-infra.conf
Normal file
@ -0,0 +1,9 @@
|
||||
[provider]
|
||||
name = OS Infra Provider
|
||||
description = This provider uses OpenStack's own services (swift, cinder) as storage
|
||||
id = cf56bd3e-97a7-4078-b6d5-f36246333fd9
|
||||
# TODO(yuvalbr)
|
||||
# bank = swift
|
||||
# plugin = cinder_backup
|
||||
# plugin = glance_backup
|
||||
# plugin = neutron_backup
|
@ -80,11 +80,6 @@ global_opts = [
|
||||
cfg.IntOpt('lease_validity_window',
|
||||
default=100,
|
||||
help='validity_window for bank lease, in seconds'),
|
||||
cfg.ListOpt('enabled_providers',
|
||||
default=None,
|
||||
help='A list of provider names to use. These provider names '
|
||||
'should be backed by a unique [CONFIG] group '
|
||||
'with its options'),
|
||||
]
|
||||
|
||||
CONF.register_opts(global_opts)
|
||||
|
@ -45,6 +45,9 @@ class LeasePlugin(object):
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BankPlugin(object):
|
||||
def __init__(self, config=None):
|
||||
self._config = config
|
||||
|
||||
@abc.abstractmethod
|
||||
def create_object(self, key, value):
|
||||
return
|
||||
|
@ -60,8 +60,6 @@ swift_client_opts = [
|
||||
'making SSL connection to Swift.'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(swift_client_opts, "swift_client")
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -70,19 +68,24 @@ class SwiftConnectionFailed(exception.SmaugException):
|
||||
|
||||
|
||||
class SwiftBankPlugin(BankPlugin, LeasePlugin):
|
||||
def __init__(self, context, object_container):
|
||||
super(BankPlugin, self).__init__()
|
||||
def __init__(self, config, context, object_container):
|
||||
super(SwiftBankPlugin, self).__init__(config)
|
||||
self.context = context
|
||||
self.swift_retry_attempts = CONF.swift_client.bank_swift_retry_attempts
|
||||
self.swift_retry_backoff = CONF.swift_client.bank_swift_retry_backoff
|
||||
self.swift_auth_insecure = CONF.swift_client.bank_swift_auth_insecure
|
||||
self.swift_ca_cert_file = CONF.swift_client.bank_swift_ca_cert_file
|
||||
self.lease_expire_window = CONF.lease_expire_window
|
||||
self.lease_renew_window = CONF.lease_renew_window
|
||||
self._config.register_opts(swift_client_opts, "swift_client")
|
||||
self.swift_retry_attempts = \
|
||||
self._config.swift_client.bank_swift_retry_attempts
|
||||
self.swift_retry_backoff = \
|
||||
self._config.swift_client.bank_swift_retry_backoff
|
||||
self.swift_auth_insecure = \
|
||||
self._config.swift_client.bank_swift_auth_insecure
|
||||
self.swift_ca_cert_file = \
|
||||
self._config.swift_client.bank_swift_ca_cert_file
|
||||
self.lease_expire_window = self._config.lease_expire_window
|
||||
self.lease_renew_window = self._config.lease_renew_window
|
||||
# TODO(luobin):
|
||||
# init lease_validity_window
|
||||
# according to lease_renew_window if not configured
|
||||
self.lease_validity_window = CONF.lease_validity_window
|
||||
self.lease_validity_window = self._config.lease_validity_window
|
||||
|
||||
# TODO(luobin): create a uuid of this bank_plugin
|
||||
self.owner_id = str(uuid.uuid4())
|
||||
@ -113,20 +116,20 @@ class SwiftBankPlugin(BankPlugin, LeasePlugin):
|
||||
initial_delay=self.lease_renew_window)
|
||||
|
||||
def _setup_connection(self):
|
||||
if CONF.swift_client.bank_swift_auth == "single_user":
|
||||
if self._config.swift_client.bank_swift_auth == "single_user":
|
||||
connection = swift.Connection(
|
||||
authurl=CONF.swift_client.bank_swift_auth_url,
|
||||
auth_version=CONF.swift_client.bank_swift_auth_version,
|
||||
tenant_name=CONF.swift_client.bank_swift_tenant_name,
|
||||
user=CONF.swift_client.bank_swift_user,
|
||||
key=CONF.swift_client.bank_swift_key,
|
||||
authurl=self._config.swift_client.bank_swift_auth_url,
|
||||
auth_version=self._config.swift_client.bank_swift_auth_version,
|
||||
tenant_name=self._config.swift_client.bank_swift_tenant_name,
|
||||
user=self._config.swift_client.bank_swift_user,
|
||||
key=self._config.swift_client.bank_swift_key,
|
||||
retries=self.swift_retry_attempts,
|
||||
starting_backoff=self.swift_retry_backoff,
|
||||
insecure=self.swift_auth_insecure,
|
||||
cacert=self.swift_ca_cert_file)
|
||||
else:
|
||||
connection = swift.Connection(
|
||||
preauthurl=CONF.swift_client.bank_swift_url,
|
||||
preauthurl=self._config.swift_client.bank_swift_url,
|
||||
preauthtoken=self.context.auth_token,
|
||||
retries=self.swift_retry_attempts,
|
||||
starting_backoff=self.swift_retry_backoff,
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
import os
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import importutils
|
||||
from smaug.i18n import _LE
|
||||
@ -36,11 +37,11 @@ class ClientFactory(object):
|
||||
yield '%s.clients.%s' % (__package__, name)
|
||||
|
||||
@classmethod
|
||||
def create_client(cls, service, context):
|
||||
def create_client(cls, service, context, conf=cfg.CONF):
|
||||
if not cls._factory:
|
||||
cls._factory = {}
|
||||
for module in cls._list_clients():
|
||||
module = importutils.import_module(module)
|
||||
cls._factory[module.SERVICE] = module
|
||||
|
||||
return cls._factory[service].create(context)
|
||||
return cls._factory[service].create(context, conf)
|
||||
|
@ -35,9 +35,10 @@ cfg.CONF.register_opts(cinder_client_opts, group=SERVICE + '_client')
|
||||
CINDERCLIENT_VERSION = '2'
|
||||
|
||||
|
||||
def create(context):
|
||||
def create(context, conf):
|
||||
conf.register_opts(cinder_client_opts, group=SERVICE + '_client')
|
||||
try:
|
||||
url = utils.get_url(SERVICE, context, append_project=True)
|
||||
url = utils.get_url(SERVICE, context, conf, append_project=True)
|
||||
except Exception:
|
||||
LOG.error(_LE("Get cinder service endpoint url failed."))
|
||||
raise
|
||||
|
@ -35,9 +35,10 @@ cfg.CONF.register_opts(glance_client_opts, group=SERVICE + '_client')
|
||||
GLANCECLIENT_VERSION = '2'
|
||||
|
||||
|
||||
def create(context):
|
||||
def create(context, conf):
|
||||
conf.register_opts(glance_client_opts, group=SERVICE + '_client')
|
||||
try:
|
||||
url = utils.get_url(SERVICE, context)
|
||||
url = utils.get_url(SERVICE, context, conf)
|
||||
except Exception:
|
||||
LOG.error(_LE("Get glance service endpoint url failed"))
|
||||
raise
|
||||
|
@ -33,9 +33,10 @@ neutron_client_opts = [
|
||||
cfg.CONF.register_opts(neutron_client_opts, group=SERVICE + '_client')
|
||||
|
||||
|
||||
def create(context):
|
||||
def create(context, conf):
|
||||
conf.register_opts(neutron_client_opts, group=SERVICE + '_client')
|
||||
try:
|
||||
url = utils.get_url(SERVICE, context)
|
||||
url = utils.get_url(SERVICE, context, conf)
|
||||
except Exception:
|
||||
LOG.error(_LE("Get neutron service endpoint url failed"))
|
||||
raise
|
||||
|
@ -36,9 +36,10 @@ cfg.CONF.register_opts(nova_client_opts, group=SERVICE + '_client')
|
||||
NOVACLIENT_VERSION = '2'
|
||||
|
||||
|
||||
def create(context):
|
||||
def create(context, conf):
|
||||
conf.register_opts(nova_client_opts, group=SERVICE + '_client')
|
||||
try:
|
||||
url = utils.get_url(SERVICE, context, append_project=True)
|
||||
url = utils.get_url(SERVICE, context, conf, append_project=True)
|
||||
except Exception:
|
||||
LOG.error(_LE("Get nova service endpoint url failed."))
|
||||
raise
|
||||
|
@ -24,6 +24,8 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class ProtectionPlugin(object):
|
||||
def __init__(self, config=None):
|
||||
self._config = config
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_supported_resources_types(self):
|
||||
|
@ -10,22 +10,28 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from smaug.common import constants
|
||||
from smaug.i18n import _LE
|
||||
from smaug.services.protection import checkpoint
|
||||
from smaug import utils
|
||||
|
||||
provider_opt = [
|
||||
provider_opts = [
|
||||
cfg.MultiStrOpt('plugin',
|
||||
default='',
|
||||
help='plugins to use for protection'),
|
||||
cfg.StrOpt('bank',
|
||||
default='',
|
||||
help='bank plugin to use for storage'),
|
||||
cfg.StrOpt('description',
|
||||
default='',
|
||||
help='the description of provider'),
|
||||
cfg.StrOpt('provider_id',
|
||||
cfg.StrOpt('name',
|
||||
default='',
|
||||
help='the name of provider'),
|
||||
cfg.StrOpt('id',
|
||||
default='',
|
||||
help='the provider id')
|
||||
]
|
||||
@ -35,13 +41,20 @@ LOG = logging.getLogger(__name__)
|
||||
|
||||
PROTECTION_NAMESPACE = 'smaug.protections'
|
||||
|
||||
CONF.register_opt(cfg.StrOpt('provider_config_dir',
|
||||
default='providers.d',
|
||||
help='Configuration directory for providers.'
|
||||
' Absolute path, or relative to smaug '
|
||||
' configuration directory.'))
|
||||
|
||||
|
||||
class PluggableProtectionProvider(object):
|
||||
def __init__(self, provider_id, provider_name, description, plugins):
|
||||
def __init__(self, provider_config):
|
||||
super(PluggableProtectionProvider, self).__init__()
|
||||
self._id = provider_id
|
||||
self._name = provider_name
|
||||
self._description = description
|
||||
self._config = provider_config
|
||||
self._id = self._config.provider.id
|
||||
self._name = self._config.provider.name
|
||||
self._description = self._config.provider.description
|
||||
self._extended_info_schema = {'options_schema': {},
|
||||
'restore_schema': {},
|
||||
'saved_info_schema': {}}
|
||||
@ -49,12 +62,21 @@ class PluggableProtectionProvider(object):
|
||||
self._bank_plugin = None
|
||||
self._plugin_map = {}
|
||||
|
||||
self._load_plugins(plugins=plugins)
|
||||
if hasattr(self._config.provider, 'bank') \
|
||||
and not self._config.provider.bank:
|
||||
raise ImportError("Empty bank")
|
||||
self._load_bank(self._config.provider.bank)
|
||||
if hasattr(self._config.provider, 'plugin'):
|
||||
for plugin_name in self._config.provider.plugin:
|
||||
if not plugin_name:
|
||||
raise ImportError("Empty protection plugin")
|
||||
self._load_plugin(plugin_name)
|
||||
|
||||
if self._bank_plugin:
|
||||
self.checkpoint_collection = checkpoint.CheckpointCollection(
|
||||
self._bank_plugin)
|
||||
else:
|
||||
LOG.error(_LE('Bank plugin not exist,check your configuration'))
|
||||
LOG.error(_LE('Bank plugin not exist, check your configuration'))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
@ -72,27 +94,43 @@ class PluggableProtectionProvider(object):
|
||||
def extended_info_schema(self):
|
||||
return self._extended_info_schema
|
||||
|
||||
def _load_plugins(self, plugins):
|
||||
for plugin_name in plugins:
|
||||
try:
|
||||
plugin = utils.load_plugin(PROTECTION_NAMESPACE, plugin_name)
|
||||
except Exception:
|
||||
LOG.exception(_LE("Load protection plugin: %s failed."),
|
||||
plugin_name)
|
||||
raise
|
||||
else:
|
||||
self._plugin_map[plugin_name] = plugin
|
||||
if constants.PLUGIN_BANK in plugin_name.lower():
|
||||
self._bank_plugin = plugin
|
||||
@property
|
||||
def bank(self):
|
||||
return self._bank_plugin
|
||||
|
||||
@property
|
||||
def plugins(self):
|
||||
return self._plugin_map
|
||||
|
||||
def _load_bank(self, bank_name):
|
||||
try:
|
||||
plugin = utils.load_plugin(PROTECTION_NAMESPACE, bank_name,
|
||||
self._config)
|
||||
except Exception:
|
||||
LOG.error(_LE("Load bank plugin: '%s' failed."), bank_name)
|
||||
raise
|
||||
else:
|
||||
self._bank_plugin = plugin
|
||||
|
||||
def _load_plugin(self, plugin_name):
|
||||
try:
|
||||
plugin = utils.load_plugin(PROTECTION_NAMESPACE, plugin_name,
|
||||
self._config)
|
||||
except Exception:
|
||||
LOG.error(_LE("Load protection plugin: '%s' failed."), plugin_name)
|
||||
raise
|
||||
else:
|
||||
self._plugin_map[plugin_name] = plugin
|
||||
for resource in plugin.get_supported_resources_types():
|
||||
if hasattr(plugin, 'get_options_schema'):
|
||||
self._extended_info_schema['options_schema'][plugin_name] \
|
||||
= plugin.get_options_schema()
|
||||
self._extended_info_schema['options_schema'][resource] \
|
||||
= plugin.get_options_schema(resource)
|
||||
if hasattr(plugin, 'get_restore_schema'):
|
||||
self._extended_info_schema['restore_schema'][plugin_name] \
|
||||
= plugin.get_restore_schema()
|
||||
self._extended_info_schema['restore_schema'][resource] \
|
||||
= plugin.get_restore_schema(resource)
|
||||
if hasattr(plugin, 'get_saved_info_schema'):
|
||||
self._extended_info_schema['saved_info_schema'][plugin_name] \
|
||||
= plugin.get_saved_info_schema()
|
||||
self._extended_info_schema['saved_info_schema'][resource] \
|
||||
= plugin.get_saved_info_schema(resource)
|
||||
|
||||
def get_checkpoint_collection(self):
|
||||
return self.checkpoint_collection
|
||||
@ -109,51 +147,29 @@ class ProviderRegistry(object):
|
||||
self._load_providers()
|
||||
|
||||
def _load_providers(self):
|
||||
"""load provider
|
||||
"""load provider"""
|
||||
config_dir = utils.find_config(CONF.provider_config_dir)
|
||||
|
||||
smaug.conf example:
|
||||
[default]
|
||||
enabled_providers=provider1,provider2
|
||||
[provider1]
|
||||
provider_id='' configured by admin
|
||||
plugin=BANK define in setup.cfg
|
||||
plugin=VolumeProtectionPlugin define in setup.cfg
|
||||
description='the description of provider1'
|
||||
[provider2]
|
||||
provider_id='' configured by admin
|
||||
plugin=BANK define in setup.cfg
|
||||
plugin=VolumeProtectionPlugin define in setup.cfg
|
||||
plugin=ServerProtectionPlugin define in setup.cfg
|
||||
description='the description of provider2'
|
||||
"""
|
||||
if CONF.enabled_providers:
|
||||
for provider_name in CONF.enabled_providers:
|
||||
CONF.register_opts(provider_opt, group=provider_name)
|
||||
plugins = getattr(CONF, provider_name).plugin
|
||||
description = getattr(CONF, provider_name).description
|
||||
provider_id = getattr(CONF, provider_name).provider_id
|
||||
if not all([plugins, provider_id]):
|
||||
LOG.error(_LE("Invalid provider:%s,check provider"
|
||||
" configuration"),
|
||||
provider_name)
|
||||
continue
|
||||
try:
|
||||
provider = PluggableProtectionProvider(provider_id,
|
||||
provider_name,
|
||||
description,
|
||||
plugins)
|
||||
except Exception:
|
||||
LOG.exception(_LE("Load provider: %s failed."),
|
||||
provider_name)
|
||||
else:
|
||||
self.providers[provider_id] = provider
|
||||
for config_file in os.listdir(config_dir):
|
||||
if not config_file.endswith('.conf'):
|
||||
continue
|
||||
config_path = os.path.abspath(os.path.join(config_dir,
|
||||
config_file))
|
||||
provider_config = cfg.ConfigOpts()
|
||||
provider_config(args=['--config-file=' + config_path])
|
||||
provider_config.register_opts(provider_opts, 'provider')
|
||||
try:
|
||||
provider = PluggableProtectionProvider(provider_config)
|
||||
except Exception:
|
||||
LOG.error(_LE("Load provider: %s failed."),
|
||||
provider_config.provider.name)
|
||||
else:
|
||||
self.providers[provider.id] = provider
|
||||
|
||||
def list_providers(self, list_option=None):
|
||||
if not list_option:
|
||||
return [dict(id=provider.id, name=provider.name,
|
||||
description=provider.description)
|
||||
for provider in self.providers.values()]
|
||||
# It seems that we don't need list_option
|
||||
def list_providers(self):
|
||||
return [dict(id=provider.id, name=provider.name,
|
||||
description=provider.description)
|
||||
for provider in self.providers.values()]
|
||||
|
||||
def show_provider(self, provider_id):
|
||||
return self.providers.get(provider_id, None)
|
||||
|
@ -10,7 +10,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from smaug import exception
|
||||
from smaug.i18n import _
|
||||
|
||||
@ -39,9 +38,9 @@ def _parse_service_endpoint(endpoint_url, context, append_project=False):
|
||||
else endpoint_url
|
||||
|
||||
|
||||
def get_url(service, context, append_project=False):
|
||||
def get_url(service, context, conf, append_project=False):
|
||||
'''Return the url of given service endpoint.'''
|
||||
client_conf = getattr(cfg.CONF, service + '_client')
|
||||
client_conf = getattr(conf, service + '_client')
|
||||
|
||||
endpoint = getattr(client_conf, service + '_endpoint')
|
||||
if endpoint is not None:
|
||||
|
@ -35,13 +35,13 @@ class CinderClientTest(base.TestCase):
|
||||
cfg.CONF.set_default('cinder_endpoint',
|
||||
'http://127.0.0.1:8776/v2',
|
||||
'cinder_client')
|
||||
client = cinder.create(self._context)
|
||||
client = cinder.create(self._context, cfg.CONF)
|
||||
self.assertEqual('volumev2', client.client.service_type)
|
||||
self.assertEqual('http://127.0.0.1:8776/v2/abcd',
|
||||
client.client.management_url)
|
||||
|
||||
def test_create_client_by_catalog(self):
|
||||
client = cinder.create(self._context)
|
||||
client = cinder.create(self._context, cfg.CONF)
|
||||
self.assertEqual('volumev2', client.client.service_type)
|
||||
self.assertEqual('http://127.0.0.1:8776/v2/abcd',
|
||||
client.client.management_url)
|
||||
|
@ -40,9 +40,9 @@ class GlanceClientTest(base.TestCase):
|
||||
cfg.CONF.set_default('glance_endpoint',
|
||||
'http://127.0.0.1:9292',
|
||||
'glance_client')
|
||||
gc = glance.create(self._context)
|
||||
gc = glance.create(self._context, cfg.CONF)
|
||||
self.assertEqual('http://127.0.0.1:9292', gc.http_client.endpoint)
|
||||
|
||||
def test_create_client_by_catalog(self):
|
||||
gc = glance.create(self._context)
|
||||
gc = glance.create(self._context, cfg.CONF)
|
||||
self.assertEqual('http://127.0.0.1:9292', gc.http_client.endpoint)
|
||||
|
@ -40,9 +40,9 @@ class NeutronClientTest(base.TestCase):
|
||||
cfg.CONF.set_default('neutron_endpoint',
|
||||
'http://127.0.0.1:9696',
|
||||
'neutron_client')
|
||||
nc = neutron.create(self._context)
|
||||
nc = neutron.create(self._context, cfg.CONF)
|
||||
self.assertEqual('http://127.0.0.1:9696', nc.httpclient.endpoint_url)
|
||||
|
||||
def test_create_client_by_catalog(self):
|
||||
nc = neutron.create(self._context)
|
||||
nc = neutron.create(self._context, cfg.CONF)
|
||||
self.assertEqual('http://127.0.0.1:9696', nc.httpclient.endpoint_url)
|
||||
|
@ -35,13 +35,13 @@ class NovaClientTest(base.TestCase):
|
||||
cfg.CONF.set_default('nova_endpoint',
|
||||
'http://127.0.0.1:8774/v2.1',
|
||||
'nova_client')
|
||||
client = nova.create(self._context)
|
||||
client = nova.create(self._context, cfg.CONF)
|
||||
self.assertEqual('compute', client.client.service_type)
|
||||
self.assertEqual('http://127.0.0.1:8774/v2.1/abcd',
|
||||
client.client.management_url)
|
||||
|
||||
def test_create_client_by_catalog(self):
|
||||
client = nova.create(self._context)
|
||||
client = nova.create(self._context, cfg.CONF)
|
||||
self.assertEqual('compute', client.client.service_type)
|
||||
self.assertEqual('http://127.0.0.1:8774/v2.1/abcd',
|
||||
client.client.management_url)
|
||||
|
@ -28,3 +28,5 @@ def set_defaults(conf):
|
||||
conf.set_default('auth_strategy', 'noauth')
|
||||
conf.set_default('state_path', os.path.abspath(
|
||||
os.path.join(os.path.dirname(__file__), '..', '..', '..')))
|
||||
conf.set_default('provider_config_dir',
|
||||
os.path.join(os.path.dirname(__file__), 'fake_providers'))
|
||||
|
40
smaug/tests/unit/fake_bank.py
Normal file
40
smaug/tests/unit/fake_bank.py
Normal file
@ -0,0 +1,40 @@
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from smaug.services.protection import bank_plugin
|
||||
|
||||
fake_bank_opts = [
|
||||
cfg.StrOpt('fake_host'),
|
||||
]
|
||||
|
||||
|
||||
class FakeBankPlugin(bank_plugin.BankPlugin):
|
||||
def __init__(self, config=None):
|
||||
super(FakeBankPlugin, self).__init__(config)
|
||||
config.register_opts(fake_bank_opts, 'fake_bank')
|
||||
|
||||
def create_object(self, key, value):
|
||||
return
|
||||
|
||||
def update_object(self, key, value):
|
||||
return
|
||||
|
||||
def get_object(self, key):
|
||||
return
|
||||
|
||||
def list_objects(self, prefix=None, limit=None, marker=None):
|
||||
return
|
||||
|
||||
def delete_object(self, key):
|
||||
return
|
49
smaug/tests/unit/fake_protection.py
Normal file
49
smaug/tests/unit/fake_protection.py
Normal file
@ -0,0 +1,49 @@
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from smaug.services.protection import protection_plugin
|
||||
|
||||
fake_plugin_opts = [
|
||||
cfg.StrOpt('fake_user'),
|
||||
]
|
||||
|
||||
|
||||
class FakeProtectionPlugin(protection_plugin.ProtectionPlugin):
|
||||
def __init__(self, config=None):
|
||||
super(FakeProtectionPlugin, self).__init__(config)
|
||||
config.register_opts(fake_plugin_opts, 'fake_plugin')
|
||||
|
||||
def get_supported_resources_types(self):
|
||||
return ['Test::Resource']
|
||||
|
||||
def get_options_schema(self, resource_type):
|
||||
return []
|
||||
|
||||
def get_saved_info_schema(self, resource_type):
|
||||
return []
|
||||
|
||||
def get_restore_schema(self, resource_type):
|
||||
return []
|
||||
|
||||
def get_saved_info(self, metadata_store, resource):
|
||||
pass
|
||||
|
||||
def get_protection_stats(self, protection_id):
|
||||
pass
|
||||
|
||||
def on_resource_start(self, context):
|
||||
pass
|
||||
|
||||
def on_resource_end(self, context):
|
||||
pass
|
12
smaug/tests/unit/fake_providers/fake_provider1.conf
Normal file
12
smaug/tests/unit/fake_providers/fake_provider1.conf
Normal file
@ -0,0 +1,12 @@
|
||||
[provider]
|
||||
name = fake_provider1
|
||||
id = fake_id1
|
||||
description = Test Provider 1
|
||||
bank = smaug.tests.unit.fake_bank.FakeBankPlugin
|
||||
plugin = smaug.tests.unit.fake_protection.FakeProtectionPlugin
|
||||
|
||||
[fake_plugin]
|
||||
fake_user = user
|
||||
|
||||
[fake_bank]
|
||||
fake_host = thor
|
4
smaug/tests/unit/fake_providers/fake_provider2.conf
Normal file
4
smaug/tests/unit/fake_providers/fake_provider2.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[provider]
|
||||
name = fake_provider2
|
||||
id = fake_id2
|
||||
description = Test Provider 2
|
@ -1,85 +1,58 @@
|
||||
# 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 mock
|
||||
from oslo_config import cfg
|
||||
from smaug.services.protection import provider
|
||||
from smaug.tests import base
|
||||
|
||||
provider_opt = [
|
||||
cfg.MultiStrOpt('plugin',
|
||||
default='',
|
||||
help='plugins to use for protection'),
|
||||
cfg.StrOpt('description',
|
||||
default='',
|
||||
help='the description of provider'),
|
||||
cfg.StrOpt('provider_id',
|
||||
default='',
|
||||
help='the provider id')
|
||||
]
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ProviderRegistryTest(base.TestCase):
|
||||
def setUp(self):
|
||||
super(ProviderRegistryTest, self).setUp()
|
||||
CONF.set_override('enabled_providers',
|
||||
['provider1', 'provider2'])
|
||||
CONF.register_opts(provider_opt, group='provider1')
|
||||
CONF.register_opts(provider_opt, group='provider2')
|
||||
CONF.set_override('plugin', ['SERVER', 'VOLUME'],
|
||||
group='provider1')
|
||||
CONF.set_override('plugin', ['SERVER'],
|
||||
group='provider2')
|
||||
CONF.set_override('description', 'FAKE1', group='provider1')
|
||||
CONF.set_override('description', 'FAKE2', group='provider2')
|
||||
CONF.set_override('provider_id', 'id1', group='provider1')
|
||||
CONF.set_override('provider_id', 'id2', group='provider2')
|
||||
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_plugins')
|
||||
def test_load_providers(self, mock_load_plugins):
|
||||
CONF.set_override('plugin', ['SERVER'],
|
||||
group='provider2')
|
||||
pr = provider.ProviderRegistry()
|
||||
self.assertTrue(mock_load_plugins.called)
|
||||
self.assertEqual(len(pr.providers), 2)
|
||||
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_plugins')
|
||||
def test_load_providers_with_no_plugins(self, mock_load_plugins):
|
||||
CONF.set_override('plugin', None,
|
||||
group='provider2')
|
||||
pr = provider.ProviderRegistry()
|
||||
self.assertEqual(mock_load_plugins.call_count, 1)
|
||||
self.assertEqual(len(pr.providers), 1)
|
||||
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_plugins')
|
||||
def test_list_provider(self, mock_load_plugins):
|
||||
CONF.set_override('plugin', ['SERVER'],
|
||||
group='provider2')
|
||||
pr = provider.ProviderRegistry()
|
||||
self.assertEqual(2, len(pr.list_providers()))
|
||||
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_plugins')
|
||||
def test_show_provider(self, mock_load_plugins):
|
||||
CONF.set_override('plugin', ['SERVER'],
|
||||
group='provider2')
|
||||
pr = provider.ProviderRegistry()
|
||||
provider_list = pr.list_providers()
|
||||
for provider_node in provider_list:
|
||||
self.assertTrue(pr.show_provider(provider_node['id']))
|
||||
|
||||
def tearDown(self):
|
||||
CONF.register_opts(provider_opt, group='provider1')
|
||||
CONF.register_opts(provider_opt, group='provider2')
|
||||
CONF.set_override('enabled_providers',
|
||||
None)
|
||||
super(ProviderRegistryTest, self).tearDown()
|
||||
# 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 mock
|
||||
|
||||
from oslo_config import cfg
|
||||
from smaug.services.protection import provider
|
||||
from smaug.tests import base
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ProviderRegistryTest(base.TestCase):
|
||||
def setUp(self):
|
||||
super(ProviderRegistryTest, self).setUp()
|
||||
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_bank')
|
||||
@mock.patch.object(provider.PluggableProtectionProvider, '_load_plugin')
|
||||
def test_load_providers(self, mock_load_bank, mock_load_plugin):
|
||||
pr = provider.ProviderRegistry()
|
||||
self.assertEqual(mock_load_plugin.call_count, 1)
|
||||
self.assertEqual(mock_load_bank.call_count, 1)
|
||||
self.assertEqual(len(pr.providers), 1)
|
||||
|
||||
self.assertEqual(pr.providers['fake_id1'].name, 'fake_provider1')
|
||||
self.assertNotIn('fake_provider2', pr.providers)
|
||||
|
||||
def test_provider_bank_config(self):
|
||||
pr = provider.ProviderRegistry()
|
||||
provider1 = pr.show_provider('fake_id1')
|
||||
self.assertEqual(provider1.bank._config.fake_bank.fake_host, 'thor')
|
||||
|
||||
def test_provider_plugin_config(self):
|
||||
pr = provider.ProviderRegistry()
|
||||
provider1 = pr.show_provider('fake_id1')
|
||||
plugin_name = 'smaug.tests.unit.fake_protection.FakeProtectionPlugin'
|
||||
self.assertEqual(
|
||||
provider1.plugins[plugin_name]._config.fake_plugin.fake_user,
|
||||
'user')
|
||||
|
||||
def test_list_provider(self):
|
||||
pr = provider.ProviderRegistry()
|
||||
self.assertEqual(1, len(pr.list_providers()))
|
||||
|
||||
def test_show_provider(self):
|
||||
pr = provider.ProviderRegistry()
|
||||
provider_list = pr.list_providers()
|
||||
for provider_node in provider_list:
|
||||
self.assertTrue(pr.show_provider(provider_node['id']))
|
||||
|
@ -41,7 +41,7 @@ class SwiftBankPluginTest(base.TestCase):
|
||||
import_str=import_str)
|
||||
swift.Connection = mock.MagicMock()
|
||||
swift.Connection.return_value = self.fake_connection
|
||||
self.swift_bank_plugin = swift_bank_plugin_cls(None,
|
||||
self.swift_bank_plugin = swift_bank_plugin_cls(CONF, None,
|
||||
self.object_container)
|
||||
|
||||
def test_acquire_lease(self):
|
||||
|
@ -125,7 +125,7 @@ def get_bool_param(param_string, params):
|
||||
return strutils.bool_from_string(param, strict=True)
|
||||
|
||||
|
||||
def load_plugin(namespace, plugin_name):
|
||||
def load_plugin(namespace, plugin_name, *args, **kwargs):
|
||||
try:
|
||||
# Try to resolve plugin by name
|
||||
mgr = driver.DriverManager(namespace, plugin_name)
|
||||
@ -138,4 +138,4 @@ def load_plugin(namespace, plugin_name):
|
||||
LOG.exception(_LE("Error loading plugin by name, %s"), e1)
|
||||
LOG.exception(_LE("Error loading plugin by class, %s"), e2)
|
||||
raise ImportError(_("Class not found."))
|
||||
return plugin_class()
|
||||
return plugin_class(*args, **kwargs)
|
||||
|
Loading…
Reference in New Issue
Block a user