得到一个dictonairy的儿童元素

时间:2017-06-08 14:58:23

标签: ansible ansible-2.x

我有一个拥有不同主机和不同网络的网络,我想使用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-adress。

---
- 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-address?

解决方案

尽管Konstantin Suvorov的片段不适合我,但它帮助我找到了合适的解决方案:

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

1 个答案:

答案 0 :(得分:0)

如果您通过bond为每个主机定义了host_vars var,则可以使用hostvars魔术变量(无需执行此丑陋的包含任务):

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

实际上这个Jinja2表达式将返回一个列表列表,但是with_items会使它们变平,所以你最终会列出当前游戏中每个主机的每个键的所有元素。