我如何获得 Ansible 中的子组列表?
How can I get a list of child groups in Ansible?
我有一个清单文件,如下所示:
[master]
host01
[nl]
host02
[us]
host03
[satellites:children]
nl
us
如何获取以 satellites
作为父组的组列表?
我正在寻找与此类似的解决方案:
- debug: msg="{{ item }}"
with_items: "{{ groups['satellites:children'] }}"
更新:
我能想到的唯一解决方案是:
- debug: {{ item }}
with_items: "{{ groups }}"
when: item != "master" and item != "satellites" and item != "all" and item != "ungrouped"
但这不是很灵活。
您可以尝试以下方法:
vars:
parent: 'satellites'
tasks:
# functional style
- debug: msg="{{hostvars[item].group_names | select('ne', parent) | first}}"
with_items: "{{groups[parent]}}"
# set style
- debug: msg="{{hostvars[item].group_names | difference(parent) | first}}"
with_items: "{{groups[parent]}}"
此外,select('ne', parent)
可与 reject('equalto', parent)
互换,具体取决于您更易读的内容。
链接:
set theory operator
select and reject filters
根据评论更新了答案。灵感来自 .
vars:
parent: 'satellites'
tasks:
- name: build a subgroups list
set_fact: subgroups="{{ ((subgroups | default([])) + hostvars[item].group_names) | difference(parent) }}"
with_items: "{{groups[parent]}}"
- debug: var=subgroups
输出:
"subgroups": [
"nl",
"us"
]
还有另一种方法,您可以使用 bash 命令将文件作为文本文件处理,例如 awk
如果文件的内容类似于
cat /tmp/test.ini
[group1]
host1
host2
[group2]
host3
host4
[first_two_groups:children]
group1
group2
[group3]
host5
host6
[group4]
host7
host8
当文件有 Linux EOL:
时,你可以使用这样的命令
awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
group1
group2
查找其子项的组称为 first_two_groups
,它可以在文件中的任何位置。只要在组定义之后有空行用作结束 awk 流的锚点,命令就可以工作。我认为大多数人会在 ansible 清单文件中添加空行以提高可读性,我们可以利用这一事实。
如果文件恰好有Windows EOL那么命令是
awk "/first_two_groups\:children/,/^[\r]$/" /tmp/test.ini | grep -v children
像这样的 ansible 示例:
- name: get group children
shell: awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
register: chlldren
#returns list of the children groups to loop through later
- debug: var=children.stdout_lines
以上内容尚未经过全面测试,但如果出现问题,则最多可能是 shell 模块中特殊字符的转义。请记住 - 当您在 ansible shell 模块中传递特殊字符时,如冒号使用 jinja 扩展 - 而不是 :
使用 {{ ':' }}
此外,为了保持一致的 bash 行为,建议通过在任务结束时添加明确地传递可执行文件
args:
executable: /bin/bash
我有一个清单文件,如下所示:
[master]
host01
[nl]
host02
[us]
host03
[satellites:children]
nl
us
如何获取以 satellites
作为父组的组列表?
我正在寻找与此类似的解决方案:
- debug: msg="{{ item }}"
with_items: "{{ groups['satellites:children'] }}"
更新:
我能想到的唯一解决方案是:
- debug: {{ item }}
with_items: "{{ groups }}"
when: item != "master" and item != "satellites" and item != "all" and item != "ungrouped"
但这不是很灵活。
您可以尝试以下方法:
vars:
parent: 'satellites'
tasks:
# functional style
- debug: msg="{{hostvars[item].group_names | select('ne', parent) | first}}"
with_items: "{{groups[parent]}}"
# set style
- debug: msg="{{hostvars[item].group_names | difference(parent) | first}}"
with_items: "{{groups[parent]}}"
此外,select('ne', parent)
可与 reject('equalto', parent)
互换,具体取决于您更易读的内容。
链接:
set theory operator
select and reject filters
根据评论更新了答案。灵感来自
vars:
parent: 'satellites'
tasks:
- name: build a subgroups list
set_fact: subgroups="{{ ((subgroups | default([])) + hostvars[item].group_names) | difference(parent) }}"
with_items: "{{groups[parent]}}"
- debug: var=subgroups
输出:
"subgroups": [
"nl",
"us"
]
还有另一种方法,您可以使用 bash 命令将文件作为文本文件处理,例如 awk
如果文件的内容类似于
cat /tmp/test.ini
[group1]
host1
host2
[group2]
host3
host4
[first_two_groups:children]
group1
group2
[group3]
host5
host6
[group4]
host7
host8
当文件有 Linux EOL:
时,你可以使用这样的命令awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
group1
group2
查找其子项的组称为 first_two_groups
,它可以在文件中的任何位置。只要在组定义之后有空行用作结束 awk 流的锚点,命令就可以工作。我认为大多数人会在 ansible 清单文件中添加空行以提高可读性,我们可以利用这一事实。
如果文件恰好有Windows EOL那么命令是
awk "/first_two_groups\:children/,/^[\r]$/" /tmp/test.ini | grep -v children
像这样的 ansible 示例:
- name: get group children
shell: awk "/first_two_groups\:children/,/^$/" /tmp/test.ini | grep -v children
register: chlldren
#returns list of the children groups to loop through later
- debug: var=children.stdout_lines
以上内容尚未经过全面测试,但如果出现问题,则最多可能是 shell 模块中特殊字符的转义。请记住 - 当您在 ansible shell 模块中传递特殊字符时,如冒号使用 jinja 扩展 - 而不是 :
使用 {{ ':' }}
此外,为了保持一致的 bash 行为,建议通过在任务结束时添加明确地传递可执行文件
args:
executable: /bin/bash