File: common.py

package info (click to toggle)
python-sushy 5.7.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,036 kB
  • sloc: python: 16,382; makefile: 24; sh: 2
file content (110 lines) | stat: -rw-r--r-- 4,227 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# 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=f'Failed to load entry point target: {e}')


def _create_extension_manager(namespace: str, resource_name: str):
    """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.
    """
    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 = (f'No extensions found for "{resource_name}" under namespace '
             f'"{namespace}"')
        LOG.error(m)
        raise exceptions.ExtensionError(error=m)

    return extension_manager


@utils.synchronized
def _get_extension_manager_of_resource(resource_name: str):
    """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 = f'sushy.resources.{resource_name}.oems'
        _global_extn_mgrs_by_resource[resource_name] = (
            _create_extension_manager(resource_namespace, resource_name)
        )
    return _global_extn_mgrs_by_resource[resource_name]


def get_resource_extension_by_vendor(
        resource_name, vendor, resource):
    """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())

    oem_resource = resource_vendor_extn.plugin()
    return resource.clone_resource(
        oem_resource).set_parent_resource(resource, vendor)