Python
Ansible:如何獲取嵌套字典列表的子元素
我想通過 Ansible 建構我們的 DNS 區域。使用者應該只為前向查找區域維護一個變數(例如 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 地址這一事實而苦苦掙扎。如果定義了 no_ptr_record: true 變數(假或未定義都可以),我不想包含 IP。
從列表上方的片段中,該列表將僅包含:ipv4_networks:
['10.180.0.200','11.180.0.200']
弄清楚如何正確使用 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 秒 :)