blob: 492a1a35002eac318712caba82312bd30ccfd415 [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 = {
30 "key": self._redfish_._session_key_,
31 "location": self._redfish_._session_location_
32 }
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 = []
114
115 self._rest_response_ = self._redfish_.get(resource_path)
116
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:
127 self._rest_response_ = self._redfish_.get(resource)
128 if self._rest_response_.status != 200:
129 continue
130 self.walk_nested_dict(self._rest_response_.dict)
131
132 resource_list.sort()
133 return resource_list
134
135 def enumerate_request(self, resource_path):
136 r"""
137 Perform a GET enumerate request and return available resource paths.
138
139 Description of argument(s):
140 resource_path URI resource absolute path
141 (e.g. "/redfish/v1/SessionService/Sessions").
142 """
143
144 url_list = self.list_request(resource_path)
145
146 resource_dict = {}
147
148 # Return empty dict.
149 if not url_list:
150 return resource_dict
151
152 for resource in url_list:
George Keishing48156e72019-02-18 13:05:55 -0600153 # JsonSchemas data are not required in enumeration.
154 # Example: '/redfish/v1/JsonSchemas/' and sub resources.
155 if 'JsonSchemas' in resource:
156 continue
George Keishingf2613b72019-02-13 12:45:59 -0600157 self._rest_response_ = self._redfish_.get(resource)
158 if self._rest_response_.status != 200:
159 continue
160 resource_dict[resource] = self._rest_response_.dict
161
162 return json.dumps(resource_dict, sort_keys=True,
163 indent=4, separators=(',', ': '))
164
165 def walk_nested_dict(self, data):
166 r"""
167 Parse through the nested dictionary and get the resource id paths.
168
169 Description of argument(s):
170 data Nested dictionary data from response message.
171 """
172
173 for key, value in data.items():
174 if isinstance(value, dict):
175 self.walk_nested_dict(value)
176 else:
177 if 'Members' == key:
178 if isinstance(value, list):
179 for index in value:
180 if index['@odata.id'] not in resource_list:
181 resource_list.append(index['@odata.id'])
182 if '@odata.id' == key:
183 if value not in resource_list and not value.endswith('/'):
184 resource_list.append(value)
George Keishing7ec45932019-02-27 14:02:16 -0600185
186 def get_key_value_nested_dict(self, data, key):
187 r"""
188 Parse through the nested dictionary and get the searched key value.
189
190 Description of argument(s):
191 data Nested dictionary data from response message.
192 key Search dictionary key element.
193 """
194
195 for k, v in data.items():
196 if isinstance(v, dict):
197 self.get_key_value_nested_dict(v, key)
198
199 if k == key:
200 target_list.append(v)