aboutsummaryrefslogtreecommitdiffstats
path: root/molecule/delete/tests/test_delete.py
diff options
context:
space:
mode:
Diffstat (limited to 'molecule/delete/tests/test_delete.py')
-rw-r--r--molecule/delete/tests/test_delete.py318
1 files changed, 318 insertions, 0 deletions
diff --git a/molecule/delete/tests/test_delete.py b/molecule/delete/tests/test_delete.py
new file mode 100644
index 0000000..4c0d859
--- /dev/null
+++ b/molecule/delete/tests/test_delete.py
@@ -0,0 +1,318 @@
+"""Tests for state: absent functionality."""
+
+import os
+
+
+testinfra_hosts = [
+ "borg-client-single-delete",
+ "borg-client-multi-delete",
+ "borg-client-per-repo-delete",
+ "borg-client-nonroot-delete",
+ "borg-client-never-delete",
+ "borg-server-delete",
+]
+
+
+def _scenario_file(filename):
+ scenario_dir = os.environ.get("MOLECULE_SCENARIO_DIRECTORY")
+ if scenario_dir:
+ return os.path.join(scenario_dir, filename)
+ test_dir = os.path.dirname(os.path.abspath(__file__))
+ return os.path.join(test_dir, "..", filename)
+
+
+def _read_local_file(filename):
+ with open(_scenario_file(filename), "r", encoding="utf-8") as file_handle:
+ return file_handle.read()
+
+
+class TestSingleRepoDelete:
+ def test_systemd_units_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-single-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@single-backup.timer")
+ service = host.file("/etc/systemd/system/borg_backup@single-backup.service")
+ assert not timer.exists
+ assert not service.exists
+
+ def test_backup_scripts_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-single-delete":
+ return
+
+ repo_script = host.file("/usr/local/bin/run_borg_backup@single-backup")
+ base_script = host.file("/usr/local/bin/run_borg_backup")
+ assert not repo_script.exists
+ assert not base_script.exists
+
+ def test_shared_ssh_key_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-single-delete":
+ return
+
+ key = host.file("/root/.ssh/id_rsa")
+ assert key.exists
+
+ def test_repository_data_deleted(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ repo = host.file("/opt/borg/single-backup")
+ assert not repo.exists
+
+ def test_authorized_keys_entry_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ auth_keys = host.file("/opt/borg/.ssh/authorized_keys")
+ assert auth_keys.exists
+ assert "root@borg-client-single-delete" not in auth_keys.content_string
+
+
+class TestMultiInstanceDelete:
+ def test_removed_repo_units_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-multi-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@multi-repo-a.timer")
+ service = host.file("/etc/systemd/system/borg_backup@multi-repo-a.service")
+ script = host.file("/usr/local/bin/run_borg_backup@multi-repo-a")
+ assert not timer.exists
+ assert not service.exists
+ assert not script.exists
+
+ def test_remaining_repo_artifacts_exist(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-multi-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@multi-repo-b.timer")
+ service = host.file("/etc/systemd/system/borg_backup@multi-repo-b.service")
+ script = host.file("/usr/local/bin/run_borg_backup@multi-repo-b")
+ assert timer.exists
+ assert service.exists
+ assert script.exists
+
+ def test_base_script_keeps_only_remaining_block(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-multi-delete":
+ return
+
+ base_script = host.file("/usr/local/bin/run_borg_backup")
+ assert base_script.exists
+ content = base_script.content_string
+ assert "/opt/borg/multi-repo-b" in content
+ assert "/opt/borg/multi-repo-a" not in content
+ assert content.count("borg create") == 1
+
+ def test_shared_ssh_key_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-multi-delete":
+ return
+
+ key = host.file("/root/.ssh/id_rsa")
+ assert key.exists
+
+ def test_repository_data_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ removed_repo = host.file("/opt/borg/multi-repo-a")
+ remaining_repo = host.file("/opt/borg/multi-repo-b")
+ assert removed_repo.exists
+ assert removed_repo.is_directory
+ assert remaining_repo.exists
+ assert remaining_repo.is_directory
+
+ def test_authorized_keys_keeps_only_remaining_repo(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ auth_keys = host.file("/opt/borg/.ssh/authorized_keys")
+ content = auth_keys.content_string
+ host_entries = [
+ line
+ for line in content.splitlines()
+ if "root@borg-client-multi-delete" in line
+ ]
+ assert len(host_entries) == 1
+ assert "--restrict-to-repository /opt/borg/multi-repo-b" in host_entries[0]
+ assert "--restrict-to-repository /opt/borg/multi-repo-a" not in host_entries[0]
+
+
+class TestPerRepoKeyDelete:
+ def test_removed_repo_artifacts_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-per-repo-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@per-repo-a.timer")
+ service = host.file("/etc/systemd/system/borg_backup@per-repo-a.service")
+ script = host.file("/usr/local/bin/run_borg_backup@per-repo-a")
+ assert not timer.exists
+ assert not service.exists
+ assert not script.exists
+
+ def test_remaining_repo_untouched(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-per-repo-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@per-repo-b.timer")
+ service = host.file("/etc/systemd/system/borg_backup@per-repo-b.service")
+ script = host.file("/usr/local/bin/run_borg_backup@per-repo-b")
+ base_script = host.file("/usr/local/bin/run_borg_backup")
+ assert timer.exists
+ assert service.exists
+ assert script.exists
+ assert base_script.exists
+ assert "/opt/borg/per-repo-b" in base_script.content_string
+ assert "/opt/borg/per-repo-a" not in base_script.content_string
+
+ def test_per_repo_ssh_key_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-per-repo-delete":
+ return
+
+ key = host.file(
+ "/root/.ssh/id_ed25519_borgbackup_borg_server_delete_per_repo_a"
+ )
+ key_pub = host.file(
+ "/root/.ssh/id_ed25519_borgbackup_borg_server_delete_per_repo_a.pub"
+ )
+ assert not key.exists
+ assert not key_pub.exists
+
+ def test_other_repo_ssh_key_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-per-repo-delete":
+ return
+
+ key = host.file(
+ "/root/.ssh/id_ed25519_borgbackup_borg_server_delete_per_repo_b"
+ )
+ key_pub = host.file(
+ "/root/.ssh/id_ed25519_borgbackup_borg_server_delete_per_repo_b.pub"
+ )
+ assert key.exists
+ assert key_pub.exists
+
+ def test_repository_data_deleted_and_remaining_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ removed_repo = host.file("/opt/borg/per-repo-a")
+ remaining_repo = host.file("/opt/borg/per-repo-b")
+ assert not removed_repo.exists
+ assert remaining_repo.exists
+
+ def test_authorized_keys_per_repo_entry_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ auth_keys = host.file("/opt/borg/.ssh/authorized_keys")
+ content = auth_keys.content_string
+ assert "--restrict-to-repository /opt/borg/per-repo-a" not in content
+ assert "--restrict-to-repository /opt/borg/per-repo-b" in content
+
+
+class TestNonRootDelete:
+ def test_removed_repo_artifacts_removed(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-nonroot-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@nonroot-a.timer")
+ service = host.file("/etc/systemd/system/borg_backup@nonroot-a.service")
+ script = host.file("/usr/local/bin/run_borg_backup@nonroot-a")
+ assert not timer.exists
+ assert not service.exists
+ assert not script.exists
+
+ def test_remaining_repo_and_shared_key_kept(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-nonroot-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@nonroot-b.timer")
+ service = host.file("/etc/systemd/system/borg_backup@nonroot-b.service")
+ script = host.file("/usr/local/bin/run_borg_backup@nonroot-b")
+ key = host.file("/home/backupuser/.ssh/id_rsa")
+ assert timer.exists
+ assert service.exists
+ assert script.exists
+ assert key.exists
+
+ def test_authorized_keys_preserves_nonroot_comment(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ auth_keys = host.file("/opt/borg/.ssh/authorized_keys")
+ content = auth_keys.content_string
+ host_entries = [
+ line
+ for line in content.splitlines()
+ if "backupuser@borg-client-nonroot-delete" in line
+ ]
+ assert len(host_entries) == 1
+ assert "root@borg-client-nonroot-delete" not in host_entries[0]
+ assert "--restrict-to-repository /opt/borg/nonroot-b" in host_entries[0]
+ assert "--restrict-to-repository /opt/borg/nonroot-a" not in host_entries[0]
+
+
+class TestDecryptionKeyCleanup:
+ def test_deleted_entries_removed_and_remaining_kept(self):
+ content = _read_local_file("decryption_keys_delete.yml")
+ assert "borg-client-single-delete_single-backup:" not in content
+ assert "borg-client-multi-delete_multi-repo-a:" not in content
+ assert "borg-client-per-repo-delete_per-repo-a:" not in content
+ assert "borg-client-nonroot-delete_nonroot-a:" not in content
+ assert "borg-client-multi-delete_multi-repo-b:" in content
+ assert "borg-client-per-repo-delete_per-repo-b:" in content
+ assert "borg-client-nonroot-delete_nonroot-b:" in content
+
+ def test_empty_decryption_keys_file_stays_valid(self):
+ content = _read_local_file("decryption_keys_empty_delete.yml")
+ assert content.strip() == "{}"
+
+
+class TestNeverConfiguredDelete:
+ def test_no_artifacts_created(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-client-never-delete":
+ return
+
+ timer = host.file("/etc/systemd/system/borg_backup@never-configured.timer")
+ service = host.file("/etc/systemd/system/borg_backup@never-configured.service")
+ script = host.file("/usr/local/bin/run_borg_backup@never-configured")
+ base_script = host.file("/usr/local/bin/run_borg_backup")
+ assert not timer.exists
+ assert not service.exists
+ assert not script.exists
+ assert not base_script.exists
+
+ def test_server_repo_not_created(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ repo = host.file("/opt/borg/never-configured")
+ assert not repo.exists
+
+ def test_no_authorized_keys_entry_created(self, host):
+ hostname = host.backend.get_hostname()
+ if hostname != "borg-server-delete":
+ return
+
+ auth_keys = host.file("/opt/borg/.ssh/authorized_keys")
+ assert "borg-client-never-delete" not in auth_keys.content_string