获取字典的子元素

get child elements of a dictonairy

我有一个包含不同主机和不同网络的网络,我想使用 ansible 来 ping 每个网络中的每个主机。

在我的host_vars 目录中,关于每个主机及其网络的所有信息都存储在其自己的文件中。主机文件如下所示:

bond:
  - conn_name: net1
    ip4: '10.10.44.21'
    gw4: '10.10.44.1'
  - conn_name: net2
    ip4: '10.10.47.21'
    gw4: '10.10.47.1'
  - conn_name: net3
    ip4: '10.10.46.21'
    gw4: '10.10.46.1'
bond_slave:
  - conn_name: eno1
    ifname: eno1
    master: net1
  - conn_name: eno2
    ifname: eno2
    master: net2
  - conn_name: ens2f1
    ifname: ens2f1
    master: net2
  - conn_name: ens2f0
    ifname: ens2f0
    master: net2
  - conn_name: ens4f1
    ifname: ens4f1
    master: net3
  - conn_name: ens4f0
    ifname: ens4f0
    master: net3

我的目的是获取每个 ip4 值并从每个主机 ping 它。我能做的是包含 host_vars 目录中的所有文件并 ping 每个文件的第一个绑定项目的 ip 地址。

---
- hosts: all

- name: Include information about all hosts
  include_vars: ../../host_vars/{{ item }}.yaml
  with_items: hosts
  register: "r"

- name: execute ping
  command: ping {{ bond[0].ip4 }} -c 3
  with_items: "{{ r.results }}"

但是债券可以有 2 到 4 个网络。我如何遍历每个绑定以访问所有 ip 地址?

解决方案

尽管 Konstantin Suvorov 的代码片段对我不起作用,但它帮助我找到了正确的解决方案:

- name: execute ping
  command: ping {{ item.ip4 }} -c 3
  with_items: "{{ r.results | map(attribute='ansible_facts.bond') | list }}"

如果您通过 host_vars 为每个主机定义了 bond 变量,您可以使用 hostvars 魔术变量(不需要执行这个难看的包含任务):

- name: ping everything
  command: ping {{ item }} -c 3
  with_items: "{{ play_hosts | map('extract',hostvars,'bond') | list }}"

实际上这个 Jinja2 表达式将 return 列表的列表,但是 with_items 将它们展平,所以你最终得到了当前游戏中每个主机的每个键的所有元素的长列表。