循环嵌套字典

时间:2019-07-27 22:14:49

标签: ansible yaml

我需要遍历一个复杂的字典并将一个键的属性应用于另一个键

我尝试了很多可能性,例如with_nested和with_subelements

我有这样的物体


group_hosts:
   - group:
      name: a
      hosts:
         - host1
         - host2
      ports:
         - 22
         - 80
   - group:
      name: b
      hosts:
         - host3
         - host4
      ports:
        - 22
        - 80

然后,给定一个主机,我需要将所有端口关联到它(例如,host1将具有与之关联的端口22和80),以便稍后,在迭代时,我可以使用wait_for模块来检查端口是否打开

我发现的唯一解决方法是对主机名重复其所具有的端口数(这样做,我删除了要循环的额外列表)

更明确地,我的var对象变成了这个

group_hosts:
   - group:
      name: a
      hosts:
         - name: host1
           port: 80

         - name: host1
           port: 22

         - name: host2
           port: 22

         - name: host2
           port: 80



   - group:
      name: b
      hosts:
         - name: host3
           port: 20

         - name: host4
           port: 2222


我玩这个:

    - name: traverse dict
      debug:
          msg: "group: {{item.0.group.name}} host is: {{item.1.name}} port is: {{item.1.port}}"

      loop: "{{ group_hosts  | subelements('group.hosts') |  list    }}"

但是我不喜欢这种解决方法,因为我不得不通过以一种不太有效的方式编写它来修改dict对象。

那么,给定第一个dict对象,我该如何循环主机并将端口关联到主机? 含义: 我想要给定的host1,我检查其22和80端口,host 2相同。

所以: 主机组A:

host1:检查端口22、80 host2:检查端口22、80

主机组b: 和上面一样

我已经知道如何“检查”某些主机上的端口,我的问题是如何迭代这样的对象

1 个答案:

答案 0 :(得分:0)

让我们简化字典。以下任务

- set_fact:
    hosts2: "{{ hosts2|default({})|
                combine({item.1:
                        {'name': item.0.group.name,
                         'ports': item.0.group.ports}}) }}"
  loop:  "{{ lookup('subelements', group_hosts, 'group.hosts') }}"
- debug:
    var: hosts2

提供一个易于迭代的字典。

"hosts2": {
    "host1": {
        "name": "a", 
        "ports": [
            22, 
            80
        ]
    }, 
    "host2": {
        "name": "a", 
        "ports": [
            22, 
            80
        ]
    }, 
    "host3": {
        "name": "b", 
        "ports": [
            22, 
            80
        ]
    }, 
    "host4": {
        "name": "b", 
        "ports": [
            22, 
            80
        ]
    }
}