redfish_utils: add support to automate multiple systems. (#50854)

* Add support to automate multiple systems

Currently `redfish_utils` module can support only one system.
These changes introduce the ability to support multiple systems.

* Update - add support to automate multiple systems

* Introduce `aggregate()` to avoid code duplication in `get_multi___` like
methods.

* Remove "set" related methods

* include systems URI in each aggregated entry

* rebased

* Fixes KeyError and merge errors
This commit is contained in:
Dhanuka 2019-03-11 20:58:42 +00:00 committed by Jordan Borean
parent 4c1476932e
commit da9b19cef7
2 changed files with 81 additions and 42 deletions

View file

@ -127,20 +127,16 @@ class RedfishUtils(object):
data = response['data'] data = response['data']
if 'Systems' not in data: if 'Systems' not in data:
return {'ret': False, 'msg': "Systems resource not found"} return {'ret': False, 'msg': "Systems resource not found"}
else: response = self.get_request(self.root_uri + data['Systems']['@odata.id'])
systems = data["Systems"]["@odata.id"] if response['ret'] is False:
response = self.get_request(self.root_uri + systems) return response
if response['ret'] is False: self.systems_uris = [
return response i['@odata.id'] for i in response['data'].get('Members', [])]
data = response['data'] if not self.systems_uris:
if data.get(u'Members'): return {
for member in data[u'Members']: 'ret': False,
systems_service = member[u'@odata.id'] 'msg': "ComputerSystem's Members array is either empty or missing"}
self.systems_uri = systems_service return {'ret': True}
return {'ret': True}
else:
return {'ret': False,
'msg': "ComputerSystem's Members array is either empty or missing"}
def _find_updateservice_resource(self, uri): def _find_updateservice_resource(self, uri):
response = self.get_request(self.root_uri + uri) response = self.get_request(self.root_uri + uri)
@ -275,7 +271,18 @@ class RedfishUtils(object):
return response return response
return {'ret': True} return {'ret': True}
def get_storage_controller_inventory(self): def aggregate(self, func):
ret = True
entries = []
for systems_uri in self.systems_uris:
inventory = func(systems_uri)
ret = inventory.pop('ret') and ret
if 'entries' in inventory:
entries.append(({'systems_uri': systems_uri},
inventory['entries']))
return dict(ret=ret, entries=entries)
def get_storage_controller_inventory(self, systems_uri):
result = {} result = {}
controller_list = [] controller_list = []
controller_results = [] controller_results = []
@ -286,7 +293,7 @@ class RedfishUtils(object):
key = "StorageControllers" key = "StorageControllers"
# Find Storage service # Find Storage service
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
data = response['data'] data = response['data']
@ -323,7 +330,10 @@ class RedfishUtils(object):
else: else:
return {'ret': False, 'msg': "Storage resource not found"} return {'ret': False, 'msg': "Storage resource not found"}
def get_disk_inventory(self): def get_multi_storage_controller_inventory(self):
return self.aggregate(self.get_storage_controller_inventory)
def get_disk_inventory(self, systems_uri):
result = {'entries': []} result = {'entries': []}
controller_list = [] controller_list = []
disk_results = [] disk_results = []
@ -336,7 +346,7 @@ class RedfishUtils(object):
'RotationSpeedRPM', 'SerialNumber', 'Status'] 'RotationSpeedRPM', 'SerialNumber', 'Status']
# Find Storage service # Find Storage service
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
data = response['data'] data = response['data']
@ -406,6 +416,9 @@ class RedfishUtils(object):
return result return result
def get_multi_disk_inventory(self):
return self.aggregate(self.get_disk_inventory)
def restart_manager_gracefully(self): def restart_manager_gracefully(self):
result = {} result = {}
key = "Actions" key = "Actions"
@ -429,7 +442,7 @@ class RedfishUtils(object):
key = "Actions" key = "Actions"
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + self.systems_uris[0])
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -577,13 +590,13 @@ class RedfishUtils(object):
result['entries'].append(firmware) result['entries'].append(firmware)
return result return result
def get_bios_attributes(self): def get_bios_attributes(self, systems_uri):
result = {} result = {}
bios_attributes = {} bios_attributes = {}
key = "Bios" key = "Bios"
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -604,13 +617,16 @@ class RedfishUtils(object):
result["entries"] = bios_attributes result["entries"] = bios_attributes
return result return result
def get_boot_order(self): def get_multi_bios_attributes(self):
return self.aggregate(self.get_bios_attributes)
def get_boot_order(self, systems_uri):
result = {} result = {}
# Get these entries from BootOption, if present # Get these entries from BootOption, if present
properties = ['DisplayName', 'BootOptionReference'] properties = ['DisplayName', 'BootOptionReference']
# Retrieve System resource # Retrieve System resource
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -673,12 +689,15 @@ class RedfishUtils(object):
result["entries"] = boot_device_list result["entries"] = boot_device_list
return result return result
def get_multi_boot_order(self):
return self.aggregate(self.get_boot_order)
def set_bios_default_settings(self): def set_bios_default_settings(self):
result = {} result = {}
key = "Bios" key = "Bios"
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + self.systems_uris[0])
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -707,7 +726,7 @@ class RedfishUtils(object):
key = "Bios" key = "Bios"
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + self.systems_uris[0])
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -729,7 +748,7 @@ class RedfishUtils(object):
else: else:
payload = {"Boot": {"BootSourceOverrideTarget": bootdevice}} payload = {"Boot": {"BootSourceOverrideTarget": bootdevice}}
response = self.patch_request(self.root_uri + self.systems_uri, payload, HEADERS) response = self.patch_request(self.root_uri + self.systems_uris[0], payload, HEADERS)
if response['ret'] is False: if response['ret'] is False:
return response return response
return {'ret': True} return {'ret': True}
@ -739,7 +758,7 @@ class RedfishUtils(object):
key = "Bios" key = "Bios"
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + self.systems_uris[0])
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -807,7 +826,7 @@ class RedfishUtils(object):
result["entries"] = fan_results result["entries"] = fan_results
return result return result
def get_cpu_inventory(self): def get_cpu_inventory(self, systems_uri):
result = {} result = {}
cpu_list = [] cpu_list = []
cpu_results = [] cpu_results = []
@ -817,7 +836,7 @@ class RedfishUtils(object):
'TotalThreads', 'Status'] 'TotalThreads', 'Status']
# Search for 'key' entry and extract URI from it # Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -854,7 +873,10 @@ class RedfishUtils(object):
result["entries"] = cpu_results result["entries"] = cpu_results
return result return result
def get_nic_inventory(self, resource_type): def get_multi_cpu_inventory(self):
return self.aggregate(self.get_cpu_inventory)
def get_nic_inventory(self, resource_type, systems_uri):
result = {} result = {}
nic_list = [] nic_list = []
nic_results = [] nic_results = []
@ -866,7 +888,7 @@ class RedfishUtils(object):
# Given resource_type, use the proper URI # Given resource_type, use the proper URI
if resource_type == 'Systems': if resource_type == 'Systems':
resource_uri = self.systems_uri resource_uri = systems_uri
elif resource_type == 'Manager': elif resource_type == 'Manager':
resource_uri = self.manager_uri resource_uri = self.manager_uri
@ -907,7 +929,18 @@ class RedfishUtils(object):
result["entries"] = nic_results result["entries"] = nic_results
return result return result
def get_psu_inventory(self): def get_multi_nic_inventory(self, resource_type):
ret = True
entries = []
for systems_uri in self.systems_uris:
inventory = self.get_nic_inventory(resource_type, systems_uri)
ret = inventory.pop('ret') and ret
if 'entries' in inventory:
entries.append(({'systems_uri': systems_uri},
inventory['entries']))
return dict(ret=ret, entries=entries)
def get_psu_inventory(self, systems_uri):
result = {} result = {}
psu_list = [] psu_list = []
psu_results = [] psu_results = []
@ -960,7 +993,10 @@ class RedfishUtils(object):
return {'ret': False, 'msg': "No PowerSupply objects found"} return {'ret': False, 'msg': "No PowerSupply objects found"}
return result return result
def get_system_inventory(self): def get_multi_psu_inventory(self):
return self.aggregate(self.get_psu_inventory)
def get_system_inventory(self, systems_uri):
result = {} result = {}
inventory = {} inventory = {}
# Get these entries, but does not fail if not found # Get these entries, but does not fail if not found
@ -969,7 +1005,7 @@ class RedfishUtils(object):
'SerialNumber', 'SKU', 'BiosVersion', 'MemorySummary', 'SerialNumber', 'SKU', 'BiosVersion', 'MemorySummary',
'ProcessorSummary', 'TrustedModules'] 'ProcessorSummary', 'TrustedModules']
response = self.get_request(self.root_uri + self.systems_uri) response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False: if response['ret'] is False:
return response return response
result['ret'] = True result['ret'] = True
@ -981,3 +1017,6 @@ class RedfishUtils(object):
result["entries"] = inventory result["entries"] = inventory
return result return result
def get_multi_system_inventory(self):
return self.aggregate(self.get_system_inventory)

