# -*- coding: utf-8 -*- # vim: ft=jinja {#- Get the `tplroot` from `tpldir` #} {%- set tplroot = tpldir.split("/")[0] %} {%- from tplroot ~ "/libmatchers.jinja" import parse_matchers, query_map %} {#- Where to lookup parameters source files #} {%- set map_sources_dir = tplroot ~ "/parameters" %} {#- List of sources to lookup for parameters #} {#- Fallback to previously used grains plus minion `id` #} {%- set map_sources = [ "Y:G@osarch", "Y:G@os_family", "Y:G@os", "Y:G@osfinger", "C@" ~ tplroot ~ ":lookup", "C@" ~ tplroot, "Y:G@id", ] %} {%- do salt["log.debug"]( "map.jinja: built-in configuration sources:\n" ~ {"values": { "map_jinja": {"sources": map_sources} } } | yaml(False) ) %} {#- Allow centralised map.jinja configuration #} {%- set _global_map_filename = "parameters/map_jinja.yaml" %} {%- do salt["log.debug"]( "map.jinja: load global map.jinja values from " ~ _global_map_filename ) %} {%- load_yaml as global_map_settings %} {%- include _global_map_filename ignore missing %} {%- endload %} {%- if global_map_settings %} {%- do salt["log.debug"]( "map.jinja: configure sources from global map.jinja configuration " ~ _global_map_filename ~ ":\n" ~ {"map_jinja": global_map_settings} | yaml(False) ) %} {%- set map_sources = global_map_settings | traverse( "values:sources", map_sources, ) %} {%- endif %} {#- Allow per formula map.jinja configuration #} {%- set _map_filename = map_sources_dir ~ "/map_jinja.yaml" %} {%- do salt["log.debug"]( "map.jinja: load per formula map.jinja values from " ~ _map_filename ) %} {%- load_yaml as map_settings %} {%- include _map_filename ignore missing %} {%- endload %} {%- if map_settings %} {%- do salt["log.debug"]( "map.jinja: configure sources from formula map.jinja configuration " ~ _map_filename ~ ":\n" ~ {"map_jinja": map_settings} | yaml(False) ) %} {%- set map_sources = map_settings | traverse( "values:sources", map_sources, ) %} {%- endif %} {%- do salt["log.debug"]( "map.jinja: load parameters from sources:\n" ~ map_sources | yaml(False) ) %} {#- Load formula defaults values #} {%- set _defaults_filename = map_sources_dir ~ "/defaults.yaml" %} {%- do salt["log.debug"]( "map.jinja: load per formula default values from " ~ _defaults_filename ) %} {%- load_yaml as default_settings %} {%- include _defaults_filename ignore missing %} {%- endload %} {%- if not default_settings %} {%- set default_settings = {'values': {} } %} {%- endif %} {#- Make sure to track `map.jinja` configuration with `_mapdata` #} {%- do default_settings["values"].update( { "map_jinja": map_settings | traverse("values", {}) } ) %} {#- Work around assignment inside for loop #} {#- load configuration values used in `config.get` merging strategies #} {%- set _config = { "stack": default_settings.get("values", {}), "merge_strategy": salt["config.get"](tplroot ~ ":strategy", None), "merge_lists": salt["config.get"](tplroot ~ ":merge_lists", False), } %} {#- `parse_matchers` returns a `list` of `dict` with #} {#- - type: `F` to load file, `C`, `G`, `I` for lookup #} {#- - option: specific to the type #} {#- - query: which key is requested #} {#- - query_method: the salt method doing the query `config.get`, `pillar.get` and `grains.get` #} {#- - value: the result of the `salt[]()` #} {%- set map_matchers = parse_matchers( matchers=map_sources, config_get_strategy=_config["merge_strategy"], log_prefix="map.jinja: " ) | load_yaml %} {%- for matcher in map_matchers %} {%- if matcher.type in query_map.keys() %} {#- Merge in `mapdata.` instead of directcly in `mapdata` #} {%- set is_sub_key = matcher.option | default(False) == "SUB" %} {#- `slsutil.merge` defaults to `smart` instead of `None` for `config.get` #} {%- set _strategy = _config["merge_strategy"] | default("smart", boolean=True) %} {%- do salt["log.debug"]( "map.jinja: merge " ~ "sub key " * is_sub_key ~ "'" ~ matcher.query ~ "' retrieved with '" ~ matcher.query_method ~ "', merge: strategy='" ~ _strategy ~ "', lists='" ~ _config["merge_lists"] ~ "'" ) %} {#- empty value is an empty list, it must be an empty dict for `.update` #} {%- set value = matcher.value | default({}, boolean=True) %} {%- if is_sub_key %} {#- Merge values with `mapdata.`, `` and `:lookup` are merged together #} {%- set value = { matcher.query | regex_replace("(:lookup)?$", ""): value } %} {%- endif %} {%- do _config.update( { "stack": salt["slsutil.merge"]( _config["stack"], value, strategy=_strategy, merge_lists=_config["merge_lists"], ) } ) %} {%- else %} {#- Load YAML file matching the grain/pillar/... #} {#- Fallback to use the source name as a direct filename #} {#- Mangle `source_key` to use it as literal path #} {%- if matcher.value | length == 0 %} {%- set query_parts = matcher.query.split("/") %} {%- set map_dirname = query_parts[0:-1] | join("/") %} {%- set map_values = query_parts[-1] | regex_replace("(\.yaml)?$", ".yaml") %} {%- else %} {%- set map_dirname = matcher.query %} {%- set map_values = matcher.value %} {%- endif %} {#- Some configuration return list #} {%- if map_values is string %} {%- set map_values = [map_values] %} {%- endif %} {#- `map_dirname` can be an empty string with literal path like `myconf.yaml` #} {%- set yaml_dir = [ map_sources_dir, map_dirname ] | select | join("/") %} {%- for map_value in map_values %} {%- set yamlfile = [ yaml_dir, map_value ~ ".yaml" ] | join("/") %} {%- do salt["log.debug"]("map.jinja: load parameters from file " ~ yamlfile) %} {%- load_yaml as loaded_values %} {%- include yamlfile ignore missing %} {%- endload %} {%- if loaded_values %} {#- Merge loaded values on the stack #} {%- do salt["log.debug"]("map.jinja: merge parameters from " ~ yamlfile) %} {%- do _config.update( { "stack": salt["slsutil.merge"]( _config["stack"], loaded_values.get("values", {}), strategy=loaded_values.get("strategy", "smart"), merge_lists=loaded_values.get("merge_lists", False) | to_bool, ) } ) %} {%- endif %} {%- endfor %} {%- endif %} {%- endfor %} {%- do salt["log.debug"]("map.jinja: save parameters in variable 'mapdata'") %} {%- set mapdata = _config["stack"] %}