Ansible/Jinja "from_yaml"过滤原始文件中的排序键



>我正在尝试从 Ansible 中的远程节点读取 YML 文件并进行修改和更新。

当我使用"from_yaml"Jinja过滤器时,我注意到键已排序,当我在远程更新文件时,它会导致问题。

有没有办法在from_yaml过滤器上设置 Sort_Keys=False?

原始文件:

key1:
key5:
key3: value3
key2:
key5: value4
key6:
key7: value5

应用"from_yaml"过滤器后(键已排序):

key1:
key2:
key3: value3
key5:
key5: value4
key6:
key7: value5

YAML 标准表示字典中没有键的顺序。最近 Python3(我不记得版本了。大概是 3.6 或 3.7。您可以在发行说明中找到它。在字典中引入了有序键。这是您看到的筛选器from_yaml的结果。当 Ansible 使用最新的 Python3 时,你会看到字典也没有任何过滤器。例如

- hosts: localhost
vars:
key1:
key5:
key3: value3
key2:
key5: value4
key6:
key7: value5
tasks:
- debug:
var: key1

给予(删节)

key1:
key2:
key5: value4
key5:
key3: value3
key6:
key7: value5

但是,Jinja,即使使用Python3.8,也不会对字典进行排序(我不知道为什么)。例如

- debug:
msg: |
{% for k,v in key1.items() %}
{{ k }}: {{ v }}
{% endfor %}

给予(删节)

msg: |-
key5: {'key3': 'value3'}
key2: {'key5': 'value4'}
key6: {'key7': 'value5'}

不幸的是,要回答您的问题,没有Sort_Keys=False这样的选择。此外,在 YAML 中,无法保证字典的键的存储顺序。如果你想确保你按照特定的顺序编写字典,你必须保留键的列表。例如

- debug:
msg: |
{% for k in list_of_keys %}
{{ k }}: {{ key1[k] }}
{% endfor %}
vars:
list_of_keys: [key5, key2, key6]

导入的数据按字典的数据结构进行组织。与数组(或列表)相反,在数组(或列表)中,元素按其位置排序并通过索引寻址,字典的值通过相应的键进行寻址。但是,您无法定义或影响订单。Ansible 始终输出按键排序的字典的数据结构。

你举的例子是错误的。因为即使输出按键排序,数据结构也不会改变。key1.key5.key3仍返回值value3。但是在您的示例中"应用"from_yaml"过滤器后",此值不再存在,在您的情况下value3现在处于key1.key2.key3.您的输出与 Ansible 在将from_yaml滤波器应用于所述输入时给出的输出不匹配。


数据文件mydata.txt

key1:
key5:
key3: value3
key2:
key5: value4
key6:
key7: value5

Ansible 任务:

- debug:
msg: "{{ lookup('file', 'mydata.txt') | from_yaml }}"

输出:

TASK [debug] *****************************
ok: [localhost] => {
"msg": {
"key1": {
"key2": {
"key5": "value4"
},
"key5": {
"key3": "value3"
},
"key6": {
"key7": "value5"
}
}
}
}

相关内容

最新更新