从 Ansible 中的地图列表中提取属性列表的正确方法

TSi*_*Sip 4 ansible

我正在寻找一种从 Ansible 中的地图列表中提取特定值列表的非丑陋方法。我可以找到一些方法来做到这一点,例如在这里:here,但是我所看到的一切都非常丑陋,感觉应该有一种方法可以让将来阅读它的人更清楚正在做什么。我可以写一个过滤器,但感觉这应该是不必要的,因为它必须相对定期地出现。

我在 Ansible 中有一个像这样的数据结构:

interfaces:
  - name: eth0
    subnet: 192.168.2
    netmask: 255.255.255.0
    static_dhcp_hosts:
      - {name: "hosta", mac: "00:01:02:03:04:05", ip: "192.168.2.20"}
  - name: eth1
    subnet: 192.168.5
    netmask: 255.255.255.0
    static_dhcp_hosts:
      - {name: "hostb", mac: "00:02:03:04:05:06", ip: "192.168.5.20"}
      - {name: "hostc", mac: "00:03:04:05:06:07", ip: "192.168.5.21"}
Run Code Online (Sandbox Code Playgroud)

我想得到一个空格分隔的接口名称列表,所以

eth0 eth1
Run Code Online (Sandbox Code Playgroud)

显然这只是示例数据,实际的顶级列表对于一台主机有 10 个元素。我知道我可以使用连接过滤器从接口列表中获取我想要的字符串以及如何做到这一点。

任何人都可以提出一个很好的方法来制作列表,这对未来的维护者来说是可读的(代码/配置应该尽可能地(而不是进一步)自我记录)?

我正在做类似的事情

{% for interface in interfaces %}{{ interface.name }} {% endfor %}
Run Code Online (Sandbox Code Playgroud)

或者

" ".join([ interface['name'] for interface in interfaces ])
Run Code Online (Sandbox Code Playgroud)

在 Python 中。

但是,AFAIK,你不能,或者被认为是不好的做法,在角色的任务/main.yml 中使用这样的 jinja2 循环,而且,正如我所说,感觉不应该使用自定义为此过滤。

(这个角色不仅仅是配置一个 DHCP 服务器,所以请不要只是建议一个预先存在的角色来做到这一点,这不会解决我的问题)。

任何不丑陋的方法都将不胜感激,人们也会确认没有不丑陋的方法。

我正在使用 Ansible 2.3,但我仍然对答案感兴趣,即使它们只适用于更高版本。

编辑:

下列:

"{{ internal_interfaces | items2dict(key_name='name',value_name='name') | list | join(\" \") }}"
Run Code Online (Sandbox Code Playgroud)

有效,并且是我能想到的最不丑的。它从列表中创建一个字典,键和值都来自列表中字典的 name 属性,然后将此字典转换为一个列表,该列表只给出一个键列表。如果任何人能想到任何东西,我仍然想要一些不那么钝和丑的东西,或者如果任何 Ansible 大师认为没有更好的东西,他们可以回答。

clo*_*net 5

映射和加入是您所需要的:

- set_fact:
    interface_names: "{{ interfaces | map(attribute='name') | join(' ') }}"
Run Code Online (Sandbox Code Playgroud)