Ansible 合并多个词典列表

Ansible 合并多个词典列表,ansible,yaml,jinja2,Ansible,Yaml,Jinja2,我有一个简单的角色,将模板推送到/etc/sysconfig/networkscripts/route-中 我们的一些路由是相同的,所以我想借助角色vars和组/主机vars来分解这些路由 我试图申请,但它期望一个dict,我有一个dict列表,我现在还不太适应jinja过滤器 这是我的数据结构: management_default_gateway: '192.168.128.254' management_interface: eth1 routes: - interface: "{{m

我有一个简单的角色,将模板推送到
/etc/sysconfig/networkscripts/route-

我们的一些路由是相同的,所以我想借助角色vars和组/主机vars来分解这些路由

我试图申请,但它期望一个dict,我有一个dict列表,我现在还不太适应jinja过滤器

这是我的数据结构:

management_default_gateway: '192.168.128.254'
management_interface: eth1
routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.1/24
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.5/24
即使模板在路由列表上循环时存在其他接口(请参见下文),它也可以工作,并按预期为每个接口创建一个文件

roles/routing/tasks/main.yml

- name: Template
  template:
    src: route.j2
    dest: "{{'-'.join((route_script_file,item.interface))}}"
    owner: root
    group: root
    mode: 0640
  notify: networking restart
  with_list: "{{routes}}"
default_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.1/24
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.5/24

routes_merged: "{{ default_routes + specific_routes }}"
specific_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.8.0.1/24
roles/routing/templates/route.j2

{% for i in item.route_array %}
{{i.network ~ ' via ' ~ i.gateway ~ '\n'}}
{%- endfor %}
我希望在角色变量文件夹(或
group\u vars/all
)上有“标准”路由,并在组或主机级别添加路由

所以我试着用:
roles/routing/vars/main.yml

- name: Template
  template:
    src: route.j2
    dest: "{{'-'.join((route_script_file,item.interface))}}"
    owner: root
    group: root
    mode: 0640
  notify: networking restart
  with_list: "{{routes}}"
default_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.1/24
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.5/24

routes_merged: "{{ default_routes + specific_routes }}"
specific_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.8.0.1/24
存货/prod/group_vars/XXX.yml

- name: Template
  template:
    src: route.j2
    dest: "{{'-'.join((route_script_file,item.interface))}}"
    owner: root
    group: root
    mode: 0640
  notify: networking restart
  with_list: "{{routes}}"
default_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.1/24
      - gateway: "{{management_default_gateway}}"
        network: 10.0.0.5/24

routes_merged: "{{ default_routes + specific_routes }}"
specific_routes:
  - interface: "{{management_interface}}"
    route_array:
      - gateway: "{{management_default_gateway}}"
        network: 10.8.0.1/24
然后我用debug var得到了这个结果:

ok: [hostname] => {
    "routes": [
        {
            "interface": "eth1",
            "route_array": [
                {
                    "gateway": "192.168.128.254",
                    "network": "10.0.0.1/24"
                },
                {
                    "gateway": "192.168.128.254",
                    "network": "10.0.0.5/24"
                }
            ]
        },
        {
            "interface": "eth1",
            "route_array": [
                {
                    "gateway": "192.168.128.254",
                    "network": "10.8.0.1/24"
                }
            ]
        }
    ]
}
我想要:

ok: [hostname] => {
    "routes": [
        {
            "interface": "eth1",
            "route_array": [
                {
                    "gateway": "192.168.128.254",
                    "network": "10.0.0.1/24"
                },
                {
                    "gateway": "192.168.128.254",
                    "network": "10.0.0.5/24"
                },
                {
                    "gateway": "192.168.128.254",
                    "network": "10.8.0.1/24"
                }
            ]
        }
    ]
}
我想按接口合并route_数组,以便接口只生成一个模板文件。

循环执行此任务

- set_fact:
    routes: "{{ default_routes + specific_routes }}"
- set_fact:
    routes2: "{{ routes2|default([]) +
                [{'interface': item.1|map(attribute='interface')|list|first,
                  'route_array': item.1|map(attribute='route_array')|list|flatten}] }}"
  loop: "{{ routes| groupby('interface') }}"
- debug:
    var: routes2
给予


这太完美了,谢谢,它生成了一个接口列表,所以我的模板任务也以同样的方式工作。我以前不知道groupby过滤器,但它非常有用,因为我不必编写自己的过滤器来完成这项工作!