From 56440620404e184ea40fe24c06eba064114d171d Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 19 Jun 2026 19:12:26 +1000 Subject: [PATCH 1/3] 0.7.0b2 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7bbc181..6acb29a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "enroll" -version = "0.7.0b1" +version = "0.7.0b2" description = "Enroll a server's running state retrospectively into Ansible" authors = ["Miguel Jacq "] license = "GPL-3.0-or-later" From d6371ccccdc03e0c67c470799c7960f26d4e0469 Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 19 Jun 2026 20:18:19 +1000 Subject: [PATCH 2/3] Fixes for ensuring /etc/enroll exists if /etc/enroll/firewall is to be created --- enroll/puppet.py | 17 +++++++------- enroll/salt.py | 17 +++++++------- tests/test_manifest_puppet.py | 43 +++++++++++++++++++++++++++++++++++ tests/test_manifest_salt.py | 41 +++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 18 deletions(-) diff --git a/enroll/puppet.py b/enroll/puppet.py index 55a8288..d8a1179 100644 --- a/enroll/puppet.py +++ b/enroll/puppet.py @@ -832,15 +832,14 @@ def _collect_puppet_roles( str(p).strip() for p in (fw.get("packages") or []) if str(p).strip() ] if has_fw or packages or fw.get("notes"): - if has_fw: - runtime_role = ensure_role("enroll_runtime") - runtime_role.add_managed_dir( - "/etc/enroll", - owner="root", - group="root", - mode="0750", - reason="enroll_runtime", - ) + runtime_role = ensure_role("enroll_runtime") + runtime_role.add_managed_dir( + "/etc/enroll", + owner="root", + group="root", + mode="0750", + reason="enroll_runtime", + ) role_name = str(fw.get("role_name") or "firewall_runtime") prole = ensure_role(role_name) prole.add_firewall_runtime_snapshot( diff --git a/enroll/salt.py b/enroll/salt.py index 97fbe97..e407b78 100644 --- a/enroll/salt.py +++ b/enroll/salt.py @@ -888,15 +888,14 @@ def _collect_salt_roles( str(p).strip() for p in (fw.get("packages") or []) if str(p).strip() ] if has_fw or packages or fw.get("notes"): - if has_fw: - runtime_role = ensure_role("enroll_runtime") - runtime_role.add_managed_dir( - "/etc/enroll", - user="root", - group="root", - mode="0750", - reason="enroll_runtime", - ) + runtime_role = ensure_role("enroll_runtime") + runtime_role.add_managed_dir( + "/etc/enroll", + user="root", + group="root", + mode="0750", + reason="enroll_runtime", + ) role_name = str(fw.get("role_name") or "firewall_runtime") srole = ensure_role(role_name) srole.add_firewall_runtime_snapshot( diff --git a/tests/test_manifest_puppet.py b/tests/test_manifest_puppet.py index fd2fa7e..467dfb0 100644 --- a/tests/test_manifest_puppet.py +++ b/tests/test_manifest_puppet.py @@ -798,3 +798,46 @@ def test_manifest_puppet_renders_firewall_runtime_resources(tmp_path: Path): ).read_text(encoding="utf-8") assert "Hash $firewall_runtime = {}" in fqdn_pp assert "$firewall_runtime['ipset_restore_cmd']" in fqdn_pp + + +def test_manifest_puppet_includes_enroll_runtime_for_firewall_notes_only( + tmp_path: Path, +): + bundle = tmp_path / "bundle" + out = tmp_path / "puppet" + state = { + "schema_version": 3, + "host": {"hostname": "test", "os": "debian", "pkg_backend": "dpkg"}, + "inventory": {"packages": {}}, + "roles": { + "firewall_runtime": { + "role_name": "firewall_runtime", + "packages": [], + "ipset_save": None, + "ipset_sets": [], + "iptables_v4_save": None, + "iptables_v6_save": None, + "notes": [ + "not running as root; live firewall runtime was not captured" + ], + } + }, + } + _write_state(bundle, state) + + manifest.manifest(str(bundle), str(out), target="puppet") + + site_pp = (out / "manifests" / "site.pp").read_text(encoding="utf-8") + assert "include enroll_runtime" in site_pp + assert "include firewall_runtime" in site_pp + assert site_pp.index("include enroll_runtime") < site_pp.index( + "include firewall_runtime" + ) + runtime_pp = ( + out / "modules" / "enroll_runtime" / "manifests" / "init.pp" + ).read_text(encoding="utf-8") + firewall_pp = ( + out / "modules" / "firewall_runtime" / "manifests" / "init.pp" + ).read_text(encoding="utf-8") + assert "file { '/etc/enroll':" in runtime_pp + assert "require => File['/etc/enroll']," in firewall_pp diff --git a/tests/test_manifest_salt.py b/tests/test_manifest_salt.py index 1fa6804..75b6942 100644 --- a/tests/test_manifest_salt.py +++ b/tests/test_manifest_salt.py @@ -624,3 +624,44 @@ def test_manifest_salt_renders_firewall_runtime_states(tmp_path: Path): fqdn_out / "states" / "roles" / "firewall_runtime" / "init.sls" ).read_text(encoding="utf-8") assert "firewall_runtime.get('ipset_restore_cmd')" in fqdn_sls + + +def test_manifest_salt_includes_enroll_runtime_for_firewall_notes_only(tmp_path: Path): + bundle = tmp_path / "bundle" + out = tmp_path / "salt" + state = { + "schema_version": 3, + "host": {"hostname": "test", "os": "debian", "pkg_backend": "dpkg"}, + "inventory": {"packages": {}}, + "roles": { + "firewall_runtime": { + "role_name": "firewall_runtime", + "packages": [], + "ipset_save": None, + "ipset_sets": [], + "iptables_v4_save": None, + "iptables_v6_save": None, + "notes": [ + "not running as root; live firewall runtime was not captured" + ], + } + }, + } + _write_state(bundle, state) + + manifest.manifest(str(bundle), str(out), target="salt") + + top = yaml.safe_load((out / "states" / "top.sls").read_text(encoding="utf-8")) + assert "roles.enroll_runtime" in top["base"]["*"] + assert "roles.firewall_runtime" in top["base"]["*"] + assert top["base"]["*"].index("roles.enroll_runtime") < top["base"]["*"].index( + "roles.firewall_runtime" + ) + runtime_sls = (out / "states" / "roles" / "enroll_runtime" / "init.sls").read_text( + encoding="utf-8" + ) + firewall_sls = ( + out / "states" / "roles" / "firewall_runtime" / "init.sls" + ).read_text(encoding="utf-8") + assert '"/etc/enroll":' in runtime_sls + assert '- file: "/etc/enroll"' in firewall_sls From 7379587a282f72538c2e7163888084ce84b6b24f Mon Sep 17 00:00:00 2001 From: Miguel Jacq Date: Fri, 19 Jun 2026 20:29:12 +1000 Subject: [PATCH 3/3] Don't enforce /etc/enroll if no firewall rules to set in subdir --- enroll/puppet.py | 5 +---- enroll/salt.py | 5 +---- pyproject.toml | 2 +- tests/test_manifest_puppet.py | 19 +++++-------------- tests/test_manifest_salt.py | 21 +++++++-------------- 5 files changed, 15 insertions(+), 37 deletions(-) diff --git a/enroll/puppet.py b/enroll/puppet.py index d8a1179..0e8a08a 100644 --- a/enroll/puppet.py +++ b/enroll/puppet.py @@ -828,10 +828,7 @@ def _collect_puppet_roles( or fw.get("iptables_v4_save") or fw.get("iptables_v6_save") ) - packages = [ - str(p).strip() for p in (fw.get("packages") or []) if str(p).strip() - ] - if has_fw or packages or fw.get("notes"): + if has_fw: runtime_role = ensure_role("enroll_runtime") runtime_role.add_managed_dir( "/etc/enroll", diff --git a/enroll/salt.py b/enroll/salt.py index e407b78..3e860b8 100644 --- a/enroll/salt.py +++ b/enroll/salt.py @@ -884,10 +884,7 @@ def _collect_salt_roles( or fw.get("iptables_v4_save") or fw.get("iptables_v6_save") ) - packages = [ - str(p).strip() for p in (fw.get("packages") or []) if str(p).strip() - ] - if has_fw or packages or fw.get("notes"): + if has_fw: runtime_role = ensure_role("enroll_runtime") runtime_role.add_managed_dir( "/etc/enroll", diff --git a/pyproject.toml b/pyproject.toml index 6acb29a..c24c6d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "enroll" -version = "0.7.0b2" +version = "0.7.0b3" description = "Enroll a server's running state retrospectively into Ansible" authors = ["Miguel Jacq "] license = "GPL-3.0-or-later" diff --git a/tests/test_manifest_puppet.py b/tests/test_manifest_puppet.py index 467dfb0..8f367f7 100644 --- a/tests/test_manifest_puppet.py +++ b/tests/test_manifest_puppet.py @@ -800,7 +800,7 @@ def test_manifest_puppet_renders_firewall_runtime_resources(tmp_path: Path): assert "$firewall_runtime['ipset_restore_cmd']" in fqdn_pp -def test_manifest_puppet_includes_enroll_runtime_for_firewall_notes_only( +def test_manifest_puppet_omits_firewall_runtime_when_no_rules_were_sampled( tmp_path: Path, ): bundle = tmp_path / "bundle" @@ -828,16 +828,7 @@ def test_manifest_puppet_includes_enroll_runtime_for_firewall_notes_only( manifest.manifest(str(bundle), str(out), target="puppet") site_pp = (out / "manifests" / "site.pp").read_text(encoding="utf-8") - assert "include enroll_runtime" in site_pp - assert "include firewall_runtime" in site_pp - assert site_pp.index("include enroll_runtime") < site_pp.index( - "include firewall_runtime" - ) - runtime_pp = ( - out / "modules" / "enroll_runtime" / "manifests" / "init.pp" - ).read_text(encoding="utf-8") - firewall_pp = ( - out / "modules" / "firewall_runtime" / "manifests" / "init.pp" - ).read_text(encoding="utf-8") - assert "file { '/etc/enroll':" in runtime_pp - assert "require => File['/etc/enroll']," in firewall_pp + assert "include enroll_runtime" not in site_pp + assert "include firewall_runtime" not in site_pp + assert not (out / "modules" / "enroll_runtime").exists() + assert not (out / "modules" / "firewall_runtime").exists() diff --git a/tests/test_manifest_salt.py b/tests/test_manifest_salt.py index 75b6942..1418258 100644 --- a/tests/test_manifest_salt.py +++ b/tests/test_manifest_salt.py @@ -626,7 +626,9 @@ def test_manifest_salt_renders_firewall_runtime_states(tmp_path: Path): assert "firewall_runtime.get('ipset_restore_cmd')" in fqdn_sls -def test_manifest_salt_includes_enroll_runtime_for_firewall_notes_only(tmp_path: Path): +def test_manifest_salt_omits_firewall_runtime_when_no_rules_were_sampled( + tmp_path: Path, +): bundle = tmp_path / "bundle" out = tmp_path / "salt" state = { @@ -652,16 +654,7 @@ def test_manifest_salt_includes_enroll_runtime_for_firewall_notes_only(tmp_path: manifest.manifest(str(bundle), str(out), target="salt") top = yaml.safe_load((out / "states" / "top.sls").read_text(encoding="utf-8")) - assert "roles.enroll_runtime" in top["base"]["*"] - assert "roles.firewall_runtime" in top["base"]["*"] - assert top["base"]["*"].index("roles.enroll_runtime") < top["base"]["*"].index( - "roles.firewall_runtime" - ) - runtime_sls = (out / "states" / "roles" / "enroll_runtime" / "init.sls").read_text( - encoding="utf-8" - ) - firewall_sls = ( - out / "states" / "roles" / "firewall_runtime" / "init.sls" - ).read_text(encoding="utf-8") - assert '"/etc/enroll":' in runtime_sls - assert '- file: "/etc/enroll"' in firewall_sls + assert "roles.enroll_runtime" not in top["base"]["*"] + assert "roles.firewall_runtime" not in top["base"]["*"] + assert not (out / "states" / "roles" / "enroll_runtime").exists() + assert not (out / "states" / "roles" / "firewall_runtime").exists()