我想为 Ansible 实现一种“默认值”,这是我的清单变量中的字典字典。 我知道可以使用过滤器来实现这些目标,但我无法弄清楚实现这一目标的确切咒语..
对于单维字典,可以使用
combine
过滤器 - 每个字典元素上是否有类似于 combine
的内容?我试过使用 map
和 map('combine')
但这个功能似乎主要是为列表构建的。
我已经在剧本和库存查找的变量中尝试过这个——我也尝试过使用角色和默认变量的方法,但是不能做出足够优雅的东西来用于生产。
给定以下 variables.yaml 文件:
---
example_base:
alice:
foo: 1
bob:
bar: 2
example_defaults:
baz: 3
foo: 0
example: >-
{%- set result = {} -%}
{%- for name, values in example_base.items() -%}
{%- set _= result.update({name: example_defaults|combine(values, recursive=true)}) -%}
{%- endfor -%}
{{ result }}
我想将
example_defaults
组合到 variables.yaml 文件中的 example_base
字典的每个子字典中,而不是在剧本中 - 这将使我不必在我的字典项中定义每个公共变量。
example
声明有效 - 是否有更简洁的方法使用 Jinja/Ansible 过滤器来实现此目的?
想要的结果:
ok: [localhost] => {
"msg": {
"alice": {
"baz": 3,
"foo": 1
},
"bob": {
"bar": 2,
"baz": 3,
"foo": 0
}
}
一个例子 playbook.yaml 可以是 -
---
- hosts: localhost
connection: local
vars_files:
- variables.yaml
tasks:
- name: Debug
debug:
msg: "{{ example }}"
在这种情况下,随着时间的推移,编写几行 python 可能是最简单和最可持续的,更具体地说,如果您需要以相同的方式将默认值应用于不同的词典。
测试文件结构:
.
├── filter_plugins
│ └── my_custom_filters.py
└── playbook.yml
filter_plugins/my_custom_filters.py
def dict_defaults(input_dict, defaults):
"""apply defaults to every key of the input dict"""
return {k: {**defaults, **v} for (k, v) in input_dict.items()}
class FilterModule(object):
"""my custom filters"""
def filters(self):
"""Return the filter list."""
return {
'dict_defaults': dict_defaults
}
playbook.yml
---
- name: Custom filter demo
hosts: localhost
gather_facts: false
vars:
example_base: {alice: {foo: 1}, bob: {bar: 2}}
example_defaults: {baz: 3, foo: 0}
tasks:
- name: Apply defaults with custom filter
debug:
var: example_base | dict_defaults(example_defaults)
运行剧本给出:
$ ansible-playbook playbook.yml
PLAY [Custom filter demo] *****************************************************************************************************************************************************************************************************
TASK [Apply defaults with custom filter] **************************************************************************************************************************************************************************************
ok: [localhost] => {
"example_base | dict_defaults(example_defaults)": {
"alice": {
"baz": 3,
"foo": 1
},
"bob": {
"bar": 2,
"baz": 3,
"foo": 0
}
}
}
PLAY RECAP ********************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0