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

Explicity pass context for salt-ssh state calls #63184

Merged
merged 2 commits into from
Dec 8, 2022
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
1 change: 1 addition & 0 deletions changelog/60003.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix salt-ssh when using imports with extra-filerefs.
24 changes: 15 additions & 9 deletions salt/client/ssh/wrapper/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ def highstate(test=None, **kwargs):
context=__context__.value(),
) as st_:
st_.push_active()
chunks = st_.compile_low_chunks()
chunks = st_.compile_low_chunks(context=__context__.value())
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(
Expand Down Expand Up @@ -768,7 +768,7 @@ def top(topfn, test=None, **kwargs):
) as st_:
st_.opts["state_top"] = os.path.join("salt://", topfn)
st_.push_active()
chunks = st_.compile_low_chunks()
chunks = st_.compile_low_chunks(context=__context__.value())
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(
Expand Down Expand Up @@ -840,7 +840,7 @@ def show_highstate(**kwargs):
context=__context__.value(),
) as st_:
st_.push_active()
chunks = st_.compile_highstate()
chunks = st_.compile_highstate(context=__context__.value())
_cleanup_slsmod_high_data(chunks)
return chunks

Expand All @@ -865,7 +865,7 @@ def show_lowstate(**kwargs):
context=__context__.value(),
) as st_:
st_.push_active()
chunks = st_.compile_low_chunks()
chunks = st_.compile_low_chunks(context=__context__.value())
_cleanup_slsmod_low_data(chunks)
return chunks

Expand Down Expand Up @@ -932,7 +932,9 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):

split_mods = _parse_mods(mods)
st_.push_active()
high_, errors = st_.render_highstate({opts["saltenv"]: split_mods})
high_, errors = st_.render_highstate(
{opts["saltenv"]: split_mods}, context=__context__.value()
)
errors += st_.state.verify_high(high_)
# Apply requisites to high data
high_, req_in_errors = st_.state.requisite_in(high_)
Expand Down Expand Up @@ -988,7 +990,9 @@ def show_sls(mods, saltenv="base", test=None, **kwargs):
) as st_:
st_.push_active()
mods = _parse_mods(mods)
high_data, errors = st_.render_highstate({saltenv: mods})
high_data, errors = st_.render_highstate(
{saltenv: mods}, context=__context__.value()
)
high_data, ext_errors = st_.state.reconcile_extend(high_data)
errors += ext_errors
errors += st_.state.verify_high(high_data)
Expand All @@ -1015,7 +1019,7 @@ def show_low_sls(mods, saltenv="base", test=None, **kwargs):

.. code-block:: bash

salt '*' state.show_sls core,edit.vim dev
salt '*' state.show_low_sls core,edit.vim dev
"""
__pillar__.update(kwargs.get("pillar", {}))
__opts__["grains"] = __grains__.value()
Expand All @@ -1034,7 +1038,9 @@ def show_low_sls(mods, saltenv="base", test=None, **kwargs):
) as st_:
st_.push_active()
mods = _parse_mods(mods)
high_data, errors = st_.render_highstate({saltenv: mods})
high_data, errors = st_.render_highstate(
{saltenv: mods}, context=__context__.value()
)
high_data, ext_errors = st_.state.reconcile_extend(high_data)
errors += ext_errors
errors += st_.state.verify_high(high_data)
Expand Down Expand Up @@ -1070,7 +1076,7 @@ def show_top(**kwargs):
__context__["fileclient"],
context=__context__.value(),
) as st_:
top_data = st_.get_top()
top_data = st_.get_top(context=__context__.value())
errors = []
errors += st_.verify_tops(top_data)
if errors:
Expand Down
27 changes: 17 additions & 10 deletions salt/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -3775,7 +3775,7 @@ def _get_envs(self):
envs.extend([env for env in client_envs if env not in envs])
return envs

def get_tops(self):
def get_tops(self, context=None):
"""
Gather the top files
"""
Expand Down Expand Up @@ -3806,6 +3806,7 @@ def get_tops(self):
self.state.opts["renderer_blacklist"],
self.state.opts["renderer_whitelist"],
saltenv=self.opts["saltenv"],
context=context,
)
]
else:
Expand All @@ -3831,6 +3832,7 @@ def get_tops(self):
self.state.opts["renderer_blacklist"],
self.state.opts["renderer_whitelist"],
saltenv=saltenv,
context=context,
)
)
else:
Expand Down Expand Up @@ -3887,6 +3889,7 @@ def get_tops(self):
self.state.opts["renderer_blacklist"],
self.state.opts["renderer_whitelist"],
saltenv,
context=context,
)
)
done[saltenv].append(sls)
Expand Down Expand Up @@ -4137,12 +4140,12 @@ def verify_tops(self, tops):

return errors

def get_top(self):
def get_top(self, context=None):
"""
Returns the high data derived from the top file
"""
try:
tops = self.get_tops()
tops = self.get_tops(context=context)
except SaltRenderError as err:
log.error("Unable to render top file: %s", err.error)
return {}
Expand Down Expand Up @@ -4379,7 +4382,11 @@ def render_state(self, sls, saltenv, mods, matches, local=False, context=None):
mod_tgt = "{}:{}".format(r_env, sls_target)
if mod_tgt not in mods:
nstate, err = self.render_state(
sls_target, r_env, mods, matches
sls_target,
r_env,
mods,
matches,
context=context,
)
if nstate:
self.merge_included_states(state, nstate, errors)
Expand Down Expand Up @@ -4761,30 +4768,30 @@ def call_highstate(

return self.state.call_high(high, orchestration_jid)

def compile_highstate(self):
def compile_highstate(self, context=None):
"""
Return just the highstate or the errors
"""
err = []
top = self.get_top()
top = self.get_top(context=context)
err += self.verify_tops(top)
matches = self.top_matches(top)
high, errors = self.render_highstate(matches)
high, errors = self.render_highstate(matches, context=context)
err += errors

if err:
return err

return high

def compile_low_chunks(self):
def compile_low_chunks(self, context=None):
"""
Compile the highstate but don't run it, return the low chunks to
see exactly what the highstate will execute
"""
top = self.get_top()
top = self.get_top(context=context)
matches = self.top_matches(top)
high, errors = self.render_highstate(matches)
high, errors = self.render_highstate(matches, context=context)

# If there is extension data reconcile it
high, ext_errors = self.state.reconcile_extend(high)
Expand Down
98 changes: 97 additions & 1 deletion tests/pytests/integration/ssh/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@pytest.fixture(scope="module")
def state_tree(base_env_state_tree_root_dir):
top_file = """
{%- from "map.jinja" import abc with context %}
base:
'localhost':
- basic
Expand All @@ -21,7 +22,6 @@ def state_tree(base_env_state_tree_root_dir):
"""
state_file = """
{%- from "map.jinja" import abc with context %}

