Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reload matcher loader when ext_pillar_first set #52851

Merged
merged 2 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions salt/pillar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,20 @@ def get_top(self):
errors.append('Error encountered while rendering pillar top file.')
return merged_tops, errors

def top_matches(self, top):
def top_matches(self, top, reload=False):
'''
Search through the top high data for matches and return the states
that this minion needs to execute.

Returns:
{'saltenv': ['state1', 'state2', ...]}

reload
Reload the matcher loader
'''
matches = {}
if reload:
self.matchers = salt.loader.matchers(self.opts)
for saltenv, body in six.iteritems(top):
if self.opts['pillarenv']:
if saltenv != self.opts['pillarenv']:
Expand Down Expand Up @@ -1001,7 +1006,7 @@ def compile_pillar(self, ext=True):
if self.opts.get('ext_pillar_first', False):
self.opts['pillar'], errors = self.ext_pillar(self.pillar_override)
self.rend = salt.loader.render(self.opts, self.functions)
matches = self.top_matches(top)
matches = self.top_matches(top, reload=True)
pillar, errors = self.render_pillar(matches, errors=errors)
pillar = merge(
self.opts['pillar'],
Expand Down
67 changes: 67 additions & 0 deletions tests/unit/test_pillar.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,51 @@ def test_ext_pillar_with_extra_minion_data_val_elem(self):
'mocked-minion', 'fake_pillar', 'bar',
extra_minion_data={'fake_key': 'foo'})

def test_ext_pillar_first(self):
'''
test when using ext_pillar and ext_pillar_first
'''
opts = {
'optimization_order': [0, 1, 2],
'renderer': 'yaml',
'renderer_blacklist': [],
'renderer_whitelist': [],
'state_top': '',
'pillar_roots': [],
'extension_modules': '',
'saltenv': 'base',
'file_roots': [],
'ext_pillar_first': True,
}
grains = {
'os': 'Ubuntu',
'os_family': 'Debian',
'oscodename': 'raring',
'osfullname': 'Ubuntu',
'osrelease': '13.04',
'kernel': 'Linux'
}

tempdir = tempfile.mkdtemp(dir=TMP)
try:
sls_files = self._setup_test_topfile_sls_pillar_match(
tempdir,)
fc_mock = MockFileclient(
cache_file=sls_files['top']['dest'],
list_states=['top', 'ssh', 'ssh.minion',
'generic', 'generic.minion'],
get_state=sls_files)
with patch.object(salt.fileclient, 'get_file_client',
MagicMock(return_value=fc_mock)), \
patch('salt.pillar.Pillar.ext_pillar',
MagicMock(return_value=({'id': 'minion',
'phase': 'alpha', 'role':
'database'}, []))):
pillar = salt.pillar.Pillar(opts, grains, 'mocked-minion', 'base')
self.assertEqual(pillar.compile_pillar()['generic']['key1'], 'value1')
finally:
shutil.rmtree(tempdir, ignore_errors=True)

def test_dynamic_pillarenv(self):
opts = {
'optimization_order': [0, 1, 2],
Expand Down Expand Up @@ -581,6 +626,28 @@ def _run_test(nodegroup_order, glob_order, expected):
# precedence over glob match.
_run_test(nodegroup_order=2, glob_order=1, expected='foo')

def _setup_test_topfile_sls_pillar_match(self, tempdir):
# Write a simple topfile and two pillar state files
top_file = tempfile.NamedTemporaryFile(dir=tempdir, delete=False)
s = '''
base:
'phase:alpha':
- match: pillar
- generic
'''
top_file.write(salt.utils.stringutils.to_bytes(s))
top_file.flush()
generic_file = tempfile.NamedTemporaryFile(dir=tempdir, delete=False)
generic_file.write(b'''
generic:
key1: value1
''')
generic_file.flush()
return {
'top': {'path': '', 'dest': top_file.name},
'generic': {'path': '', 'dest': generic_file.name},
}

def _setup_test_topfile_sls(self, tempdir, nodegroup_order, glob_order):
# Write a simple topfile and two pillar state files
top_file = tempfile.NamedTemporaryFile(dir=tempdir, delete=False)
Expand Down