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_attribute(self, resource_path, attribute): 21 r""" 22 Get resource attribute. 23 24 Description of argument(s): 25 resource_path URI resource absolute path (e.g. "/redfish/v1/Systems/1"). 26 attribute Name of the attribute (e.g. 'PowerState'). 27 """ 28 29 resp = self._redfish_.get(resource_path) 30 if attribute in resp.dict: 31 return resp.dict[attribute] 32 33 return None 34 35 def get_properties(self, resource_path): 36 r""" 37 Returns dictionary of attributes for the resource. 38 39 Description of argument(s): 40 resource_path URI resource absolute path (e.g. "/redfish/v1/Systems/1"). 41 """ 42 43 resp = self._redfish_.get(resource_path) 44 return resp.dict 45 46 def list_request(self, resource_path): 47 r""" 48 Perform a GET list request and return available resource paths. 49 50 Description of argument(s): 51 resource_path URI resource absolute path 52 (e.g. "/redfish/v1/SessionService/Sessions"). 53 """ 54 55 global resource_list 56 resource_list = [] 57 58 self._rest_response_ = self._redfish_.get(resource_path) 59 60 # Return empty list. 61 if self._rest_response_.status != 200: 62 return resource_list 63 64 self.walk_nested_dict(self._rest_response_.dict) 65 66 if not resource_list: 67 return uri_path 68 69 for resource in resource_list: 70 self._rest_response_ = self._redfish_.get(resource) 71 if self._rest_response_.status != 200: 72 continue 73 self.walk_nested_dict(self._rest_response_.dict) 74 75 resource_list.sort() 76 return resource_list 77 78 def enumerate_request(self, resource_path): 79 r""" 80 Perform a GET enumerate request and return available resource paths. 81 82 Description of argument(s): 83 resource_path URI resource absolute path 84 (e.g. "/redfish/v1/SessionService/Sessions"). 85 """ 86 87 url_list = self.list_request(resource_path) 88 89 resource_dict = {} 90 91 # Return empty dict. 92 if not url_list: 93 return resource_dict 94 95 for resource in url_list: 96 # JsonSchemas data are not required in enumeration. 97 # Example: '/redfish/v1/JsonSchemas/' and sub resources. 98 if 'JsonSchemas' in resource: 99 continue 100 self._rest_response_ = self._redfish_.get(resource) 101 if self._rest_response_.status != 200: 102 continue 103 resource_dict[resource] = self._rest_response_.dict 104 105 return json.dumps(resource_dict, sort_keys=True, 106 indent=4, separators=(',', ': ')) 107 108 def walk_nested_dict(self, data): 109 r""" 110 Parse through the nested dictionary and get the resource id paths. 111 112 Description of argument(s): 113 data Nested dictionary data from response message. 114 """ 115 116 for key, value in data.items(): 117 if isinstance(value, dict): 118 self.walk_nested_dict(value) 119 else: 120 if 'Members' == key: 121 if isinstance(value, list): 122 for index in value: 123 if index['@odata.id'] not in resource_list: 124 resource_list.append(index['@odata.id']) 125 if '@odata.id' == key: 126 if value not in resource_list and not value.endswith('/'): 127 resource_list.append(value) 128