Repository: ansible-collections/community.general

Issue:
nrdp callback plugin string argument without an encoding
### Summary

When using nrdp callback plugin, the play ends with a warning and the callback is not invoked:

    PLAY RECAP **********************************************************************************************************************************
    wsp-infadmin21             : ok=4    changed=0    unreachable=0    failed=1    skipped=1    rescued=0    ignored=0   

    [WARNING]: Failure using method (v2_playbook_on_stats) in callback plugin
    (<ansible_collections.community.general.plugins.callback.nrdp.CallbackModule object at 0x7f67a98d54f0>): string argument without an encoding

### Issue Type

Bug Report

### Component Name

nrdp

### Ansible Version

```
ansible [core 2.12.1]
  config file = /home/harrisj/src/usceduau/Ansible_Base/project/ansible.cfg
  configured module search path = ['/home/harrisj/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/linuxbrew/.linuxbrew/opt/python@3.9/lib/python3.9/site-packages/ansible
  ansible collection location = /home/harrisj/src/usceduau/Ansible_Base/project/collections
  executable location = /home/linuxbrew/.linuxbrew/bin/ansible
  python version = 3.9.9 (main, Nov 15 2021, 18:05:17) [GCC 5.4.0 20160609]
  jinja version = 3.0.3
  libyaml = True
```

### Community.general Version

```
# /home/harrisj/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 4.1.0
```

### Configuration

```
ANSIBLE_PIPELINING(/home/harrisj/test-nrdp/ansible.cfg) = True
CALLBACKS_ENABLED(/home/harrisj/test-nrdp/ansible.cfg) = ['community.general.nrdp']
```

ansible.cfg callback_nrdp settings
```
cat ansible.cfg 
[connection]
pipelining=True

[defaults]
callbacks_enabled = community.general.nrdp

[callback_nrdp]
hostname=lsd-awx01
servicename=Check_awx_jobstatus
token=blahblahblah
url=https://nrdphost.example.com:8443/
validate_certs=False
```

### OS / Environment

Gentoo

### Steps to Reproduce

```
---

- name: Test nrdp callback plugin
  hosts: localhost
  gather_facts: false
  tasks:
    - fail:

```


### Expected Results

I expect that the nrdp callback plugin will send play stats to our nrdp host for processing on nagios.
I was able to produce the correct expected results with this patch:

```
cat nrdp.py.patch 
diff --git a/nrdp.py b/nrdp.py
index 744c2d2..bad4d6b 100644
--- a/nrdp.py
+++ b/nrdp.py
@@ -143,7 +143,7 @@ class CallbackModule(CallbackBase):
         body = {
             'cmd': 'submitcheck',
             'token': self.token,
-            'XMLDATA': bytes(xmldata)
+            'XMLDATA': bytes(xmldata,'utf-8')
         }
 
         try:
```

### Actual Results

```ansible-playbook [core 2.12.1]
  config file = /home/harrisj/test-nrdp/ansible.cfg
  configured module search path = ['/home/harrisj/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/harrisj/.local/python-old/lib/python3.8/site-packages/ansible
  ansible collection location = /home/harrisj/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/harrisj/.local/python-old/bin/ansible-playbook
  python version = 3.8.12 (default, Nov  2 2021, 10:10:30) [GCC 11.2.0]
  jinja version = 3.0.3
  libyaml = True
Using /home/harrisj/test-nrdp/ansible.cfg as config file
setting up inventory plugins
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'
Loading callback plugin default of type stdout, v2.0 from /home/harrisj/.local/python-old/lib/python3.8/site-packages/ansible/plugins/callback/default.py
Loading collection community.general from /home/harrisj/.ansible/collections/ansible_collections/community/general
Attempting to use 'default' callback.
Skipping callback 'default', as we already have a stdout callback.
Attempting to use 'junit' callback.
Attempting to use 'minimal' callback.
Skipping callback 'minimal', as we already have a stdout callback.
Attempting to use 'oneline' callback.
Skipping callback 'oneline', as we already have a stdout callback.
Attempting to use 'tree' callback.
Attempting to use 'community.general.nrdp' callback.
Loading callback plugin community.general.nrdp of type notification, v2.0 from /home/harrisj/.ansible/collections/ansible_collections/community/general/plugins/callback/nrdp.py

PLAYBOOK: main.yml *****************************************************************************************************
Positional arguments: main.yml
verbosity: 5
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('/etc/ansible/hosts',)
forks: 5
1 plays in main.yml

PLAY [Test nrdp callback plugin] ***************************************************************************************
META: ran handlers

TASK [fail] ************************************************************************************************************
task path: /home/harrisj/test-nrdp/main.yml:7
fatal: [localhost]: FAILED! => {
    "changed": false,
    "msg": "Failed as requested from task"
}

PLAY RECAP *************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[WARNING]: Failure using method (v2_playbook_on_stats) in callback plugin
(<ansible_collections.community.general.plugins.callback.nrdp.CallbackModule object at 0x7fd3ef45e460>): string
argument without an encoding
Callback Exception: 
  File "/home/harrisj/.local/python-old/lib/python3.8/site-packages/ansible/executor/task_queue_manager.py", line 450, in send_callback
    method(*new_args, **kwargs)
   File "/home/harrisj/.ansible/collections/ansible_collections/community/general/plugins/callback/nrdp.py", line 187, in v2_playbook_on_stats
    self._send_nrdp(self.CRITICAL, msg)
   File "/home/harrisj/.ansible/collections/ansible_collections/community/general/plugins/callback/nrdp.py", line 146, in _send_nrdp
    'XMLDATA': bytes(xmldata)
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`plugins/callback/nrdp.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/callback/nrdp.py)

If these files are incorrect, 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/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @rverchere
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
My guess would be that the plugin isn't compatible with Python 3.
Would a simple PR be accepted with the change that worked for me, or would there be a bit more work involved? Ie, creating tests, etc.
Can you use `to_bytes(xmldata)` instead of `bytes(xmldata,'utf-8')`? (Where `from ansible.module_utils.common.text.converters import to_bytes`.)

Since the plugin right now has no tests, I don't think you have to create some. (Of course if you want to, feel free to create some :) ) What you have to do is add a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (Also take a look at https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md#open-pull-requests)

Resolving patch:
diff --git a/plugins/callback/nrdp.py b/plugins/callback/nrdp.py
--- a/plugins/callback/nrdp.py
+++ b/plugins/callback/nrdp.py
@@ -70,6 +70,7 @@
 import json
 
 from ansible.module_utils.six.moves.urllib.parse import urlencode
+from ansible.module_utils.common.text.converters import to_bytes
 from ansible.module_utils.urls import open_url
 from ansible.plugins.callback import CallbackBase
 
@@ -143,7 +144,7 @@ def _send_nrdp(self, state, msg):
         body = {
             'cmd': 'submitcheck',
             'token': self.token,
-            'XMLDATA': bytes(xmldata)
+            'XMLDATA': to_bytes(xmldata)
         }
 
         try:


Test patch: