You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Customization of the map sources in parameters/map_jinja.yaml, such as
values:
sources:
- Y:I:!@my_pillar!nested_pillar_key
# include the defaults
Custom parameters TEMPLATE/parameters/my_pillar!nested_pillar_key/value.yaml, such as
values:
parameter: override
Bug details
Describe the bug
The map function, and more specifically the libmatchers macro is not correctly respecting non-default delimiters for yaml-parameters selected by grains or pillars.
currently, the matchers macro would look up the value of my_pillar!nested_pillar_key instead of the value of nested_pillar_key within the parent my_pillar.
Since the my_pillar!nested_pillar_key key does not exist custom parameters of the specified source type (yaml, pillar, with non-default delimiter) are ignored.
However, Y:C:!@my_pillar!nested_pillar_key is respecting custom delimiters.
Using non-default delimiters is often required, that developers on windows-based clients can use repositories with custom parameters based on nested grains or pillar.
Steps to reproduce the bug
Provide a nested pillar as specified in the setup
Add a custom map source, or add it to the map.jinja defaults
run formula._mapdata with debug output
inspect the query result of Y:I:!@my_pillar!nested_pillar_key with is likely None
inspect the mapdata yaml with is likely missing the custom parameter provided by grain/pillar-selected yaml-source
Expected behaviour
Non-default delimiters should be respected for grain-based or pillar-based yaml-file selection.
I need a brief discussion whether to implement tests, since this might require adding test parameter files, including them through the kitchen.yml, and finally updating the mapdata results.
Additional context
I had to convert custom parameters for a formula to windows compatible delimiters since colons are invalid characters in filenames on windows. The previously used default delimiter, a colon, worked fine to work on repositories on linux clients. Though this condition was preventing coworkers from cloning on windows machines...
After that change, custom parameters where not respected in formulas anymore.
Anyhow, I had to "dive deep" to find the cause why the explicitly stated pattern [<TYPE>[:<OPTION>[:<DELIMITER>]]@]<KEY> wasn't fully usable. Below I try to give an analysis.
Boundary conditions
Approximately, i have this boundary condition,
A nested pillar:
my_pillar:
nested_pillar_key: value
Customization of the map sources in parameters/map_jinja.yaml
values:
sources:
- Y:I:!@my_pillar!nested_pillar_key
# include the defaults
a formula (closely) derived from the template-formula, using unmodified jinja macros as given in the template formula
conventional minion and master, no salt-ssh, api calls, or unknown
no merging strategies for specified for custom parameters
Issue
The source Y:I@my_pillar:nested_pillar_key was correctly using TEMPLATE/parameters/my_pillar:nested_pillar_key/value.yaml. But Y:I:!@my_pillar!nested_pillar_key was resulting in querying TEMPLATE/parameters/my_pillar!nested_pillar_key.yaml
Drilling down
Identifying the resulting query
Searching for the query which should use pillar.get resulted in
{%- set values = salt[parsed.query_method](
parsed.query,
default=[],
**query_opts
) %}
query_opts is only non-empty if this expression is true, including boundary condition 4: parsed.query_method == "config.get" and config_get_strategy
otherwise it's set to an empty dict in line 186.
There is a hole in this logic sequence. only config.get and non-empty config_get_strategy would allow to use custom delimiters. As "specified" in the docs for map.jinja the pillar and grain lookups for yaml files should support custom delimiters. But never setting query_opts results in missing this feature for the concrete lookups (instead of config.get).
I can understand why the ssh/unknown cli flag are handled.
handling only config.get is likely done to apply the config_get_strategy option.
The argument merge (line 167) is not exclusive for config.get, but since in line 201 default=[] is set, merge is only effective for config.get. I think that's why config.get with config_get_strategy was handled.
Proposal
I believe, query_opts should contain delimiter in the default case, and should only be emptied when cli is in "ssh", "unknown".
This could be done in different fashions, for example one of these:
minimally invasive by extending the else case in line 185 as shown in the patch at the top of this issue.
rearranging and flatten the assignments, such as
{%- setquery_opts = {
"delimiter": parsed.query_delimiter,
} %}{%- setquery_opts_msg = (
", delimiter='"
~ parsed.query_delimiter
~ "'"
) %}{#- Add `merge:` option to `salt["config.get"]` if configured #}{%- ifparsed.query_method == "config.get"andconfig_get_strategy%}{%- doquery_opts.update({
"merge": config_get_strategy
} %}{%- setquery_opts_msg = (
", delimiter='"
~ parsed.query_delimiter
~ "', merge: strategy='"
~ config_get_strategy
~ "'"
) %}{%- endif%}{#- reset 'query_opts' and 'query_opts_msg' if 'cli' is 'ssh' or 'unknown' #}{%- ifcliin ["ssh", "unknown"] %}{%- dosalt["log.warning"](
log_prefix
~ "the 'delimiter' and 'merge' options of 'config.get' are skipped when the salt command type is '"
~ cli
~ "'"
) %}{%- setquery_opts = {} %}{%- setquery_opts_msg = ""%}{%- endif%}
Testing
I think, it would be useful to include nested metadata as edge cases in the test-pipelines. but this would require to extend the config and test files.
For example,
the kitchen.yml would further include test-only parameters such as test/salt/TEMPLATE/parameters/nested:pillar/value.yml. The test/salt/pillar/defaults.sls would include an additional nested key structure, including the respective mapdata renderings.
The text was updated successfully, but these errors were encountered:
Your setup
Formula commit hash / release tag
latest, fd8430b
Versions reports (master & minion)
latest, bug effectively independent from version
Pillar / config used
A nested pillar, such as:
Customization of the map sources in
parameters/map_jinja.yaml
, such asCustom parameters
TEMPLATE/parameters/my_pillar!nested_pillar_key/value.yaml
, such asBug details
Describe the bug
The map function, and more specifically the libmatchers macro is not correctly respecting non-default delimiters for yaml-parameters selected by grains or pillars.
currently, the matchers macro would look up the value of
my_pillar!nested_pillar_key
instead of the value ofnested_pillar_key
within the parentmy_pillar
.Since the
my_pillar!nested_pillar_key
key does not exist custom parameters of the specified source type (yaml, pillar, with non-default delimiter) are ignored.However,
Y:C:!@my_pillar!nested_pillar_key
is respecting custom delimiters.Using non-default delimiters is often required, that developers on windows-based clients can use repositories with custom parameters based on nested grains or pillar.
Steps to reproduce the bug
Y:I:!@my_pillar!nested_pillar_key
with is likely NoneExpected behaviour
Non-default delimiters should be respected for grain-based or pillar-based yaml-file selection.
Attempts to fix the bug
Additional context
I had to convert custom parameters for a formula to windows compatible delimiters since colons are invalid characters in filenames on windows. The previously used default delimiter, a colon, worked fine to work on repositories on linux clients. Though this condition was preventing coworkers from cloning on windows machines...
After that change, custom parameters where not respected in formulas anymore.
Anyhow, I had to "dive deep" to find the cause why the explicitly stated pattern
[<TYPE>[:<OPTION>[:<DELIMITER>]]@]<KEY>
wasn't fully usable. Below I try to give an analysis.Boundary conditions
Approximately, i have this boundary condition,
parameters/map_jinja.yaml
Issue
The source
Y:I@my_pillar:nested_pillar_key
was correctly usingTEMPLATE/parameters/my_pillar:nested_pillar_key/value.yaml
. ButY:I:!@my_pillar!nested_pillar_key
was resulting in queryingTEMPLATE/parameters/my_pillar!nested_pillar_key.yaml
Drilling down
Identifying the resulting query
Searching for the query which should use
pillar.get
resulted inhttps://github.com/saltstack-formulas/template-formula/blob/fd8430b203101eee8d124f5734ba678e71ac3e11/TEMPLATE/libmatchers.jinja#L199C1-L203C13
For
Y:I:!@my_pillar!nested_pillar_key
i would expect this jinja call to effectively be rendered to:but for some reason query_opts did not contain the delimiter argument.
Where is
query_opts
setSearching for the symbol
query_opts
shows that it is only referenced (and assigned) in this section:https://github.com/saltstack-formulas/template-formula/blob/fd8430b203101eee8d124f5734ba678e71ac3e11/TEMPLATE/libmatchers.jinja#L164C1-L188C17
query_opts
is only non-empty if this expression is true, including boundary condition 4:parsed.query_method == "config.get" and config_get_strategy
otherwise it's set to an empty dict in line 186.
There is a hole in this logic sequence. only config.get and non-empty config_get_strategy would allow to use custom delimiters. As "specified" in the docs for map.jinja the pillar and grain lookups for yaml files should support custom delimiters. But never setting
query_opts
results in missing this feature for the concrete lookups (instead of config.get).Source Parser always assigns delimiter
The section where the map source state is parsed always sets the default delimiter or custom delimiter if present into the
parsed
dictionary.Compare to
https://github.com/saltstack-formulas/template-formula/blob/fd8430b203101eee8d124f5734ba678e71ac3e11/TEMPLATE/libmatchers.jinja#L49C1-L144C17
I haven't found a logic issue here, and therefore assume parsing always correctly dissects the map source DSL - returning a dictionary with these keys
query_method is finalized in
https://github.com/saltstack-formulas/template-formula/blob/fd8430b203101eee8d124f5734ba678e71ac3e11/TEMPLATE/libmatchers.jinja#L146C1-L162C17
Why is only the config.get handled?
I don't know the history of the section which sets
query_opts
https://github.com/saltstack-formulas/template-formula/blob/fd8430b203101eee8d124f5734ba678e71ac3e11/TEMPLATE/libmatchers.jinja#L164C1-L188C17
I can understand why the
ssh
/unknown
cli flag are handled.handling only config.get is likely done to apply the
config_get_strategy
option.The argument
merge
(line 167) is not exclusive forconfig.get
, but since in line 201default=[]
is set,merge
is only effective forconfig.get
. I think that's whyconfig.get
withconfig_get_strategy
was handled.Proposal
I believe,
query_opts
should containdelimiter
in the default case, and should only be emptied whencli
is in"ssh", "unknown"
.This could be done in different fashions, for example one of these:
else
case in line 185 as shown in the patch at the top of this issue.Testing
I think, it would be useful to include nested metadata as edge cases in the test-pipelines. but this would require to extend the config and test files.
For example,
the kitchen.yml would further include test-only parameters such as
test/salt/TEMPLATE/parameters/nested:pillar/value.yml
. Thetest/salt/pillar/defaults.sls
would include an additional nested key structure, including the respective mapdata renderings.The text was updated successfully, but these errors were encountered: