展平双层嵌套 Ansible dict

问题描述 投票:0回答:2

在 Ansible 中调用

sessions
时,如何从
sessions_flat
转到
set_fact

sessions:
  - name: "clientALPHA"
    vpns:
      - name: "tun10"
        password: 56813252
        port: 1194
      - name: "tun20"
        password: 90871307
        port: 1195
  - name: "clientBRAVO"
    vpns:
      - name: "tun10"
        password: 76530913
        port: 1196


sessions_flat:
  - oid: "clientALPHA-tun10"
    password: 56813252
    port: 1194
  - oid: "clientALPHA-tun20"
    password: 90871307
    port: 1195
  - oid: "clientBRAVO-tun10"
    password: 76530913
    port: 1196
ansible jinja2
2个回答
0
投票

您可以使用带有

subelements
过滤器的循环,如下所示:

- set_fact:
    sessions_flat: >-
      {{
        sessions_flat + [{
          "port": item.1.port,
          "password": item.1.password
        }|combine({"oid": "%s-%s" % (item.0.name, item.1.name)})]
      }}
  vars:
    sessions_flat: []
  loop: "{{ sessions|subelements('vpns')}}"

如果您使用的是 jmespath

社区版,则可以使用 
let
表达式
:

- set_fact:
    sessions_flat: >-
      {{
      sessions | json_query('[].[let $top = @ in $top.vpns[]|[].{"oid": join(`"-"`, [$top.name, name]), "port": port, "password": password}][][]')
      }}

上述两项任务都会导致:

{
  "sessions_flat": [
      {
          "oid": "clientALPHA-tun10",
          "password": 56813252,
          "port": 1194
      },
      {
          "oid": "clientALPHA-tun20",
          "password": 90871307,
          "port": 1195
      },
      {
          "oid": "clientBRAVO-tun10",
          "password": 76530913,
          "port": 1196
      }
  ]
}

0
投票

连接名称

  name: |
    {% for i in  sessions %}
    {% for j in i.vpns %}
    {{ i.name }}-{{ j.name }} {% endfor %}
    {% endfor %}

给予

  name: |-
    clientALPHA-tun10 clientALPHA-tun20 clientBRAVO-tun10

并创建字典列表

  oid: "{{ name | split | map('community.general.dict_kv', 'oid') }}"

给予

  oid:
  - oid: clientALPHA-tun10
  - oid: clientALPHA-tun20
  - oid: clientBRAVO-tun10

展平属性列表 vpnszip oid 列表,以及 组合 项目

  sessions_flat: "{{ sessions | map(attribute='vpns') | flatten |
                                zip(oid) | map('combine') }}"

给予

  sessions_flat:
  - name: tun10
    oid: clientALPHA-tun10
    password: 56813252
    port: 1194
  - name: tun20
    oid: clientALPHA-tun20
    password: 90871307
    port: 1195
  - name: tun10
    oid: clientBRAVO-tun10
    password: 76530913
    port: 1196

(可选)使用过滤器 ansible.utils.remove_keys 并删除冗余属性 name

  sessions_flat: "{{ sessions | map(attribute='vpns') | flatten |
                                zip(oid) | map('combine') |
                                ansible.utils.remove_keys(target=['name']) }}"

给你想要的东西

  sessions_flat:
  - oid: clientALPHA-tun10
    password: 56813252
    port: 1194
  - oid: clientALPHA-tun20
    password: 90871307
    port: 1195
  - oid: clientBRAVO-tun10
    password: 76530913
    port: 1196

用于测试的完整剧本示例

- hosts: localhost

  vars:

    sessions:
      - name: clientALPHA
        vpns:
          - name: tun10
            password: 56813252
            port: 1194
          - name: tun20
            password: 90871307
            port: 1195
      - name: clientBRAVO
        vpns:
          - name: tun10
            password: 76530913
            port: 1196

    name: |
      {% for i in  sessions %}
      {% for j in i.vpns %}
      {{ i.name }}-{{ j.name }} {% endfor %}
      {% endfor %}
    oid: "{{ name | split | map('community.general.dict_kv', 'oid') }}"
    sessions_flat: "{{ sessions | map(attribute='vpns') | flatten |
                                  zip(oid) | map('combine') }}"
    sessions_fla2: "{{ sessions | map(attribute='vpns') | flatten |
                                  zip(oid) | map('combine') |
                                  ansible.utils.remove_keys(target=['name']) }}"

  tasks:

    - debug:
        var: name
    - debug:
        var: oid
    - debug:
        var: sessions_flat
    - debug:
        var: sessions_fla2
© www.soinside.com 2019 - 2024. All rights reserved.