Repository: ansible-collections/community.general

Issue:
Cobbler inventory plugin auth
### Summary

Looks like when logging into cobbler, plugin passes `yaml.objects.AnsibleUnicode` to `xmlrpc/client.py` and it doesn't understand what to do with it.

Found out this by printing type of object that is returned by `self.get_option('user')` or `self.get_option('password')`
<class 'ansible.parsing.yaml.objects.AnsibleUnicode'>

If i would wrap it in `str(self.get_option('user'))` it works as expected.

Is it intentional? Maybe it has something to do with specific ansible version? Thanks.

### Issue Type

Bug Report

### Component Name

plugins.inventory.cobbler

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.11.12]
```


### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general
Collection        Version
----------------- -------
community.general 7.1.0 
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

_No response_

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)

```


### Expected Results

It should login to cobbler with correct password

### Actual Results

```console (paste below)
failis with `raise TypeError("cannot marshal %s objects" % type(value))` from xmlrpc client
```


### Code of Conduct

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


Discussion:
Files identified in the description:
* [`plugins/inventory/cobbler.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/inventory/cobbler.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 @opoplawski
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
Probably using `to_text()` instead of `str()` is better.
> Probably using `to_text()` instead of `str()` is better.

Isn't it opposite? At least from what I'm reading here:
https://docs.ansible.com/ansible/latest/dev_guide/developing_plugins.html#string-encoding

To me it looks like it converts simple string into unicode string, eg: str ---> AnsibleUnicode no?
IMHO: at this point user/password is one-way data that will be not returned to ansible in any way, in that way, do we need to think about unicode? To my understanding it is used because of jinja2, however since it will never be returned.....
You are confusing Python unicode strings (in Python 3, that's simply `str`) with the `AnsibleUnicode` class (which extends `str`). `to_text` makes sure you have a Python unicode string. Your aproach - using `str()` - only works on Python 3, but not on Python 2 (which we still support on the controller side, since we still support ansible-core 2.11).

Resolving patch:
diff --git a/plugins/inventory/cobbler.py b/plugins/inventory/cobbler.py
--- a/plugins/inventory/cobbler.py
+++ b/plugins/inventory/cobbler.py
@@ -87,6 +87,7 @@
 from ansible.module_utils.common.text.converters import to_text
 from ansible.module_utils.six import iteritems
 from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, to_safe_group_name
+from ansible.module_utils.six import text_type
 
 # xmlrpc
 try:
@@ -128,7 +129,7 @@ def _get_connection(self):
             self.connection = xmlrpc_client.Server(self.cobbler_url, allow_none=True)
             self.token = None
             if self.get_option('user') is not None:
-                self.token = self.connection.login(self.get_option('user'), self.get_option('password'))
+                self.token = self.connection.login(text_type(self.get_option('user')), text_type(self.get_option('password')))
         return self.connection
 
     def _init_cache(self):


Test patch: