Проблема с нестандартным модулем Ansible - PullRequest
0 голосов
/ 09 июля 2020

Я пишу собственный модуль Ansible, и python работает нормально, но у меня проблемы с преобразованием его в модуль. Я создал фиктивный модуль, чтобы уменьшить сложность, и у меня такая же проблема. Итак, проблема в моем коде плиты котла Ansible. Мы используем версию 2.9.2 для Ansible, python 3.6.9.

Я передал два обязательных параметра в модуль, и он должен вернуть их в словаре вместе с двумя другими установить по умолчанию.

Я создал AnsibleModule с параметрами, вытащил их, использовал их в сценарии python, затем проверил результат и вышел из модуля. Что я пропустил?

Структура каталогов:

ansible .cfg

inventory.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
}

1 Ответ

0 голосов
/ 09 июля 2020

Исправлено, у меня есть код шаблона, следовало использовать страницу 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()
...