Add SimpleUpdate command (#65074)

* add SimpleUpdate command

* add AllowableValues check for Targets property
pull/45569/head
Bill Dodd 5 years ago committed by GitHub
parent c64202a495
commit b5b23efdcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1255,6 +1255,93 @@ class RedfishUtils(object):
else:
return self._software_inventory(self.software_uri)
def _get_allowable_values(self, action, name, default_values=None):
if default_values is None:
default_values = []
allowable_values = None
# get Allowable values from ActionInfo
if '@Redfish.ActionInfo' in action:
action_info_uri = action.get('@Redfish.ActionInfo')
response = self.get_request(self.root_uri + action_info_uri)
if response['ret'] is True:
data = response['data']
if 'Parameters' in data:
params = data['Parameters']
for param in params:
if param.get('Name') == name:
allowable_values = param.get('AllowableValues')
break
# fallback to @Redfish.AllowableValues annotation
if allowable_values is None:
prop = '%s@Redfish.AllowableValues' % name
if prop in action:
allowable_values = action[prop]
# fallback to default values
if allowable_values is None:
allowable_values = default_values
return allowable_values
def simple_update(self, update_opts):
image_uri = update_opts.get('update_image_uri')
protocol = update_opts.get('update_protocol')
targets = update_opts.get('update_targets')
creds = update_opts.get('update_creds')
if not image_uri:
return {'ret': False, 'msg':
'Must specify update_image_uri for the SimpleUpdate command'}
response = self.get_request(self.root_uri + self.update_uri)
if response['ret'] is False:
return response
data = response['data']
if 'Actions' not in data:
return {'ret': False, 'msg': 'Service does not support SimpleUpdate'}
if '#UpdateService.SimpleUpdate' not in data['Actions']:
return {'ret': False, 'msg': 'Service does not support SimpleUpdate'}
action = data['Actions']['#UpdateService.SimpleUpdate']
if 'target' not in action:
return {'ret': False, 'msg': 'Service does not support SimpleUpdate'}
update_uri = action['target']
if protocol:
default_values = ['CIFS', 'FTP', 'SFTP', 'HTTP', 'HTTPS', 'NSF',
'SCP', 'TFTP', 'OEM', 'NFS']
allowable_values = self._get_allowable_values(action,
'TransferProtocol',
default_values)
if protocol not in allowable_values:
return {'ret': False,
'msg': 'Specified update_protocol (%s) not supported '
'by service. Supported protocols: %s' %
(protocol, allowable_values)}
if targets:
allowable_values = self._get_allowable_values(action, 'Targets')
if allowable_values:
for target in targets:
if target not in allowable_values:
return {'ret': False,
'msg': 'Specified target (%s) not supported '
'by service. Supported targets: %s' %
(target, allowable_values)}
payload = {
'ImageURI': image_uri
}
if protocol:
payload["TransferProtocol"] = protocol
if targets:
payload["Targets"] = targets
if creds:
if creds.get('username'):
payload["Username"] = creds.get('username')
if creds.get('password'):
payload["Password"] = creds.get('password')
response = self.post_request(self.root_uri + update_uri, payload)
if response['ret'] is False:
return response
return {'ret': True, 'changed': True,
'msg': "SimpleUpdate requested"}
def get_bios_attributes(self, systems_uri):
result = {}
bios_attributes = {}

@ -119,6 +119,42 @@ options:
- The ID of the System, Manager or Chassis to modify
type: str
version_added: "2.10"
update_image_uri:
required: false
description:
- The URI of the image for the update
type: str
version_added: "2.10"
update_protocol:
required: false
description:
- The protocol for the update
type: str
version_added: "2.10"
update_targets:
required: false
description:
- The list of target resource URIs to apply the update to
type: list
elements: str
version_added: "2.10"
update_creds:
required: false
description:
- The credentials for retrieving the update image
type: dict
suboptions:
username:
required: false
description:
- The username for retrieving the update image
type: str
password:
required: false
description:
- The password for retrieving the update image
type: str
version_added: "2.10"
author: "Jose Delarosa (@jose-delarosa)"
'''
@ -302,6 +338,30 @@ EXAMPLES = '''
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
- name: Simple update
redfish_command:
category: Update
command: SimpleUpdate
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
update_image_uri: https://example.com/myupdate.img
- name: Simple update with additional options
redfish_command:
category: Update
command: SimpleUpdate
baseuri: "{{ baseuri }}"
username: "{{ username }}"
password: "{{ password }}"
update_image_uri: //example.com/myupdate.img
update_protocol: FTP
update_targets:
- /redfish/v1/UpdateService/FirmwareInventory/BMC
update_creds:
username: operator
password: supersecretpwd
'''
RETURN = '''
@ -327,6 +387,7 @@ CATEGORY_COMMANDS_ALL = {
"UpdateAccountServiceProperties"],
"Sessions": ["ClearSessions"],
"Manager": ["GracefulRestart", "ClearLogs"],
"Update": ["SimpleUpdate"]
}
@ -349,7 +410,17 @@ def main():
timeout=dict(type='int', default=10),
uefi_target=dict(),
boot_next=dict(),
resource_id=dict()
resource_id=dict(),
update_image_uri=dict(),
update_protocol=dict(),
update_targets=dict(type='list', elements='str', default=[]),
update_creds=dict(
type='dict',
options=dict(
username=dict(),
password=dict()
)
)
),
supports_check_mode=False
)
@ -375,6 +446,14 @@ def main():
# System, Manager or Chassis ID to modify
resource_id = module.params['resource_id']
# update options
update_opts = {
'update_image_uri': module.params['update_image_uri'],
'update_protocol': module.params['update_protocol'],
'update_targets': module.params['update_targets'],
'update_creds': module.params['update_creds']
}
# Build root URI
root_uri = "https://" + module.params['baseuri']
rf_utils = RedfishUtils(creds, root_uri, timeout, module,
@ -466,6 +545,16 @@ def main():
for command in command_list:
result = MANAGER_COMMANDS[command]()
elif category == "Update":
# execute only if we find UpdateService resources
resource = rf_utils._find_updateservice_resource()
if resource['ret'] is False:
module.fail_json(msg=resource['msg'])
for command in command_list:
if command == "SimpleUpdate":
result = rf_utils.simple_update(update_opts)
# Return data back or fail with proper message
if result['ret'] is True:
del result['ret']

Loading…
Cancel
Save