ansible - 在ansible中,如何打印任务失败的每个项目的标准错误?
问题描述
我有一组由用户输入提供的服务器,我想测试列表中的每个服务器,如果有任何失败,我想知道哪些失败以及为什么失败(stderr)。注意,服务器的数量不会是一致的,所以解决方案需要动态地发送服务器的数量。
命令
ansible-playbook test.yml -e '{"chrony_servers":["0.centos.pool.ntp.org","10.centos.pool.ntp.org"]}'
测试.yml
- name: Services Playbook
hosts: localhost
tasks:
- name: Install nmap-ncat
yum: name=nc state=present
- name: Validate chrony_servers
command: nc -vzu {{ item }} 123
with_items:
- "{{ chrony_servers }}"
ignore_errors: yes
register: chrony_server_results
- debug: var=chrony_server_results
- fail:
msg: "{{ chrony_server_results.results.stderr }}"
when: chrony_server_results.failed is defined and chrony_server_results.failed == true
这是来自此示例的输出
TASK [debug] ********************************************************************************************************************************************************************
ok: [localhost] => {
"chrony_server_results": {
"changed": true,
"failed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": true,
"_ansible_item_label": "0.centos.pool.ntp.org",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": [
"nc",
"-vzu",
"0.centos.pool.ntp.org",
"123"
],
"delta": "0:00:02.217171",
"end": "2019-05-16 18:58:54.070600",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "nc -vzu 0.centos.pool.ntp.org 123",
"_uses_shell": false,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "0.centos.pool.ntp.org",
"rc": 0,
"start": "2019-05-16 18:58:51.853429",
"stderr": "Ncat: Version 7.50 ( https://nmap.org/ncat )\nNcat: Connected to 208.75.88.4:123.\nNcat: UDP packet sent successfully\nNcat: 1 bytes sent, 0 bytes received in 2.21 seconds.",
"stderr_lines": [
"Ncat: Version 7.50 ( https://nmap.org/ncat )",
"Ncat: Connected to 208.75.88.4:123.",
"Ncat: UDP packet sent successfully",
"Ncat: 1 bytes sent, 0 bytes received in 2.21 seconds."
],
"stdout": "",
"stdout_lines": []
},
{
"_ansible_item_label": "10.centos.pool.ntp.org",
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": [
"nc",
"-vzu",
"10.centos.pool.ntp.org",
"123"
],
"delta": "0:00:00.312970",
"end": "2019-05-16 18:58:54.510976",
"failed": true,
"invocation": {
"module_args": {
"_raw_params": "nc -vzu 10.centos.pool.ntp.org 123",
"_uses_shell": false,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.centos.pool.ntp.org",
"msg": "non-zero return code",
"rc": 2,
"start": "2019-05-16 18:58:54.198006",
"stderr": "Ncat: Version 7.50 ( https://nmap.org/ncat )\nNcat: Could not resolve hostname \"10.centos.pool.ntp.org\": Name or service not known. QUITTING.",
"stderr_lines": [
"Ncat: Version 7.50 ( https://nmap.org/ncat )",
"Ncat: Could not resolve hostname \"10.centos.pool.ntp.org\": Name or service not known. QUITTING."
],
"stdout": "",
"stdout_lines": []
}
]
}
}
TASK [fail] *********************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'list object' has no attribute 'stderr'\n\nThe error appears to have been in '/home/vera/test.yml': line 14, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n - debug: var=chrony_server_results\n - fail:\n ^ here\n"}
to retry, use: --limit @/home/vera/test.retry
PLAY RECAP **********************************************************************************************************************************************************************
预期结果应该类似于
"stderr": "Ncat: Version 7.50 ( https://nmap.org/ncat )\nNcat: Could not resolve hostname \"10.centos.pool.ntp.org\": Name or service not known. QUITTING."
解决方案
你的结构chrony_server_results
是一个字典,与你的调试任务假设的结构有点不同。
它在顶层有一些键,它们适用于您with_items
作为一个整体调用的任务,例如changed
和failed
。各个调用的“子结果”包含各自的stderr
和rc
属性,存储在具有键的数组中results
。
这意味着这chrony_server_results.results.stderr
是错误的,并且该错误告诉您该数组没有stderr
属性,而是单个条目有多个属性,您需要对其进行迭代。您可以检查rc
以了解相应的调用是否实际失败(因为 netcat 显然在所有情况下都会写入 stderr)。
rc
以下解决方案首先构建一个仅包含大于零的结果的数组,然后仅显示这些结果的调试消息:
- set_fact:
failed_results: "{{ chrony_server_results.results | selectattr('rc', '>', 0) | list }}"
- name: Show the stderrs of failed_results
debug:
msg: "{{ item.stderr }}"
with_items: "{{ failed_results }}"
- fail:
msg: "See debug output above"
when: failed_results | length > 0
第一个表达式中使用的过滤器是 jinja2 的一部分,并在此处记录:http: //jinja.pocoo.org/docs/2.10/templates/#selectattr
推荐阅读
- reactjs - 如何在 react-native 中创建类似 Spotify 的持久通知
- java - 如何遍历一个集合
- exception - 实际上在不创建 GOTO 的情况下捕获异常
- amazon-web-services - 主名称服务器未在父级中列出
- griddb - 如何将 input modifiable 设置为 true 以更改我的架构?
- python - 如何将我的框架中显示的图像转换为 tkinter 中的 BLOB?
- api - Pandora 非官方 REST API 是否损坏
- typescript - Axios:标题内容中的无效字符['适配器']
- vba - 字典与数据透视表和一些办公室问题
- javascript - 反应原生
显示错误的值