Remove puppet and salt

This commit is contained in:
Miguel Jacq 2026-06-25 16:54:23 +10:00
parent 88e9dba39a
commit e9d7d74445
Signed by: mig5
GPG key ID: 03906B4110AAD3B8
24 changed files with 256 additions and 7714 deletions

View file

@ -48,7 +48,6 @@ def test_cli_manifest_subcommand_calls_manifest(monkeypatch, tmp_path):
called["fqdn"] = kwargs.get("fqdn")
called["jinjaturtle"] = kwargs.get("jinjaturtle")
called["no_common_roles"] = kwargs.get("no_common_roles")
called["target"] = kwargs.get("target")
monkeypatch.setattr(cli, "manifest", fake_manifest)
monkeypatch.setattr(
@ -70,7 +69,6 @@ def test_cli_manifest_subcommand_calls_manifest(monkeypatch, tmp_path):
assert called["fqdn"] is None
assert called["jinjaturtle"] == "auto"
assert called["no_common_roles"] is False
assert called["target"] == "ansible"
def test_cli_force_unsafe_path_before_subcommand_reaches_guard(monkeypatch, tmp_path):
@ -131,36 +129,6 @@ def test_cli_force_unsafe_path_after_subcommand_reaches_guard(monkeypatch, tmp_p
assert seen["force"] is True
def test_cli_manifest_target_puppet_is_forwarded(monkeypatch, tmp_path):
called = {}
def fake_manifest(harvest_dir: str, out_dir: str, **kwargs):
called["harvest"] = harvest_dir
called["out"] = out_dir
called["target"] = kwargs.get("target")
monkeypatch.setattr(cli, "manifest", fake_manifest)
monkeypatch.setattr(
sys,
"argv",
[
"enroll",
"manifest",
"--harvest",
str(tmp_path / "bundle"),
"--out",
str(tmp_path / "puppet"),
"--target",
"puppet",
],
)
cli.main()
assert called["harvest"] == str(tmp_path / "bundle")
assert called["out"] == str(tmp_path / "puppet")
assert called["target"] == "puppet"
def test_cli_manifest_no_common_roles_is_forwarded(monkeypatch, tmp_path):
called = {}

View file

@ -1025,7 +1025,7 @@ def test_report_markdown_with_enforcement_failed():
},
}
result = _report_markdown(report)
assert "ansible-playbook failed" in result
assert "but failed" in result
def test_report_markdown_with_enforcement_skipped():
@ -1378,7 +1378,7 @@ def test_report_text_with_enforcement_applied():
}
result = d._report_text(report)
assert "Enforcement" in result
assert "applied old harvest via ansible-playbook" in result
assert "applied old harvest" in result
assert "tags=test" in result
@ -1398,7 +1398,7 @@ def test_report_text_with_enforcement_failed():
}
result = d._report_text(report)
assert "Enforcement" in result
assert "ansible-playbook failed" in result
assert "failed" in result
def test_report_text_with_enforcement_skipped():

View file

