1#!/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 20 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 35 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 50 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 61 def list_request(self, resource_path): 62 r""" 63 Perform a GET list request and return available resource paths. 64 65 Description of argument(s): 66 resource_path URI resource absolute path 67 (e.g. "/redfish/v1/SessionService/Sessions"). 68 """ 69 70 global resource_list 71 resource_list = [] 72 73 self._rest_response_ = self._redfish_.get(resource_path) 74 75 # Return empty list. 76 if self._rest_response_.status != 200: 77 return resource_list 78 79 self.walk_nested_dict(self._rest_response_.dict) 80 81 if not resource_list: 82 return uri_path 83 84 for resource in resource_list: 85 self._rest_response_ = self._redfish_.get(resource) 86 if self._rest_response_.status != 200: 87 continue 88 self.walk_nested_dict(self._rest_response_.dict) 89 90 resource_list.sort() 91 return resource_list 92 93 def enumerate_request(self, resource_path): 94 r""" 95 Perform a GET enumerate request and return available resource paths. 96 97 Description of argument(s): 98 resource_path URI resource absolute path 99 (e.g. "/redfish/v1/SessionService/Sessions"). 100 """ 101 102 url_list = self.list_request(resource_path) 103 104 resource_dict = {} 105 106 # Return empty dict. 107 if not url_list: 108 return resource_dict 109 110 for resource in url_list: 111 # JsonSchemas data are not required in enumeration. 112 # Example: '/redfish/v1/JsonSchemas/' and sub resources. 113 if 'JsonSchemas' in resource: 114 continue 115 self._rest_response_ = self._redfish_.get(resource) 116 if self._rest_response_.status != 200: 117 continue 118 resource_dict[resource] = self._rest_response_.dict 119 120 return json.dumps(resource_dict, sort_keys=True, 121 indent=4, separators=(',', ': ')) 122 123 def walk_nested_dict(self, data): 124 r""" 125 Parse through the nested dictionary and get the resource id paths. 126 127 Description of argument(s): 128 data Nested dictionary data from response message. 129 """ 130 131 for key, value in data.items(): 132 if isinstance(value, dict): 133 self.walk_nested_dict(value) 134 else: 135 if 'Members' == key: 136 if isinstance(value, list): 137 for index in value: 138 if index['@odata.id'] not in resource_list: 139 resource_list.append(index['@odata.id']) 140 if '@odata.id' == key: 141 if value not in resource_list and not value.endswith('/'): 142 resource_list.append(value) 143