Repository: ansible-collections/community.general

Issue:
redfish modules yielding Failed GET request for any command
##### SUMMARY
Using redfish_info, redfish_config, or redfish_command under Python 3 is producing the error "Failed GET request the JSON object must be str, not 'bytes'"

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
redfish_info
redfish_config
redfish_command

##### ANSIBLE VERSION
```ansible 2.9.11
  config file = None
  configured module search path = ['/home/tcole/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/tcole/.local/lib/python3.5/site-packages/ansible
  executable location = /home/tcole/.local/bin/ansible
  python version = 3.5.3 (default, Jul  9 2020, 13:00:10) [GCC 6.3.0 20170516]
```

##### CONFIGURATION
```
No output from ansible-config dump --only-changed
```

##### OS / ENVIRONMENT
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=debian

##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->
pip3 install --user ansible
~/.local/bin/ansible-playbook redfish.yaml -e baseuri=10.101.129.17 -e username=admin -e password=${PASSWORD}

<!--- Paste example playbooks or commands between quotes below -->
```yaml
---
- hosts: localhost
  gather_facts: false
  tasks:
    - name: redfish facts
      redfish_info:
        baseuri: "{{ baseuri }}"
        username: "{{ username }}"
        password: "{{ password }}"
      ignore_errors: true
    - name: redfish config
      redfish_config:
        baseuri: "{{ baseuri }}"
        username: "{{ username }}"
        password: "{{ password }}"
        category: Systems
        command: SetBiosDefaultSettings
      ignore_errors: true
    - name: redfish command
      redfish_command:
        baseuri: "{{ baseuri }}"
        username: "{{ username }}"
        password: "{{ password }}"
        category: Systems
        command: PowerGracefulRestart
      ignore_errors: true
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->
Modules should return ok / changed after connecting to the redfish api

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes -->
```
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [localhost] ***************************************************************

TASK [redfish facts] ***********************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed GET request to 'https://10.101.129.17/redfish/v1/': 'the JSON object must be str, not 'bytes''"}
...ignoring

TASK [redfish config] **********************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed GET request to 'https://10.101.129.17/redfish/v1/': 'the JSON object must be str, not 'bytes''"}
...ignoring

TASK [redfish command] *********************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed GET request to 'https://10.101.129.17/redfish/v1/': 'the JSON object must be str, not 'bytes''"}
...ignoring

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=3

Exception ignored in: <function WeakValueDictionary.__init__.<locals>.remove at 0x7fcebde0e8c8>
Traceback (most recent call last):
  File "/usr/lib/python3.5/weakref.py", line 117, in remove
TypeError: 'NoneType' object is not callable
<---snip repeated lots of time --->
```



Discussion:
Files identified in the description:
* [`plugins/modules/remote_management/redfish/redfish_command.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/remote_management/redfish/redfish_command.py)
* [`plugins/modules/remote_management/redfish/redfish_config.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/remote_management/redfish/redfish_config.py)
* [`plugins/modules/remote_management/redfish/redfish_info.py`](https://github.com/ansible-collections/community.general/blob/master/plugins/modules/remote_management/redfish/redfish_info.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @billdodd @jose-delarosa @mraineri @tomasg2012
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
@m33x-7 Thanks for opening this. I should have the PR submitted sometime today.

Resolving patch:
diff --git a/plugins/module_utils/redfish_utils.py b/plugins/module_utils/redfish_utils.py
--- a/plugins/module_utils/redfish_utils.py
+++ b/plugins/module_utils/redfish_utils.py
@@ -6,6 +6,7 @@
 
 import json
 from ansible.module_utils.urls import open_url
+from ansible.module_utils._text import to_native
 from ansible.module_utils._text import to_text
 from ansible.module_utils.six.moves import http_client
 from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
@@ -47,7 +48,7 @@ def get_request(self, uri):
                             force_basic_auth=True, validate_certs=False,
                             follow_redirects='all',
                             use_proxy=True, timeout=self.timeout)
-            data = json.loads(resp.read())
+            data = json.loads(to_native(resp.read()))
             headers = dict((k.lower(), v) for (k, v) in resp.info().items())
         except HTTPError as e:
             msg = self._get_extended_message(e)


Test patch: