blob: bf8ac293aaf780b9c29940e23eb4bbbe6c1eaa42 [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 Keishingdabf38f2019-03-10 09:52:40 -0500103 def get_member_list(self, resource_path):
104 r"""
105 Perform a GET list request and return available members entries.
106
107 Description of argument(s):
108 resource_path URI resource absolute path
109 (e.g. "/redfish/v1/SessionService/Sessions").
110
111 "Members": [
112 {
113 "@odata.id": "/redfish/v1/SessionService/Sessions/Z5HummWPZ7"
114 }
115 {
116 "@odata.id": "/redfish/v1/SessionService/Sessions/46CmQmEL7H"
117 }
118 ],
119 """
120
121 member_list = []
122 resp_list_dict = self.get_attribute(resource_path, "Members")
123 if resp_list_dict is None:
124 return member_list
125
126 for member_id in range(0, len(resp_list_dict)):
127 member_list.append(resp_list_dict[member_id]["@odata.id"])
128
129 return member_list
130
George Keishingf2613b72019-02-13 12:45:59 -0600131 def list_request(self, resource_path):
132 r"""
133 Perform a GET list request and return available resource paths.
134
135 Description of argument(s):
136 resource_path URI resource absolute path
137 (e.g. "/redfish/v1/SessionService/Sessions").
138 """
139
140 global resource_list
141 resource_list = []
George Keishingdabf38f2019-03-10 09:52:40 -0500142 self._rest_response_ = self._redfish_.get(resource_path, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600143
144 # Return empty list.
145 if self._rest_response_.status != 200:
146 return resource_list
147
148 self.walk_nested_dict(self._rest_response_.dict)
149
150 if not resource_list:
151 return uri_path
152
153 for resource in resource_list:
George Keishingdabf38f2019-03-10 09:52:40 -0500154 self._rest_response_ = self._redfish_.get(resource, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600155 if self._rest_response_.status != 200:
156 continue
157 self.walk_nested_dict(self._rest_response_.dict)
158
159 resource_list.sort()
160 return resource_list
161
162 def enumerate_request(self, resource_path):
163 r"""
164 Perform a GET enumerate request and return available resource paths.
165
166 Description of argument(s):
167 resource_path URI resource absolute path
168 (e.g. "/redfish/v1/SessionService/Sessions").
169 """
170
171 url_list = self.list_request(resource_path)
172
173 resource_dict = {}
174
175 # Return empty dict.
176 if not url_list:
177 return resource_dict
178
179 for resource in url_list:
George Keishing48156e72019-02-18 13:05:55 -0600180 # JsonSchemas data are not required in enumeration.
181 # Example: '/redfish/v1/JsonSchemas/' and sub resources.
182 if 'JsonSchemas' in resource:
183 continue
George Keishingdabf38f2019-03-10 09:52:40 -0500184 self._rest_response_ = self._redfish_.get(resource, valid_status_codes=[200, 404, 500])
George Keishingf2613b72019-02-13 12:45:59 -0600185 if self._rest_response_.status != 200:
186 continue
187 resource_dict[resource] = self._rest_response_.dict
188
189 return json.dumps(resource_dict, sort_keys=True,
190 indent=4, separators=(',', ': '))
191
192 def walk_nested_dict(self, data):
193 r"""
194 Parse through the nested dictionary and get the resource id paths.
195
196 Description of argument(s):
197 data Nested dictionary data from response message.
198 """
199
200 for key, value in data.items():
201 if isinstance(value, dict):
202 self.walk_nested_dict(value)
203 else:
204 if 'Members' == key:
205 if isinstance(value, list):
206 for index in value:
207 if index['@odata.id'] not in resource_list:
208 resource_list.append(index['@odata.id'])
209 if '@odata.id' == key:
210 if value not in resource_list and not value.endswith('/'):
211 resource_list.append(value)
George Keishing7ec45932019-02-27 14:02:16 -0600212
213 def get_key_value_nested_dict(self, data, key):
214 r"""
215 Parse through the nested dictionary and get the searched key value.
216
217 Description of argument(s):
218 data Nested dictionary data from response message.
219 key Search dictionary key element.
220 """
221
222 for k, v in data.items():
223 if isinstance(v, dict):
224 self.get_key_value_nested_dict(v, key)
225
226 if k == key:
227 target_list.append(v)