提问人:stackprotector 提问时间:11/17/2022 更新时间:11/17/2022 访问量:1059
遍历子元素的子元素
Loop through subelements of subelements
问:
我在 Ansible 中使用以下数据结构:
datacenters:
- name: Datacenter1
clusters:
- name: ClusterA
hosts:
- 192.168.0.1
- 192.168.0.2
- name: ClusterB
hosts:
- 192.168.1.1
- 192.168.1.2
- name: Datacenter2
clusters:
- name: ClusterC
hosts:
- 192.168.2.1
- 192.168.2.2
在一项任务中,我想在访问所有父层数据的同时遍历每个主机。如果只有一个嵌套级别,则可以使用过滤器轻松完成:subelements
loop: '{{ datacenters | subelements(''clusters'') }}'
这将使我能够访问数据,如下所示:
'Datacenter: {{ item.0.name }}, Cluster: {{ item.1.name }}'
我希望能够像这样扩展这个概念:
loop: '{{ datacenters | subelements(''clusters'') | subelements(''hosts'') }}'
并且能够像这样访问数据:
'Datacenter: {{ item.0.name }}, Cluster: {{ item.1.name }}, Host: {{ item.2 }}'
但这不起作用,我收到以下错误消息:
Unexpected templating type error occurred on ({{ datacenters | subelements('clusters') | subelements('hosts') }}): the key hosts should point to a dictionary, got ...(the result of the first layer)
我找到了这个问题,它解决了类似的问题,但依赖于在所有嵌套级别上具有不同的字典键,而我没有,因为数据中心和集群具有相同的键。name
那么,如何在 Ansible 中迭代子元素的子元素呢?
答:
3赞
Zeitounator
11/17/2022
#1
有点牵强,但以下剧本将实现您的目标:
---
- hosts: localhost
gather_facts: false
vars:
datacenters:
- name: Datacenter1
clusters:
- name: ClusterA
hosts:
- 192.168.0.1
- 192.168.0.2
- name: ClusterB
hosts:
- 192.168.1.1
- 192.168.1.2
- name: Datacenter2
clusters:
- name: ClusterC
hosts:
- 192.168.2.1
- 192.168.2.2
# Get the list of datacenters
_dcs: "{{ datacenters | map(attribute='name') }}"
# Get the corresponding list of clusters with subelements on hosts
_clusters: "{{ datacenters | map(attribute='clusters') | map('subelements', 'hosts') }}"
# Recreate a list with the sublisted hosts per clusters and create subelements on that final result
_overall: "{{ dict(_dcs | zip(_clusters)) | dict2items(key_name='datacenter', value_name='clusters') | subelements('clusters') }}"
tasks:
- name: Loop on the result
debug:
msg:
- "DC: {{ item.0.datacenter }}"
- "Cluster: {{ item.1.0.name }}"
- "Host: {{ item.1.1 }}"
loop: "{{ _overall }}"
loop_control:
label: "{{ item.0.datacenter }} - {{ item.1.0.name }}"
这给出了:
PLAY [localhost] **************************************************************************************************************************************************
TASK [Loop on the result] *****************************************************************************************************************************************
ok: [localhost] => (item=Datacenter1 - ClusterA) => {
"msg": [
"DC: Datacenter1",
"Cluster: ClusterA",
"Host: 192.168.0.1"
]
}
ok: [localhost] => (item=Datacenter1 - ClusterA) => {
"msg": [
"DC: Datacenter1",
"Cluster: ClusterA",
"Host: 192.168.0.2"
]
}
ok: [localhost] => (item=Datacenter1 - ClusterB) => {
"msg": [
"DC: Datacenter1",
"Cluster: ClusterB",
"Host: 192.168.1.1"
]
}
ok: [localhost] => (item=Datacenter1 - ClusterB) => {
"msg": [
"DC: Datacenter1",
"Cluster: ClusterB",
"Host: 192.168.1.2"
]
}
ok: [localhost] => (item=Datacenter2 - ClusterC) => {
"msg": [
"DC: Datacenter2",
"Cluster: ClusterC",
"Host: 192.168.2.1"
]
}
ok: [localhost] => (item=Datacenter2 - ClusterC) => {
"msg": [
"DC: Datacenter2",
"Cluster: ClusterC",
"Host: 192.168.2.2"
]
}
PLAY RECAP ********************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
评论