简体   繁体   English

使用 ansible 循环遍历多个字典列表

[英]loop over multiple list of dictionaries using ansible

I am trying to loop over a following variable structure using ansible and what I want is to loop over each subnet.我正在尝试使用 ansible 遍历以下变量结构,我想要的是遍历每个子网。 For subnets-1 I want to get network, cidr, vlan similarly loop other keys subnets-2 , subnets-3对于子网-1,我想获得网络、cidr、vlan 类似地循环其他键子网-2子网-3

flavor.json风味.json

{
  "subnets-1": [
    {
      "network": "test1",
      "cidr": 21,
      "vlan": 123
    },
    {
      "network": "test2",
      "cidr": 22,
      "vlan": 234
    }
  ],
  "subnets-2": [
    {
      "network": "test3",
      "cidr": 43,
      "vlan": 879
    },
    {
      "network": "test4",
      "cidr": 21,
      "vlan": "12fsd"
    },
    {
      "network": "test5",
      "cidr": "22sdf",
      "vlan": "234sdfd"
    }
  ],
  "subnets-3": [
    {
      "network": "test44",
      "cidr": "fg",
      "vlan": "dsfsd"
    }
  ]
}

I have tried something like below using with_dict我使用 with_dict 尝试过类似下面的操作

playbook.yml (ansible 2.9.7) playbook.yml(ansible 2.9.7)

---
- hosts: local
  gather_facts: no  
  tasks:
  - name: lookup yaml
    set_fact:
      flavors: "{{ lookup('file','flavor.json') | from_json }}"
  - name: json out
    debug:
      msg: "{{ flavors }}"
  - name: check keys
    shell: |
      echo "s_name = {{ item.network }}"
      echo "s_cidr = {{ item.cidr }}"
      echo "s_vlan = {{ item.vlan }}"
    with_dict:
      "{{ flavors }}"

This is the error I get when playbook was executed这是我在执行 playbook 时得到的错误

Error:错误:

fatal: [192.168.110.128]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'network'\n\nThe error appears to be in '/root/fla.yml': line 19, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: check keys\n    ^ here\n"
}

Use include_vars .使用include_vars It's simpler compared to lookup and from_yaml , eglookupfrom_yaml相比,它更简单,例如

    - include_vars:
        file: flavor.json
        name: flavors

gives

  flavors:
    subnets-1:
    - {cidr: 21, network: test1, vlan: 123}
    - {cidr: 22, network: test2, vlan: 234}
    subnets-2:
    - {cidr: 43, network: test3, vlan: 879}
    - {cidr: 21, network: test4, vlan: 12fsd}
    - {cidr: 22sdf, network: test5, vlan: 234sdfd}
    subnets-3:
    - {cidr: fg, network: test44, vlan: dsfsd}

Then convert the dictionary to list and iterate with_subelements , eg然后将字典转换为列表并迭代with_subelements ,例如

    - debug:
        msg: "{{ item.0.key }}
              {{ item.1.network }}
              {{ item.1.cidr }}
              {{ item.1.vlan }}"
      with_subelements:
        - "{{ flavors|dict2items }}"
        - value

gives

  msg: subnets-1 test1 21 123
  msg: subnets-1 test2 22 234
  msg: subnets-2 test3 43 879
  msg: subnets-2 test4 21 12fsd
  msg: subnets-2 test5 22sdf 234sdfd
  msg: subnets-3 test44 fg dsfsd

Ansible does not do nested loops well. Ansible 不能很好地处理嵌套循环。 In this case, you know you have a maximum of three array elements.在这种情况下,您知道最多有三个数组元素。 So you can loop like this:所以你可以像这样循环:

- name: loop over flavors
  debug:
    msg: "{{ flavors[item.0][item.1] }}"
  with_nested:
    - "{{ flavors }}"
    - [ 0, 1, 2 ]
  when: flavors[item.0][item.1] is defined

Which results in something like this:结果是这样的:

TASK [loop over flavors] *********************************************************************************************
ok: [localhost] => (item=['subnets-1', 0]) => {
    "msg": {
        "cidr": 21,
        "network": "test1",
        "vlan": 123
    }
}
ok: [localhost] => (item=['subnets-1', 1]) => {
    "msg": {
        "cidr": 22,
        "network": "test2",
        "vlan": 234
    }
}
skipping: [localhost] => (item=['subnets-1', 2]) 
ok: [localhost] => (item=['subnets-2', 0]) => {
    "msg": {
        "cidr": 43,
        "network": "test3",
        "vlan": 879
    }
}
ok: [localhost] => (item=['subnets-2', 1]) => {
    "msg": {
        "cidr": 21,
        "network": "test4",
        "vlan": "12fsd"
    }
}
ok: [localhost] => (item=['subnets-2', 2]) => {
    "msg": {
        "cidr": "22sdf",
        "network": "test5",
        "vlan": "234sdfd"
    }
}
ok: [localhost] => (item=['subnets-3', 0]) => {
    "msg": {
        "cidr": "fg",
        "network": "test44",
        "vlan": "dsfsd"
    }
}
skipping: [localhost] => (item=['subnets-3', 1]) 
skipping: [localhost] => (item=['subnets-3', 2]) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM