aboutsummaryrefslogtreecommitdiffstats
path: root/molecule/default/tests
diff options
context:
space:
mode:
Diffstat (limited to 'molecule/default/tests')
-rw-r--r--molecule/default/tests/test_client_setup.py117
-rw-r--r--molecule/default/tests/test_server_setup.py21
-rw-r--r--molecule/default/tests/test_ssh_connectivity.py45
-rw-r--r--molecule/default/tests/test_systemd.py59
4 files changed, 224 insertions, 18 deletions
diff --git a/molecule/default/tests/test_client_setup.py b/molecule/default/tests/test_client_setup.py
index 290e3dc..a0e4f4a 100644
--- a/molecule/default/tests/test_client_setup.py
+++ b/molecule/default/tests/test_client_setup.py
@@ -1,7 +1,7 @@
"""Tests for client setup configuration"""
import pytest
-testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot']
+testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot', 'borg-client-multi-keys']
CLIENT_USER_MAP = {
@@ -9,6 +9,7 @@ CLIENT_USER_MAP = {
'borg-client-2': 'root',
'borg-client-multi': 'root',
'borg-client-nonroot': 'backupuser',
+ 'borg-client-multi-keys': 'root',
}
CLIENT_SSH_KEY_TYPE_MAP = {
@@ -16,6 +17,15 @@ CLIENT_SSH_KEY_TYPE_MAP = {
'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,
}
@@ -29,6 +39,11 @@ def get_client_ssh_key_type(host):
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'
@@ -49,20 +64,48 @@ class TestSSHSetup:
client_home = get_client_home(host)
client_user = get_client_user(host)
key_type = get_client_ssh_key_type(host)
- 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
+ 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)
- key = host.file(f'{client_home}/.ssh/id_{key_type}.pub')
- assert key.exists
- assert key.user == client_user
- assert key.group == client_user
+ 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)
@@ -87,6 +130,17 @@ class TestBackupScript:
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
@@ -110,6 +164,11 @@ class TestBackupScript:
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')
@@ -127,6 +186,11 @@ class TestBackupScript:
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')
@@ -148,6 +212,13 @@ class TestBackupScript:
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')
@@ -168,6 +239,12 @@ class TestBackupScript:
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
@@ -187,6 +264,11 @@ class TestBackupScript:
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
@@ -196,6 +278,21 @@ class TestBackupScript:
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):
diff --git a/molecule/default/tests/test_server_setup.py b/molecule/default/tests/test_server_setup.py
index 3c494f7..5ec1520 100644
--- a/molecule/default/tests/test_server_setup.py
+++ b/molecule/default/tests/test_server_setup.py
@@ -1,5 +1,6 @@
"""Tests for borg server setup and repository configuration"""
import pytest
+import re
testinfra_hosts = ['borg-server']
@@ -62,8 +63,13 @@ class TestBorgSSHSetup:
def test_authorized_keys_multi_instance_repo_count(self, host):
auth_keys = host.file('/opt/borg/.ssh/authorized_keys')
content = auth_keys.content_string
- configs_count = content.count('/opt/borg/configs')
- home_data_count = content.count('/opt/borg/home-data')
+
+ restricted_repos = re.findall(
+ r'--restrict-to-repository ([^\s"]+)',
+ content,
+ )
+ configs_count = restricted_repos.count('/opt/borg/configs')
+ home_data_count = restricted_repos.count('/opt/borg/home-data')
assert configs_count == 1, f"configs repo should appear once in authorized_keys, found {configs_count}"
assert home_data_count == 1, f"home-data repo should appear once in authorized_keys, found {home_data_count}"
@@ -71,11 +77,18 @@ class TestBorgSSHSetup:
def test_authorized_keys_format_valid(self, host):
auth_keys = host.file('/opt/borg/.ssh/authorized_keys')
content = auth_keys.content_string
+ valid_hosts = (
+ 'borg-client',
+ 'borg-client-2',
+ 'borg-client-multi',
+ 'borg-client-nonroot',
+ 'borg-client-multi-keys',
+ )
for line in content.split('\n'):
if not line.strip():
continue
assert line.startswith('restrict,command="borg serve'), f"Line should start with restrict,command: {line[:50]}"
- assert '@' in line and line.rstrip().endswith(('borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot')), f"Line should contain user@hostname marker: {line[-40:]}"
+ assert '@' in line and line.rstrip().endswith(valid_hosts), f"Line should contain user@hostname marker: {line[-40:]}"
assert '--restrict-to-repository' in line, f"Line should have repo restriction: {line[:80]}"
def test_authorized_keys_multi_instance_no_cross_host_repos(self, host):
@@ -85,7 +98,7 @@ class TestBorgSSHSetup:
multi_lines = [
line for line in content.split('\n')
- if line and 'root@borg-client-multi' in line
+ if line.rstrip().endswith('root@borg-client-multi')
]
assert len(multi_lines) == 1, (
f"Should have exactly one entry for borg-client-multi, found {len(multi_lines)}"
diff --git a/molecule/default/tests/test_ssh_connectivity.py b/molecule/default/tests/test_ssh_connectivity.py
index 89b24a5..0cc1897 100644
--- a/molecule/default/tests/test_ssh_connectivity.py
+++ b/molecule/default/tests/test_ssh_connectivity.py
@@ -1,7 +1,19 @@
"""Tests for SSH connectivity between client and server"""
import pytest
-testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi']
+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 test_ssh_connection_to_server(host):
@@ -10,7 +22,19 @@ def test_ssh_connection_to_server(host):
def test_no_password_prompt_on_connect(host):
- c = host.run('ssh -o BatchMode=yes -o PreferredAuthentications=publickey borg@borg-server exit')
+ hostname = host.backend.get_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 '
+ 'borg@borg-server exit'
+ )
+ else:
+ c = host.run(
+ 'ssh -o BatchMode=yes -o PreferredAuthentications=publickey '
+ 'borg@borg-server exit'
+ )
assert c.rc == 0
@@ -27,6 +51,12 @@ def test_borg_can_connect_to_server(host):
if hostname == 'borg-client-multi':
c = host.run('borg list borg@borg-server:/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")} '
+ 'borg list borg@borg-server:/opt/borg/configs-keys'
+ )
+ assert c.rc == 0, 'Should be able to connect to configs-keys repo'
elif hostname == 'borg-client':
c = host.run('borg list borg@borg-server:/opt/borg/borg-client')
assert c.rc == 0
@@ -45,6 +75,17 @@ def test_borg_info_works(host):
assert c.rc == 0, 'Should be able to get info for configs repo'
c2 = host.run('borg info borg@borg-server:/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")} '
+ 'borg info borg@borg-server:/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")} '
+ 'borg info borg@borg-server:/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('borg info borg@borg-server:/opt/borg/borg-client')
assert c.rc == 0
diff --git a/molecule/default/tests/test_systemd.py b/molecule/default/tests/test_systemd.py
index 7b7b2ab..b713c27 100644
--- a/molecule/default/tests/test_systemd.py
+++ b/molecule/default/tests/test_systemd.py
@@ -2,7 +2,7 @@
import pytest
-testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot']
+testinfra_hosts = ['borg-client', 'borg-client-2', 'borg-client-multi', 'borg-client-nonroot', 'borg-client-multi-keys']
CLIENT_USER_MAP = {
@@ -10,6 +10,7 @@ CLIENT_USER_MAP = {
'borg-client-2': 'root',
'borg-client-multi': 'root',
'borg-client-nonroot': 'backupuser',
+ 'borg-client-multi-keys': 'root',
}
@@ -31,6 +32,15 @@ class TestSystemdServiceFile:
assert service2.exists
assert service2.user == 'root'
assert service2.group == 'root'
+ elif hostname == 'borg-client-multi-keys':
+ service1 = host.file('/etc/systemd/system/borg_backup@configs-keys.service')
+ service2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.service')
+ assert service1.exists
+ assert service1.user == 'root'
+ assert service1.group == 'root'
+ assert service2.exists
+ assert service2.user == 'root'
+ assert service2.group == 'root'
elif hostname == 'borg-client-nonroot':
service = host.file('/etc/systemd/system/borg_backup@borg-server.service')
assert service.exists
@@ -57,6 +67,14 @@ class TestSystemdServiceFile:
assert service.contains('[Service]')
assert service.contains('[Install]')
assert service.contains('Type=oneshot')
+ elif hostname == 'borg-client-multi-keys':
+ service1 = host.file('/etc/systemd/system/borg_backup@configs-keys.service')
+ service2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.service')
+ for service in [service1, service2]:
+ assert service.contains('[Unit]')
+ assert service.contains('[Service]')
+ assert service.contains('[Install]')
+ assert service.contains('Type=oneshot')
elif hostname == 'borg-client-nonroot':
service = host.file('/etc/systemd/system/borg_backup@borg-server.service')
assert service.contains('[Unit]')
@@ -84,6 +102,12 @@ class TestSystemdServiceFile:
for service in [service1, service2]:
assert service.contains(f'User={client_user}')
assert service.contains(f'Group={client_user}')
+ elif hostname == 'borg-client-multi-keys':
+ service1 = host.file('/etc/systemd/system/borg_backup@configs-keys.service')
+ service2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.service')
+ for service in [service1, service2]:
+ assert service.contains(f'User={client_user}')
+ assert service.contains(f'Group={client_user}')
elif hostname in ('borg-client', 'borg-client-2', 'borg-client-nonroot'):
service = host.file('/etc/systemd/system/borg_backup@borg-server.service')
assert service.contains(f'User={client_user}')
@@ -93,7 +117,7 @@ class TestSystemdServiceFile:
def test_success_exit_status(self, host):
hostname = host.backend.get_hostname()
- if hostname in ('borg-client-multi', 'borg-client-nonroot'):
+ if hostname in ('borg-client-multi', 'borg-client-nonroot', 'borg-client-multi-keys'):
return
service = host.file('/etc/systemd/system/borg_backup@borg-server.service')
@@ -123,6 +147,11 @@ class TestSystemdTimerFile:
timer2 = host.file('/etc/systemd/system/borg_backup@home-data.timer')
assert timer1.exists
assert timer2.exists
+ elif hostname == 'borg-client-multi-keys':
+ timer1 = host.file('/etc/systemd/system/borg_backup@configs-keys.timer')
+ timer2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.timer')
+ assert timer1.exists
+ assert timer2.exists
elif hostname in ('borg-client', 'borg-client-2', 'borg-client-nonroot'):
timer = host.file('/etc/systemd/system/borg_backup@borg-server.timer')
assert timer.exists
@@ -144,6 +173,15 @@ class TestSystemdTimerFile:
assert timer.contains('[Install]')
assert timer.contains('OnCalendar=')
assert timer.contains('AccuracySec=')
+ elif hostname == 'borg-client-multi-keys':
+ timer1 = host.file('/etc/systemd/system/borg_backup@configs-keys.timer')
+ timer2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.timer')
+ for timer in [timer1, timer2]:
+ assert timer.contains('[Unit]')
+ assert timer.contains('[Timer]')
+ assert timer.contains('[Install]')
+ assert timer.contains('OnCalendar=')
+ assert timer.contains('AccuracySec=')
elif hostname in ('borg-client', 'borg-client-2', 'borg-client-nonroot'):
timer = host.file('/etc/systemd/system/borg_backup@borg-server.timer')
assert timer.contains('[Unit]')
@@ -162,6 +200,11 @@ class TestSystemdTimerFile:
timer2 = host.file('/etc/systemd/system/borg_backup@home-data.timer')
assert 'OnCalendar=*-*-* 02:00:00' in timer1.content_string
assert 'OnCalendar=*-*-* 04:00:00' in timer2.content_string
+ elif hostname == 'borg-client-multi-keys':
+ timer1 = host.file('/etc/systemd/system/borg_backup@configs-keys.timer')
+ timer2 = host.file('/etc/systemd/system/borg_backup@home-data-keys.timer')
+ assert 'OnCalendar=*-*-* 02:00:00' in timer1.content_string
+ assert 'OnCalendar=*-*-* 04:00:00' in timer2.content_string
elif hostname == 'borg-client-2':
timer = host.file('/etc/systemd/system/borg_backup@borg-server.timer')
assert 'OnCalendar=*-*-* 03:00:00' in timer.content_string
@@ -183,6 +226,13 @@ class TestSystemdState:
assert c1.stdout.strip() == 'enabled'
assert c2.rc == 0
assert c2.stdout.strip() == 'enabled'
+ elif hostname == 'borg-client-multi-keys':
+ c1 = host.run('systemctl is-enabled borg_backup@configs-keys.timer')
+ c2 = host.run('systemctl is-enabled borg_backup@home-data-keys.timer')
+ assert c1.rc == 0
+ assert c1.stdout.strip() == 'enabled'
+ assert c2.rc == 0
+ assert c2.stdout.strip() == 'enabled'
elif hostname in ('borg-client', 'borg-client-2', 'borg-client-nonroot'):
timer_name = 'borg_backup@borg-server.timer'
c = host.run(f"systemctl is-enabled {timer_name}")
@@ -199,6 +249,11 @@ class TestSystemdState:
c2 = host.run('systemctl is-active borg_backup@home-data.timer')
assert c1.rc == 0
assert c2.rc == 0
+ elif hostname == 'borg-client-multi-keys':
+ c1 = host.run('systemctl is-active borg_backup@configs-keys.timer')
+ c2 = host.run('systemctl is-active borg_backup@home-data-keys.timer')
+ assert c1.rc == 0
+ assert c2.rc == 0
elif hostname in ('borg-client', 'borg-client-2', 'borg-client-nonroot'):
timer_name = 'borg_backup@borg-server.timer'
c = host.run(f"systemctl is-active {timer_name}")