Add option to specify ID of System/Manager/Chassis to modify (#62921)

* add option to specify ID of System/Manager/Chassis to modify

* added version to deprecate() call

* fix merge TODOs to use new self.systems_uri variable
This commit is contained in:
Bill Dodd 2019-10-31 17:09:48 -05:00 committed by John R Barker
parent c3838b5d73
commit 4349ab5777
5 changed files with 149 additions and 38 deletions

View file

@ -17,15 +17,24 @@ PATCH_HEADERS = {'content-type': 'application/json', 'accept': 'application/json
'OData-Version': '4.0'}
DELETE_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'}
DEPRECATE_MSG = 'Issuing a data modification command without specifying the '\
'ID of the target %(resource)s resource when there is more '\
'than one %(resource)s will use the first one in the '\
'collection. Use the `resource_id` option to specify the '\
'target %(resource)s ID'
class RedfishUtils(object):
def __init__(self, creds, root_uri, timeout, module):
def __init__(self, creds, root_uri, timeout, module, resource_id=None,
data_modification=False):
self.root_uri = root_uri
self.creds = creds
self.timeout = timeout
self.module = module
self.service_root = '/redfish/v1/'
self.resource_id = resource_id
self.data_modification = data_modification
self._init_session()
# The following functions are to send GET/POST/PATCH/DELETE requests
@ -198,6 +207,16 @@ class RedfishUtils(object):
self.sessions_uri = sessions
return {'ret': True}
def _get_resource_uri_by_id(self, uris, id_prop):
for uri in uris:
response = self.get_request(self.root_uri + uri)
if response['ret'] is False:
continue
data = response['data']
if id_prop == data.get('Id'):
return uri
return None
def _find_systems_resource(self):
response = self.get_request(self.root_uri + self.service_root)
if response['ret'] is False:
@ -214,6 +233,18 @@ class RedfishUtils(object):
return {
'ret': False,
'msg': "ComputerSystem's Members array is either empty or missing"}
self.systems_uri = self.systems_uris[0]
if self.data_modification:
if self.resource_id:
self.systems_uri = self._get_resource_uri_by_id(self.systems_uris,
self.resource_id)
if not self.systems_uri:
return {
'ret': False,
'msg': "System resource %s not found" % self.resource_id}
elif len(self.systems_uris) > 1:
self.module.deprecate(DEPRECATE_MSG % {'resource': 'System'},
version='2.13')
return {'ret': True}
def _find_updateservice_resource(self):
@ -245,16 +276,28 @@ class RedfishUtils(object):
data = response['data']
if 'Chassis' not in data:
return {'ret': False, 'msg': "Chassis resource not found"}
else:
chassis = data["Chassis"]["@odata.id"]
response = self.get_request(self.root_uri + chassis)
if response['ret'] is False:
return response
data = response['data']
for member in data[u'Members']:
chassis_service.append(member[u'@odata.id'])
self.chassis_uri_list = chassis_service
return {'ret': True}
chassis = data["Chassis"]["@odata.id"]
response = self.get_request(self.root_uri + chassis)
if response['ret'] is False:
return response
self.chassis_uri_list = [
i['@odata.id'] for i in response['data'].get('Members', [])]
if not self.chassis_uri_list:
return {'ret': False,
'msg': "Chassis Members array is either empty or missing"}
self.chassis_uri = self.chassis_uri_list[0]
if self.data_modification:
if self.resource_id:
self.chassis_uri = self._get_resource_uri_by_id(self.chassis_uri_list,
self.resource_id)
if not self.chassis_uri:
return {
'ret': False,
'msg': "Chassis resource %s not found" % self.resource_id}
elif len(self.chassis_uri_list) > 1:
self.module.deprecate(DEPRECATE_MSG % {'resource': 'Chassis'},
version='2.13')
return {'ret': True}
def _find_managers_resource(self):
response = self.get_request(self.root_uri + self.service_root)
@ -263,16 +306,28 @@ class RedfishUtils(object):
data = response['data']
if 'Managers' not in data:
return {'ret': False, 'msg': "Manager resource not found"}
else:
manager = data["Managers"]["@odata.id"]
response = self.get_request(self.root_uri + manager)
if response['ret'] is False:
return response
data = response['data']
for member in data[u'Members']:
manager_service = member[u'@odata.id']
self.manager_uri = manager_service
return {'ret': True}
manager = data["Managers"]["@odata.id"]
response = self.get_request(self.root_uri + manager)
if response['ret'] is False:
return response
self.manager_uri_list = [
i['@odata.id'] for i in response['data'].get('Members', [])]
if not self.manager_uri_list:
return {'ret': False,
'msg': "Managers Members array is either empty or missing"}
self.manager_uri = self.manager_uri_list[0]
if self.data_modification:
if self.resource_id:
self.manager_uri = self._get_resource_uri_by_id(self.manager_uri_list,
self.resource_id)
if not self.manager_uri:
return {
'ret': False,
'msg': "Manager resource %s not found" % self.resource_id}
elif len(self.manager_uri_list) > 1:
self.module.deprecate(DEPRECATE_MSG % {'resource': 'Manager'},
version='2.13')
return {'ret': True}
def get_logs(self):
log_svcs_uri_list = []
@ -696,7 +751,7 @@ class RedfishUtils(object):
return {'ret': False, 'msg': 'Invalid Command (%s)' % command}
# read the system resource and get the current power state
response = self.get_request(self.root_uri + self.systems_uris[0])
response = self.get_request(self.root_uri + self.systems_uri)
if response['ret'] is False:
return response
data = response['data']
@ -1317,7 +1372,7 @@ class RedfishUtils(object):
key = "Bios"
# Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uris[0])
response = self.get_request(self.root_uri + self.systems_uri)
if response['ret'] is False:
return response
result['ret'] = True
@ -1350,7 +1405,7 @@ class RedfishUtils(object):
'msg': "bootdevice option required for SetOneTimeBoot"}
# Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uris[0])
response = self.get_request(self.root_uri + self.systems_uri)
if response['ret'] is False:
return response
result['ret'] = True
@ -1414,7 +1469,7 @@ class RedfishUtils(object):
}
}
response = self.patch_request(self.root_uri + self.systems_uris[0], payload)
response = self.patch_request(self.root_uri + self.systems_uri, payload)
if response['ret'] is False:
return response
return {'ret': True, 'changed': True}
@ -1424,7 +1479,7 @@ class RedfishUtils(object):
key = "Bios"
# Search for 'key' entry and extract URI from it
response = self.get_request(self.root_uri + self.systems_uris[0])
response = self.get_request(self.root_uri + self.systems_uri)
if response['ret'] is False:
return response
result['ret'] = True
@ -1473,8 +1528,7 @@ class RedfishUtils(object):
return {'ret': False,
'msg': "boot_order list required for SetBootOrder command"}
# TODO(billdodd): change to self.systems_uri after PR 62921 merged
systems_uri = self.systems_uris[0]
systems_uri = self.systems_uri
response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False:
return response
@ -1512,8 +1566,7 @@ class RedfishUtils(object):
return {'ret': True, 'changed': True, 'msg': "BootOrder set"}
def set_default_boot_order(self):
# TODO(billdodd): change to self.systems_uri after PR 62921 merged
systems_uri = self.systems_uris[0]
systems_uri = self.systems_uri
response = self.get_request(self.root_uri + systems_uri)
if response['ret'] is False:
return response

