1 {%- macro files_switch(source_files,
3 default_files_switch=['id', 'os_family'],
7 Returns a valid value for the "source" parameter of a "file.managed"
8 state function. This makes easier the usage of the Template Override and
9 Files Switch (TOFS) pattern.
12 * source_files: ordered list of files to look for
13 * lookup: key under '<tplroot>:tofs:source_files' to prepend to the
15 * default_files_switch: if there's no config (e.g. pillar)
16 '<tplroot>:tofs:files_switch' this is the ordered list of grains to
17 use as selector switch of the directories under
19 * indent_width: indentation of the result value to conform to YAML
20 * use_subpath: defaults to `False` but if set, lookup the source file
21 recursively from the current state directory up to `tplroot`
23 Example (based on a `tplroot` of `xxx`):
29 - name: /etc/yyy/zzz.conf
30 - source: {{ files_switch(['/etc/yyy/zzz.conf', '/etc/yyy/zzz.conf.jinja'],
31 lookup='Deploy configuration'
35 In a minion with id=theminion and os_family=RedHat, it's going to be
40 - name: /etc/yyy/zzz.conf
42 - salt://xxx/files/theminion/etc/yyy/zzz.conf
43 - salt://xxx/files/theminion/etc/yyy/zzz.conf.jinja
44 - salt://xxx/files/RedHat/etc/yyy/zzz.conf
45 - salt://xxx/files/RedHat/etc/yyy/zzz.conf.jinja
46 - salt://xxx/files/default/etc/yyy/zzz.conf
47 - salt://xxx/files/default/etc/yyy/zzz.conf.jinja
50 {#- Get the `tplroot` from `tpldir` #}
51 {%- set tplroot = tpldir.split('/')[0] %}
52 {%- set path_prefix = salt['config.get'](tplroot ~ ':tofs:path_prefix', tplroot) %}
53 {%- set files_dir = salt['config.get'](tplroot ~ ':tofs:dirs:files', 'files') %}
54 {%- set files_switch_list = salt['config.get'](
55 tplroot ~ ':tofs:files_switch',
58 {#- Lookup source_files (v2), files (v1), or fallback to an empty list #}
59 {%- set src_files = salt['config.get'](
60 tplroot ~ ':tofs:source_files:' ~ lookup,
61 salt['config.get'](tplroot ~ ':tofs:files:' ~ lookup, [])
63 {#- Append the default source_files #}
64 {%- set src_files = src_files + source_files %}
65 {#- Only add to [''] when supporting older TOFS implementations #}
66 {%- set path_prefix_exts = [''] %}
67 {%- if use_subpath and tplroot != tpldir %}
68 {#- Walk directory tree to find {{ files_dir }} #}
69 {%- set subpath_parts = tpldir.lstrip(tplroot).lstrip('/').split('/') %}
70 {%- for path in subpath_parts %}
71 {%- set subpath = subpath_parts[0:loop.index] | join('/') %}
72 {%- do path_prefix_exts.append('/' ~ subpath) %}
75 {%- for path_prefix_ext in path_prefix_exts|reverse %}
76 {%- set path_prefix_inc_ext = path_prefix ~ path_prefix_ext %}
77 {#- For older TOFS implementation, use `files_switch` from the config #}
78 {#- Use the default, new method otherwise #}
79 {%- set fsl = salt['config.get'](
80 tplroot ~ path_prefix_ext|replace('/', ':') ~ ':files_switch',
83 {#- Append an empty value to evaluate as `default` in the loop below #}
84 {%- if '' not in fsl %}
85 {%- set fsl = fsl + [''] %}
88 {%- for src_file in src_files %}
90 {%- set fs_dirs = salt['config.get'](fs, fs) %}
92 {%- set fs_dirs = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %}
94 {#- Force the `config.get` lookup result as a list where necessary #}
95 {#- since we need to also handle grains that are lists #}
96 {%- if fs_dirs is string %}
97 {%- set fs_dirs = [fs_dirs] %}
99 {%- for fs_dir in fs_dirs %}
102 path_prefix_inc_ext.strip('/'),
103 files_dir.strip('/'),
106 ] | select | join('/') %}
107 {{ url | indent(indent_width, true) }}