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:
Bill Dodd 2019-10-29 08:10:58 -05:00 committed by John R Barker
parent 16d4d2dba9
commit 2b8553b242
2 changed files with 153 additions and 43 deletions

View file

@ -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 = []

View file

@ -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: