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

时间:2019-01-08 12:03:26

标签: 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"}

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

eth0 eth1

显然,这只是示例数据,实际的顶级列表中有一个主机包含10个元素。我知道我可以使用联接过滤器从接口列表中获取所需的字符串以及执行该操作的方法。

任何人都可以提出一种可供以后的维护者阅读的清单的好方法(代码/配置应尽可能(且不能再进行)自我记录)?

我想做类似的事情

{% for interface in interfaces %}{{ interface.name }} {% endfor %}

" ".join([ interface['name'] for interface in interfaces ])

在Python中。

但是AFAIK不能或在角色的task / main.yml中使用像这样的jinja2循环,或者被认为是不好的做法,就像我说的那样,感觉不需要为此使用自定义过滤器。

(此角色不仅是配置DHCP服务器,所以请不要只是建议一个已有的角色来执行此操作,否则将无法解决我的问题)。

任何非丑陋的方式都会受到人们的赞赏,人们会证实没有非丑陋的方式。

我正在使用Ansible 2.3,但即使答案仅在更高版本中有效,我仍然对答案感兴趣。

编辑:

以下内容:

"{{ internal_interfaces | items2dict(key_name='name',value_name='name') | list | join(\" \") }}"

有效,这是我能想到的最丑陋的地方。它从列表中创建字典,键和值均来自列表中字典的name属性,然后将此字典转换为仅给出键列表的列表。如果异性恋者能想到任何东西,或者如果任何Ansible专家都认为没有更好的东西,我仍然希望它们变得不那么笨拙和丑陋。

2 个答案:

答案 0 :(得分:1)

您需要映射并加入:

- set_fact:
    interface_names: "{{ interfaces | map(attribute='name') | join(' ') }}"

答案 1 :(得分:0)

好。我很傻有一个很好的方法可以做到这一点:

"{{ interfaces | map(attribute='name') | join(\" \") }}"

map的输出是一个生成器,该生成器生成接口名称列表,而join将其转换为我想要的字符串。完美。