forked from saltstack/salt
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix salt-ssh master access during pillar rendering
This also ports saltstack#50489 into the present
- Loading branch information
Showing
4 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Fixed gpg pillar rendering with salt-ssh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
238 changes: 238 additions & 0 deletions
238
tests/pytests/integration/ssh/test_pillar_compilation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
import logging | ||
import pathlib | ||
import shutil | ||
import subprocess | ||
import textwrap | ||
|
||
import pytest | ||
from pytestshellutils.utils.processes import ProcessResult | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
# The following fixtures are copied from pytests/functional/pillar/test_gpg.py | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def test_key(): | ||
""" | ||
Private key for setting up GPG pillar environment. | ||
""" | ||
return textwrap.dedent( | ||
"""\ | ||
-----BEGIN PGP PRIVATE KEY BLOCK----- | ||
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 | ||
=06Tz | ||
-----END PGP PRIVATE KEY BLOCK----- | ||
""" | ||
) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def gpg_pillar_yaml(): | ||
""" | ||
Yaml data for testing GPG pillar. | ||
""" | ||
return textwrap.dedent( | ||
""" | ||
#!yaml|gpg | ||
secrets: | ||
foo: | | ||
-----BEGIN PGP MESSAGE----- | ||
hQEMAw2B674HRhwSAQgAhTrN8NizwUv/VunVrqa4/X8t6EUulrnhKcSeb8sZS4th | ||
W1Qz3K2NjL4lkUHCQHKZVx/VoZY7zsddBIFvvoGGfj8+2wjkEDwFmFjGE4DEsS74 | ||
ZLRFIFJC1iB/O0AiQ+oU745skQkU6OEKxqavmKMrKo3rvJ8ZCXDC470+i2/Hqrp7 | ||
+KWGmaDOO422JaSKRm5D9bQZr9oX7KqnrPG9I1+UbJyQSJdsdtquPWmeIpamEVHb | ||
VMDNQRjSezZ1yKC4kCWm3YQbBF76qTHzG1VlLF5qOzuGI9VkyvlMaLfMibriqY73 | ||
zBbPzf6Bkp2+Y9qyzuveYMmwS4sEOuZL/PetqisWe9JGAWD/O+slQ2KRu9hNww06 | ||
KMDPJRdyj5bRuBVE4hHkkP23KrYr7SuhW2vpe7O/MvWEJ9uDNegpMLhTWruGngJh | ||
iFndxegN9w== | ||
=bAuo | ||
-----END PGP MESSAGE----- | ||
""" | ||
) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def gpg_homedir(salt_master, test_key): | ||
""" | ||
Setup gpg environment | ||
""" | ||
_gpg_homedir = pathlib.Path(salt_master.config_dir) / "gpgkeys" | ||
_gpg_homedir.mkdir(0o700) | ||
agent_started = False | ||
try: | ||
cmd_prefix = ["gpg", "--homedir", str(_gpg_homedir)] | ||
|
||
cmd = cmd_prefix + ["--list-keys"] | ||
proc = subprocess.run( | ||
cmd, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT, | ||
check=True, | ||
universal_newlines=True, | ||
) | ||
ret = ProcessResult( | ||
returncode=proc.returncode, | ||
stdout=proc.stdout, | ||
stderr=proc.stderr or "", | ||
cmdline=proc.args, | ||
) | ||
log.debug("Instantiating gpg keyring...\n%s", ret) | ||
|
||
cmd = cmd_prefix + ["--import", "--allow-secret-key-import"] | ||
proc = subprocess.run( | ||
cmd, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT, | ||
check=True, | ||
universal_newlines=True, | ||
input=test_key, | ||
) | ||
ret = ProcessResult( | ||
returncode=proc.returncode, | ||
stdout=proc.stdout, | ||
stderr=proc.stderr or "", | ||
cmdline=proc.args, | ||
) | ||
log.debug("Importing keypair...:\n%s", ret) | ||
|
||
agent_started = True | ||
|
||
yield _gpg_homedir | ||
finally: | ||
if agent_started: | ||
try: | ||
cmd = ["gpg-connect-agent", "--homedir", str(_gpg_homedir)] | ||
proc = subprocess.run( | ||
cmd, | ||
stdout=subprocess.PIPE, | ||
stderr=subprocess.STDOUT, | ||
check=True, | ||
universal_newlines=True, | ||
input="KILLAGENT", | ||
) | ||
ret = ProcessResult( | ||
returncode=proc.returncode, | ||
stdout=proc.stdout, | ||
stderr=proc.stderr or "", | ||
cmdline=proc.args, | ||
) | ||
log.debug("Killed gpg-agent...\n%s", ret) | ||
except (OSError, subprocess.CalledProcessError): | ||
log.debug("No need to kill: old gnupg doesn't start the agent.") | ||
shutil.rmtree(str(_gpg_homedir), ignore_errors=True) | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def pillar_setup(base_env_pillar_tree_root_dir, gpg_pillar_yaml, salt_minion): | ||
""" | ||
Setup gpg pillar | ||
""" | ||
saltutil_contents = f""" | ||
saltutil: {{{{ salt["saltutil.runner"]("mine.get", tgt="{salt_minion.id}", fun="test.ping") | json }}}} | ||
""" | ||
top_file_contents = """ | ||
base: | ||
'*': | ||
- gpg | ||
- saltutil | ||
""" | ||
with pytest.helpers.temp_file( | ||
"top.sls", top_file_contents, base_env_pillar_tree_root_dir | ||
), pytest.helpers.temp_file( | ||
"gpg.sls", gpg_pillar_yaml, base_env_pillar_tree_root_dir | ||
), pytest.helpers.temp_file( | ||
"saltutil.sls", saltutil_contents, base_env_pillar_tree_root_dir | ||
): | ||
yield | ||
|
||
|
||
@pytest.mark.skip_if_binaries_missing("gpg") | ||
@pytest.mark.usefixtures("pillar_setup", "gpg_homedir") | ||
def test_gpg_pillar(salt_ssh_cli): | ||
""" | ||
Ensure that GPG-encrypted pillars can be decrypted, i.e. the | ||
gpg_keydir should not be overridden. This is issue #60002, | ||
which has the same cause as the one below. | ||
""" | ||
ret = salt_ssh_cli.run("pillar.items") | ||
assert ret.returncode == 0 | ||
assert isinstance(ret.data, dict) | ||
assert ret.data | ||
assert "secrets" in ret.data | ||
assert "foo" in ret.data["secrets"] | ||
assert "BEGIN PGP MESSAGE" not in ret.data["secrets"]["foo"] | ||
|
||
|
||
@pytest.mark.usefixtures("pillar_setup") | ||
def test_saltutil_runner(salt_ssh_cli, salt_minion, salt_run_cli): | ||
""" | ||
Ensure that during pillar compilation, the cache dir is not | ||
overridden. For a history, see PR #50489 and issue #36796, | ||
notice that the initial description is probably unrelated | ||
to this. | ||
""" | ||
ret = salt_ssh_cli.run("pillar.items") | ||
assert ret.returncode == 0 | ||
assert isinstance(ret.data, dict) | ||
assert ret.data | ||
assert "saltutil" in ret.data | ||
assert isinstance(ret.data["saltutil"], dict) | ||
assert ret.data["saltutil"] | ||
assert salt_minion.id in ret.data["saltutil"] | ||
assert ret.data["saltutil"][salt_minion.id] is True |