"""Tests for SSH connectivity between client and server""" import pytest testinfra_hosts = [ "borg-client", "borg-client-2", "borg-client-multi", "borg-client-multi-keys", ] def get_borg_rsh(host, repo_name): hostname = host.backend.get_hostname() if hostname != "borg-client-multi-keys": return "" sanitized_repo_name = repo_name.replace("-", "_") return ( 'BORG_RSH="ssh -i ' f'/root/.ssh/id_ed25519_borgbackup_borg_server_{sanitized_repo_name}"' ) def get_server_user(hostname): if hostname == "borg-client-2": return "backupserver" return "borg" def get_server_host(hostname): if hostname == "borg-client-2": return "borg-server-2" return "borg-server" def test_ssh_connection_to_server(host): hostname = host.backend.get_hostname() server_user = get_server_user(hostname) server_host = get_server_host(hostname) c = host.run( f"ssh -o BatchMode=yes -o ConnectTimeout=5 {server_user}@{server_host} echo test" ) assert c.rc == 0 or "Connection refused" not in c.stderr def test_no_password_prompt_on_connect(host): hostname = host.backend.get_hostname() server_user = get_server_user(hostname) server_host = get_server_host(hostname) if hostname == "borg-client-multi-keys": c = host.run( "ssh -i /root/.ssh/id_ed25519_borgbackup_borg_server_configs_keys " "-o BatchMode=yes -o PreferredAuthentications=publickey " f"{server_user}@{server_host} exit" ) else: c = host.run( "ssh -o BatchMode=yes -o PreferredAuthentications=publickey " f"{server_user}@{server_host} exit" ) assert c.rc == 0 def test_known_hosts_has_correct_entry(host): hostname = host.backend.get_hostname() server_host = get_server_host(hostname) known_hosts = host.file("/root/.ssh/known_hosts") content = known_hosts.content_string assert server_host in content assert "ssh-" in content def test_borg_can_connect_to_server(host): hostname = host.backend.get_hostname() server_user = get_server_user(hostname) server_host = get_server_host(hostname) if hostname == "borg-client-multi": c = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") assert c.rc == 0, "Should be able to connect to configs repo" elif hostname == "borg-client-multi-keys": c = host.run( f"{get_borg_rsh(host, 'configs-keys')} " f"borg list {server_user}@{server_host}:/opt/borg/configs-keys" ) assert c.rc == 0, "Should be able to connect to configs-keys repo" elif hostname == "borg-client": c = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client") assert c.rc == 0 elif hostname == "borg-client-2": c = host.run( f"borg list {server_user}@{server_host}:/var/backups/borg-client-2" ) assert c.rc == 0, "Should be able to connect to borg-client-2 repo" else: pytest.fail(f"Unexpected hostname: {hostname}") def test_borg_info_works(host): hostname = host.backend.get_hostname() server_user = get_server_user(hostname) server_host = get_server_host(hostname) if hostname == "borg-client-multi": c = host.run(f"borg info {server_user}@{server_host}:/opt/borg/configs") assert c.rc == 0, "Should be able to get info for configs repo" c2 = host.run(f"borg info {server_user}@{server_host}:/opt/borg/home-data") assert c2.rc == 0, "Should be able to get info for home-data repo" elif hostname == "borg-client-multi-keys": c = host.run( f"{get_borg_rsh(host, 'configs-keys')} " f"borg info {server_user}@{server_host}:/opt/borg/configs-keys" ) assert c.rc == 0, "Should be able to get info for configs-keys repo" c2 = host.run( f"{get_borg_rsh(host, 'home-data-keys')} " f"borg info {server_user}@{server_host}:/opt/borg/home-data-keys" ) assert c2.rc == 0, "Should be able to get info for home-data-keys repo" elif hostname == "borg-client": c = host.run(f"borg info {server_user}@{server_host}:/opt/borg/borg-client") assert c.rc == 0 elif hostname == "borg-client-2": c = host.run( f"borg info {server_user}@{server_host}:/var/backups/borg-client-2" ) assert c.rc == 0, "Should be able to get info for borg-client-2 repo" else: pytest.fail(f"Unexpected hostname: {hostname}") def test_multi_instance_can_access_both_repos(host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return server_user = get_server_user(hostname) server_host = get_server_host(hostname) c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") assert c1.rc == 0, "borg-client-multi should access configs repo" c2 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/home-data") assert c2.rc == 0, "borg-client-multi should access home-data repo" def test_multi_instance_cannot_access_other_hosts_repos(host): hostname = host.backend.get_hostname() if hostname != "borg-client-multi": return server_user = get_server_user(hostname) server_host = get_server_host(hostname) c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client") assert c1.rc != 0, "borg-client-multi should NOT access borg-client repo" c2 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/borg-client-2") assert c2.rc != 0, "borg-client-multi should NOT access borg-client-2 repo" def test_single_host_cannot_access_multi_repos(host): hostname = host.backend.get_hostname() if hostname not in ["borg-client", "borg-client-2"]: return server_user = get_server_user(hostname) server_host = get_server_host(hostname) if hostname == "borg-client": c1 = host.run(f"borg list {server_user}@{server_host}:/opt/borg/configs") assert c1.rc != 0, ( f"{hostname} should NOT access configs repo (belongs to borg-client-multi)" ) c2 = host.run("borg list borg@borg-server:/opt/borg/home-data") assert c2.rc != 0, ( f"{hostname} should NOT access home-data repo (belongs to borg-client-multi)" ) def test_single_hosts_cannot_access_each_others_repos(host): """Verify single-instance hosts cannot access each other's repos""" hostname = host.backend.get_hostname() if hostname == "borg-client": c = host.run("borg list borg@borg-server:/opt/borg/borg-client-2") assert c.rc != 0, "borg-client should NOT access borg-client-2 repo" elif hostname == "borg-client-2": c = host.run("borg list borg@borg-server:/opt/borg/borg-client") assert c.rc != 0, "borg-client-2 should NOT access borg-client repo"