"""Tests for client setup configuration""" import pytest testinfra_hosts = [ "borg-client", "borg-client-2", "borg-client-multi", "borg-client-nonroot", "borg-client-multi-keys", ] CLIENT_USER_MAP = { "borg-client": "root", "borg-client-2": "root", "borg-client-multi": "root", "borg-client-nonroot": "backupuser", "borg-client-multi-keys": "root", } CLIENT_SSH_KEY_TYPE_MAP = { "borg-client": "rsa", "borg-client-2": "ed25519", "borg-client-multi": "rsa", "borg-client-nonroot": "rsa", "borg-client-multi-keys": "ed25519", } CLIENT_SSH_KEY_PER_REPO_MAP = { "borg-client": False, "borg-client-2": False, "borg-client-multi": False, "borg-client-nonroot": False, "borg-client-multi-keys": True, } def get_client_user(host): hostname = host.backend.get_hostname() return CLIENT_USER_MAP.get(hostname, "root") def get_client_ssh_key_type(host): hostname = host.backend.get_hostname() return CLIENT_SSH_KEY_TYPE_MAP.get(hostname, "rsa") def get_client_ssh_key_per_repo(host): hostname = host.backend.get_hostname() return CLIENT_SSH_KEY_PER_REPO_MAP.get(hostname, False) def get_client_home(host): user = get_client_user(host) return f"/home/{user}" if user != "root" else "/root" class TestSSHSetup: def test_ssh_directory_exists(self, host): client_home = get_client_home(host) client_user = get_client_user(host) ssh_dir = host.file(f"{client_home}/.ssh") assert ssh_dir.exists assert ssh_dir.is_directory assert ssh_dir.user == client_user assert ssh_dir.group == client_user assert ssh_dir.mode == 0o700 def test_ssh_private_key_exists(self, host): client_home = get_client_home(host) client_user = get_client_user(host) key_type = get_client_ssh_key_type(host) per_repo = get_client_ssh_key_per_repo(host) hostname = host.backend.get_hostname() if per_repo and hostname == "borg-client-multi-keys": key1 = host.file( f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys" ) key2 = host.file( f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys" ) assert key1.exists assert key1.user == client_user assert key1.group == client_user assert key1.mode == 0o600 assert key2.exists assert key2.user == client_user assert key2.group == client_user assert key2.mode == 0o600 else: key = host.file(f"{client_home}/.ssh/id_{key_type}") assert key.exists assert key.user == client_user assert key.group == client_user assert key.mode == 0o600 def test_ssh_public_key_exists(self, host): client_home = get_client_home(host) client_user = get_client_user(host) key_type = get_client_ssh_key_type(host) per_repo = get_client_ssh_key_per_repo(host) hostname = host.backend.get_hostname() if per_repo and hostname == "borg-client-multi-keys": key1 = host.file( f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_configs_keys.pub" ) key2 = host.file( f"{client_home}/.ssh/id_{key_type}_borgbackup_borg_server_home_data_keys.pub" ) assert key1.exists assert key1.user == client_user assert key1.group == client_user assert key2.exists assert key2.user == client_user assert key2.group == client_user else: key = host.file(f"{client_home}/.ssh/id_{key_type}.pub") assert key.exists assert key.user == client_user assert key.group == client_user def test_known_hosts_contains_borg_server(self, host): client_home = get_client_home(host) known_hosts = host.file(f"{client_home}/.ssh/known_hosts") assert known_hosts.exists assert known_hosts.contains("borg-server") class TestBackupScript: def test_backup_script_exists(self, host): hostname = host.backend.get_hostname() client_user = get_client_user(host) if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.exists assert script1.user == client_user assert script1.group == client_user assert script1.mode == 0o711 assert script2.exists assert script2.user == client_user assert script2.group == client_user assert script2.mode == 0o711 elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.exists assert script1.user == client_user assert script1.group == client_user assert script1.mode == 0o711 assert script2.exists assert script2.user == client_user assert script2.group == client_user assert script2.mode == 0o711 elif hostname == "borg-client-nonroot": script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.exists assert script.user == client_user assert script.group == client_user assert script.mode == 0o711 elif hostname in ("borg-client", "borg-client-2"): script = host.file("/usr/local/bin/run_borg_backup") assert script.exists assert script.user == client_user assert script.group == client_user assert script.mode == 0o711 else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_borg_command(self, host): hostname = host.backend.get_hostname() if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.contains("borg create") assert script2.contains("borg create") elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.contains("borg create") assert script2.contains("borg create") elif hostname == "borg-client-nonroot": script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.contains("borg create") elif hostname in ("borg-client", "borg-client-2"): script = host.file("/usr/local/bin/run_borg_backup") assert script.contains("borg create") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_compression(self, host): hostname = host.backend.get_hostname() if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.contains("-C zstd") assert script2.contains("-C lz4") elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.contains("-C zstd") assert script2.contains("-C lz4") elif hostname == "borg-client-2": script = host.file("/usr/local/bin/run_borg_backup") assert script.contains("-C") assert script.contains("lz4") elif hostname in ("borg-client", "borg-client-nonroot"): script = ( host.file("/usr/local/bin/run_borg_backup") if hostname == "borg-client" else host.file("/usr/local/bin/run_borg_backup@borg-server") ) assert script.contains("-C") assert script.contains("zstd") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_repo_path(self, host): hostname = host.backend.get_hostname() if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.contains("borg@borg-server") assert script1.contains("/opt/borg/configs") assert script2.contains("borg@borg-server") assert script2.contains("/opt/borg/home-data") elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.contains("borg@borg-server") assert script1.contains("/opt/borg/configs-keys") assert script2.contains("borg@borg-server") assert script2.contains("/opt/borg/home-data-keys") elif hostname == "borg-client-nonroot": script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.contains("borg@borg-server") assert script.contains("/opt/borg") elif hostname == "borg-client": script = host.file("/usr/local/bin/run_borg_backup") assert script.contains("borg@borg-server") assert script.contains("/opt/borg") elif hostname == "borg-client-2": script = host.file("/usr/local/bin/run_borg_backup") assert script.contains("backupserver@borg-server-2") assert script.contains("/var/backups") else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_backup_paths(self, host): hostname = host.backend.get_hostname() if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert "/etc" in script1.content_string assert "/home" in script2.content_string assert "--exclude" in script2.content_string elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert "/etc" in script1.content_string assert "/home" in script2.content_string assert "--exclude" in script2.content_string elif hostname == "borg-client-nonroot": script = host.file("/usr/local/bin/run_borg_backup@borg-server") content = script.content_string assert "/etc" in content elif hostname in ("borg-client", "borg-client-2"): script = host.file("/usr/local/bin/run_borg_backup") content = script.content_string assert "/etc" in content or "/home" in content else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_is_executable(self, host): hostname = host.backend.get_hostname() if hostname == "borg-client-multi": script1 = host.file("/usr/local/bin/run_borg_backup@configs") script2 = host.file("/usr/local/bin/run_borg_backup@home-data") assert script1.mode == 0o711 assert script2.mode == 0o711 elif hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert script1.mode == 0o711 assert script2.mode == 0o711 elif hostname == "borg-client-nonroot": script = host.file("/usr/local/bin/run_borg_backup@borg-server") assert script.mode == 0o711 elif hostname in ("borg-client", "borg-client-2"): script = host.file("/usr/local/bin/run_borg_backup") assert script.mode == 0o711 else: pytest.fail(f"Unexpected hostname: {hostname}") def test_backup_script_contains_borg_rsh_when_per_repo(self, host): hostname = host.backend.get_hostname() per_repo = get_client_ssh_key_per_repo(host) if not per_repo: return if hostname == "borg-client-multi-keys": script1 = host.file("/usr/local/bin/run_borg_backup@configs-keys") script2 = host.file("/usr/local/bin/run_borg_backup@home-data-keys") assert "BORG_RSH" in script1.content_string assert "BORG_RSH" in script2.content_string assert "ssh -i" in script1.content_string assert "ssh -i" in script2.content_string class TestMultiInstanceBaseScript: def test_base_script_exists(self, host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return client_user = get_client_user(host) base_script = host.file("/usr/local/bin/run_borg_backup") assert base_script.exists assert base_script.user == client_user assert base_script.mode == 0o711 def test_base_script_contains_both_blocks(self, host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string assert "borg-server/configs" in content assert "borg-server/home-data" in content def test_base_script_contains_both_repos(self, host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string assert "/opt/borg/configs" in content assert "/opt/borg/home-data" in content def test_base_script_contains_both_compressions(self, host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string assert "-C zstd" in content assert "-C lz4" in content def test_base_script_two_borg_create_commands(self, host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return base_script = host.file("/usr/local/bin/run_borg_backup") content = base_script.content_string assert content.count("borg create") == 2