133 lines
4.9 KiB
Python
133 lines
4.9 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.
|
|
|
|
import logging
|
|
|
|
import stevedore
|
|
|
|
from sushy import exceptions
|
|
from sushy import utils
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
_global_extn_mgrs_by_resource = {}
|
|
|
|
|
|
def _raise(m, ep, e):
|
|
raise exceptions.ExtensionError(
|
|
error='Failed to load entry point target: %(error)s' % {'error': e})
|
|
|
|
|
|
def _create_extension_manager(namespace):
|
|
"""Create the resource specific ExtensionManager instance.
|
|
|
|
Use stevedore to find all vendor extensions of resource from their
|
|
namespace and return the ExtensionManager instance.
|
|
:param namespace: The namespace for the entry points. It maps to a
|
|
specific Sushy resource type.
|
|
:returns: the ExtensionManager instance
|
|
:raises ExtensionError: on resource OEM extension load error.
|
|
"""
|
|
# namespace format is:
|
|
# ``sushy.resources.<underscore_joined_resource_name>.oems``
|
|
resource_name = namespace.split('.')[-2]
|
|
|
|
extension_manager = (
|
|
stevedore.ExtensionManager(namespace=namespace,
|
|
propagate_map_exceptions=True,
|
|
on_load_failure_callback=_raise))
|
|
|
|
LOG.debug('Resource OEM extensions for "%(resource)s" under namespace '
|
|
'"%(namespace)s":',
|
|
{'resource': resource_name, 'namespace': namespace})
|
|
for extension in extension_manager:
|
|
LOG.debug('Found vendor: %(name)s target: %(target)s',
|
|
{'name': extension.name,
|
|
'target': extension.entry_point_target})
|
|
|
|
if not extension_manager.names():
|
|
m = (('No extensions found for "%(resource)s" under namespace '
|
|
'"%(namespace)s"') %
|
|
{'resource': resource_name,
|
|
'namespace': namespace})
|
|
LOG.error(m)
|
|
raise exceptions.ExtensionError(error=m)
|
|
|
|
return extension_manager
|
|
|
|
|
|
@utils.synchronized
|
|
def _get_extension_manager_of_resource(resource_name):
|
|
"""Get the resource specific ExtensionManager instance.
|
|
|
|
:param resource_name: The name of the resource e.g.
|
|
'system' / 'ethernet_interface' / 'update_service'
|
|
:returns: the ExtensionManager instance
|
|
:raises ExtensionError: on resource OEM extension load error.
|
|
"""
|
|
global _global_extn_mgrs_by_resource
|
|
|
|
if resource_name not in _global_extn_mgrs_by_resource:
|
|
resource_namespace = 'sushy.resources.' + resource_name + '.oems'
|
|
_global_extn_mgrs_by_resource[resource_name] = (
|
|
_create_extension_manager(resource_namespace)
|
|
)
|
|
return _global_extn_mgrs_by_resource[resource_name]
|
|
|
|
|
|
@utils.synchronized
|
|
def _get_resource_vendor_extension_obj(extension, resource, *args, **kwds):
|
|
"""Get the object returned by extension's plugin() method.
|
|
|
|
:param extension: stevedore Extension
|
|
:param resource: The Sushy resource instance
|
|
:param *args, **kwds: constructor arguments to plugin() method.
|
|
:returns: The object returned by ``plugin(*args, **kwds)`` of extension.
|
|
"""
|
|
if extension.obj is None:
|
|
extension.obj = extension.plugin(resource, *args, **kwds)
|
|
|
|
return extension.obj
|
|
|
|
|
|
def get_resource_extension_by_vendor(
|
|
resource_name, vendor, resource, *args, **kwds):
|
|
"""Helper method to get Resource specific OEM extension object for vendor
|
|
|
|
:param resource_name: The underscore joined name of the resource e.g.
|
|
'system' / 'ethernet_interface' / 'update_service'
|
|
:param vendor: This is the OEM vendor string which is the vendor-specific
|
|
extensibility identifier. Examples are: 'Contoso', 'Hpe'. As a matter
|
|
of fact the lowercase of this string will be the plugin entry point
|
|
name.
|
|
:param resource: The Sushy resource instance
|
|
:returns: The object returned by ``plugin(*args, **kwds)`` of extension.
|
|
:raises OEMExtensionNotFoundError: if no valid resource OEM extension
|
|
found.
|
|
"""
|
|
if resource_name in _global_extn_mgrs_by_resource:
|
|
resource_extn_mgr = _global_extn_mgrs_by_resource[resource_name]
|
|
else:
|
|
resource_extn_mgr = _get_extension_manager_of_resource(resource_name)
|
|
|
|
try:
|
|
resource_vendor_extn = resource_extn_mgr[vendor.lower()]
|
|
except KeyError:
|
|
raise exceptions.OEMExtensionNotFoundError(
|
|
resource=resource_name, name=vendor.lower())
|
|
|
|
if resource_vendor_extn.obj is None:
|
|
return _get_resource_vendor_extension_obj(
|
|
resource_vendor_extn, resource, *args, **kwds)
|
|
return resource_vendor_extn.obj
|