在 Ansible 中,如何将 vars 字典中的每个元素与一组默认参数组合

问题描述 投票:0回答:1

我想为 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 }}"
ansible ansible-inventory ansible-facts ansible-template
1个回答
0
投票

在这种情况下,随着时间的推移,编写几行 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
© www.soinside.com 2019 - 2024. All rights reserved.