Ansible json_query 过滤器
Ansible json_query filter
所以我得到了 ansible 的输出(使用 shell 模块 ping 一些主机:
TASK [debug] ***************************************************************************************************************************************************************************************
skipping: [10.240.18.58]
ok: [10.240.18.57] => {
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.18.20\"",
"delta": "0:00:00.005339",
"end": "2020-02-05 10:41:06.527708",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.18.20\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.18.20",
"rc": 0,
"start": "2020-02-05 10:41:06.522369",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.\n64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms\n\n--- 10.240.18.20 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.268/0.268/0.268/0.000 ms",
"stdout_lines": [
"PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.",
"64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms",
"",
"--- 10.240.18.20 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 0.268/0.268/0.268/0.000 ms"
]
},
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.23.34\"",
"delta": "0:00:00.006229",
"end": "2020-02-05 10:41:09.889206",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.23.34\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.23.34",
"rc": 0,
"start": "2020-02-05 10:41:09.882977",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.23.34 (10.240.23.34) 56(84) bytes of data.\n64 bytes from 10.240.23.34: icmp_req=1 ttl=63 time=1.33 ms\n\n--- 10.240.23.34 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 1.333/1.333/1.333/0.000 ms",
"stdout_lines": [
"PING 10.240.23.34 (10.240.23.34) 56(84) bytes of data.",
"64 bytes from 10.240.23.34: icmp_req=1 ttl=63 time=1.33 ms",
"",
"--- 10.240.23.34 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 1.333/1.333/1.333/0.000 ms"
]
},
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.23.35\"",
"delta": "0:00:00.006403",
"end": "2020-02-05 10:41:13.237920",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.23.35\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.23.35",
"rc": 0,
"start": "2020-02-05 10:41:13.231517",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.23.35 (10.240.23.35) 56(84) bytes of data.\n64 bytes from 10.240.23.35: icmp_req=1 ttl=63 time=1.36 ms\n\n--- 10.240.23.35 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 1.364/1.364/1.364/0.000 ms",
"stdout_lines": [
"PING 10.240.23.35 (10.240.23.35) 56(84) bytes of data.",
"64 bytes from 10.240.23.35: icmp_req=1 ttl=63 time=1.36 ms",
"",
"--- 10.240.23.35 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 1.364/1.364/1.364/0.000 ms"
]
}
]
}
}
我创建了一个 ansible 任务,我想严格使用调试显示这些行:
"stdout_lines": [
"PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.",
"64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms",
对于每个主机。
ansible 任务是这样的:
- debug:
msg: "{{ smm_ping.json | json_query(pfilter) }}"
vars:
pfilter: "[*].{Ping response: stdout_lines}"
when: "('primary' in default_hostname or 'Primary' in default_hostname)"
tags: ['ic', 'smm']
由于某种原因它不工作:
TASK [debug]
fatal: [10.240.18.57]: FAILED! => {"msg": "JMESPathError in json_query filter plugin:\nExpecting: colon, got: unquoted_identifier: Parse error at column 10, token \"response\" (UNQUOTED_IDENTIFIER), for expression:\n\"[*].{Ping response: stdout_lines}\"\n ^"}
由于您的标识符中有一个 space,因此您需要将其引用。
pfilter: "[*].{\"Ping response\": stdout_lines}"
为了简化 writing/readability,您可以使用 yaml 折叠块标量并删除一级引号转义:
pfilter: >-
[*].{"Ping response": stdout_lines}
注意:jmespath 标识符的引号字符是双引号 ("
)。 不要使用用于字符串值的单引号。请参阅下面的 jmespath 规范。
参考文献:
所以我得到了 ansible 的输出(使用 shell 模块 ping 一些主机:
TASK [debug] ***************************************************************************************************************************************************************************************
skipping: [10.240.18.58]
ok: [10.240.18.57] => {
"msg": {
"changed": true,
"msg": "All items completed",
"results": [
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.18.20\"",
"delta": "0:00:00.005339",
"end": "2020-02-05 10:41:06.527708",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.18.20\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.18.20",
"rc": 0,
"start": "2020-02-05 10:41:06.522369",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.\n64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms\n\n--- 10.240.18.20 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 0.268/0.268/0.268/0.000 ms",
"stdout_lines": [
"PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.",
"64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms",
"",
"--- 10.240.18.20 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 0.268/0.268/0.268/0.000 ms"
]
},
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.23.34\"",
"delta": "0:00:00.006229",
"end": "2020-02-05 10:41:09.889206",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.23.34\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.23.34",
"rc": 0,
"start": "2020-02-05 10:41:09.882977",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.23.34 (10.240.23.34) 56(84) bytes of data.\n64 bytes from 10.240.23.34: icmp_req=1 ttl=63 time=1.33 ms\n\n--- 10.240.23.34 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 1.333/1.333/1.333/0.000 ms",
"stdout_lines": [
"PING 10.240.23.34 (10.240.23.34) 56(84) bytes of data.",
"64 bytes from 10.240.23.34: icmp_req=1 ttl=63 time=1.33 ms",
"",
"--- 10.240.23.34 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 1.333/1.333/1.333/0.000 ms"
]
},
{
"_ansible_ignore_errors": true,
"_ansible_item_result": true,
"_ansible_no_log": false,
"_ansible_parsed": true,
"changed": true,
"cmd": "ping -c1 -W1 \"10.240.23.35\"",
"delta": "0:00:00.006403",
"end": "2020-02-05 10:41:13.237920",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "ping -c1 -W1 \"10.240.23.35\"",
"_uses_shell": true,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"warn": true
}
},
"item": "10.240.23.35",
"rc": 0,
"start": "2020-02-05 10:41:13.231517",
"stderr": "",
"stderr_lines": [],
"stdout": "PING 10.240.23.35 (10.240.23.35) 56(84) bytes of data.\n64 bytes from 10.240.23.35: icmp_req=1 ttl=63 time=1.36 ms\n\n--- 10.240.23.35 ping statistics ---\n1 packets transmitted, 1 received, 0% packet loss, time 0ms\nrtt min/avg/max/mdev = 1.364/1.364/1.364/0.000 ms",
"stdout_lines": [
"PING 10.240.23.35 (10.240.23.35) 56(84) bytes of data.",
"64 bytes from 10.240.23.35: icmp_req=1 ttl=63 time=1.36 ms",
"",
"--- 10.240.23.35 ping statistics ---",
"1 packets transmitted, 1 received, 0% packet loss, time 0ms",
"rtt min/avg/max/mdev = 1.364/1.364/1.364/0.000 ms"
]
}
]
}
}
我创建了一个 ansible 任务,我想严格使用调试显示这些行:
"stdout_lines": [
"PING 10.240.18.20 (10.240.18.20) 56(84) bytes of data.",
"64 bytes from 10.240.18.20: icmp_req=1 ttl=64 time=0.268 ms",
对于每个主机。
ansible 任务是这样的:
- debug:
msg: "{{ smm_ping.json | json_query(pfilter) }}"
vars:
pfilter: "[*].{Ping response: stdout_lines}"
when: "('primary' in default_hostname or 'Primary' in default_hostname)"
tags: ['ic', 'smm']
由于某种原因它不工作:
TASK [debug]
fatal: [10.240.18.57]: FAILED! => {"msg": "JMESPathError in json_query filter plugin:\nExpecting: colon, got: unquoted_identifier: Parse error at column 10, token \"response\" (UNQUOTED_IDENTIFIER), for expression:\n\"[*].{Ping response: stdout_lines}\"\n ^"}
由于您的标识符中有一个 space,因此您需要将其引用。
pfilter: "[*].{\"Ping response\": stdout_lines}"
为了简化 writing/readability,您可以使用 yaml 折叠块标量并删除一级引号转义:
pfilter: >-
[*].{"Ping response": stdout_lines}
注意:jmespath 标识符的引号字符是双引号 ("
)。 不要使用用于字符串值的单引号。请参阅下面的 jmespath 规范。
参考文献: