如何在Ansible中获取子组列表?

7

我有一个类似于这样的清单文件:

[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"

但这不是非常灵活的。


with_items: "{{ groups['satellites'] }}"有什么问题? - stacksonstacks
1
@stacksonstacks,即使我发布了那条评论,但我后来将其删除了。因为问题“如何获取以卫星为父级的组列表?”不会给出组。它只会给出该组内的主机。 - Tarun Lalwani
2个回答

7
您可以尝试以下方法:
  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) 互换使用,具体取决于哪个更容易理解。

链接:
集合理论运算符
选择和拒绝过滤器


根据评论更新的答案。灵感来自于 这个帖子

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"
    ]

谢谢回复!我遇到的问题是,结果只输出了某个主机所在的一个子“卫星”组。我需要得到的是“卫星”子组的列表,在我的情况下是“nl”和“us”。 - Konstantin Kelemen
这是我得到的确切结果:https://gist.github.com/konstantin-kelemen/91c3d47edba0ea77736edf03df7616f6期望输出: "nl", "us" }``` - Konstantin Kelemen
1
@KonstantinKelemen 我已更新答案以创建子组列表。 - stacksonstacks
嗨,谢谢你的更新,你提供的示例完全符合预期!我已将其标记为已接受。谢谢你的帮助! - Konstantin Kelemen
1
嗨,回复很好,但是当 nlus 是其他组的一部分时会出现问题:那些其他组将出现在列表中。 - ady8531
这是一个有效的答案,但有一个警告 - 如果主机是多个父组的成员,则会获取所有父组而不是您正在查找的那个。要获取确切的父子关系,请参见下面的我的答案。 - Iskren P.

0

还有另一种方法,您可以使用像 awk 这样的 bash 命令将文件处理为文本文件。

如果文件内容如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接