View file

@ -210,19 +210,19 @@ def main():
for command in command_list: for command in command_list:
if command == "GetSystemInventory": if command == "GetSystemInventory":
result["system"] = rf_utils.get_system_inventory() result["system"] = rf_utils.get_multi_system_inventory()
elif command == "GetCpuInventory": elif command == "GetCpuInventory":
result["cpu"] = rf_utils.get_cpu_inventory() result["cpu"] = rf_utils.get_multi_cpu_inventory()
elif command == "GetNicInventory": elif command == "GetNicInventory":
result["nic"] = rf_utils.get_nic_inventory(category) result["nic"] = rf_utils.get_multi_nic_inventory(category)
elif command == "GetStorageControllerInventory": elif command == "GetStorageControllerInventory":
result["storage_controller"] = rf_utils.get_storage_controller_inventory() result["storage_controller"] = rf_utils.get_multi_storage_controller_inventory()
elif command == "GetDiskInventory": elif command == "GetDiskInventory":
result["disk"] = rf_utils.get_disk_inventory() result["disk"] = rf_utils.get_multi_disk_inventory()
elif command == "GetBiosAttributes": elif command == "GetBiosAttributes":
result["bios_attribute"] = rf_utils.get_bios_attributes() result["bios_attribute"] = rf_utils.get_multi_bios_attributes()
elif command == "GetBootOrder": elif command == "GetBootOrder":
result["boot_order"] = rf_utils.get_boot_order() result["boot_order"] = rf_utils.get_multi_boot_order()
elif category == "Chassis": elif category == "Chassis":
# execute only if we find Chassis resource # execute only if we find Chassis resource
@ -264,7 +264,7 @@ def main():
for command in command_list: for command in command_list:
if command == "GetManagerNicInventory": if command == "GetManagerNicInventory":
result["manager_nics"] = rf_utils.get_nic_inventory(resource_type=category) result["manager_nics"] = rf_utils.get_multi_nic_inventory(resource_type=category)
elif command == "GetLogs": elif command == "GetLogs":
result["log"] = rf_utils.get_logs() result["log"] = rf_utils.get_logs()