We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
community.general.xenserver_facts module error __init__() missing 1 required positional argument: 'argument_spec'
### Summary

When I try to use the [community.general.xenserver_facts module](https://docs.ansible.com/ansible/latest/collections/community/general/xenserver_facts_module.html) I get an error.

### Issue Type

Bug Report

### Component Name

xenserver_facts_module

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.13.4]
  config file = /home/chris/.ansible.cfg
  configured module search path = ['/home/chris/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/chris/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.10.7 (main, Oct  1 2022, 04:31:04) [GCC 12.2.0]
  jinja version = 3.0.3
  libyaml = True
```


### Community.general Version

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

# /home/chris/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 5.7.0  

# /usr/lib/python3/dist-packages/ansible_collections
Collection        Version
----------------- -------
community.general 5.6.0  
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
DEFAULT_TIMEOUT(/home/chris/.ansible.cfg) = 300
```


### OS / Environment

Debian Bookworm

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Gather Xen facts
  community.general.xenserver_facts:
```


### Expected Results

Something other than an error...

### Actual Results

```console (paste below)
TASK [xen : Gather Xen facts] ********************************************************************************************************
task path: /home/chris/webarch/servers/galaxy/roles/xen/tasks/main.yml:2
redirecting (type: modules) community.general.xenserver_facts to community.general.cloud.misc.xenserver_facts
redirecting (type: modules) community.general.xenserver_facts to community.general.cloud.misc.xenserver_facts
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: __init__() missing 1 required positional argument: 'argument_spec'
fatal: [xen4.webarch.net]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"<stdin>\", line 107, in <module>\n  File \"<stdin>\", line 99, in _ansiballz_main\n  File \"<stdin>\", line 47, in invoke_module\n  File \"/usr/lib/python3.9/runpy.py\", line 210, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.9/runpy.py\", line 97, in _run_module_code\n    _run_code(code, mod_globals, init_globals,\n  File \"/usr/lib/python3.9/runpy.py\", line 87, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_community.general.xenserver_facts_payload_ilqmvdk8/ansible_community.general.xenserver_facts_payload.zip/ansible_collections/community/general/plugins/modules/cloud/misc/xenserver_facts.py\", line 206, in <module>\n  File \"/tmp/ansible_community.general.xenserver_facts_payload_ilqmvdk8/ansible_community.general.xenserver_facts_payload.zip/ansible_collections/community/general/plugins/modules/cloud/misc/xenserver_facts.py\", line 165, in main\nTypeError: __init__() missing 1 required positional argument: 'argument_spec'\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
```


### Code of Conduct

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

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/modules/cloud/misc/xenserver_facts.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 #
4 # Copyright Ansible Project
5 # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
6 # SPDX-License-Identifier: GPL-3.0-or-later
7 
8 from __future__ import absolute_import, division, print_function
9 __metaclass__ = type
10 
11 
12 DOCUMENTATION = '''
13 ---
14 module: xenserver_facts
15 short_description: get facts reported on xenserver
16 description:
17   - Reads data out of XenAPI, can be used instead of multiple xe commands.
18 author:
19     - Andy Hill (@andyhky)
20     - Tim Rupp (@caphrim007)
21     - Robin Lee (@cheese)
22 options: {}
23 '''
24 
25 EXAMPLES = '''
26 - name: Gather facts from xenserver
27   community.general.xenserver_facts:
28 
29 - name: Print running VMs
30   ansible.builtin.debug:
31     msg: "{{ item }}"
32   with_items: "{{ xs_vms.keys() }}"
33   when: xs_vms[item]['power_state'] == "Running"
34 
35 # Which will print:
36 #
37 # TASK: [Print running VMs] ***********************************************************
38 # skipping: [10.13.0.22] => (item=CentOS 4.7 (32-bit))
39 # ok: [10.13.0.22] => (item=Control domain on host: 10.0.13.22) => {
40 #     "item": "Control domain on host: 10.0.13.22",
41 #     "msg": "Control domain on host: 10.0.13.22"
42 # }
43 '''
44 
45 
46 HAVE_XENAPI = False
47 try:
48     import XenAPI
49     HAVE_XENAPI = True
50 except ImportError:
51     pass
52 
53 from ansible.module_utils import distro
54 from ansible.module_utils.basic import AnsibleModule
55 
56 
57 class XenServerFacts:
58     def __init__(self):
59         self.codes = {
60             '5.5.0': 'george',
61             '5.6.100': 'oxford',
62             '6.0.0': 'boston',
63             '6.1.0': 'tampa',
64             '6.2.0': 'clearwater'
65         }
66 
67     @property
68     def version(self):
69         result = distro.linux_distribution()[1]
70         return result
71 
72     @property
73     def codename(self):
74         if self.version in self.codes:
75             result = self.codes[self.version]
76         else:
77             result = None
78 
79         return result
80 
81 
82 def get_xenapi_session():
83     session = XenAPI.xapi_local()
84     session.xenapi.login_with_password('', '')
85     return session
86 
87 
88 def get_networks(session):
89     recs = session.xenapi.network.get_all_records()
90     networks = change_keys(recs, key='name_label')
91     return networks
92 
93 
94 def get_pifs(session):
95     recs = session.xenapi.PIF.get_all_records()
96     pifs = change_keys(recs, key='uuid')
97     xs_pifs = {}
98     devicenums = range(0, 7)
99     for pif in pifs.values():
100         for eth in devicenums:
101             interface_name = "eth%s" % (eth)
102             bond_name = interface_name.replace('eth', 'bond')
103             if pif['device'] == interface_name:
104                 xs_pifs[interface_name] = pif
105             elif pif['device'] == bond_name:
106                 xs_pifs[bond_name] = pif
107     return xs_pifs
108 
109 
110 def get_vlans(session):
111     recs = session.xenapi.VLAN.get_all_records()
112     return change_keys(recs, key='tag')
113 
114 
115 def change_keys(recs, key='uuid', filter_func=None):
116     """
117     Take a xapi dict, and make the keys the value of recs[ref][key].
118 
119     Preserves the ref in rec['ref']
120 
121     """
122     new_recs = {}
123 
124     for ref, rec in recs.items():
125         if filter_func is not None and not filter_func(rec):
126             continue
127 
128         for param_name, param_value in rec.items():
129             # param_value may be of type xmlrpc.client.DateTime,
130             # which is not simply convertable to str.
131             # Use 'value' attr to get the str value,
132             # following an example in xmlrpc.client.DateTime document
133             if hasattr(param_value, "value"):
134                 rec[param_name] = param_value.value
135         new_recs[rec[key]] = rec
136         new_recs[rec[key]]['ref'] = ref
137 
138     return new_recs
139 
140 
141 def get_host(session):
142     """Get the host"""
143     host_recs = session.xenapi.host.get_all()
144     # We only have one host, so just return its entry
145     return session.xenapi.host.get_record(host_recs[0])
146 
147 
148 def get_vms(session):
149     recs = session.xenapi.VM.get_all_records()
150     if not recs:
151         return None
152     vms = change_keys(recs, key='name_label')
153     return vms
154 
155 
156 def get_srs(session):
157     recs = session.xenapi.SR.get_all_records()
158     if not recs:
159         return None
160     srs = change_keys(recs, key='name_label')
161     return srs
162 
163 
164 def main():
165     module = AnsibleModule(
166         supports_check_mode=True,
167     )
168 
169     if not HAVE_XENAPI:
170         module.fail_json(changed=False, msg="python xen api required for this module")
171 
172     obj = XenServerFacts()
173     try:
174         session = get_xenapi_session()
175     except XenAPI.Failure as e:
176         module.fail_json(msg='%s' % e)
177 
178     data = {
179         'xenserver_version': obj.version,
180         'xenserver_codename': obj.codename
181     }
182 
183     xs_networks = get_networks(session)
184     xs_pifs = get_pifs(session)
185     xs_vlans = get_vlans(session)
186     xs_vms = get_vms(session)
187     xs_srs = get_srs(session)
188 
189     if xs_vlans:
190         data['xs_vlans'] = xs_vlans
191     if xs_pifs:
192         data['xs_pifs'] = xs_pifs
193     if xs_networks:
194         data['xs_networks'] = xs_networks
195 
196     if xs_vms:
197         data['xs_vms'] = xs_vms
198 
199     if xs_srs:
200         data['xs_srs'] = xs_srs
201 
202     module.exit_json(ansible_facts=data)
203 
204 
205 if __name__ == '__main__':
206     main()
207
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plugins/modules/cloud/misc/xenserver_facts.py b/plugins/modules/cloud/misc/xenserver_facts.py
--- a/plugins/modules/cloud/misc/xenserver_facts.py
+++ b/plugins/modules/cloud/misc/xenserver_facts.py
@@ -162,9 +162,7 @@
 
 
 def main():
-    module = AnsibleModule(
-        supports_check_mode=True,
-    )
+    module = AnsibleModule({}, supports_check_mode=True)
 
     if not HAVE_XENAPI:
         module.fail_json(changed=False, msg="python xen api required for this module")

{"golden_diff": "diff --git a/plugins/modules/cloud/misc/xenserver_facts.py b/plugins/modules/cloud/misc/xenserver_facts.py\n--- a/plugins/modules/cloud/misc/xenserver_facts.py\n+++ b/plugins/modules/cloud/misc/xenserver_facts.py\n@@ -162,9 +162,7 @@\n \n \n def main():\n-    module = AnsibleModule(\n-        supports_check_mode=True,\n-    )\n+    module = AnsibleModule({}, supports_check_mode=True)\n \n     if not HAVE_XENAPI:\n         module.fail_json(changed=False, msg=\"python xen api required for this module\")\n", "issue": "community.general.xenserver_facts module error __init__() missing 1 required positional argument: 'argument_spec'\n### Summary\n\nWhen I try to use the [community.general.xenserver_facts module](https://docs.ansible.com/ansible/latest/collections/community/general/xenserver_facts_module.html) I get an error.\n\n### Issue Type\n\nBug Report\n\n### Component Name\n\nxenserver_facts_module\n\n### Ansible Version\n\n```console (paste below)\r\n$ ansible --version\r\nansible [core 2.13.4]\r\n  config file = /home/chris/.ansible.cfg\r\n  configured module search path = ['/home/chris/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']\r\n  ansible python module location = /usr/lib/python3/dist-packages/ansible\r\n  ansible collection location = /home/chris/.ansible/collections:/usr/share/ansible/collections\r\n  executable location = /usr/bin/ansible\r\n  python version = 3.10.7 (main, Oct  1 2022, 04:31:04) [GCC 12.2.0]\r\n  jinja version = 3.0.3\r\n  libyaml = True\r\n```\r\n\n\n### Community.general Version\n\n```console (paste below)\r\n$ ansible-galaxy collection list community.general\r\n\r\n# /home/chris/.ansible/collections/ansible_collections\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 5.7.0  \r\n\r\n# /usr/lib/python3/dist-packages/ansible_collections\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 5.6.0  \r\n```\r\n\n\n### Configuration\n\n```console (paste below)\r\n$ ansible-config dump --only-changed\r\nDEFAULT_TIMEOUT(/home/chris/.ansible.cfg) = 300\r\n```\r\n\n\n### OS / Environment\n\nDebian Bookworm\n\n### Steps to Reproduce\n\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml (paste below)\r\n- name: Gather Xen facts\r\n  community.general.xenserver_facts:\r\n```\r\n\n\n### Expected Results\n\nSomething other than an error...\n\n### Actual Results\n\n```console (paste below)\r\nTASK [xen : Gather Xen facts] ********************************************************************************************************\r\ntask path: /home/chris/webarch/servers/galaxy/roles/xen/tasks/main.yml:2\r\nredirecting (type: modules) community.general.xenserver_facts to community.general.cloud.misc.xenserver_facts\r\nredirecting (type: modules) community.general.xenserver_facts to community.general.cloud.misc.xenserver_facts\r\nAn exception occurred during task execution. To see the full traceback, use -vvv. The error was: TypeError: __init__() missing 1 required positional argument: 'argument_spec'\r\nfatal: [xen4.webarch.net]: FAILED! => {\"changed\": false, \"module_stderr\": \"Traceback (most recent call last):\\n  File \\\"<stdin>\\\", line 107, in <module>\\n  File \\\"<stdin>\\\", line 99, in _ansiballz_main\\n  File \\\"<stdin>\\\", line 47, in invoke_module\\n  File \\\"/usr/lib/python3.9/runpy.py\\\", line 210, in run_module\\n    return _run_module_code(code, init_globals, run_name, mod_spec)\\n  File \\\"/usr/lib/python3.9/runpy.py\\\", line 97, in _run_module_code\\n    _run_code(code, mod_globals, init_globals,\\n  File \\\"/usr/lib/python3.9/runpy.py\\\", line 87, in _run_code\\n    exec(code, run_globals)\\n  File \\\"/tmp/ansible_community.general.xenserver_facts_payload_ilqmvdk8/ansible_community.general.xenserver_facts_payload.zip/ansible_collections/community/general/plugins/modules/cloud/misc/xenserver_facts.py\\\", line 206, in <module>\\n  File \\\"/tmp/ansible_community.general.xenserver_facts_payload_ilqmvdk8/ansible_community.general.xenserver_facts_payload.zip/ansible_collections/community/general/plugins/modules/cloud/misc/xenserver_facts.py\\\", line 165, in main\\nTypeError: __init__() missing 1 required positional argument: 'argument_spec'\\n\", \"module_stdout\": \"\", \"msg\": \"MODULE FAILURE\\nSee stdout/stderr for the exact error\", \"rc\": 1}\r\n```\r\n\n\n### Code of Conduct\n\n- [X] I agree to follow the Ansible Code of Conduct\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n#\n# Copyright Ansible Project\n# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: xenserver_facts\nshort_description: get facts reported on xenserver\ndescription:\n  - Reads data out of XenAPI, can be used instead of multiple xe commands.\nauthor:\n    - Andy Hill (@andyhky)\n    - Tim Rupp (@caphrim007)\n    - Robin Lee (@cheese)\noptions: {}\n'''\n\nEXAMPLES = '''\n- name: Gather facts from xenserver\n  community.general.xenserver_facts:\n\n- name: Print running VMs\n  ansible.builtin.debug:\n    msg: \"{{ item }}\"\n  with_items: \"{{ xs_vms.keys() }}\"\n  when: xs_vms[item]['power_state'] == \"Running\"\n\n# Which will print:\n#\n# TASK: [Print running VMs] ***********************************************************\n# skipping: [10.13.0.22] => (item=CentOS 4.7 (32-bit))\n# ok: [10.13.0.22] => (item=Control domain on host: 10.0.13.22) => {\n#     \"item\": \"Control domain on host: 10.0.13.22\",\n#     \"msg\": \"Control domain on host: 10.0.13.22\"\n# }\n'''\n\n\nHAVE_XENAPI = False\ntry:\n    import XenAPI\n    HAVE_XENAPI = True\nexcept ImportError:\n    pass\n\nfrom ansible.module_utils import distro\nfrom ansible.module_utils.basic import AnsibleModule\n\n\nclass XenServerFacts:\n    def __init__(self):\n        self.codes = {\n            '5.5.0': 'george',\n            '5.6.100': 'oxford',\n            '6.0.0': 'boston',\n            '6.1.0': 'tampa',\n            '6.2.0': 'clearwater'\n        }\n\n    @property\n    def version(self):\n        result = distro.linux_distribution()[1]\n        return result\n\n    @property\n    def codename(self):\n        if self.version in self.codes:\n            result = self.codes[self.version]\n        else:\n            result = None\n\n        return result\n\n\ndef get_xenapi_session():\n    session = XenAPI.xapi_local()\n    session.xenapi.login_with_password('', '')\n    return session\n\n\ndef get_networks(session):\n    recs = session.xenapi.network.get_all_records()\n    networks = change_keys(recs, key='name_label')\n    return networks\n\n\ndef get_pifs(session):\n    recs = session.xenapi.PIF.get_all_records()\n    pifs = change_keys(recs, key='uuid')\n    xs_pifs = {}\n    devicenums = range(0, 7)\n    for pif in pifs.values():\n        for eth in devicenums:\n            interface_name = \"eth%s\" % (eth)\n            bond_name = interface_name.replace('eth', 'bond')\n            if pif['device'] == interface_name:\n                xs_pifs[interface_name] = pif\n            elif pif['device'] == bond_name:\n                xs_pifs[bond_name] = pif\n    return xs_pifs\n\n\ndef get_vlans(session):\n    recs = session.xenapi.VLAN.get_all_records()\n    return change_keys(recs, key='tag')\n\n\ndef change_keys(recs, key='uuid', filter_func=None):\n    \"\"\"\n    Take a xapi dict, and make the keys the value of recs[ref][key].\n\n    Preserves the ref in rec['ref']\n\n    \"\"\"\n    new_recs = {}\n\n    for ref, rec in recs.items():\n        if filter_func is not None and not filter_func(rec):\n            continue\n\n        for param_name, param_value in rec.items():\n            # param_value may be of type xmlrpc.client.DateTime,\n            # which is not simply convertable to str.\n            # Use 'value' attr to get the str value,\n            # following an example in xmlrpc.client.DateTime document\n            if hasattr(param_value, \"value\"):\n                rec[param_name] = param_value.value\n        new_recs[rec[key]] = rec\n        new_recs[rec[key]]['ref'] = ref\n\n    return new_recs\n\n\ndef get_host(session):\n    \"\"\"Get the host\"\"\"\n    host_recs = session.xenapi.host.get_all()\n    # We only have one host, so just return its entry\n    return session.xenapi.host.get_record(host_recs[0])\n\n\ndef get_vms(session):\n    recs = session.xenapi.VM.get_all_records()\n    if not recs:\n        return None\n    vms = change_keys(recs, key='name_label')\n    return vms\n\n\ndef get_srs(session):\n    recs = session.xenapi.SR.get_all_records()\n    if not recs:\n        return None\n    srs = change_keys(recs, key='name_label')\n    return srs\n\n\ndef main():\n    module = AnsibleModule(\n        supports_check_mode=True,\n    )\n\n    if not HAVE_XENAPI:\n        module.fail_json(changed=False, msg=\"python xen api required for this module\")\n\n    obj = XenServerFacts()\n    try:\n        session = get_xenapi_session()\n    except XenAPI.Failure as e:\n        module.fail_json(msg='%s' % e)\n\n    data = {\n        'xenserver_version': obj.version,\n        'xenserver_codename': obj.codename\n    }\n\n    xs_networks = get_networks(session)\n    xs_pifs = get_pifs(session)\n    xs_vlans = get_vlans(session)\n    xs_vms = get_vms(session)\n    xs_srs = get_srs(session)\n\n    if xs_vlans:\n        data['xs_vlans'] = xs_vlans\n    if xs_pifs:\n        data['xs_pifs'] = xs_pifs\n    if xs_networks:\n        data['xs_networks'] = xs_networks\n\n    if xs_vms:\n        data['xs_vms'] = xs_vms\n\n    if xs_srs:\n        data['xs_srs'] = xs_srs\n\n    module.exit_json(ansible_facts=data)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/cloud/misc/xenserver_facts.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n#\n# Copyright Ansible Project\n# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: xenserver_facts\nshort_description: get facts reported on xenserver\ndescription:\n  - Reads data out of XenAPI, can be used instead of multiple xe commands.\nauthor:\n    - Andy Hill (@andyhky)\n    - Tim Rupp (@caphrim007)\n    - Robin Lee (@cheese)\noptions: {}\n'''\n\nEXAMPLES = '''\n- name: Gather facts from xenserver\n  community.general.xenserver_facts:\n\n- name: Print running VMs\n  ansible.builtin.debug:\n    msg: \"{{ item }}\"\n  with_items: \"{{ xs_vms.keys() }}\"\n  when: xs_vms[item]['power_state'] == \"Running\"\n\n# Which will print:\n#\n# TASK: [Print running VMs] ***********************************************************\n# skipping: [10.13.0.22] => (item=CentOS 4.7 (32-bit))\n# ok: [10.13.0.22] => (item=Control domain on host: 10.0.13.22) => {\n#     \"item\": \"Control domain on host: 10.0.13.22\",\n#     \"msg\": \"Control domain on host: 10.0.13.22\"\n# }\n'''\n\n\nHAVE_XENAPI = False\ntry:\n    import XenAPI\n    HAVE_XENAPI = True\nexcept ImportError:\n    pass\n\nfrom ansible.module_utils import distro\nfrom ansible.module_utils.basic import AnsibleModule\n\n\nclass XenServerFacts:\n    def __init__(self):\n        self.codes = {\n            '5.5.0': 'george',\n            '5.6.100': 'oxford',\n            '6.0.0': 'boston',\n            '6.1.0': 'tampa',\n            '6.2.0': 'clearwater'\n        }\n\n    @property\n    def version(self):\n        result = distro.linux_distribution()[1]\n        return result\n\n    @property\n    def codename(self):\n        if self.version in self.codes:\n            result = self.codes[self.version]\n        else:\n            result = None\n\n        return result\n\n\ndef get_xenapi_session():\n    session = XenAPI.xapi_local()\n    session.xenapi.login_with_password('', '')\n    return session\n\n\ndef get_networks(session):\n    recs = session.xenapi.network.get_all_records()\n    networks = change_keys(recs, key='name_label')\n    return networks\n\n\ndef get_pifs(session):\n    recs = session.xenapi.PIF.get_all_records()\n    pifs = change_keys(recs, key='uuid')\n    xs_pifs = {}\n    devicenums = range(0, 7)\n    for pif in pifs.values():\n        for eth in devicenums:\n            interface_name = \"eth%s\" % (eth)\n            bond_name = interface_name.replace('eth', 'bond')\n            if pif['device'] == interface_name:\n                xs_pifs[interface_name] = pif\n            elif pif['device'] == bond_name:\n                xs_pifs[bond_name] = pif\n    return xs_pifs\n\n\ndef get_vlans(session):\n    recs = session.xenapi.VLAN.get_all_records()\n    return change_keys(recs, key='tag')\n\n\ndef change_keys(recs, key='uuid', filter_func=None):\n    \"\"\"\n    Take a xapi dict, and make the keys the value of recs[ref][key].\n\n    Preserves the ref in rec['ref']\n\n    \"\"\"\n    new_recs = {}\n\n    for ref, rec in recs.items():\n        if filter_func is not None and not filter_func(rec):\n            continue\n\n        for param_name, param_value in rec.items():\n            # param_value may be of type xmlrpc.client.DateTime,\n            # which is not simply convertable to str.\n            # Use 'value' attr to get the str value,\n            # following an example in xmlrpc.client.DateTime document\n            if hasattr(param_value, \"value\"):\n                rec[param_name] = param_value.value\n        new_recs[rec[key]] = rec\n        new_recs[rec[key]]['ref'] = ref\n\n    return new_recs\n\n\ndef get_host(session):\n    \"\"\"Get the host\"\"\"\n    host_recs = session.xenapi.host.get_all()\n    # We only have one host, so just return its entry\n    return session.xenapi.host.get_record(host_recs[0])\n\n\ndef get_vms(session):\n    recs = session.xenapi.VM.get_all_records()\n    if not recs:\n        return None\n    vms = change_keys(recs, key='name_label')\n    return vms\n\n\ndef get_srs(session):\n    recs = session.xenapi.SR.get_all_records()\n    if not recs:\n        return None\n    srs = change_keys(recs, key='name_label')\n    return srs\n\n\ndef main():\n    module = AnsibleModule({}, supports_check_mode=True)\n\n    if not HAVE_XENAPI:\n        module.fail_json(changed=False, msg=\"python xen api required for this module\")\n\n    obj = XenServerFacts()\n    try:\n        session = get_xenapi_session()\n    except XenAPI.Failure as e:\n        module.fail_json(msg='%s' % e)\n\n    data = {\n        'xenserver_version': obj.version,\n        'xenserver_codename': obj.codename\n    }\n\n    xs_networks = get_networks(session)\n    xs_pifs = get_pifs(session)\n    xs_vlans = get_vlans(session)\n    xs_vms = get_vms(session)\n    xs_srs = get_srs(session)\n\n    if xs_vlans:\n        data['xs_vlans'] = xs_vlans\n    if xs_pifs:\n        data['xs_pifs'] = xs_pifs\n    if xs_networks:\n        data['xs_networks'] = xs_networks\n\n    if xs_vms:\n        data['xs_vms'] = xs_vms\n\n    if xs_srs:\n        data['xs_srs'] = xs_srs\n\n    module.exit_json(ansible_facts=data)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/cloud/misc/xenserver_facts.py"}]}