diff --git a/salt/libtofs.jinja b/salt/libtofs.jinja index 0668925..f39fd42 100644 --- a/salt/libtofs.jinja +++ b/salt/libtofs.jinja @@ -1,40 +1,37 @@ -{%- macro files_switch(source_files, - lookup=None, - default_files_switch=['id', 'os_family'], - indent_width=6, - use_subpath=False) %} - {#- +{%- macro files_switch( + source_files, + lookup=None, + default_files_switch=["id", "os_family"], + indent_width=6, + use_subpath=False + ) %} +{#- Returns a valid value for the "source" parameter of a "file.managed" state function. This makes easier the usage of the Template Override and Files Switch (TOFS) pattern. - Params: * source_files: ordered list of files to look for - * lookup: key under ':tofs:source_files' to prepend to the + * lookup: key under ":tofs:source_files" to prepend to the list of source files * default_files_switch: if there's no config (e.g. pillar) - ':tofs:files_switch' this is the ordered list of grains to + ":tofs:files_switch" this is the ordered list of grains to use as selector switch of the directories under "/files" * indent_width: indentation of the result value to conform to YAML * use_subpath: defaults to `False` but if set, lookup the source file recursively from the current state directory up to `tplroot` - Example (based on a `tplroot` of `xxx`): - If we have a state: - Deploy configuration: file.managed: - name: /etc/yyy/zzz.conf - - source: {{ files_switch(['/etc/yyy/zzz.conf', '/etc/yyy/zzz.conf.jinja'], - lookup='Deploy configuration' - ) }} + - source: {{ files_switch( + ["/etc/yyy/zzz.conf", "/etc/yyy/zzz.conf.jinja"], + lookup="Deploy configuration", + ) }} - template: jinja - In a minion with id=theminion and os_family=RedHat, it's going to be rendered as: - Deploy configuration: file.managed: - name: /etc/yyy/zzz.conf @@ -46,67 +43,73 @@ - salt://xxx/files/default/etc/yyy/zzz.conf - salt://xxx/files/default/etc/yyy/zzz.conf.jinja - template: jinja - #} - {#- Get the `tplroot` from `tpldir` #} - {%- set tplroot = tpldir.split('/')[0] %} - {%- set path_prefix = salt['config.get'](tplroot ~ ':tofs:path_prefix', tplroot) %} - {%- set files_dir = salt['config.get'](tplroot ~ ':tofs:dirs:files', 'files') %} - {%- set files_switch_list = salt['config.get']( - tplroot ~ ':tofs:files_switch', - default_files_switch - ) %} - {#- Lookup source_files (v2), files (v1), or fallback to an empty list #} - {%- set src_files = salt['config.get']( - tplroot ~ ':tofs:source_files:' ~ lookup, - salt['config.get'](tplroot ~ ':tofs:files:' ~ lookup, []) - ) %} - {#- Append the default source_files #} - {%- set src_files = src_files + source_files %} - {#- Only add to [''] when supporting older TOFS implementations #} - {%- set path_prefix_exts = [''] %} - {%- if use_subpath and tplroot != tpldir %} - {#- Walk directory tree to find {{ files_dir }} #} - {%- set subpath_parts = tpldir.lstrip(tplroot).lstrip('/').split('/') %} - {%- for path in subpath_parts %} - {%- set subpath = subpath_parts[0:loop.index] | join('/') %} - {%- do path_prefix_exts.append('/' ~ subpath) %} - {%- endfor %} - {%- endif %} - {%- for path_prefix_ext in path_prefix_exts|reverse %} - {%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %} - {#- For older TOFS implementation, use `files_switch` from the config #} - {#- Use the default, new method otherwise #} - {%- set fsl = salt['config.get']( - tplroot ~ path_prefix_ext|replace('/', ':') ~ ':files_switch', - files_switch_list - ) %} - {#- Append an empty value to evaluate as `default` in the loop below #} - {%- if '' not in fsl %} - {%- set fsl = fsl + [''] %} - {%- endif %} - {%- for fs in fsl %} - {%- for src_file in src_files %} - {%- if fs %} - {%- set fs_dirs = salt['config.get'](fs, fs) %} - {%- else %} - {%- set fs_dirs = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %} - {%- endif %} - {#- Force the `config.get` lookup result as a list where necessary #} - {#- since we need to also handle grains that are lists #} - {%- if fs_dirs is string %} - {%- set fs_dirs = [fs_dirs] %} - {%- endif %} - {%- for fs_dir in fs_dirs %} - {%- set url = [ - '- salt:/', - path_prefix_inc_ext.strip('/'), - files_dir.strip('/'), - fs_dir.strip('/'), - src_file.strip('/'), - ] | select | join('/') %} +#} +{#- Get the `tplroot` from `tpldir` #} +{%- set tplroot = tpldir.split("/")[0] %} +{%- set path_prefix = salt["config.get"](tplroot ~ ":tofs:path_prefix", tplroot) %} +{%- set files_dir = salt["config.get"](tplroot ~ ":tofs:dirs:files", "files") %} +{%- set files_switch_list = salt["config.get"]( + tplroot ~ ":tofs:files_switch", default_files_switch + ) %} +{#- Lookup source_files (v2), files (v1), or fallback to an empty list #} +{%- set src_files = salt["config.get"]( + tplroot ~ ":tofs:source_files:" ~ lookup, + salt["config.get"](tplroot ~ ":tofs:files:" ~ lookup, []), + ) %} +{#- Append the default source_files #} +{%- set src_files = src_files + source_files %} +{#- Only add to [""] when supporting older TOFS implementations #} +{%- set path_prefix_exts = [""] %} +{%- if use_subpath and tplroot != tpldir %} +{#- Walk directory tree to find {{ files_dir }} #} +{%- set subpath_parts = tpldir.lstrip(tplroot).lstrip("/").split("/") %} +{%- for path in subpath_parts %} +{%- set subpath = subpath_parts[0 : loop.index] | join("/") %} +{%- do path_prefix_exts.append("/" ~ subpath) %} +{%- endfor %} +{%- endif %} +{%- for path_prefix_ext in path_prefix_exts | reverse %} +{%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %} +{#- For older TOFS implementation, use `files_switch` from the config #} +{#- Use the default, new method otherwise #} +{%- set fsl = salt["config.get"]( + tplroot ~ path_prefix_ext | replace("/", ":") ~ ":files_switch", + files_switch_list, + ) %} +{#- Append an empty value to evaluate as `default` in the loop below #} +{%- if "" not in fsl %} +{%- set fsl = fsl + [""] %} +{%- endif %} +{%- for fs in fsl %} +{%- for src_file in src_files %} +{%- if fs %} +{%- set fs_dirs = salt["config.get"](fs, fs) %} +{%- else %} +{%- set fs_dirs = salt["config.get"]( + tplroot ~ ":tofs:dirs:default", "default" + ) %} +{%- endif %} +{#- Force the `config.get` lookup result as a list where necessary #} +{#- since we need to also handle grains that are lists #} +{%- if fs_dirs is string %} +{%- set fs_dirs = [fs_dirs] %} +{%- endif %} +{%- for fs_dir in fs_dirs %} +{#- strip empty elements by using a select #} +{%- set url = ( + [ + "- salt:/", + path_prefix_inc_ext.strip("/"), + files_dir.strip("/"), + fs_dir.strip("/"), + src_file.strip("/"), + ] + | select + | join("/") + ) %} {{ url | indent(indent_width, true) }} - {%- endfor %} - {%- endfor %} - {%- endfor %} - {%- endfor %} +{%- endfor %} +{%- endfor %} +{%- endfor %} +{%- endfor %} {%- endmacro %}