Skip to content

Commit d87b6c0

Browse files
committed
Merge pull request #2697 from tsclausing/xenv-include
#2683 - include state sls from any env which the minion matches in top
2 parents 80b2b16 + 1fa275f commit d87b6c0

File tree

1 file changed

+47
-10
lines changed

1 file changed

+47
-10
lines changed

salt/state.py

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,7 @@ def load_dynamic(self, matches):
14441444
faux = {'state': 'file', 'fun': 'recurse'}
14451445
self.state.module_refresh(faux)
14461446

1447-
def render_state(self, sls, env, mods):
1447+
def render_state(self, sls, env, mods, matches):
14481448
'''
14491449
Render a state file and retrieve all of the include states
14501450
'''
@@ -1475,21 +1475,58 @@ def render_state(self, sls, env, mods):
14751475
errors.append(err)
14761476
else:
14771477
for inc_sls in state.pop('include'):
1478-
if fnmatch.filter(self.avail[env], inc_sls):
1478+
# inc_sls may take the form of:
1479+
# 'sls.to.include' <- same as {<env>: 'sls.to.include'}
1480+
# {<env_key>: 'sls.to.include'}
1481+
# {'_xenv': 'sls.to.resolve'}
1482+
XENV_KEY = '_xenv'
1483+
1484+
if isinstance(inc_sls, dict):
1485+
env_key, inc_sls = inc_sls.popitem()
1486+
else:
1487+
env_key = env
1488+
1489+
if env_key != XENV_KEY:
1490+
# Resolve inc_sls in the specified environment
1491+
if env_key in matches and fnmatch.filter(self.avail[env_key], inc_sls):
1492+
resolved_envs = [env_key]
1493+
else:
1494+
resolved_envs = []
1495+
else:
1496+
# Resolve inc_sls in the subset of environment matches
1497+
resolved_envs = [
1498+
aenv for aenv in matches
1499+
if fnmatch.filter(self.avail[aenv], inc_sls)
1500+
]
1501+
1502+
# An include must be resolved to a single environment, or
1503+
# the include must exist in the current environment
1504+
if len(resolved_envs) == 1 or env in resolved_envs:
14791505
if inc_sls not in mods:
14801506
nstate, mods, err = self.render_state(
1481-
inc_sls,
1482-
env,
1483-
mods
1484-
)
1507+
inc_sls,
1508+
resolved_envs[0] if len(resolved_envs) == 1 else env,
1509+
mods,
1510+
matches
1511+
)
14851512
if nstate:
14861513
state.update(nstate)
14871514
if err:
14881515
errors += err
14891516
else:
1490-
msg = ('Specified SLS {0} in environment {1} '
1491-
'is not available on the salt master'
1492-
).format(inc_sls, env)
1517+
msg = ''
1518+
if not resolved_envs:
1519+
msg = ('Unknown include: Specified SLS {0}: {1} is not available on the salt '
1520+
'master in environment(s): {2} '
1521+
).format(env_key,
1522+
inc_sls,
1523+
', '.join(matches) if env_key == XENV_KEY else env_key)
1524+
elif len(resolved_envs) > 1:
1525+
msg = ('Ambiguous include: Specified SLS {0}: {1} is available on the salt master '
1526+
'in multiple available environments: {2}'
1527+
).format(env_key,
1528+
inc_sls,
1529+
', '.join(resolved_envs))
14931530
log.error(msg)
14941531
if self.opts['failhard']:
14951532
errors.append(msg)
@@ -1595,7 +1632,7 @@ def render_highstate(self, matches):
15951632
mods = set()
15961633
for sls_match in states:
15971634
for sls in fnmatch.filter(self.avail[env], sls_match):
1598-
state, mods, err = self.render_state(sls, env, mods)
1635+
state, mods, err = self.render_state(sls, env, mods, matches)
15991636
# The extend members can not be treated as globally unique:
16001637
if '__extend__' in state and '__extend__' in highstate:
16011638
highstate['__extend__'].extend(state.pop('__extend__'))

0 commit comments

Comments
 (0)