ansible yaml 变量提取/过滤器保留 "parent" 名称

ansible yaml variable extraction / filter keeping the "parent" names

我有一个 ansible yaml 变量:

tenants:
- tenant_name: ccf_demo
  description: "ccf demo tenant"
  state: present
  segments:
  - segment_name: segment1
    state: present
    ifgroups:
    - ifgroup_name: group1
      tag: untagged
    - ifgroup_name: group2
      tag: untagged
- tenant_name: ccf_demo2
  description: "ccf demo2 tenant"
  state: absent
  segments:
  - segment_name: t2seg1
    state: present
    ifgroups:
    - ifgroup_name: othergroup
      tag: untagged
- tenant_name: ccf_demo3
  description: "ccf demo3 tenant"
  state: present

现在我想 extract/loop 遍历每个租户的所有段(如果有的话)的所有 ifgroups保留 tenantsegment.

最后我想要一个循环体,使我能够编写如下内容:

- debug:
    msg: "name: {{ item.tenant_name }}_{{ item.segment_name }}_{{ item.ifgroup_name }} is {{ item.?...ifgroup_name }}:{{ item.?...tag }}"
  loop: "{{ ??? | json_query('???') | ??? }}"

期望的输出:

  1. 姓名:ccf_demo_segment1_group1 是 group1:untagged
  2. 姓名:ccf_demo_segment1_group2 是 group2:untagged
  3. 姓名:ccf_demo2_t2seg1_othergroup 是 othergroup:untagged

已编辑 ------------------

理想情况下,我想用结果定义一个新的 yaml 变量,例如喜欢

resultVar:
  - tenant_name: ccf_demo
    segment_name: segment1
    ifgroup_name: group1
    tag: untagged
  - tenant_name: ccf_demo
    segment_name: segment1
    ifgroup_name: group2
    tag: untagged
  - tenant_name: ccf_demo2
    segment_name: t2seg1
    ifgroup_name: othergroup
    tag: untagged

感谢任何帮助。

不是使用 JMESPath 过滤列表,这最终不会消除您对结果列表进行循环的需要,更好的选择可能是使用带有嵌套循环的基本 Jinja 模板。

鉴于剧本:

- hosts: localhost
  gather_facts: no

  tasks:
    - debug:
        msg: >-
          {% for segment in item.segments %}
          {%- for ifgroup in segment.ifgroups -%}
            name: {{ item.tenant_name }}_{{ segment.segment_name }}_{{ ifgroup.ifgroup_name }} is {{ ifgroup.ifgroup_name }}:{{ ifgroup.tag }}
          {% endfor %}
          {% endfor %}
      loop: "{{ tenants }}"
      loop_control:
        label: "{{ item.tenant_name }}"
      when: item.segments is defined
      vars:
        tenants:
          - tenant_name: ccf_demo
            description: "ccf demo tenant"
            state: present
            segments:
            - segment_name: segment1
              state: present
              ifgroups:
              - ifgroup_name: group1
                tag: untagged
              - ifgroup_name: group2
                tag: untagged
          - tenant_name: ccf_demo2
            description: "ccf demo2 tenant"
            state: absent
            segments:
            - segment_name: t2seg1
              state: present
              ifgroups:
              - ifgroup_name: othergroup
                tag: untagged
          - tenant_name: ccf_demo3
            description: "ccf demo3 tenant"
            state: present

这产生:

ok: [localhost] => (item=ccf_demo) => 
  msg: |-
    name: ccf_demo_segment1_group1 is group1:untagged
    name: ccf_demo_segment1_group2 is group2:untagged
ok: [localhost] => (item=ccf_demo2) => 
  msg: |-
    name: ccf_demo2_t2seg1_othergroup is othergroup:untagged
skipping: [localhost] => (item=ccf_demo3) 

这就是我最终得到的:

---

- hosts: localhost
  connection: local
  gather_facts: no

  tasks:
  - name: include businessVars
    include_vars: ./businessVars/busVars.yml

  - name: "DEBUG3 -> write template variable to file"
    template:
      src: ifgroups.j2
      dest: tmp/ifgroups.yml
      mode: 0600
    tags: DEBUG3

  - name: extract interface data by jinja template
    set_fact: 
      theIfGroups: "{{ lookup('template', 'ifgroups.j2') | from_yaml }}"
    ## theIfGroups:
    ## - tenant_name: ccf_demo
    ##   segment_name: segment1
    ##   ifgroup_name: group1
    ##   tag: untagged

  - name: final output
    debug:
      msg: "{{ item.tenant_name }}__{{ item.segment_name }}__{{ item.ifgroup_name }}: {{ item.ifgroup_name }}:{{ item.tag }}"
    loop: "{{ theIfGroups }}"

./templates/ifgroups.j2

{% for tenant in tenants %}
{%- if tenant.segments is defined -%}{% for segment in tenant.segments %}
{%- if segment.ifgroups is defined -%}{%- for ifgroup in segment.ifgroups -%}
- tenant_name: {{ tenant.tenant_name }}
  segment_name: {{ segment.segment_name }}
  ifgroup_name: {{ ifgroup.ifgroup_name }}
  tag: {{ ifgroup.tag }}
{% endfor %}{% endif %}
{% endfor %}{% endif %}
{% endfor %}

./businessVars/busVars.yml

tenants:
- tenant_name: ccf_demo
  description: "ccf demo tenant"
  state: present
  segments:
  - segment_name: segment1
    state: present
    ifgroups:
    - ifgroup_name: group1
      tag: untagged
    - ifgroup_name: group2
      tag: untagged
- tenant_name: ccf_demo2
  description: "ccf demo2 tenant"
  state: absent
  segments:
  - segment_name: t2seg1
    state: present
    ifgroups:
    - ifgroup_name: group3
      tag: untagged
- tenant_name: ccf_demo3
  description: "ccf demo3 tenant"
  state: absent
  segments:
  - segment_name: t3seg1
    state: present
- tenant_name: ccf_demo3
  description: "ccf demo3 tenant"
  state: present