Ansible: как получить подэлемент вложенного списка словарей

Я бы хотел создать наши зоны DNS через Ansible. Пользователь должен просто поддерживать одну переменную для зон прямого просмотра (например, foo.bar). Зоны обратного просмотра (0.0.10.in-appr.arpa) должны автоматически создаваться с помощью Ansible.

Переменная зоны прямого просмотра должна иметь вид

dns_zone_config:
    - name: "internal.foo.bar"
      acl:
        - 10.180.0.0/24
        - 10.180.8.0/24
      hosts:
        - name: "fileshare"
          ip: 10.180.0.200
    - name: "infra.foo.bar"
      acl:
        - acl-intern
      hosts:
        - name: "testhost1"
          ip: 11.180.0.100
          no_ptr_record: true
        - name: "testhost2"
          ipv6: fe80::1
        - name: "testhost3"
          ip: 11.180.0.200
    - name: "mx.foo.bar"
      mx:
        - name: "xxxx"
          priority: xxxx
          target: xxxx

dns_zone_config - это список словарей, которые могут содержать ключ с именем "hosts", который снова представляет собой список словарей.

Мой текущий способ выглядит так:

- name: Collect all networks
  include_tasks: 01-networks.yml
  loop: "{{ dns_zone_config }}"
  when: item_dns_zone_config.hosts is defined
  loop_control:
    loop_var: item_dns_zone_config

#from 01-networks.yml
- name: Determine IPv4 networks
  set_fact:
    ipv4_networks: "{{ (ipv4_networks | default([])) + [ item.ip ] }}"
  loop: "{{ item_dns_zone_config.hosts }}"
  when: item.ip is defined and (item.no_ptr_record is not defined or not item.no_ptr_record)

Я дважды перебираю dns_zone_config и их записи о хостах. Это очень неэффективно и медленно. Я почти уверен, что это можно решить умнее: D

В основном мне просто нужен список всех IP-адресов всех зон. Я пробовал фильтры json_query () и selectattr (), но я борюсь с тем фактом, что не для каждой записи хоста определены адреса IPv4 или IPv6. И я не хочу содержать IP-адреса, если определена переменная no_ptr_record: true (false или not defined - нормально).

Из приведенного выше фрагмента список будет содержать только: ipv4_networks:

['10.180.0.200','11.180.0.200']
1
задан 30 January 2019 в 01:28
1 ответ

Узнал, как правильно использовать json_query.

  - debug:                                                                      
      msg: "{{ dns_zone_config | json_query(_query) }}"                         
    vars:                                                                       
      _query: "[].hosts[?!no_ptr_record][].[ip,ipv6][]"    

Результат:

TASK [debug] ***********************************************************************************
ok: [localhost] => {
    "msg": [
        "10.180.0.200",
        "fe80::1",
        "11.180.0.200"
    ]
}

Нужно всего 1-2 секунды вместо ~30 с двойными петлями :)

.
0
ответ дан 4 December 2019 в 03:17

Теги

Похожие вопросы