Support dynamic pillar_root environment

Allow users to specify a __env__ pillar_root directory that applies
equally to all environments that are not explicitly specified.

fixes #20581
Signed-off-by: Benjamin Drung <benjamin.drung@profitbricks.com>
This commit is contained in:
Benjamin Drung 2018-03-02 11:14:35 +01:00
parent 2bad0a21c0
commit 584b451fd1
3 changed files with 58 additions and 0 deletions

View file

@ -168,6 +168,28 @@ And the actual pillar file at '/srv/pillar/common_pillar.sls':
context.
Dynamic Pillar Environments
===========================
If environment ``__env__`` is specified in :conf_master:`pillar_roots`, all
environments that are not explicitly specified in :conf_master:`pillar_roots`
will map to the directories from ``__env__``. This allows one to use dynamic
git branch based environments for state/pillar files with the same file-based
pillar applying to all environments. For example:
.. code-block:: yaml
pillar_roots:
__env__:
- /srv/pillar
ext_pillar:
- git:
- __env__ https://example.com/git-pillar.git
.. versionadded:: 2017.7.5,2018.3.1
Pillar Namespace Flattening
===========================

View file

@ -374,6 +374,15 @@ class Pillar(object):
opts['ext_pillar'].append(self.ext)
else:
opts['ext_pillar'] = [self.ext]
if '__env__' in opts['file_roots']:
env = opts.get('pillarenv') or opts.get('saltenv') or 'base'
if env not in opts['file_roots']:
log.debug("pillar environment '%s' maps to __env__ pillar_roots directory", env)
opts['file_roots'][env] = opts['file_roots'].pop('__env__')
else:
log.debug("pillar_roots __env__ ignored (environment '%s' found in pillar_roots)",
env)
opts['file_roots'].pop('__env__')
return opts
def _get_envs(self):

View file

@ -49,6 +49,33 @@ class PillarTestCase(TestCase):
self.assertEqual(pillar.opts['environment'], 'dev')
self.assertEqual(pillar.opts['pillarenv'], 'dev')
def test_dynamic_pillarenv(self):
opts = {
'renderer': 'json',
'renderer_blacklist': [],
'renderer_whitelist': [],
'state_top': '',
'pillar_roots': {'__env__': '/srv/pillar/__env__', 'base': '/srv/pillar/base'},
'file_roots': {'base': '/srv/salt/base', 'dev': '/svr/salt/dev'},
'extension_modules': '',
}
pillar = salt.pillar.Pillar(opts, {}, 'mocked-minion', 'base', pillarenv='dev')
self.assertEqual(pillar.opts['file_roots'],
{'base': '/srv/pillar/base', 'dev': '/srv/pillar/__env__'})
def test_ignored_dynamic_pillarenv(self):
opts = {
'renderer': 'json',
'renderer_blacklist': [],
'renderer_whitelist': [],
'state_top': '',
'pillar_roots': {'__env__': '/srv/pillar/__env__', 'base': '/srv/pillar/base'},
'file_roots': {'base': '/srv/salt/base', 'dev': '/svr/salt/dev'},
'extension_modules': '',
}
pillar = salt.pillar.Pillar(opts, {}, 'mocked-minion', 'base', pillarenv='base')
self.assertEqual(pillar.opts['file_roots'], {'base': '/srv/pillar/base'})
def test_malformed_pillar_sls(self):
with patch('salt.pillar.compile_template') as compile_template:
opts = {