aboutsummaryrefslogtreecommitdiffstats
path: root/molecule/default/tests/test_client_setup.py
diff options
context:
space:
mode:
authorColin Wilk <colin@wilk.cx>2026-06-27 23:01:10 +0200
committerColin Wilk <colin@wilk.cx>2026-06-27 23:05:21 +0200
commit8d872069976c5445c4396804ef3a0196f10eb14b (patch)
tree53ba2a34baf356fa9711e9be472d2d5322f1010e /molecule/default/tests/test_client_setup.py
parentcce7d2d258292c283d64ce8da14a6d1e366b564d (diff)
downloadansible-role-borgbackup-8d872069976c5445c4396804ef3a0196f10eb14b.tar.gz
ansible-role-borgbackup-8d872069976c5445c4396804ef3a0196f10eb14b.zip
feat: add per-repo SSH key support
Add borg_ssh_key_per_repo option to generate unique SSH keypairs per (server, repo) combination. When enabled, each repository gets its own authorized_keys entry, enabling: - Independent --append-only settings per repository - Per-repo storage quotas
Diffstat (limited to 'molecule/default/tests/test_client_setup.py')
-rw-r--r--molecule/default/tests/test_client_setup.py117
1 files changed, 107 insertions, 10 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):