Ok with {{ abc }}:
test.succeed_without_changes
"""
Expand All @@ -34,6 +34,42 @@ def state_tree(base_env_state_tree_root_dir):
state_tempfile = pytest.helpers.temp_file(
"test.sls", state_file, base_env_state_tree_root_dir
)
with top_tempfile, map_tempfile, state_tempfile:
yield


@pytest.fixture(scope="module")
def state_tree_dir(base_env_state_tree_root_dir):
"""
State tree with files to test salt-ssh
when the map.jinja file is in another directory
"""
top_file = """
{%- from "test/map.jinja" import abc with context %}
base:
'localhost':
- test
'127.0.0.1':
- test
"""
map_file = """
{%- set abc = "def" %}
"""
state_file = """
{%- from "test/map.jinja" import abc with context %}

Ok with {{ abc }}:
test.succeed_without_changes
"""
top_tempfile = pytest.helpers.temp_file(
"top.sls", top_file, base_env_state_tree_root_dir
)
map_tempfile = pytest.helpers.temp_file(
"test/map.jinja", map_file, base_env_state_tree_root_dir
)
state_tempfile = pytest.helpers.temp_file(
"test.sls", state_file, base_env_state_tree_root_dir
)

with top_tempfile, map_tempfile, state_tempfile:
yield
Expand All @@ -49,6 +85,66 @@ def test_state_with_import(salt_ssh_cli, state_tree):
assert ret.data


@pytest.mark.parametrize(
"ssh_cmd",
[
"state.sls",
"state.highstate",
"state.apply",
"state.show_top",
"state.show_highstate",
"state.show_low_sls",
"state.show_lowstate",
"state.sls_id",
"state.show_sls",
"state.top",
],
)
@pytest.mark.slow_test
def test_state_with_import_dir(salt_ssh_cli, state_tree_dir, ssh_cmd):
"""
verify salt-ssh can use imported map files in states
when the map files are in another directory outside of
sls files importing them.
"""
if ssh_cmd in ("state.sls", "state.show_low_sls", "state.show_sls"):
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "test")
elif ssh_cmd == "state.top":
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "top.sls")
elif ssh_cmd == "state.sls_id":
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd, "Ok with def", "test")
else:
ret = salt_ssh_cli.run("-w", "-t", ssh_cmd)
assert ret.returncode == 0
if ssh_cmd == "state.show_top":
assert ret.data == {"base": ["test", "master_tops_test"]} or {"base": ["test"]}
elif ssh_cmd in ("state.show_highstate", "state.show_sls"):
assert ret.data == {
"Ok with def": {
"__sls__": "test",
"__env__": "base",
"test": ["succeed_without_changes", {"order": 10000}],
}
}
elif ssh_cmd in ("state.show_low_sls", "state.show_lowstate", "state.show_sls"):
assert ret.data == [
{
"state": "test",
"name": "Ok with def",
"__sls__": "test",
"__env__": "base",
"__id__": "Ok with def",
"order": 10000,
"fun": "succeed_without_changes",
}
]
else:
assert ret.data["test_|-Ok with def_|-Ok with def_|-succeed_without_changes"][
"result"
]
assert ret.data


@pytest.fixture
def nested_state_tree(base_env_state_tree_root_dir, tmp_path):
top_file = """
Expand Down