-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathresource_manager.py
156 lines (137 loc) · 5.98 KB
/
resource_manager.py
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Copyright Notice:
# Copyright 2016-2019 DMTF. All rights reserved.
# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Interface-Emulator/blob/master/LICENSE.md
#
# The original DMTF contents of this file have been modified to support
# The CSM Redfish Interface Emulator. These modifications are subject to the following:
# Copyright 2022 Hewlett Packard Enterprise Development LP
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# Resource Manager Module
# External imports
import os
import json
from uuid import uuid4
import logging
import copy
import traceback
# Local imports
import g
from . import utils
from .resource_dictionary import ResourceDictionary
from .static_loader import load_static
from .redfish.redfish_auth import auth
from .redfish.redfish_api import RedfishAPI, RedfishBaseAPI, CreateRedfishBase
# BMC mockup imports
from .loader import Loader
from .ex235a_loader import EX235a
# The ResourceManager __init__ method sets up the static and dynamic
# resources.
#
# When a resource is accessed, the resource is sought in the following
# order:
# 1. Dynamic resources for specific URIs
# 2. Default dynamic resources
# 3. Static resource dictionary
#
# This allows specific resources to be implemented as dynamic resources
# while leaving the remainder of the URI path as static resources.
#
# Static resources are loaded from the ./redfish/static directory.
# This directory is a copy of the one of the ./mockups directories.
#
# Dynamic resources are attached to endpoints using the Flask-restful
# mechanism, not the Flask mechanism.
# - This involves associating an API class to a resource endpoint.
# A collection resource requires the association of the collection
# resource and the member resource(s).
# - Once the API is added, explicit calls can be made to one or more
# singleton resources that have been populated.
# - The EgResource* and EgSubResource* files provide examples of how
# to add dynamic resources.
#
# Note: There is one additional change that needs to be made in order
# to create multiple instances of a resource. The resource endpoint
# for a second instance will collide with the first, because flask does
# not re-use endpoint names for subordinate resources. This results
# in an assertion error failure:
# "AssertionError: View function mapping is overwriting an existing
# endpoint function"
#
# The fix would be to form unique endpoint names and pass them in
# with the call to api_add_resource(), as shown in the following:
# api.add_resource(Todo, '/todo/<int:todo_id>', endpoint='todo_ep')
class ResourceManager(object):
"""
ResourceManager Class
Load static resources and dynamic resources
Defines ServiceRoot
"""
def __init__(self, rest_base, spec, mode, config_data):
"""
Arguments:
rest_base - Base URL for the REST interface
spec - Which spec to use, Redfish
When a resource is accessed, the resource is sought in the following order
1. Dynamic resource for specific URI
2. Static resource dictionary
"""
self.rest_base = rest_base
self.mode = mode
self.spec = spec
self.modified = utils.timestamp()
self.uuid = str(uuid4())
self.time = self.modified
# Load the static resources into the dictionary
self.resource_dictionary = ResourceDictionary()
mockupfolder = copy.copy(g.staticfolder)
self.Root = load_static(mockupfolder, 'redfish', mode, rest_base, self.resource_dictionary)
# Sync auth with the Mockup's Account Service
# This will add accounts that were specified via ENV or the default accounts
auth.sync_with_account_service(self.resource_dictionary)
# Add the base resource
g.api.add_resource(RedfishBaseAPI, '/redfish/v1/')
# This is a catch all for any static resource defined above by the Mockup that is not defined below as a dynamic resource.
g.api.add_resource(RedfishAPI, '/redfish/v1/<path:path>')
CreateRedfishBase(self)
if 'EX235a' == mockupfolder:
self.BMC = EX235a(self.resource_dictionary, config_data)
else:
self.BMC = Loader(self.resource_dictionary, config_data, mockupfolder)
@property
def configuration(self):
"""
Configuration property - Service Root
"""
config = self.get_resource('')
return config
def get_resource(self, path):
"""
Call Resource_Dictionary's get_resource
"""
obj = self.resource_dictionary.get_resource(path)
return obj