121 lines
4.4 KiB
Python
121 lines
4.4 KiB
Python
# 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 karbor.exception import ListProtectableResourceFailed
|
|
from karbor.services.protection.graph import build_graph
|
|
|
|
from oslo_config import cfg
|
|
from oslo_log import log as logging
|
|
from stevedore import extension
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def _warn_missing_protectable(extmanager, ep, err):
|
|
LOG.warning("Could not load %(name)s: %(error)s")
|
|
|
|
|
|
class ProtectableRegistry(object):
|
|
|
|
def __init__(self):
|
|
super(ProtectableRegistry, self).__init__()
|
|
self._protectable_map = {}
|
|
self._plugin_map = {}
|
|
|
|
def load_plugins(self):
|
|
"""Load all protectable plugins configured and register them.
|
|
|
|
"""
|
|
mgr = extension.ExtensionManager(
|
|
namespace='karbor.protectables',
|
|
invoke_on_load=True,
|
|
on_load_failure_callback=_warn_missing_protectable)
|
|
|
|
for e in mgr:
|
|
self.register_plugin(e.obj)
|
|
|
|
def register_plugin(self, plugin):
|
|
self._plugin_map[plugin.get_resource_type()] = plugin
|
|
|
|
def _get_protectable(self, context, resource_type, conf=cfg.CONF):
|
|
if resource_type in self._protectable_map:
|
|
return self._protectable_map[resource_type]
|
|
|
|
protectable = self._plugin_map[resource_type].instance(
|
|
context, conf)
|
|
self._protectable_map[resource_type] = protectable
|
|
return protectable
|
|
|
|
def list_resource_types(self):
|
|
"""List all resource types supported by protectables.
|
|
|
|
:return: The list of supported resource types.
|
|
"""
|
|
return [type for type in self._plugin_map.keys()]
|
|
|
|
def get_protectable_resource_plugin(self, resource_type):
|
|
"""Get the protectable plugin with the specified type."""
|
|
return self._plugin_map.get(resource_type)
|
|
|
|
def list_resources(self, context, resource_type, parameters=None):
|
|
"""List resource instances of given type.
|
|
|
|
:param resource_type: The resource type to list instance.
|
|
:return: The list of resource instance.
|
|
"""
|
|
protectable = self._get_protectable(context, resource_type)
|
|
return protectable.list_resources(context, parameters=parameters)
|
|
|
|
def show_resource(self, context, resource_type, resource_id,
|
|
parameters=None):
|
|
"""List resource instances of given type.
|
|
|
|
:param resource_type: The resource type of instance.
|
|
:param resource_id: The resource id of instance.
|
|
:return: The show of resource instance.
|
|
"""
|
|
protectable = self._get_protectable(context, resource_type)
|
|
return protectable.show_resource(context, resource_id,
|
|
parameters=parameters)
|
|
|
|
def fetch_dependent_resources(self, context, resource):
|
|
"""List dependent resources under given parent resource.
|
|
|
|
:param resource: The parent resource to list dependent resources.
|
|
:return: The list of dependent resources.
|
|
"""
|
|
result = []
|
|
for plugin in self._plugin_map.values():
|
|
if resource.type in plugin.get_parent_resource_types():
|
|
protectable = self._get_protectable(
|
|
context,
|
|
plugin.get_resource_type())
|
|
try:
|
|
protectable_resources = \
|
|
protectable.get_dependent_resources(context, resource)
|
|
except ListProtectableResourceFailed as e:
|
|
LOG.error("List resources failed, so skip it. "
|
|
"Error: {0}".format(e))
|
|
protectable_resources = []
|
|
result.extend(protectable_resources)
|
|
|
|
return result
|
|
|
|
def build_graph(self, context, resources):
|
|
def fetch_dependent_resources_context(resource):
|
|
return self.fetch_dependent_resources(context, resource)
|
|
|
|
return build_graph(
|
|
start_nodes=resources,
|
|
get_child_nodes_func=fetch_dependent_resources_context,
|
|
)
|