From 1f786a6171c1fc357e50fed2c9d725b51350ec1d Mon Sep 17 00:00:00 2001 From: Tan Siewert Date: Sat, 16 Nov 2024 09:32:49 -0800 Subject: [PATCH] redfish_command: add update_custom_oem options (#9123) * redfish_command: add update_custom_oem options The Multipart HTTP push update implementation allows OEM specific parts that are not part of the `UpdateParameters` body part, but a separate one. This OEM part shall start with `Oem` and is optional. The OEM part implementation is specified in the Redfish spec point 12.6.2.2 [1]. Right now, the implementation will only support JSON as MIME Type, although it is not limited to JSON. [1] https://www.dmtf.org/sites/default/files/standards/documents/DSP0266_1.21.0.html#oem Signed-off-by: Tan Siewert * redfish_command: add option to set custom mime type The implementation of using a custom MIME type will also remove the default JSON type. Converting the payload to JSON or any other type is up to the user. Signed-off-by: Tan Siewert * redfish_command: apply docs changes from review Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> * redfish_command: add mime type option to changelog Co-authored-by: Felix Fontein --------- Signed-off-by: Tan Siewert Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> Co-authored-by: Felix Fontein --- ...9123-redfish-command-custom-oem-params.yml | 2 + plugins/module_utils/redfish_utils.py | 8 +++ plugins/modules/redfish_command.py | 54 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 changelogs/fragments/9123-redfish-command-custom-oem-params.yml diff --git a/changelogs/fragments/9123-redfish-command-custom-oem-params.yml b/changelogs/fragments/9123-redfish-command-custom-oem-params.yml new file mode 100644 index 0000000000..a09219515a --- /dev/null +++ b/changelogs/fragments/9123-redfish-command-custom-oem-params.yml @@ -0,0 +1,2 @@ +minor_changes: + - redfish_command - add ``update_custom_oem_header``, ``update_custom_oem_params``, and ``update_custom_oem_mime_type`` options (https://github.com/ansible-collections/community.general/pull/9123). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 9f638c51f4..388fc93669 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -1933,6 +1933,9 @@ class RedfishUtils(object): targets = update_opts.get('update_targets') apply_time = update_opts.get('update_apply_time') oem_params = update_opts.get('update_oem_params') + custom_oem_header = update_opts.get('update_custom_oem_header') + custom_oem_mime_type = update_opts.get('update_custom_oem_mime_type') + custom_oem_params = update_opts.get('update_custom_oem_params') # Ensure the image file is provided if not image_file: @@ -1969,6 +1972,11 @@ class RedfishUtils(object): 'UpdateParameters': {'content': json.dumps(payload), 'mime_type': 'application/json'}, 'UpdateFile': {'filename': image_file, 'content': image_payload, 'mime_type': 'application/octet-stream'} } + if custom_oem_params: + multipart_payload[custom_oem_header] = {'content': custom_oem_params} + if custom_oem_mime_type: + multipart_payload[custom_oem_header]['mime_type'] = custom_oem_mime_type + response = self.post_request(self.root_uri + update_uri, multipart_payload, multipart=True) if response['ret'] is False: return response diff --git a/plugins/modules/redfish_command.py b/plugins/modules/redfish_command.py index 103f9e1d50..829b77897d 100644 --- a/plugins/modules/redfish_command.py +++ b/plugins/modules/redfish_command.py @@ -216,6 +216,36 @@ options: - Handle to check the status of an update in progress. type: str version_added: '6.1.0' + update_custom_oem_header: + required: false + description: + - Optional OEM header, sent as separate form-data for + the Multipart HTTP push update. + - The header shall start with "Oem" according to DMTF + Redfish spec 12.6.2.2. + - For more details, see U(https://www.dmtf.org/sites/default/files/standards/documents/DSP0266_1.21.0.html) + - If set, then O(update_custom_oem_params) is required too. + type: str + version_added: '10.1.0' + update_custom_oem_params: + required: false + description: + - Custom OEM properties for HTTP Multipart Push updates. + - If set, then O(update_custom_oem_header) is required too. + - The properties will be passed raw without any validation or conversion by Ansible. + This means the content can be a file, a string, or any other data. + If the content is a dict that should be converted to JSON, then the + content must be converted to JSON before passing it to this module using the + P(ansible.builtin.to_json#filter) filter. + type: raw + version_added: '10.1.0' + update_custom_oem_mime_type: + required: false + description: + - MIME Type for custom OEM properties for HTTP Multipart + Push updates. + type: str + version_added: '10.1.0' virtual_media: required: false description: @@ -654,6 +684,23 @@ EXAMPLES = ''' update_oem_params: PreserveConfiguration: false + - name: Multipart HTTP push with custom OEM options + vars: + oem_payload: + ImageType: BMC + community.general.redfish_command: + category: Update + command: MultipartHTTPPushUpdate + baseuri: "{{ baseuri }}" + username: "{{ username }}" + password: "{{ password }}" + update_image_file: ~/images/myupdate.img + update_targets: + - /redfish/v1/UpdateService/FirmwareInventory/BMC + update_custom_oem_header: OemParameters + update_custom_oem_mime_type: "application/json" + update_custom_oem_params: "{{ oem_payload | to_json }}" + - name: Perform requested operations to continue the update community.general.redfish_command: category: Update @@ -863,6 +910,9 @@ def main(): update_protocol=dict(), update_targets=dict(type='list', elements='str', default=[]), update_oem_params=dict(type='dict'), + update_custom_oem_header=dict(type='str'), + update_custom_oem_mime_type=dict(type='str'), + update_custom_oem_params=dict(type='raw'), update_creds=dict( type='dict', options=dict( @@ -895,6 +945,7 @@ def main(): ), required_together=[ ('username', 'password'), + ('update_custom_oem_header', 'update_custom_oem_params'), ], required_one_of=[ ('username', 'auth_token'), @@ -941,6 +992,9 @@ def main(): 'update_creds': module.params['update_creds'], 'update_apply_time': module.params['update_apply_time'], 'update_oem_params': module.params['update_oem_params'], + 'update_custom_oem_header': module.params['update_custom_oem_header'], + 'update_custom_oem_params': module.params['update_custom_oem_params'], + 'update_custom_oem_mime_type': module.params['update_custom_oem_mime_type'], 'update_handle': module.params['update_handle'], }