0

我正在编写一个自定义 Ansible 模块,python 工作正常,但我无法将其转换为模块。我创建了一个虚拟模块来降低复杂性,我遇到了同样的问题。所以问题出在我的 Ansible 样板代码上。我们为 Ansible 使用 2.9.2 版本,python 3.6.9。

我已经将两个必需参数传递到模块中,它应该在字典中返回它们,另外两个设置为默认值。

我用参数创建了 AnsibleModule,在 python 脚本中使用它们,然后检查结果并退出模块。我错过了什么?

目录结构:

ansible.cfg

库存.ini

module_test.yml

库/module_test.py

这是 Ansible 测试脚本:


 - name: Testing module
   any_errors_fatal: true
   connection: local
   gather_facts: false
   hosts: localhost

   tasks:
     - name: test the ansible module
       module_test:
         var1: "test var 1"
         var2: "test var 2"
       register: output
     - name: debug output
       debug:
         msg: "{{ output }}"

这是python模块:

#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule


class AnsibleModuleTest(object):

    def __init__(self, var1, var2, var3, var4):

        self._var1 = var1
        self._var2 = var2
        self._var3 = var3
        self._var4 = var4

    def run(self, check):

        if check:
            return {"result": True, "data": {"var1": self._var1, "var2": self._var2, "var3": self._var3, "var4": self._var4}}
        else:
            return {"result": False, "error": "fail"}


def main():

    module = AnsibleModule(
            argument_spec=dict(
                var1=dict(required=True),
                var2=dict(required=True),
                var3=dict(required=False, default=None),
                var4=dict(required=False, default=None),
                supports_check_mode=False
            )
        )

    var1 = module.params["var1"]
    var2 = module.params["var2"]
    var3 = module.params["var3"]
    var4 = module.params["var4"]

    _test_module = AnsibleModuleTest(var1, var2, var3, var4)
    _returned_data = _test_module.run(True)

    if _returned_data["result"]:
        result = dict(msg=_returned_data["data"], changed=False)
        module.exit_json(**result)
    else:
        module.fail_json(msg=_returned_data["error"])


if __name__ == '__main__':
    main()

这是回溯:

TASK [test the ansible module] **************************************************************************************************
task path: /root/test_role/module_test.yml:9
<127.0.0.1> ESTABLISH LOCAL CONNECTION FOR USER: root
<127.0.0.1> EXEC /bin/sh -c 'echo ~root && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367 `" && echo ansible-tmp-1594296428.9225461-257853634365367="` echo /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367 `" ) && sleep 0'
Using module file /root/test_role/library/module_test.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-34085udiksek/tmphun0ptk_ TO /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py
<127.0.0.1> EXEC /bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/ /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c '/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py && sleep 0'
<127.0.0.1> EXEC /bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/ > /dev/null 2>&1 && sleep 0'
The full traceback is:
Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py", line 102, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible.modules.module_test', init_globals=None, run_name='__main__', alter_sys=True)
  File "/usr/lib/python3.6/runpy.py", line 205, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/modules/module_test.py", line 52, in <module>
  File "/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/modules/module_test.py", line 32, in main
  File "/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/module_utils/basic.py", line 639, in __init__
  File "/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/module_utils/basic.py", line 1847, in _set_fallbacks
AttributeError: 'bool' object has no attribute 'get'

fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/root/.ansible/tmp/ansible-tmp-1594296428.9225461-257853634365367/AnsiballZ_module_test.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.module_test', init_globals=None, run_name='__main__', alter_sys=True)\n  File \"/usr/lib/python3.6/runpy.py\", line 205, in run_module\n    return _run_module_code(code, init_globals, run_name, mod_spec)\n  File \"/usr/lib/python3.6/runpy.py\", line 96, in _run_module_code\n    mod_name, mod_spec, pkg_name, script_name)\n  File \"/usr/lib/python3.6/runpy.py\", line 85, in _run_code\n    exec(code, run_globals)\n  File \"/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/modules/module_test.py\", line 52, in <module>\n  File \"/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/modules/module_test.py\", line 32, in main\n  File \"/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/module_utils/basic.py\", line 639, in __init__\n  File \"/tmp/ansible_module_test_payload_13zt59h5/ansible_module_test_payload.zip/ansible/module_utils/basic.py\", line 1847, in _set_fallbacks\nAttributeError: 'bool' object has no attribute 'get'\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}
4

1 回答 1

0

已修复,我有我的样板代码,应该遵循 Ansible 页面而不是其他人的解决方案。

#!/usr/bin/python
from ansible.module_utils.basic import AnsibleModule


class AnsibleModuleTest(object):

    def __init__(self, var1, var2, var3, var4):

        self._var1 = var1
        self._var2 = var2
        self._var3 = var3
        self._var4 = var4

    def run(self, check):

        if check:
            return {"result": True,
                    "data": {"var1": self._var1, "var2": self._var2, "var3": self._var3, "var4": self._var4}
                    }
        else:
            return {"result": False, "error": "fail"}


def run_module():

    module_args = dict(
        var1=dict(type="str", required=True),
        var2=dict(type="str", required=True),
        var3=dict(type="str", required=False, default=None),
        var4=dict(type="str", required=False, default=None)
    )
    module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)

    _test_module = AnsibleModuleTest(
        module.params["var1"],
        module.params["var2"],
        module.params["var3"],
        module.params["var4"]
    )
    _returned_data = _test_module.run(True)

    if _returned_data["result"]:
        result = dict(msg=_returned_data["data"], changed=False)
    else:
        result = dict(msg=_returned_data["error"], changed=False)
        module.fail_json(**result)

    if module.check_mode:
        module.exit_json(**result)

    module.exit_json(**result)


def main():

    run_module()


if __name__ == '__main__':
    main()
于 2020-07-09T15:16:35.983 回答