diff --git a/pillar.example b/pillar.example index bd2241a50..24d8fa31c 100644 --- a/pillar.example +++ b/pillar.example @@ -46,7 +46,32 @@ salt: salt_minion_pkg_source: 'https://repo.saltstack.com/osx/salt-2017.7.4-py3-x86_64.pkg' salt_minion_pkg_hash: 'https://repo.saltstack.com/osx/salt-2017.7.4-py3-x86_64.pkg.md5' + # tofs: + # The files_switch key serves as a selector for alternative + # directories under the formula files directory. See TOFS pattern + # doc for more info. + # Note: Any value not evaluated by `config.get` will be used literally. + # This can be used to set custom paths, as many levels deep as required. + # files_switch: + # - any/path/can/be/used/here + # - id + # - osfinger + # - os + # - os_family + # All aspects of path/file resolution are customisable using the options below. + # This is unnecessary in most cases; there are sensible defaults. + # path_prefix: template_alt + # dirs: + # files: files_alt + # default: default_alt + # source_files: + # salt-master: + # - 'alt_master.d' + # salt-minion: + # - 'alt_minion.d' + # salt master config + master_config_use_TOFS: True master: fileserver_backend: - git @@ -127,6 +152,7 @@ salt: - /srv/salt/reactors/deploy.sls # salt minion config: + minion_config_use_TOFS: True minion: # single master setup diff --git a/salt/defaults.yaml b/salt/defaults.yaml index 12e22f87d..44ea3aa4b 100644 --- a/salt/defaults.yaml +++ b/salt/defaults.yaml @@ -10,6 +10,8 @@ salt: minion_remove_config: False master_remove_config: False + minion_config_use_TOFS: False + master_config_use_TOFS: False minion_service: salt-minion master_service: salt-master diff --git a/salt/files/default/master.d/engine.conf b/salt/files/default/master.d/engine.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/master.d/engine.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/master.d/f_defaults.conf b/salt/files/default/master.d/f_defaults.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/master.d/f_defaults.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/master.d/lxc_profiles.conf b/salt/files/default/master.d/lxc_profiles.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/master.d/lxc_profiles.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/master.d/reactor.conf b/salt/files/default/master.d/reactor.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/master.d/reactor.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/minion.d/beacons.conf b/salt/files/default/minion.d/beacons.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/minion.d/beacons.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/minion.d/engine.conf b/salt/files/default/minion.d/engine.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/minion.d/engine.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/minion.d/f_defaults.conf b/salt/files/default/minion.d/f_defaults.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/minion.d/f_defaults.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/files/default/minion.d/reactor.conf b/salt/files/default/minion.d/reactor.conf new file mode 100644 index 000000000..d57d388b0 --- /dev/null +++ b/salt/files/default/minion.d/reactor.conf @@ -0,0 +1,4 @@ +######################################################################## +## File managed by Salt. +## Your changes will be overwritten. +######################################################################## diff --git a/salt/libtofs.jinja b/salt/libtofs.jinja new file mode 100644 index 000000000..da656a5e9 --- /dev/null +++ b/salt/libtofs.jinja @@ -0,0 +1,101 @@ +{%- macro files_switch(source_files, + lookup=None, + default_files_switch=['id', 'os_family'], + indent_width=6, + v1_path_prefix='') %} + {#- + 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 override + 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 + use as selector switch of the directories under + "/files" + * indent_witdh: indentation of the result value to conform to YAML + * v1_path_prefix: (deprecated) only used for injecting a path prefix into + the source, to support older TOFS configs + + 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' + ) }} + - 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 + - source: + - salt://xxx/files/theminion/etc/yyy/zzz.conf + - salt://xxx/files/theminion/etc/yyy/zzz.conf.jinja + - salt://xxx/files/RedHat/etc/yyy/zzz.conf + - salt://xxx/files/RedHat/etc/yyy/zzz.conf.jinja + - 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 source_files parameter #} + {%- set src_files = salt['config.get']( + tplroot ~ ':tofs:source_files:' ~ lookup, + salt['config.get']( + tplroot ~ ':tofs:files:' ~ lookup, + source_files + ) + ) %} + {#- Only add to [''] when supporting older TOFS implementations #} + {%- set path_prefix_exts = [''] %} + {%- if v1_path_prefix != '' %} + {%- do path_prefix_exts.append(v1_path_prefix) %} + {%- endif %} + {%- for path_prefix_ext in path_prefix_exts %} + {%- 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 %} + {%- do fsl.append('') %} + {%- endif %} + {%- for fs in fsl %} + {%- for src_file in src_files %} + {%- if fs %} + {%- set fs_dir = salt['config.get'](fs, fs) %} + {%- else %} + {%- set fs_dir = salt['config.get'](tplroot ~ ':tofs:dirs:default', 'default') %} + {%- endif %} + {%- 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 %} +{%- endmacro %} diff --git a/salt/master.sls b/salt/master.sls index d20c0b83b..4a23ccabd 100644 --- a/salt/master.sls +++ b/salt/master.sls @@ -1,4 +1,6 @@ -{% from "salt/map.jinja" import salt_settings with context %} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import salt_settings with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} salt-master: {% if salt_settings.install_packages %} @@ -14,8 +16,16 @@ salt-master: {% endif %} file.recurse: - name: {{ salt_settings.config_path }}/master.d + {%- if salt_settings.master_config_use_TOFS %} + - template: '' + - source: {{ files_switch(['master.d'], + lookup='salt-master' + ) + }} + {%- else %} - template: jinja - source: salt://{{ slspath }}/files/master.d + {%- endif %} - clean: {{ salt_settings.clean_config_d_dir }} - exclude_pat: _* service.running: diff --git a/salt/minion.sls b/salt/minion.sls index 6022fe97b..391defa74 100644 --- a/salt/minion.sls +++ b/salt/minion.sls @@ -1,4 +1,6 @@ -{% from "salt/map.jinja" import salt_settings with context %} +{%- set tplroot = tpldir.split('/')[0] %} +{%- from tplroot ~ "/map.jinja" import salt_settings with context %} +{%- from tplroot ~ "/libtofs.jinja" import files_switch with context %} {% if salt_settings.install_packages and grains.os == 'MacOS' and salt_settings.salt_minion_pkg_source != '' and salt_settings.version != '' %} {# only download IF we know where to get the pkg from and if we know what version to check the current install (if installed) against #} @@ -45,12 +47,20 @@ salt-minion: {% endif %} file.recurse: - name: {{ salt_settings.config_path }}/minion.d + {%- if salt_settings.minion_config_use_TOFS %} + - template: '' + - source: {{ files_switch(['minion.d'], + lookup='salt-minion' + ) + }} + {%- else %} - template: jinja - source: salt://{{ slspath }}/files/minion.d - - clean: {{ salt_settings.clean_config_d_dir }} - - exclude_pat: _* - context: standalone: False + {%- endif %} + - clean: {{ salt_settings.clean_config_d_dir }} + - exclude_pat: _* service.running: - enable: True - name: {{ salt_settings.minion_service }}