在Ansible中使用json_查询查询字典列表中包含的字典列表

在Ansible中使用json_查询查询字典列表中包含的字典列表,ansible,json-query,Ansible,Json Query,我在使用json_查询搜索下面的数据结构时遇到了问题,我想从中创建两个单独的列表 对于其成员列表包含子路径键且其值包含特定值的条目,列表1应包含每个字典中的名称键 对于成员列表不包含子路径键且名称包含特定值的条目,列表2应包含每个字典中的名称键 到目前为止,我能找到的最接近的词典是那些其成员词典具有子路径键的词典: - name: debug debug: msg: "{{ device_facts.gtm_a_pools | json_query(query) }}&qu

我在使用json_查询搜索下面的数据结构时遇到了问题,我想从中创建两个单独的列表

对于其成员列表包含子路径键且其值包含特定值的条目,列表1应包含每个字典中的名称键

对于成员列表不包含子路径键且名称包含特定值的条目,列表2应包含每个字典中的名称键

到目前为止,我能找到的最接近的词典是那些其成员词典具有
子路径
键的词典:

- name: debug
  debug:
    msg: "{{ device_facts.gtm_a_pools | json_query(query) }}"
  vars:
    query: "[].members[?!subPath][].name"
或者没有子路径键:

- name: debug
  debug:
    msg: "{{ device_facts.gtm_a_pools | json_query(query) }}"
  vars:
    query: "[].members[?subPath][].name"
但是这是从members字典中返回name键,而我需要的是基于上述两个标准(一个列表有子路径,一个列表没有子路径)的每个gtm_a_pools字典中的name键

使用以下数据结构:

  • 列表1=['a2-测试池']
  • 列表2=['aci_池']
Q:“根据上述两个标准(一个列表有子路径,一个列表没有子路径)命名每个gtm_a_池字典中的键”

答:代替json_查询,迭代列表并比较成员数,例如

