From c089260c888756715825186e231cd54d5390fc8e Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 07:07:57 +0000 Subject: [PATCH] [PR #8004/2a8da769 backport][stable-8] Redfish: Enhanced GetUpdateStatus to allow for empty responses to accomodate possible usage of 204 No Content (#8011) Redfish: Enhanced GetUpdateStatus to allow for empty responses to accomodate possible usage of 204 No Content (#8004) * Added handling for 204 No Content in some circumstances Signed-off-by: Mike Raineri * Correcting gzip usage; open_url does the decompression automatically Signed-off-by: Mike Raineri * Changelog fragment Signed-off-by: Mike Raineri * Removed imports no longer used Signed-off-by: Mike Raineri * Updated data unpacking to dynamically check ansible-core version and response headers to see if gzip decompression is needed Signed-off-by: Mike Raineri --------- Signed-off-by: Mike Raineri (cherry picked from commit 2a8da76907f8e7de07a6c9010955a69d149b84da) Co-authored-by: Mike Raineri --- ...dfish-get-update-status-empty-response.yml | 2 ++ plugins/module_utils/redfish_utils.py | 26 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/8003-redfish-get-update-status-empty-response.yml diff --git a/changelogs/fragments/8003-redfish-get-update-status-empty-response.yml b/changelogs/fragments/8003-redfish-get-update-status-empty-response.yml new file mode 100644 index 0000000000..21796e7a0e --- /dev/null +++ b/changelogs/fragments/8003-redfish-get-update-status-empty-response.yml @@ -0,0 +1,2 @@ +bugfixes: + - redfish_info - allow for a GET operation invoked by ``GetUpdateStatus`` to allow for an empty response body for cases where a service returns 204 No Content (https://github.com/ansible-collections/community.general/issues/8003). diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py index 262b2774d2..2fbb7eb798 100644 --- a/plugins/module_utils/redfish_utils.py +++ b/plugins/module_utils/redfish_utils.py @@ -20,6 +20,8 @@ from ansible.module_utils.six import text_type from ansible.module_utils.six.moves import http_client from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError from ansible.module_utils.six.moves.urllib.parse import urlparse +from ansible.module_utils.ansible_release import __version__ as ansible_version +from ansible_collections.community.general.plugins.module_utils.version import LooseVersion GET_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'} POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json', @@ -130,7 +132,7 @@ class RedfishUtils(object): return resp # The following functions are to send GET/POST/PATCH/DELETE requests - def get_request(self, uri, override_headers=None): + def get_request(self, uri, override_headers=None, allow_no_resp=False): req_headers = dict(GET_HEADERS) if override_headers: req_headers.update(override_headers) @@ -145,13 +147,19 @@ class RedfishUtils(object): force_basic_auth=basic_auth, validate_certs=False, follow_redirects='all', use_proxy=True, timeout=self.timeout) - if override_headers: - resp = gzip.open(BytesIO(resp.read()), 'rt', encoding='utf-8') - data = json.loads(to_native(resp.read())) - headers = req_headers - else: - data = json.loads(to_native(resp.read())) - headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + headers = dict((k.lower(), v) for (k, v) in resp.info().items()) + try: + if headers.get('content-encoding') == 'gzip' and LooseVersion(ansible_version) < LooseVersion('2.14'): + # Older versions of Ansible do not automatically decompress the data + # Starting in 2.14, open_url will decompress the response data by default + data = json.loads(to_native(gzip.open(BytesIO(resp.read()), 'rt', encoding='utf-8').read())) + else: + data = json.loads(to_native(resp.read())) + except Exception as e: + # No response data; this is okay in certain cases + data = None + if not allow_no_resp: + raise except HTTPError as e: msg = self._get_extended_message(e) return {'ret': False, @@ -1813,7 +1821,7 @@ class RedfishUtils(object): return {'ret': False, 'msg': 'Must provide a handle tracking the update.'} # Get the task or job tracking the update - response = self.get_request(self.root_uri + update_handle) + response = self.get_request(self.root_uri + update_handle, allow_no_resp=True) if response['ret'] is False: return response