gpt4 book ai didi

loops - 在 Ansible 中迭代嵌套字典,保留键名称

转载 作者:行者123 更新时间:2023-12-03 08:04:47 26 4
gpt4 key购买 nike

我有一个如下所示的数据结构:

all_vms:
clusterA:
group1:
- vm-01
- vm-02
group2:
- vm-03
- vm-04
clusterB:
group1:
- vm-05
- vm-06

事先不知道键名。集群之间可能存在共享的“组”键名称。

我想循环遍历该数据结构并对每个数组运行一个任务,但我需要它们所包含的键的名称。循环任务看起来像这样:

- task:
vms: "{{ item.value }}"
group: "{{ item.key }}"
cluster: "{{ item.parentkey }}"
loop: "{{ all_vms | ??? }}"

这将展开为:

- task:
vms:
- vm-01
- vm-02
group: group1
cluster: clusterA
- task:
vms:
- vm-03
- vm-04
group: group2
cluster: clusterA
- task:
vms:
- vm-05
- vm-06
group: group3
cluster: clusterB

我无法更改主簇/组结构,但我可以更改当前数组元素的结构。我考虑过将键复制为值,如下所示:

all_vms:
clusterA:
group1:
cluster: "clusterA"
group: "group1"
vms:
- vm-01
- vm-02
group2:
cluster: "clusterA"
group: "group2"
vms:
- vm-03
- vm-04
clusterB:
group1:
cluster: "clusterB"
group: "group1"
vms:
- vm-05
- vm-06

宁愿不这样做,因为这很糟糕,但我可以。但我什至无法找到一种方法将这些内容弹出到数组中。 (编辑:实际上,我认为在发布后就发现了这一点:all_vms | json_query('*.* | []')。我想如果没有办法使用更整洁的数据结构。)

或者如果我可以使用 @!#$% 嵌套循环,如果 ansible 允许的话:

- block:
- task:
vms: "{{ item.value }}"
group: "{{ item.key }}"
cluster: "{{ cluster.key }}"
loop: "{{ cluster.value | dict2items }}"
loop: "{{ all_vms | dict2items }}"
loop_control:
loop_var: cluster

(是的,我可以使用 include_tasks 来做到这一点,但是必须为嵌套循环使用单独的文件只是荒谬。)

有什么想法可以迭代这个数据结构,而不必求助于单独的文件来执行嵌套循环吗?

最佳答案

这是解决方案 using several combinations of filters directly in Ansible / Jinja

它将第一级键和值与 zip 过滤器结合起来,以便获得已知的子元素名称 - 1 - 然后我们可以在其上使用 子元素

由于映射到第一级值的 dict2items,可以访问第二级键/值对。

任务最终是

- set_fact:
tasks: "{{ tasks | default([]) + [_task] }}"
loop: >-
{{
all_vms.keys()
| zip(all_vms.values() | map('dict2items'))
| subelements([1])
}}
loop_control:
label: "{{ item.0.0 }} — {{ item.1.key }}"
vars:
_task:
task:
vms: "{{ item.1.value }}"
group: "{{ item.1.key }}"
cluster: "{{ item.0.0 }}"

鉴于剧本:

- hosts: localhost
gather_facts: no

tasks:
- set_fact:
tasks: "{{ tasks | default([]) + [_task] }}"
loop: >-
{{
all_vms.keys()
| zip(all_vms.values() | map('dict2items'))
| subelements([1])
}}
loop_control:
label: "{{ item.0.0 }} — {{ item.1.key }}"
vars:
_task:
task:
vms: "{{ item.1.value }}"
group: "{{ item.1.key }}"
cluster: "{{ item.0.0 }}"
all_vms:
clusterA:
group1:
- vm-01
- vm-02
group2:
- vm-03
- vm-04
clusterB:
group1:
- vm-05
- vm-06

- debug:
var: tasks

这会产生:

TASK [set_fact] ***************************************************************
ok: [localhost] => (item=clusterA — group1)
ok: [localhost] => (item=clusterA — group2)
ok: [localhost] => (item=clusterB — group1)

TASK [debug] ******************************************************************
ok: [localhost] =>
tasks:
- task:
cluster: clusterA
group: group1
vms:
- vm-01
- vm-02
- task:
cluster: clusterA
group: group2
vms:
- vm-03
- vm-04
- task:
cluster: clusterB
group: group1
vms:
- vm-05
- vm-06

关于loops - 在 Ansible 中迭代嵌套字典,保留键名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72750712/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com