diff --git a/changelogs/fragments/4839-fix-VirtualMediaInsert-Supermicro.yml b/changelogs/fragments/4839-fix-VirtualMediaInsert-Supermicro.yml new file mode 100644 index 0000000000..cd0aeeeb5b --- /dev/null +++ b/changelogs/fragments/4839-fix-VirtualMediaInsert-Supermicro.yml @@ -0,0 +1,8 @@ +bugfixes: + - redfish_command - fix the check if a virtual media is unmounted to just check for ``instered= false`` + caused by Supermicro hardware that does not clear the ``ImageName`` + (https://github.com/ansible-collections/community.general/pull/4839). + - redfish_command - the Supermicro Redfish implementation only supports the ``image_url`` parameter in + the underlying API calls to ``VirtualMediaInsert`` and ``VirtualMediaEject``. Any values set + (or the defaults) for ``write_protected`` or ``inserted`` will be ignored + (https://github.com/ansible-collections/community.general/pull/4839). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 31750861f7..0c5bc1b0de 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -2187,9 +2187,8 @@ class RedfishUtils(object): else: if media_match_strict: continue - # if ejected, 'Inserted' should be False and 'ImageName' cleared - if (not data.get('Inserted', False) and - not data.get('ImageName')): + # if ejected, 'Inserted' should be False + if (not data.get('Inserted', False)): return uri, data return None, None @@ -2225,7 +2224,7 @@ class RedfishUtils(object): return resources, headers @staticmethod - def _insert_virt_media_payload(options, param_map, data, ai): + def _insert_virt_media_payload(options, param_map, data, ai, image_only=False): payload = { 'Image': options.get('image_url') } @@ -2239,6 +2238,12 @@ class RedfishUtils(object): options.get(option), option, allowable)} payload[param] = options.get(option) + + # Some hardware (such as iLO 4 or Supermicro) only supports the Image property + # Inserted and WriteProtected are not writable + if image_only: + del payload['Inserted'] + del payload['WriteProtected'] return payload def virtual_media_insert_via_patch(self, options, param_map, uri, data, image_only=False): @@ -2247,16 +2252,10 @@ class RedfishUtils(object): {'AllowableValues': v}) for k, v in data.items() if k.endswith('@Redfish.AllowableValues')) # construct payload - payload = self._insert_virt_media_payload(options, param_map, data, ai) - if 'Inserted' not in payload: + payload = self._insert_virt_media_payload(options, param_map, data, ai, image_only) + if 'Inserted' not in payload and not image_only: payload['Inserted'] = True - # Some hardware (such as iLO 4) only supports the Image property on the PATCH operation - # Inserted and WriteProtected are not writable - if image_only: - del payload['Inserted'] - del payload['WriteProtected'] - # PATCH the resource response = self.patch_request(self.root_uri + uri, payload) if response['ret'] is False: @@ -2292,6 +2291,13 @@ class RedfishUtils(object): if data["FirmwareVersion"].startswith("iLO 4"): image_only = True + # Supermicro does also not support Inserted and WriteProtected + # Supermicro uses as firmware version only a number so we can't check for it because we + # can't be sure that this firmware version is nut used by another vendor + # Tested with Supermicro Firmware 01.74.02 + if 'Supermicro' in data['Oem']: + image_only = True + virt_media_uri = data["VirtualMedia"]["@odata.id"] response = self.get_request(self.root_uri + virt_media_uri) if response['ret'] is False: @@ -2346,7 +2352,7 @@ class RedfishUtils(object): # get ActionInfo or AllowableValues ai = self._get_all_action_info_values(action) # construct payload - payload = self._insert_virt_media_payload(options, param_map, data, ai) + payload = self._insert_virt_media_payload(options, param_map, data, ai, image_only) # POST to action response = self.post_request(self.root_uri + action_uri, payload) if response['ret'] is False: @@ -2392,6 +2398,9 @@ class RedfishUtils(object): if data["FirmwareVersion"].startswith("iLO 4"): image_only = True + if 'Supermicro' in data['Oem']: + image_only = True + virt_media_uri = data["VirtualMedia"]["@odata.id"] response = self.get_request(self.root_uri + virt_media_uri) if response['ret'] is False: