Ansible:需要将两个文件中的信息组合起来,以便稍后执行任务



我在Red Hat Linux 7.4上运行Ansible 2.7.9。在我的剧本中,我需要将两个yml文件中的信息组合成一个数据结构,然后在任务中对其进行迭代。

例如,在一个.yml文件中,我可能有:

---
network_interfaces:
  big_computer:
    - name: eth0.10
    - name: eth1.20
    - name: ens224
    - name: bond1
      type: bond
      device: intel

在另一个名为definitions.yml的.yml文件中,我可能有:

---
eth0.10:
  type: vlan
  slave: true
  master: bond1
  subnet: 192.168.10.0/24
eth1.20:
  type: vlan
  slave: true
  master: bond1
  subnet: 192.168.20.0/24
ens224:
  type: ethernet
  subnet: 172.19.22.0/23
bond1:
  type: bond

例如,我可以从network_interfaces[computer_type] 中设置变量network_interfaces_list

computer_typebig_computer时,我想取network_interfaces_list的名称、来自network_interfaces_list的数据和来自definitions.yml的数据,并创建这个组合的数据结构。然后在任务中使用该数据结构。请注意,一些信息可能包含在network_interfaces文件中,但其中一些信息位于definitions文件中。或者它可能仍然是未定义的——;从";或";主";例如bond1接口的设置。

network_interfaces_list最终应该是这样的:

-  eth0.10:
    type: vlan
    slave: true
    master: bond1
    subnet: 192.168.10.0/24
- eth1.20:
    type: vlan
    slave: true
    master: bond1
    subnet: 192.168.20.0/24
- ens224:
    type: ethernet
    subnet: 172.19.22.0/23
- bond1:
    type: bond
    device: intel

字典中任何给定列表项缺少的条目都被认为对该项不重要,并且本质上为null。

我一整天都在为这个绞尽脑汁。我可以调试任何一个条目,但试图将它们组合在一起——尤其是在没有Ansible给我关于缺少字典键的错误的情况下——我发现这是不可能的。

本质上,我想要的是一个简短的信息文件,对于那些乍一看不重要的项目,我想把它们放在另一层,如果我们愿意的话,我们可以仔细阅读以收集更多细节。

我已经成功地做到了:

- debug:
    msg: "interface_list: {{ network_interfaces_list }}"
- name: MIKE debug
  debug:
    msg: "thingy: {{ interface['name'] }} 
                  {{ interface['type']|default('NULL') }} 
                  {{ interface['device']|default('NULL') }}"
  loop: "{{ network_interfaces_list }}"
  loop_control:
    loop_var: interface
- name: MIKE2 debug
  debug:
    msg: "thing2: {{ lookup ( 'vars', interface['name'], default='XXX' ) }}"
  loop: "{{ network_interfaces_list }}"
  loop_control:
    loop_var: interface
~~~
But I'm stuck in trying to get merge the members of `interface['name']` from the two data structures.

例如

    - set_fact:
        network_interfaces_list: "{{ network_interfaces_list|default([]) +
                                     [{item: _val}] }}"
      loop: "{{ _keys }}"
      vars:
        computer_type: big_computer
        _keys: "{{ network_interfaces[computer_type]|map(attribute='name')|list }}"
        _vals: "{{ network_interfaces[computer_type] }}"
        _dict: "{{ dict(_keys|zip(_vals)) }}"
        _val: "{{ _dict[item]|combine(definitions[item]) }}"

给出

  network_interfaces_list:
  - eth0.10:
      master: bond1
      name: eth0.10
      slave: true
      subnet: 192.168.10.0/24
      type: vlan
  - eth1.20:
      master: bond1
      name: eth1.20
      slave: true
      subnet: 192.168.20.0/24
      type: vlan
  - ens224:
      name: ens224
      subnet: 172.19.22.0/23
      type: ethernet
  - bond1:
      device: intel
      name: bond1
      type: bond

票据

  • 字典保留冗余属性名称

  • definitions.yml中变量的名称无效。请参阅创建有效的变量名。将它们包含在字典中,例如

    - include_vars:
        file: definitions.yml
        name: definitions

给出

  definitions:
    bond1:
      type: bond
    ens224:
      subnet: 172.19.22.0/23
      type: ethernet
    eth0.10:
      master: bond1
      slave: true
      subnet: 192.168.10.0/24
      type: vlan
    eth1.20:
      master: bond1
      slave: true
      subnet: 192.168.20.0/24
      type: vlan
  • 在某些情况下,字典可能是更好的结构,例如
    - set_fact:
        network_interfaces_dict: "{{ network_interfaces_dict|default({})|
                                     combine({item: _val}) }}"
      ...

会给出

  network_interfaces_dict:
    bond1:
      device: intel
      name: bond1
      type: bond
    ens224:
      name: ens224
      subnet: 172.19.22.0/23
      type: ethernet
    eth0.10:
      master: bond1
      name: eth0.10
      slave: true
      subnet: 192.168.10.0/24
      type: vlan
    eth1.20:
      master: bond1
      name: eth1.20
      slave: true
      subnet: 192.168.20.0/24
      type: vlan

相关内容

最新更新