"""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' )