@ -218,18 +218,6 @@ def test_diff_exclude_path_only_filters_files_not_packages(tmp_path: Path):
assert report["packages"]["added"] == ["htop"]
def test_enforce_old_harvest_requires_ansible_playbook(monkeypatch, tmp_path: Path):
import enroll.diff as d
monkeypatch.setattr(d.shutil, "which", lambda name: None)
old = tmp_path / "old"
_write_bundle(old, {"inventory": {"packages": {}}, "roles": _minimal_roles()})
with pytest.raises(RuntimeError, match="ansible-playbook not found"):
d.enforce_old_harvest(str(old))
def test_enforce_old_harvest_runs_ansible_with_tags_from_file_drift(
monkeypatch, tmp_path: Path
):
@ -310,121 +298,6 @@ def test_enforce_old_harvest_runs_ansible_with_tags_from_file_drift(
assert "role_usr_local_custom" in str(argv[i + 1])
def test_enforce_old_harvest_runs_puppet_target(monkeypatch, tmp_path: Path):
import enroll.diff as d
import enroll.manifest as mf
monkeypatch.setattr(
d.shutil,
"which",
lambda name: "/usr/bin/puppet" if name == "puppet" else None,
)
calls: dict[str, object] = {}
def fake_manifest(_harvest_dir: str, out_dir: str, **kwargs):
calls["manifest_target"] = kwargs.get("target")
out = Path(out_dir)
(out / "manifests").mkdir(parents=True)
(out / "modules").mkdir(parents=True)
(out / "manifests" / "site.pp").write_text(
"node default { }\n", encoding="utf-8"
)
monkeypatch.setattr(mf, "manifest", fake_manifest)
def fake_run(
argv, cwd=None, env=None, capture_output=False, text=False, check=False
):
calls["argv"] = list(argv)
calls["cwd"] = cwd
return types.SimpleNamespace(returncode=0, stdout="ok", stderr="")
monkeypatch.setattr(d.subprocess, "run", fake_run)
old = tmp_path / "old"
_write_bundle(old, {"inventory": {"packages": {}}, "roles": _minimal_roles()})
report = {
"packages": {"added": [], "removed": ["curl"], "version_changed": []},
"services": {"enabled_added": [], "enabled_removed": [], "changed": []},
"users": {"added": [], "removed": [], "changed": []},
"files": {"added": [], "removed": [], "changed": []},
}
info = d.enforce_old_harvest(str(old), report=report, target="puppet")
assert info["status"] == "applied"
assert info["target"] == "puppet"
assert info["tool"] == "puppet apply"
assert info["scope"] == "full_manifest"
assert info["tags"] == []
assert calls["manifest_target"] == "puppet"
argv = calls.get("argv")
assert argv and argv[:2] == ["/usr/bin/puppet", "apply"]
assert "--modulepath" in argv
assert any(
str(Path(calls["cwd"]) / "manifest" / "manifests" / "site.pp") == str(a)
for a in argv
)
def test_enforce_old_harvest_runs_salt_target(monkeypatch, tmp_path: Path):
import enroll.diff as d
import enroll.manifest as mf
monkeypatch.setattr(
d.shutil,
"which",
lambda name: "/usr/bin/salt-call" if name == "salt-call" else None,
)
calls: dict[str, object] = {}
def fake_manifest(_harvest_dir: str, out_dir: str, **kwargs):
calls["manifest_target"] = kwargs.get("target")
out = Path(out_dir)
(out / "states").mkdir(parents=True)
(out / "states" / "top.sls").write_text("base:\n '*': []\n", encoding="utf-8")
monkeypatch.setattr(mf, "manifest", fake_manifest)
def fake_run(
argv, cwd=None, env=None, capture_output=False, text=False, check=False
):
calls["argv"] = list(argv)
calls["cwd"] = cwd
return types.SimpleNamespace(returncode=0, stdout="ok", stderr="")
monkeypatch.setattr(d.subprocess, "run", fake_run)
old = tmp_path / "old"
_write_bundle(old, {"inventory": {"packages": {}}, "roles": _minimal_roles()})
report = {
"packages": {"added": [], "removed": ["curl"], "version_changed": []},
"services": {"enabled_added": [], "enabled_removed": [], "changed": []},
"users": {"added": [], "removed": [], "changed": []},
"files": {"added": [], "removed": [], "changed": []},
}
info = d.enforce_old_harvest(str(old), report=report, target="salt")
assert info["status"] == "applied"
assert info["target"] == "salt"
assert info["tool"] == "salt-call"
assert info["scope"] == "full_manifest"
assert calls["manifest_target"] == "salt"
argv = calls.get("argv")
assert argv and argv[0] == "/usr/bin/salt-call"
assert "--local" in argv
assert "--file-root" in argv
assert "state.apply" in argv
assert str(Path(calls["cwd"]) / "manifest" / "states") in argv
def test_cli_diff_enforce_forwards_target(monkeypatch):
import enroll.cli as cli
@ -458,17 +331,38 @@ def test_cli_diff_enforce_forwards_target(monkeypatch):
"--new",
"/tmp/new",
"--enforce",
"--target",
"puppet",
],
)
cli.main()
assert calls["old"] == "/tmp/old"
assert calls["target"] == "puppet"
assert calls["report"] is report
def test_cli_diff_enforce_rejects_non_ansible_target(monkeypatch):
"""Salt and Puppet targets have been removed from --enforce."""
import enroll.cli as cli
monkeypatch.setattr(
sys,
"argv",
[
"enroll",
"diff",
"--old",
"/tmp/old",
"--new",
"/tmp/new",
"--enforce",
"--target",
"puppet",
],
)
with pytest.raises(SystemExit):
cli.main()
def test_cli_diff_forwards_exclude_and_ignore_flags(monkeypatch, capsys):
import enroll.cli as cli

