如果数组元素与 Ansible 中的值匹配,则获取数组变量名称

Get the array variable name if the array element matches with a value in Ansible

如果输入文件中的特定键值(此处为 cidr)匹配,我想获取数组名称(如 DNS_OneNTP 等) .
我已尝试使用以下剧本,但这会导致错误。

Input.yaml:

[
    {
        "id": "111177789966",
        "cidr": "10.10.10.10/24"
    },
   
    {
        "id": "13215464897",
        "cidr": "10.100.100.0/24" 
    }
]

Input_var.yaml:

---
Stores:
    -   name: "Test1"
        DNS_One:
             - "10.10.10.10/24"
             - "192.168.1.1/24"
        DNS_One-HO: 
             - "10.20.25.100"
             - "10.100.100.0/24"
    -   name: "Test2"
        DNS_One:
             - "10.20.10.10/24"
             

预期输出:

[
    {
        "id": "111177789966",
        "cidr": "10.10.10.10/24",
        "net_name": "DNS_One"
    },
   
    {
        "id": "13215464897",
        "cidr": "10.100.100.0/24",
        "net_name": "DNS_One-HO"
    }
]

剧本:

- name: Search
  vars:
        test-merge: >-
            {{ 
                input_var
                | selectattr('name', 'eq', Test1 | string )
                | map(attribute= item)
                | first
                | default([])
            }}
      set_fact:
        po_g: >-
         {{
            po_g | default([]) + 
            [{  
                'id': item.id,
                'cidr': item.cidr,
                'subnetname': test-merge
                 }] 
         }} 
      loop: "{{ input }}"

您将不得不使用 dict2items on the elements of your input_var.Stores list, in order to make it more queryable. You can apply this filter on all the items of the list, with the help of map

然后你回到你想做的事情,Ansible 在 Jinja 内置测试之上提供的 selectattr to fetch the element that correspond to the CIDR of the input item your are currently looping on. On a list, this can be achieved with the help of the contains 测试。

最后在这个 set_fact:

- set_fact:
    output: >-
      {{
        output | default([])
        + [item | combine({'net_name': DNS.key})]
      }}
  vars: 
    DNS: >-
      {{ 
        input_var.Stores 
        | map('dict2items') 
        | flatten 
        | selectattr('value', 'contains', item.cidr)
        | first
      }}
  loop: "{{ input }}"
  loop_control:
    label: "{{ item.id }}"

鉴于剧本:

- hosts: localhost
  gather_facts: no
  vars:
    input:
      - id: "111177789966"
        cidr: 10.10.10.10/24
      - id: "13215464897"
        cidr: 10.100.100.0/24
    input_var:
      Stores:
        - name: Test1
          DNS_One:
            - 10.10.10.10/24
            - 192.168.1.1/24
          DNS_One-HO: 
            - 10.20.25.100
            - 10.100.100.0/24
        - name: Test2
          DNS_One:
            - 10.20.10.10/24

  tasks:
    - set_fact:
        output: >-
          {{
            output | default([])
            + [item | combine({'net_name': DNS.key})]
          }}
      vars: 
        DNS: >-
          {{ 
            input_var.Stores 
            | map('dict2items') 
            | flatten 
            | selectattr('value', 'contains', item.cidr)
            | first
          }}
      loop: "{{ input }}"
      loop_control:
        label: "{{ item.id }}"

    - debug:
        var: output

这产生:

TASK [set_fact] ***************************************************************
ok: [localhost] => (item=111177789966)
ok: [localhost] => (item=13215464897)

TASK [debug] ******************************************************************
ok: [localhost] => 
  output:
  - cidr: 10.10.10.10/24
    id: '111177789966'
    net_name: DNS_One
  - cidr: 10.100.100.0/24
    id: '13215464897'
    net_name: DNS_One-HO