View file

@ -52,6 +52,12 @@ options:
default: 10
type: int
version_added: '2.8'
resource_id:
required: false
description:
- The ID of the System, Manager or Chassis to modify
type: str
version_added: '2.10'
author: "Jose Delarosa (@jose-delarosa)"
'''
@ -61,6 +67,7 @@ EXAMPLES = '''
idrac_redfish_command:
category: Systems
command: CreateBiosConfigJob
resource_id: System.Embedded.1
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
@ -137,7 +144,8 @@ def main():
baseuri=dict(required=True),
username=dict(required=True),
password=dict(required=True, no_log=True),
timeout=dict(type='int', default=10)
timeout=dict(type='int', default=10),
resource_id=dict()
),
supports_check_mode=False
)
@ -152,9 +160,13 @@ def main():
# timeout
timeout = module.params['timeout']
# System, Manager or Chassis ID to modify
resource_id = module.params['resource_id']
# Build root URI
root_uri = "https://" + module.params['baseuri']
rf_utils = IdracRedfishUtils(creds, root_uri, timeout, module)
rf_utils = IdracRedfishUtils(creds, root_uri, timeout, module,
resource_id=resource_id, data_modification=True)
# Check that Category is valid
if category not in CATEGORY_COMMANDS_ALL:

View file

@ -63,6 +63,12 @@ options:
- Timeout in seconds for URL requests to iDRAC controller
default: 10
type: int
resource_id:
required: false
description:
- The ID of the System, Manager or Chassis to modify
type: str
version_added: '2.10'
author: "Jose Delarosa (@jose-delarosa)"
'''
@ -72,6 +78,7 @@ EXAMPLES = '''
idrac_redfish_config:
category: Manager
command: SetManagerAttributes
resource_id: iDRAC.Embedded.1
manager_attribute_name: NTPConfigGroup.1.NTPEnable
manager_attribute_value: Enabled
baseuri: "{{ baseuri }}"
@ -81,6 +88,7 @@ EXAMPLES = '''
idrac_redfish_config:
category: Manager
command: SetManagerAttributes
resource_id: iDRAC.Embedded.1
manager_attribute_name: NTPConfigGroup.1.NTP1
manager_attribute_value: "{{ ntpserver1 }}"
baseuri: "{{ baseuri }}"
@ -90,6 +98,7 @@ EXAMPLES = '''
idrac_redfish_config:
category: Manager
command: SetManagerAttributes
resource_id: iDRAC.Embedded.1
manager_attribute_name: Time.1.Timezone
manager_attribute_value: "{{ timezone }}"
baseuri: "{{ baseuri }}"
@ -168,7 +177,8 @@ def main():
password=dict(required=True, no_log=True),
manager_attribute_name=dict(default='null'),
manager_attribute_value=dict(default='null'),
timeout=dict(type='int', default=10)
timeout=dict(type='int', default=10),
resource_id=dict()
),
supports_check_mode=False
)
@ -187,9 +197,13 @@ def main():
mgr_attributes = {'mgr_attr_name': module.params['manager_attribute_name'],
'mgr_attr_value': module.params['manager_attribute_value']}
# System, Manager or Chassis ID to modify
resource_id = module.params['resource_id']
# Build root URI
root_uri = "https://" + module.params['baseuri']
rf_utils = IdracRedfishUtils(creds, root_uri, timeout, module)
rf_utils = IdracRedfishUtils(creds, root_uri, timeout, module,
resource_id=resource_id, data_modification=True)
# Check that Category is valid
if category not in CATEGORY_COMMANDS_ALL:

