blob: 1bf53a7c77225dc4113917489767c3d51a23faaa [file] [log] [blame]
George Keishingf2613b72019-02-13 12:45:59 -06001#!/usr/bin/env python
2
3r"""
4BMC redfish utility functions.
5"""
6
7import json
8from robot.libraries.BuiltIn import BuiltIn
9
10
11class bmc_redfish_utils(object):
12
13 def __init__(self):
14 r"""
15 Initialize the bmc_redfish_utils object.
16 """
17 # Obtain a reference to the global redfish object.
18 self._redfish_ = BuiltIn().get_library_instance('redfish')
19
George Keishing374e6842019-02-20 08:57:18 -060020 def get_redfish_session_info(self):
21 r"""
22 Returns redfish sessions info dictionary.
23
24 {
25 'key': 'yLXotJnrh5nDhXj5lLiH' ,
26 'location': '/redfish/v1/SessionService/Sessions/nblYY4wlz0'
27 }
28 """
29 session_dict = {
George Keishing97c93942019-03-04 12:45:07 -060030 "key": self._redfish_.get_session_key(),
31 "location": self._redfish_.get_session_location()
George Keishing374e6842019-02-20 08:57:18 -060032 }
33 return session_dict
34
George Keishingf2613b72019-02-13 12:45:59 -060035 def get_attribute(self, resource_path, attribute):
36 r"""
37 Get resource attribute.
38
39 Description of argument(s):
40 resource_path URI resource absolute path (e.g. "/redfish/v1/Systems/1").
41 attribute Name of the attribute (e.g. 'PowerState').
42 """
43
44 resp = self._redfish_.get(resource_path)
45 if attribute in resp.dict:
46 return resp.dict[attribute]
47
48 return None
49
George Keishingc3c05c22019-02-19 01:04:54 -060050 def get_properties(self, resource_path):
51 r"""
52 Returns dictionary of attributes for the resource.
53
54 Description of argument(s):
55 resource_path URI resource absolute path (e.g. "/redfish/v1/Systems/1").
56 """
57
58 resp = self._redfish_.get(resource_path)
59 return resp.dict
60
George Keishing7ec45932019-02-27 14:02:16 -060061 def get_target_actions(self, resource_path, target_attribute):
62 r"""
63 Returns resource target entry of the searched target attribute.
64
65 Description of argument(s):
66 resource_path URI resource absolute path
67 (e.g. "/redfish/v1/Systems/system").
68 target_attribute Name of the attribute (e.g. 'ComputerSystem.Reset').
69
70 Example:
71 "Actions": {
72 "#ComputerSystem.Reset": {
73 "ResetType@Redfish.AllowableValues": [
74 "On",
75 "ForceOff",
76 "GracefulRestart",
77 "GracefulShutdown"
78 ],
79 "target": "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
80 }
81 }
82 """
83
84 global target_list
85 target_list = []
86
87 resp_dict = self.get_attribute(resource_path, "Actions")
88 if resp_dict is None:
89 return None
90
91 # Recursively search the "target" key in the nested dictionary.
92 # Populate the target_list of target entries.
93 self.get_key_value_nested_dict(resp_dict, "target")
94
95 # Return the matching target URL entry.
96 for target in target_list:
97 # target "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
98 if target_attribute in target:
99 return target
100
101 return None
102
George Keishingf2613b72019-02-13 12:45:59 -0600103 def list_request(self, resource_path):
104 r"""
105 Perform a GET list request and return available resource paths.
106
107 Description of argument(s):
108 resource_path URI resource absolute path
109 (e.g. "/redfish/v1/SessionService/Sessions").
110 """
111
112 global resource_list
113 resource_list = []
George Keishing97c93942019-03-04 12:45:07 -0600114 self._rest_response_ = \
115 self._redfish_.get(resource_path, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600116
117 # Return empty list.
118 if self._rest_response_.status != 200:
119 return resource_list
120
121 self.walk_nested_dict(self._rest_response_.dict)
122
123 if not resource_list:
124 return uri_path
125
126 for resource in resource_list:
George Keishing97c93942019-03-04 12:45:07 -0600127 self._rest_response_ = \
128 self._redfish_.get(resource, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600129 if self._rest_response_.status != 200:
130 continue
131 self.walk_nested_dict(self._rest_response_.dict)
132
133 resource_list.sort()
134 return resource_list
135
136 def enumerate_request(self, resource_path):
137 r"""
138 Perform a GET enumerate request and return available resource paths.
139
140 Description of argument(s):
141 resource_path URI resource absolute path
142 (e.g. "/redfish/v1/SessionService/Sessions").
143 """
144
145 url_list = self.list_request(resource_path)
146
147 resource_dict = {}
148
149 # Return empty dict.
150 if not url_list:
151 return resource_dict
152
153 for resource in url_list:
George Keishing48156e72019-02-18 13:05:55 -0600154 # JsonSchemas data are not required in enumeration.
155 # Example: '/redfish/v1/JsonSchemas/' and sub resources.
156 if 'JsonSchemas' in resource:
157 continue
George Keishing97c93942019-03-04 12:45:07 -0600158 self._rest_response_ = \
159 self._redfish_.get(resource, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600160 if self._rest_response_.status != 200:
161 continue
162 resource_dict[resource] = self._rest_response_.dict
163
164 return json.dumps(resource_dict, sort_keys=True,
165 indent=4, separators=(',', ': '))
166
167 def walk_nested_dict(self, data):
168 r"""
169 Parse through the nested dictionary and get the resource id paths.
170
171 Description of argument(s):
172 data Nested dictionary data from response message.
173 """
174
175 for key, value in data.items():
176 if isinstance(value, dict):
177 self.walk_nested_dict(value)
178 else:
179 if 'Members' == key:
180 if isinstance(value, list):
181 for index in value:
182 if index['@odata.id'] not in resource_list:
183 resource_list.append(index['@odata.id'])
184 if '@odata.id' == key:
185 if value not in resource_list and not value.endswith('/'):
186 resource_list.append(value)
George Keishing7ec45932019-02-27 14:02:16 -0600187
188 def get_key_value_nested_dict(self, data, key):
189 r"""
190 Parse through the nested dictionary and get the searched key value.
191
192 Description of argument(s):
193 data Nested dictionary data from response message.
194 key Search dictionary key element.
195 """
196
197 for k, v in data.items():
198 if isinstance(v, dict):
199 self.get_key_value_nested_dict(v, key)
200
201 if k == key:
202 target_list.append(v)