ansible - Ansible 过滤器以查找具有指定名称的所有列表
问题描述
我有一个任务
- name: Verify all app states
shell: get_cluster_states {{item.name}}
register: service_states
until: <all services are in 'up' state, this is what I need>
retries: 20
delay: 3
with_items: "{{ apps }}"
返回的“service_states”的内容格式如下:
"service_states": {
"changed": true,
"msg": "All items completed",
"results": [
{
......
"stdout": "Service Status: up\nService Status: up\nService Status: up",
"stdout_lines": [
"Service Status: up",
"Service Status: down",
"Service Status: up"
]
},
{
......
"stdout": "Service Status: up\nService Status: up\nService Status: up",
"stdout_lines": [
"Service Status: up",
"Service Status: up",
"Service Status: down"
]
}
]
}
我需要将过滤器应用于 service_states 数据,因此我可以从所有“stdout_lines”中获得一个组合的简单列表。在这种情况下,来自 2 个列表的总共 6 个值 - 列表元素的数量不固定:
expected: [
"Service Status: up",
"Service Status: down",
"Service Status: up",
"Service Status: up",
"Service Status: up",
"Service Status: down"
]
如果我能做到这一点,我就可以使用唯一/计数/值来确定所有服务是否启动。我尝试使用 {{ service_states.results | subelements('stdout_lines') }} 来获取 6 个条目,但不知道如何进一步过滤以获得上述最终列表。
解决方案
使用json_query,例如
- set_fact:
expected: "{{ service_states.results|
json_query('[].stdout_lines')|flatten }}"
,或地图属性,例如
- set_fact:
expected: "{{ service_states.results|
map(attribute='stdout_lines')|flatten }}"
问:“确定所有服务是否启动。 ”
答:例如
- debug:
msg: All services are up.
when: _all == _up
vars:
_list: "{{ service_states.results|
map(attribute='stdout_lines')|flatten }}"
_all: "{{ _list|length }}"
_up: "{{ _list|select('match', 'Service Status: up')|list|length }}"
- debug:
msg: "{{ _all|int - _up|int }} services are down."
vars:
_list: "{{ service_states.results|
map(attribute='stdout_lines')|flatten }}"
_all: "{{ _list|length }}"
_up: "{{ _list|select('match', 'Service Status: up')|list|length }}"
给
TASK [debug] *************************************************************
skipping: [localhost]
TASK [debug] *************************************************************
ok: [localhost] =>
msg: 2 services are down.
问:“有没有办法打印出直到位置的 service_states 的样子? ”
A: 没有。没有打印中间结果的方法。该任务正在远程主机上运行。在任务完成注册变量后,我们的例子中的service_states将被发送回控制器。相反,您可以调试模块以详细了解发生了什么。请参阅调试模块。
问:“也许循环内部没有结果层”
答:是的。循环内的结果是不同的。当循环完成时,注册变量必须包含所有结果的列表。请参阅循环任务直到成功
问:“需要直到”
A:没有循环直到文档中描述的工作,例如创建下面的脚本来生成随机数据
shell> cat random.sh
#!/bin/bash
printf "Service Status: "
[ "$((1 + $RANDOM % 10))" -lt "5" ] && echo up || echo down
printf "Service Status: "
[ "$((1 + $RANDOM % 10))" -lt "5" ] && echo up || echo down
printf "Service Status: "
[ "$((1 + $RANDOM % 10))" -lt "5" ] && echo up || echo down
shell> ./random.sh
Service Status: up
Service Status: up
Service Status: down
然后,剧本
shell> cat playbook.yml
- hosts: localhost
vars:
_pattern: "Service Status: up"
tasks:
- command: "{{ playbook_dir }}/random.sh"
register: service_states
until: service_states.stdout_lines|
select('match', _pattern)|list|length == 3
retries: 10
delay: 1
- debug:
msg: "{{ service_states.stdout_lines }}"
给
shell> ansible-playbook playbook.yml
TASK [command] **********************************************************
FAILED - RETRYING: command (10 retries left).
FAILED - RETRYING: command (9 retries left).
FAILED - RETRYING: command (8 retries left).
changed: [localhost]
TASK [debug] ************************************************************
ok: [localhost] =>
msg:
- 'Service Status: up'
- 'Service Status: up'
- 'Service Status: up'
推荐阅读
- python - 在 AWS 实例上的 Docker 容器中使用 PyCharm 进行开发
- validation - 在 type=text Ionic 的离子输入中只允许数字
- c++-cli - 在 C++/CLI 中截屏
- google-chrome-extension - 是否可以将 ccTTL 域与 webRequest 侦听器匹配?
- android - iOS/Android SDK 中的 C++17 支持
- apache-kafka - 对于为 kafka 流应用程序创建的 kafka 内部主题,kafka 代理中的 UnknownProducerIdException 过多
- javascript - 如何在不使浏览器崩溃的情况下将“月”更改为“秒”?
- html - 使用 Bootstrap 4 创建居中的页脚
- xcode - Xcode10.1 未启动
- node.js - 如何从 url 中删除端口号,并使用节点应用程序添加 slug?