问题描述
我是Ansible的新手,在这里我创建了一个将CSV作为参数的模块,如下所示:但是它不断抛出错误,即找不到CSV_TEST.csv文件。我是否可以在ansible模块中以正确的方式创建它作为变量?
module.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()
Playbook.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位于同一树形结构(父文件夹)下
解决方法
我认为,如果您在Ansible中有一个相对的文件路径,则Ansible首先会在本地目录中查找(如果您从ansible运行则输出该目录),然后它将在其他位置查找(请查看{ {3}},以获取更多信息。
所以在我看来,您的目录结构就像
WorkingDir
|- playbook.yml
|- Ansible
|- CSV_TEST.csv
我认为您在ansible-playbook playbook.yml
内部像WorkingDir
一样运行ansible。它找不到CSV_TEST.csv
,因为它在WorkingDir
中寻找。
如果在python内部,您必须放置Ansible/CSV_TEST.csv
到您的剧本中。所以
Ansible/CSV_TEST.csv
如果这无济于事,那么您能以文本格式写出目录结构并显示所有内容从何处执行以及python在何处运行(---
- 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
输出什么)?
一旦我修正了以上评论中报告的问题,您的代码就不会再出现其他问题。可能存在逻辑问题(但我不知道确切的期望是什么)。目前,这是一个证明运行,它可以按照我在您的模块代码中可以读取的预期运行。下面的路径都与我从中启动剧本的当前工作目录有关。
存储在./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_TEST.csv
中的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