View file

@ -113,6 +113,12 @@ options:
- properties of account service to update
type: dict
version_added: "2.10"
resource_id:
required: false
description:
- The ID of the System, Manager or Chassis to modify
type: str
version_added: "2.10"
author: "Jose Delarosa (@jose-delarosa)"
'''
@ -122,6 +128,7 @@ EXAMPLES = '''
redfish_command:
category: Systems
command: PowerGracefulRestart
resource_id: 437XR1138R2
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
@ -130,6 +137,7 @@ EXAMPLES = '''
redfish_command:
category: Systems
command: SetOneTimeBoot
resource_id: 437XR1138R2
bootdevice: "{{ bootdevice }}"
baseuri: "{{ baseuri }}"
username: "{{ username }}"
@ -139,6 +147,7 @@ EXAMPLES = '''
redfish_command:
category: Systems
command: SetOneTimeBoot
resource_id: 437XR1138R2
bootdevice: "UefiTarget"
uefi_target: "/0x31/0x33/0x01/0x01"
baseuri: "{{ baseuri }}"
@ -149,6 +158,7 @@ EXAMPLES = '''
redfish_command:
category: Systems
command: SetOneTimeBoot
resource_id: 437XR1138R2
bootdevice: "UefiBootNext"
boot_next: "Boot0001"
baseuri: "{{ baseuri }}"
@ -159,6 +169,7 @@ EXAMPLES = '''
redfish_command:
category: Chassis
command: IndicatorLedBlink
resource_id: 1U
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
@ -278,6 +289,7 @@ EXAMPLES = '''
redfish_command:
category: Manager
command: ClearLogs
resource_id: BMC
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
@ -327,7 +339,8 @@ def main():
bootdevice=dict(),
timeout=dict(type='int', default=10),
uefi_target=dict(),
boot_next=dict()
boot_next=dict(),
resource_id=dict()
),
supports_check_mode=False
)
@ -350,9 +363,13 @@ def main():
# timeout
timeout = module.params['timeout']
# System, Manager or Chassis ID to modify
resource_id = module.params['resource_id']
# Build root URI
root_uri = "https://" + module.params['baseuri']
rf_utils = RedfishUtils(creds, root_uri, timeout, module)
rf_utils = RedfishUtils(creds, root_uri, timeout, module,
resource_id=resource_id, data_modification=True)
# Check that Category is valid
if category not in CATEGORY_COMMANDS_ALL:

View file

@ -88,6 +88,12 @@ options:
- setting dict of manager services to update
type: dict
version_added: "2.10"
resource_id:
required: false
description:
- The ID of the System, Manager or Chassis to modify
type: str
version_added: "2.10"
author: "Jose Delarosa (@jose-delarosa)"
'''
@ -97,6 +103,7 @@ EXAMPLES = '''
redfish_config:
category: Systems
command: SetBiosAttributes
resource_id: 437XR1138R2
bios_attributes:
BootMode: "Uefi"
baseuri: "{{ baseuri }}"
@ -107,6 +114,7 @@ EXAMPLES = '''
redfish_config:
category: Systems
command: SetBiosAttributes
resource_id: 437XR1138R2
bios_attributes:
BootMode: "Bios"
OneTimeBootMode: "Enabled"
@ -119,6 +127,7 @@ EXAMPLES = '''
redfish_config:
category: Systems
command: SetBiosAttributes
resource_id: 437XR1138R2
bios_attribute_name: PxeDev1EnDis
bios_attribute_value: Enabled
baseuri: "{{ baseuri }}"
@ -129,6 +138,7 @@ EXAMPLES = '''
redfish_config:
category: Systems
command: SetBiosDefaultSettings
resource_id: 437XR1138R2
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
@ -210,7 +220,8 @@ def main():
network_protocols=dict(
type='dict',
default={}
)
),
resource_id=dict()
),
supports_check_mode=False
)
@ -237,9 +248,13 @@ def main():
# boot order
boot_order = module.params['boot_order']
# System, Manager or Chassis ID to modify
resource_id = module.params['resource_id']
# Build root URI
root_uri = "https://" + module.params['baseuri']
rf_utils = RedfishUtils(creds, root_uri, timeout, module)
rf_utils = RedfishUtils(creds, root_uri, timeout, module,
resource_id=resource_id, data_modification=True)
# Check that Category is valid
if category not in CATEGORY_COMMANDS_ALL: