saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:

Home Page:https://repo.saltproject.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[BUG] update_dict_key_value() should work on entire dict, not just its keys

mirko opened this issue · comments

Description
update_dict_key_value() only works on keys within the dict, not on the entire dict itself.
For example {{ defaults | update_dict_key_value('', override) does not work.
Maybe it's not intended to work, however it appears to be the only method to overwrite existing keys in a struct with an empty dict.

If this is intended behaviour, feel free to close and I'm happy to open a feature request for the following behaviour which I wasn't yet able to achieve and for which update_dict_key_value() seemed the best candidate so far.

For example with slsutil.merge() or slsutil.update() I can't replace values to empty dicts.

What I want to achieve is:
FUNCTION({foo: "bar", sub: {bla: "blub"}}, {sub: {}})
resulting in
{'foo': 'bar', 'sub': {}}

There are two ways to do this:

{% set d = {"foo": "bar", "sub": {"bla": "blub"}} %}

{# method 1 #}
{{ salt["slsutil.update"](d, {"sub": {}), recursive_update=False) }}

{# method 2 #}
{% do d.update({"sub": {}) %}
{{ d }}

Touche, in this use case it works - however I /want/ recursive updates - "just" being able to replace nested dicts with empty ones.

Examples:

salt-call --output=txt slsutil.update \
'{foo: "bar", sub: {bla: "blub", subsub: {x: 1, y: 2}}}' \
'{sub: {subsub: {}}}' \
'recursive_update=False'

results in
local: {'foo': 'bar', 'sub': {'subsub': {}}}

subsub is correctly set to the empty dict ({}), however the rest of the sub-keys (bla) is now gone - not being merged due to recursive merging disabled.

What I want as a result is:
{'foo': 'bar', 'sub': {'bla': 'blub', 'subsub': {}
where sub keeps its keys (merged with 1st arg) but only explicitly set (nested) keys are being updated.

The more I think about it I'd describe it as: Merge all dicts along the way till the most inner one (of the 2nd arg), and set respective (sub)key of the 1st arg dict to respective value of the 2nd arg dict.

It will need to be a feature request for a new option. Reducing to the base case, update({}) should do nothing, not remove all keys.