View file

@ -136,7 +136,7 @@ def test_ansible_static_marks_harvested_jinja_values_unsafe(tmp_path: Path):
payload = "{{ lookup('pipe','touch /tmp/PWNED_BY_ENROLL_ANSIBLE') }}"
write_schema_state(bundle, _ansible_jinja_payload_state(payload))
manifest.manifest(str(bundle), str(out), target="ansible")
manifest.manifest(str(bundle), str(out))
defaults = out / "roles" / "users" / "defaults" / "main.yml"
text = defaults.read_text(encoding="utf-8")
@ -152,7 +152,7 @@ def test_ansible_fqdn_marks_harvested_jinja_values_unsafe(tmp_path: Path):
payload = "{{ lookup('pipe','touch /tmp/PWNED_BY_ENROLL_ANSIBLE') }}"
write_schema_state(bundle, _ansible_jinja_payload_state(payload))
manifest.manifest(str(bundle), str(out), target="ansible", fqdn="host.example.test")
manifest.manifest(str(bundle), str(out), fqdn="host.example.test")
hostvars = out / "inventory" / "host_vars" / "host.example.test" / "users.yml"
text = hostvars.read_text(encoding="utf-8")

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,74 @@
"""Regression test: safe-mode content sniff must catch URI-embedded credentials
and HTTP Authorization headers, not just assignment-style credential keys."""
from enroll.ignore import IgnorePolicy
def test_uri_embedded_credentials_denied():
pol = IgnorePolicy(dangerous=False)
leaking = [
b"DATABASE_URL=postgresql://admin:S3cr3tPass@db:5432/app\n",
b"REDIS_URL=redis://:mypassword@localhost:6379/0\n",
b"broker_url = amqp://guest:guest@rabbit:5672//\n",
b"uri: mongodb+srv://user:p%40ss@cluster0.mongodb.net\n",
]
for data in leaking:
assert (
pol._content_deny_reason("/etc/svc/app.conf", data) == "sensitive_content"
), data
def test_authorization_headers_denied():
pol = IgnorePolicy(dangerous=False)
for data in [
b"Authorization: Bearer eyJhbGciOiJIUzI1NiIs\n",
b"Authorization: Basic dXNlcjpwYXNzd29yZA==\n",
b"Proxy-Authorization: Bearer xyz\n",
]:
assert (
pol._content_deny_reason("/etc/svc/app.conf", data) == "sensitive_content"
), data
def test_benign_urls_not_false_positive():
pol = IgnorePolicy(dangerous=False)
for data in [
b"homepage = https://example.com/docs\n",
b"server = http://localhost:8080/api\n",
b"origin = git://github.com/u/repo.git\n",
b"bind = http://[::1]:9000/\n",
b"contact = mailto:admin@example.com\n",
b"log_level = info\nworkers = 4\n",
]:
assert pol._content_deny_reason("/etc/svc/app.conf", data) is None, data
def test_bare_word_password_denied():
"""Credential lines using the word password/passphrase/credentials without
an assignment delimiter (netrc, ppp, space/tab separated) must be denied."""
pol = IgnorePolicy(dangerous=False)
for data in [
b"machine api.example.com login bob password s3cret\n",
b"passphrase mysecretphrase\n",
b"credentials /run/creds/db\n",
]:
assert (
pol._content_deny_reason("/etc/svc.conf", data) == "sensitive_content"
), data
def test_ppp_secrets_paths_denied():
pol = IgnorePolicy(dangerous=False)
for p in ("/etc/ppp/chap-secrets", "/etc/ppp/pap-secrets", "/etc/ppp/my-secrets"):
assert pol._path_deny_reason(p) == "denied_path", p
def test_password_keyword_no_false_positives():
pol = IgnorePolicy(dangerous=False)
for data in [
b"passive_mode = true\n",
b"PassengerRoot /usr/lib\n",
b"description = reset the account\n",
b"compression = gzip\n",
]:
assert pol._content_deny_reason("/etc/app.conf", data) is None, data