-设置事实:
列表1:{{list1}默认值([])+[item.name]}”
循环:“{gtm_a_pools}”
时间:项长度==子路径长度
变量:
子路径长度:“{item.members | map('intersect',['subPath'])|展平|长度}”
项目长度:{{item.members | length}”
给予

list1:
-a2-测试池
如果“无子路径”是指“任何无子路径的成员”

-设置事实:
列表2:{{list2}默认值([])+[item.name]}”
循环:“{gtm_a_pools}”
时间:项目长度!=子路径长度
变量:
子路径长度:“{item.members | map('intersect',['subPath'])|展平|长度}”
项目长度:{{item.members | length}”
给予

list2:
-aci_池
如果“无子路径”表示“所有成员无子路径”,则下面的任务给出相同的结果

-设置事实:
列表2:{{list2}默认值([])+[item.name]}”
循环:“{gtm_a_pools}”
时间:子路径长度| int==0
变量:
子路径长度:“{item.members | map('intersect',['subPath'])|展平|长度}”
谢谢你,弗拉基米尔

当我在等待别人的回应时,我想到了这个,所以我想在这里分享一下。我要说的是,这可能不一定能解释清单2的两种情况,即我解释了“没有子路径的所有成员”和“没有子路径的任何成员”。因此,我使用上面的解决方案在最后运行验证,以处理整个加载并绘制该比较,并输出具有混合成员类型的任何池:

---
- name: Determine if Server List product is Generic Host (static) or otherwise
  bigip_device_info:
    gather_subset:
      - gtm-servers
    provider: "{{ vcmp_guest_provider }}"
  delegate_to: localhost
  register: device_facts

# server_type = generic-host vs. bigip
# bigip = dynamic
# generic-host = static
- name: Set type fact
  set_fact:
    server_type: "{{ device_facts | json_query(jmesquery) | join }}"
  vars:
    jmesquery: "gtm_servers[?name == '{{ gtm_source_server }}'].product"

- name: debug
  debug:
    var: server_type

- name: Gather GTM pools 
  bigip_device_info:
    gather_subset:
      - gtm-a-pools
    provider: "{{ vcmp_guest_provider }}"
  delegate_to: localhost
  register: device_facts

- name: Create list of pools that use discovered objects and are part of {{ gtm_source_server }}
  set_fact:
    pool_list: "{{ pool_list | default([]) + [ item.0 ] }}"
  loop: "{{ pool_name | zip(payload) | list }}"
  when:
    - item.1 | json_query('members[*].subPath') | length > 0
    - item.1 | json_query('members[*].subPath') is search(gtm_source_server)
    - server_type == "bigip"
  vars:
    pool_name: "{{ device_facts | json_query('gtm_a_pools[*].name') }}"
    payload: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  no_log: true

- name: Create list of pools that use static objects and are part of {{ gtm_source_server }}
  set_fact:
    pool_list: "{{ pool_list | default([]) + [ item.0 ] }}"
  loop: "{{ pool_name | zip(payload) | list }}"
  when:
    - item.1 | json_query('members[*].subPath') | length == 0
    - item.1 | json_query('members[*].name') is search(gtm_source_server)
    - server_type == "generic-host"
  vars:
    pool_name: "{{ device_facts | json_query('gtm_a_pools[*].name') }}"
    payload: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  no_log: true

- debug:
    var: pool_list

- name: Check if any pools contain a mix of static and dynamic members
  set_fact:
    counter: "{{ counter | default([]) + [ item.name + ' has ' + subPath_length + ' dynamic entries and ' + member_length + ' static entries.' ] }}"
  loop: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  vars:
    subPath_length: "{{ item.members|map('intersect', ['subPath'])|flatten|length }}"
    member_length: "{{ item.members|length }}"
  when:
    - subPath_length | int > 0
    - member_length != subPath_length
  no_log: true

- debug:
    msg: "{{ counter | default('No mixture found') }}"
---
- name: Determine if Server List product is Generic Host (static) or otherwise
  bigip_device_info:
    gather_subset:
      - gtm-servers
    provider: "{{ vcmp_guest_provider }}"
  delegate_to: localhost
  register: device_facts

# server_type = generic-host vs. bigip
# bigip = dynamic
# generic-host = static
- name: Set type fact
  set_fact:
    server_type: "{{ device_facts | json_query(jmesquery) | join }}"
  vars:
    jmesquery: "gtm_servers[?name == '{{ gtm_source_server }}'].product"

- name: debug
  debug:
    var: server_type

- name: Gather GTM pools 
  bigip_device_info:
    gather_subset:
      - gtm-a-pools
    provider: "{{ vcmp_guest_provider }}"
  delegate_to: localhost
  register: device_facts

- name: Create list of pools that use discovered objects and are part of {{ gtm_source_server }}
  set_fact:
    pool_list: "{{ pool_list | default([]) + [ item.0 ] }}"
  loop: "{{ pool_name | zip(payload) | list }}"
  when:
    - item.1 | json_query('members[*].subPath') | length > 0
    - item.1 | json_query('members[*].subPath') is search(gtm_source_server)
    - server_type == "bigip"
  vars:
    pool_name: "{{ device_facts | json_query('gtm_a_pools[*].name') }}"
    payload: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  no_log: true

- name: Create list of pools that use static objects and are part of {{ gtm_source_server }}
  set_fact:
    pool_list: "{{ pool_list | default([]) + [ item.0 ] }}"
  loop: "{{ pool_name | zip(payload) | list }}"
  when:
    - item.1 | json_query('members[*].subPath') | length == 0
    - item.1 | json_query('members[*].name') is search(gtm_source_server)
    - server_type == "generic-host"
  vars:
    pool_name: "{{ device_facts | json_query('gtm_a_pools[*].name') }}"
    payload: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  no_log: true

- debug:
    var: pool_list

- name: Check if any pools contain a mix of static and dynamic members
  set_fact:
    counter: "{{ counter | default([]) + [ item.name + ' has ' + subPath_length + ' dynamic entries and ' + member_length + ' static entries.' ] }}"
  loop: "{{ device_facts | json_query('gtm_a_pools[*]') }}"
  vars:
    subPath_length: "{{ item.members|map('intersect', ['subPath'])|flatten|length }}"
    member_length: "{{ item.members|length }}"
  when:
    - subPath_length | int > 0
    - member_length != subPath_length
  no_log: true

- debug:
    msg: "{{ counter | default('No mixture found') }}"