0

我是 Ansible 的新手,在这里我创建了一个将 CSV 作为参数的模块,如下所示:但它不断抛出错误,它无法找到 CSV_TEST.csv 文件。我是否以正确的方式将其创建为 ansible 模块中的变量?

模块.py

def main():
    field = dict(
        csv=dict(type='str', required=True)
    )

    result = dict(
        changed=False,
        response='')

    module = AnsibleModule(argument_spec=field)

    csvFile = module.params['csv']

    listFinal = list()
    final = list()

    if csvFile:
        with open(csvFile, "r", newline='', encoding='utf-8-sig') as csvImport:
            reader = csv.DictReader(csvImport)
            for row in reader:
                newDict = dict({
                    'name': row.get("Name"),
                    'address': row.get("Address")
                    'val': row.get("Val")
                })
                listFinal.append(newDict)


    if listFinal:
        for entry in listFinal:
            if entry.get("val") == "Incorrect":
                name = entry.get('name')
                add = entry.get('address')
                update = f'set add {add} of {name}'

                final.append(update)

        result['final'] = final

    module.exit_json(changed=False, meta=result)


if __name__ == '__main__':
    main()

剧本.yml

---
- name: Test Variables with Ansible
  hosts: localhost
  vars:
    x: 30
    xName: "Sai"
  gather_facts: false
  become: false
  tasks:
    - name: Test Device Validation
      portDescription:
        csv: CSV_TEST.csv
      register: result

    - debug: var=result

错误是:

***
FileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'
fatal: [localhost]: FAILED! => {
    "changed": false,
    "module_stderr": "Shared connection to localhost closed.\r\n",
***

有人可以建议,我在这里做错了什么吗?CSV_TEST.csv 位于与 Playbook.yml 相同的树结构(父文件夹)下

4

2 回答 2

0

一旦我解决了我在上述评论中报告的问题,我看不出您的代码有任何其他问题。可能存在逻辑问题(但我不知道确切的期望是什么)。现在,这是一个证明运行,它可以从我在您的模块代码中读到的内容按预期工作。下面的路径都是相对于我从中启动剧本的当前工作目录。

模块存储在./library/port_description.py

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

def main():
    field = dict(
        csv=dict(type='str', required=True)
    )

    result = dict(
        changed=False,
        response='')

    module = AnsibleModule(argument_spec=field)

    csvFile = module.params['csv']

    listFinal = list()
    final = list()

    if csvFile:
        with open(csvFile, "r", newline='', encoding='utf-8-sig') as csvImport:
            module.debug("csv openned")
            reader = csv.DictReader(csvImport)
            for row in reader:
                newDict = dict({
                    'name': row.get("Name"),
                    'address': row.get("Address"),
                    'val': row.get("Val")
                })
                listFinal.append(newDict)

    if listFinal:
        for entry in listFinal:
            if entry.get("val") == "Incorrect":
                name = entry.get('name')
                add = entry.get('address')
                update = f'set add {add} of {name}'

                final.append(update)

        result['final'] = final

    module.exit_json(changed=False, meta=result)


if __name__ == '__main__':
    main()

存储的 csv 文件./CSV_TEST.csv(试图创建与预期名称和 python 代码一致的东西......)

Name,Address,Val
toto,127.0.0.1,3
titi,192.168.0.1,Incorrect

剧本存储在./test.yml

---
- name: Use a custom module reading csv file
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Use our module and register result
      port_description:
        csv: CSV_TEST.csv
      register: port_result

    - name: Show the result
      debug:
        var: port_result

结果:

$ ansible-playbook test.yml 

PLAY [Use a custom module reading csv file] ********************************************************************************************************************************************************************************************

TASK [Use our module and register result] **********************************************************************************************************************************************************************************************
ok: [localhost]

TASK [Show the result] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "port_result": {
        "changed": false,
        "failed": false,
        "meta": {
            "changed": false,
            "final": [
                "set add 192.168.0.1 of titi"
            ],
            "response": ""
        }
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

请注意,如果我从预期位置删除给定的 CSV 文件,我可以轻松重现您的确切问题:

$ mv CSV_TEST.csv CSV_TEST.csv.BAK
$ ansible-playbook test.yml 

PLAY [Use a custom module reading csv file] ********************************************************************************************************************************************************************************************

TASK [Use our module and register result] **********************************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: FileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'
fatal: [localhost]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/user/.ansible/tmp/ansible-tmp-1602932173.7323837-24457-268203592954263/AnsiballZ_port_description.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.port_description', 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_port_description_payload_6v82vnu_/ansible_port_description_payload.zip/ansible/modules/port_description.py\", line 48, in <module>\n  File \"/tmp/ansible_port_description_payload_6v82vnu_/ansible_port_description_payload.zip/ansible/modules/port_description.py\", line 22, in main\nFileNotFoundError: [Errno 2] No such file or directory: 'CSV_TEST.csv'\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
于 2020-10-17T11:03:02.547 回答
0

我认为如果你在 Ansible 中有一个相对文件路径,Ansible 将首先在本地目录中查找(如果你运行 ansible 则输出任何目录)然后它会在其他一些位置查找(查看角色目录结构相关信息)。

所以在我看来你的目录结构就像

WorkingDir
|- playbook.yml
|- Ansible
   |- CSV_TEST.csv

而且我认为您正在像ansible-playbook playbook.yml从内部一样运行 ansible WorkingDir。它找不到CSV_TEST.csv,因为它正在寻找WorkingDir

如果你必须把它放在 python 里面,Ansible/CSV_TEST.csv那么你也必须把Ansible/CSV_TEST.csv你的剧本放进去。所以

---
- name: Test Variables with Ansible
  hosts: localhost
  vars:
    x: 30
    xName: "Sai"
  gather_facts: false
  become: false
  tasks:
    - name: Test Device Validation
      portDescription:
        csv: Ansible/CSV_TEST.csv
      register: result

    - debug: var=result

如果这没有帮助,那么您能否以文本格式写出目录结构并显示所有内容的执行位置以及 python 的运行位置(os.getcwd()输出什么)?

于 2020-10-16T19:17:24.610 回答