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:
parent
4c1476932e
commit
da9b19cef7
2 changed files with 81 additions and 42 deletions
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue