Add SetBootOrder and SetDefaultBootOrder commands (#63915)
* add SetBootOrder and SetDefaultBootOrder commands * change boot_order version added from 2.9 to 2.10
This commit is contained in:
parent
16d4d2dba9
commit
2b8553b242
2 changed files with 153 additions and 43 deletions
|
@ -1106,11 +1106,53 @@ class RedfishUtils(object):
|
||||||
def get_multi_bios_attributes(self):
|
def get_multi_bios_attributes(self):
|
||||||
return self.aggregate(self.get_bios_attributes)
|
return self.aggregate(self.get_bios_attributes)
|
||||||
|
|
||||||
def get_boot_order(self, systems_uri):
|
def _get_boot_options_dict(self, boot):
|
||||||
result = {}
|
|
||||||
# Get these entries from BootOption, if present
|
# Get these entries from BootOption, if present
|
||||||
properties = ['DisplayName', 'BootOptionReference']
|
properties = ['DisplayName', 'BootOptionReference']
|
||||||
|
|
||||||
|
# Retrieve BootOptions if present
|
||||||
|
if 'BootOptions' in boot and '@odata.id' in boot['BootOptions']:
|
||||||
|
boot_options_uri = boot['BootOptions']["@odata.id"]
|
||||||
|
# Get BootOptions resource
|
||||||
|
response = self.get_request(self.root_uri + boot_options_uri)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return {}
|
||||||
|
data = response['data']
|
||||||
|
|
||||||
|
# Retrieve Members array
|
||||||
|
if 'Members' not in data:
|
||||||
|
return {}
|
||||||
|
members = data['Members']
|
||||||
|
else:
|
||||||
|
members = []
|
||||||
|
|
||||||
|
# Build dict of BootOptions keyed by BootOptionReference
|
||||||
|
boot_options_dict = {}
|
||||||
|
for member in members:
|
||||||
|
if '@odata.id' not in member:
|
||||||
|
return {}
|
||||||
|
boot_option_uri = member['@odata.id']
|
||||||
|
response = self.get_request(self.root_uri + boot_option_uri)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return {}
|
||||||
|
data = response['data']
|
||||||
|
if 'BootOptionReference' not in data:
|
||||||
|
return {}
|
||||||
|
boot_option_ref = data['BootOptionReference']
|
||||||
|
|
||||||
|
# fetch the props to display for this boot device
|
||||||
|
boot_props = {}
|
||||||
|
for prop in properties:
|
||||||
|
if prop in data:
|
||||||
|
boot_props[prop] = data[prop]
|
||||||
|
|
||||||
|
boot_options_dict[boot_option_ref] = boot_props
|
||||||
|
|
||||||
|
return boot_options_dict
|
||||||
|
|
||||||
|
def get_boot_order(self, systems_uri):
|
||||||
|
result = {}
|
||||||
|
|
||||||
# Retrieve System resource
|
# Retrieve System resource
|
||||||
response = self.get_request(self.root_uri + systems_uri)
|
response = self.get_request(self.root_uri + systems_uri)
|
||||||
if response['ret'] is False:
|
if response['ret'] is False:
|
||||||
|
@ -1124,45 +1166,7 @@ class RedfishUtils(object):
|
||||||
|
|
||||||
boot = data['Boot']
|
boot = data['Boot']
|
||||||
boot_order = boot['BootOrder']
|
boot_order = boot['BootOrder']
|
||||||
|
boot_options_dict = self._get_boot_options_dict(boot)
|
||||||
# Retrieve BootOptions if present
|
|
||||||
if 'BootOptions' in boot and '@odata.id' in boot['BootOptions']:
|
|
||||||
boot_options_uri = boot['BootOptions']["@odata.id"]
|
|
||||||
# Get BootOptions resource
|
|
||||||
response = self.get_request(self.root_uri + boot_options_uri)
|
|
||||||
if response['ret'] is False:
|
|
||||||
return response
|
|
||||||
data = response['data']
|
|
||||||
|
|
||||||
# Retrieve Members array
|
|
||||||
if 'Members' not in data:
|
|
||||||
return {'ret': False,
|
|
||||||
'msg': "Members not found in BootOptionsCollection"}
|
|
||||||
members = data['Members']
|
|
||||||
else:
|
|
||||||
members = []
|
|
||||||
|
|
||||||
# Build dict of BootOptions keyed by BootOptionReference
|
|
||||||
boot_options_dict = {}
|
|
||||||
for member in members:
|
|
||||||
if '@odata.id' not in member:
|
|
||||||
return {'ret': False, 'msg': "@odata.id not found in BootOptions"}
|
|
||||||
boot_option_uri = member['@odata.id']
|
|
||||||
response = self.get_request(self.root_uri + boot_option_uri)
|
|
||||||
if response['ret'] is False:
|
|
||||||
return response
|
|
||||||
data = response['data']
|
|
||||||
if 'BootOptionReference' not in data:
|
|
||||||
return {'ret': False, 'msg': "BootOptionReference not found in BootOption"}
|
|
||||||
boot_option_ref = data['BootOptionReference']
|
|
||||||
|
|
||||||
# fetch the props to display for this boot device
|
|
||||||
boot_props = {}
|
|
||||||
for prop in properties:
|
|
||||||
if prop in data:
|
|
||||||
boot_props[prop] = data[prop]
|
|
||||||
|
|
||||||
boot_options_dict[boot_option_ref] = boot_props
|
|
||||||
|
|
||||||
# Build boot device list
|
# Build boot device list
|
||||||
boot_device_list = []
|
boot_device_list = []
|
||||||
|
@ -1357,6 +1361,74 @@ class RedfishUtils(object):
|
||||||
return response
|
return response
|
||||||
return {'ret': True, 'changed': True, 'msg': "Modified BIOS attribute"}
|
return {'ret': True, 'changed': True, 'msg': "Modified BIOS attribute"}
|
||||||
|
|
||||||
|
def set_boot_order(self, boot_list):
|
||||||
|
if not boot_list:
|
||||||
|
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]
|
||||||
|
response = self.get_request(self.root_uri + systems_uri)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return response
|
||||||
|
data = response['data']
|
||||||
|
|
||||||
|
# Confirm needed Boot properties are present
|
||||||
|
if 'Boot' not in data or 'BootOrder' not in data['Boot']:
|
||||||
|
return {'ret': False, 'msg': "Key BootOrder not found"}
|
||||||
|
|
||||||
|
boot = data['Boot']
|
||||||
|
boot_order = boot['BootOrder']
|
||||||
|
boot_options_dict = self._get_boot_options_dict(boot)
|
||||||
|
|
||||||
|
# validate boot_list against BootOptionReferences if available
|
||||||
|
if boot_options_dict:
|
||||||
|
boot_option_references = boot_options_dict.keys()
|
||||||
|
for ref in boot_list:
|
||||||
|
if ref not in boot_option_references:
|
||||||
|
return {'ret': False,
|
||||||
|
'msg': "BootOptionReference %s not found in BootOptions" % ref}
|
||||||
|
|
||||||
|
# If requested BootOrder is already set, nothing to do
|
||||||
|
if boot_order == boot_list:
|
||||||
|
return {'ret': True, 'changed': False,
|
||||||
|
'msg': "BootOrder already set to %s" % boot_list}
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
'Boot': {
|
||||||
|
'BootOrder': boot_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = self.patch_request(self.root_uri + systems_uri, payload)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return response
|
||||||
|
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]
|
||||||
|
response = self.get_request(self.root_uri + systems_uri)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return response
|
||||||
|
data = response['data']
|
||||||
|
|
||||||
|
# get the #ComputerSystem.SetDefaultBootOrder Action and target URI
|
||||||
|
action = '#ComputerSystem.SetDefaultBootOrder'
|
||||||
|
if 'Actions' not in data or action not in data['Actions']:
|
||||||
|
return {'ret': False, 'msg': 'Action %s not found' % action}
|
||||||
|
if 'target' not in data['Actions'][action]:
|
||||||
|
return {'ret': False,
|
||||||
|
'msg': 'target URI missing from Action %s' % action}
|
||||||
|
action_uri = data['Actions'][action]['target']
|
||||||
|
|
||||||
|
# POST to Action URI
|
||||||
|
payload = {}
|
||||||
|
response = self.post_request(self.root_uri + action_uri, payload)
|
||||||
|
if response['ret'] is False:
|
||||||
|
return response
|
||||||
|
return {'ret': True, 'changed': True,
|
||||||
|
'msg': "BootOrder set to default"}
|
||||||
|
|
||||||
def get_chassis_inventory(self):
|
def get_chassis_inventory(self):
|
||||||
result = {}
|
result = {}
|
||||||
chassis_results = []
|
chassis_results = []
|
||||||
|
|
|
@ -68,6 +68,13 @@ options:
|
||||||
default: 10
|
default: 10
|
||||||
type: int
|
type: int
|
||||||
version_added: "2.8"
|
version_added: "2.8"
|
||||||
|
boot_order:
|
||||||
|
required: false
|
||||||
|
description:
|
||||||
|
- list of BootOptionReference strings specifying the BootOrder
|
||||||
|
default: []
|
||||||
|
type: list
|
||||||
|
version_added: "2.10"
|
||||||
|
|
||||||
author: "Jose Delarosa (@jose-delarosa)"
|
author: "Jose Delarosa (@jose-delarosa)"
|
||||||
'''
|
'''
|
||||||
|
@ -111,6 +118,28 @@ EXAMPLES = '''
|
||||||
username: "{{ username }}"
|
username: "{{ username }}"
|
||||||
password: "{{ password }}"
|
password: "{{ password }}"
|
||||||
timeout: 20
|
timeout: 20
|
||||||
|
|
||||||
|
- name: Set boot order
|
||||||
|
redfish_config:
|
||||||
|
category: Systems
|
||||||
|
command: SetBootOrder
|
||||||
|
boot_order:
|
||||||
|
- Boot0002
|
||||||
|
- Boot0001
|
||||||
|
- Boot0000
|
||||||
|
- Boot0003
|
||||||
|
- Boot0004
|
||||||
|
baseuri: "{{ baseuri }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
|
|
||||||
|
- name: Set boot order to the default
|
||||||
|
redfish_config:
|
||||||
|
category: Systems
|
||||||
|
command: SetDefaultBootOrder
|
||||||
|
baseuri: "{{ baseuri }}"
|
||||||
|
username: "{{ username }}"
|
||||||
|
password: "{{ password }}"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = '''
|
||||||
|
@ -128,7 +157,8 @@ from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
# More will be added as module features are expanded
|
# More will be added as module features are expanded
|
||||||
CATEGORY_COMMANDS_ALL = {
|
CATEGORY_COMMANDS_ALL = {
|
||||||
"Systems": ["SetBiosDefaultSettings", "SetBiosAttributes"]
|
"Systems": ["SetBiosDefaultSettings", "SetBiosAttributes", "SetBootOrder",
|
||||||
|
"SetDefaultBootOrder"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,7 +173,8 @@ def main():
|
||||||
password=dict(required=True, no_log=True),
|
password=dict(required=True, no_log=True),
|
||||||
bios_attribute_name=dict(default='null'),
|
bios_attribute_name=dict(default='null'),
|
||||||
bios_attribute_value=dict(default='null'),
|
bios_attribute_value=dict(default='null'),
|
||||||
timeout=dict(type='int', default=10)
|
timeout=dict(type='int', default=10),
|
||||||
|
boot_order=dict(type='list', elements='str', default=[])
|
||||||
),
|
),
|
||||||
supports_check_mode=False
|
supports_check_mode=False
|
||||||
)
|
)
|
||||||
|
@ -162,6 +193,9 @@ def main():
|
||||||
bios_attributes = {'bios_attr_name': module.params['bios_attribute_name'],
|
bios_attributes = {'bios_attr_name': module.params['bios_attribute_name'],
|
||||||
'bios_attr_value': module.params['bios_attribute_value']}
|
'bios_attr_value': module.params['bios_attribute_value']}
|
||||||
|
|
||||||
|
# boot order
|
||||||
|
boot_order = module.params['boot_order']
|
||||||
|
|
||||||
# Build root URI
|
# Build root URI
|
||||||
root_uri = "https://" + module.params['baseuri']
|
root_uri = "https://" + module.params['baseuri']
|
||||||
rf_utils = RedfishUtils(creds, root_uri, timeout, module)
|
rf_utils = RedfishUtils(creds, root_uri, timeout, module)
|
||||||
|
@ -188,6 +222,10 @@ def main():
|
||||||
result = rf_utils.set_bios_default_settings()
|
result = rf_utils.set_bios_default_settings()
|
||||||
elif command == "SetBiosAttributes":
|
elif command == "SetBiosAttributes":
|
||||||
result = rf_utils.set_bios_attributes(bios_attributes)
|
result = rf_utils.set_bios_attributes(bios_attributes)
|
||||||
|
elif command == "SetBootOrder":
|
||||||
|
result = rf_utils.set_boot_order(boot_order)
|
||||||
|
elif command == "SetDefaultBootOrder":
|
||||||
|
result = rf_utils.set_default_boot_order()
|
||||||
|
|
||||||
# Return data back or fail with proper message
|
# Return data back or fail with proper message
|
||||||
if result['ret'] is True:
|
if result['ret'] is True:
|
||||||
|
|
Loading…
Reference in a new issue