我正在尝试构建字典,但无法掌握jinja2如何对变量进行插值。
我想将数组中的特定项目(例如item [0])设置为特定的键值字典项目。
- set_fact:
nodes:
- node1
- node2
- set_fact:
list_one:
- f-one
- f-two
- set_fact:
list_two:
- n-one
- n-two
我想要什么:
- set_fact:
**node_dict:
node1:
labels:
f-one: n-one
node2:
labels:
f-two: n-two**
我跑步时:
- name: check loop1
debug:
msg: '{{item[0]}} - {{item[1]}} - {{ item[2]}} '
with_nested:
- '{{ nodes }}'
- '{{ list_one }}'
- '{{ list_two }}'
item
变量可用。但是要这样做:
- set_fact:
final:
'{{item[0]}}':
labels:
"{{item[1] }}" : "{{item[2]}}"
with_nested:
- '{{ nodes }}'
- '{{ list_one }}'
- '{{ list_two }}'
导致错误。
有人可以解释为什么吗?我如何最终得到理想的结果?
答案 0 :(得分:0)
一种选择是创建标签列表,然后组合字典。下面的游戏
- hosts: localhost
vars:
nodes:
- node1
- node2
list_one:
- f-one
- f-two
list_two:
- n-one
- n-two
node_dict: {}
my_labels: []
tasks:
- set_fact:
my_labels: "{{ my_labels + [ {list_one[my_idx]:list_two[my_idx]} ] }}"
loop: "{{ nodes }}"
loop_control:
index_var: my_idx
- set_fact:
node_dict: "{{ node_dict | combine({item:{'labels':my_labels[my_idx]}}) }}"
loop: "{{ nodes }}"
loop_control:
index_var: my_idx
- debug:
var: node_dict
给予:
"node_dict": {
"node1": {
"labels": {
"f-one": "n-one"
}
},
"node2": {
"labels": {
"f-two": "n-two"
}
}
}
答案 1 :(得分:0)
set_fact
在每个循环上都覆盖您的final
变量。要将元素添加到像您尝试执行的dict一样,您需要将var初始化为一个空dict,并使用您为每次迭代计算的值combine对其进行初始化。由于计算的值本身就是字典,因此如果必须在字典的深处编写表达式,则需要使用recursive=True
。nested
所做的(在nodes
上有一个子循环,在list_one
上有一个子循环,在list_two
上循环...)。在您的情况下,您只需要遍历列表长度的索引,并将相同索引的元素组合在一起。我的看法如下。---
- name: test for SO
hosts: localhost
vars:
nodes:
- node1
- node2
list_one:
- f-one
- f-two
list_two:
- n-one
- n-two
tasks:
- name: Make my config
set_fact:
final: >-
{{
final
| default({})
| combine ({
nodes[item]: {
'labels': {
list_one[item]: list_two[item]
}
}
}, recursive=True)
}}
loop: "{{ range(nodes | length) | list }}"
- name: debug
debug:
var: final
给出以下结果
$ ansible-playbook test.yml
PLAY [test for SO] ******************************************************************
TASK [Gathering Facts] **************************************************************
ok: [localhost]
TASK [Make my config] ***************************************************************
ok: [localhost] => (item=0)
ok: [localhost] => (item=1)
TASK [debug] ************************************************************************
ok: [localhost] => {
"final": {
"node1": {
"labels": {
"f-one": "n-one"
}
},
"node2": {
"labels": {
"f-two": "n-two"
}
}
}
}
PLAY RECAP **************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
编辑:使用zip filter(今天我(重新)发现reading an other contribution)可以得到相同的结果。
- name: Make my config
set_fact:
final: >-
{{
final
| default({})
| combine ({
item.0: {
'labels': {
item.1: item.2
}
}
}, recursive=True)
}}
loop: "{{ nodes | zip(list_one, list_two) | list }}"