aboutsummaryrefslogtreecommitdiffstats
path: root/molecule/default
diff options
context:
space:
mode:
authorColin Wilk <colin@wilk.cx>2026-06-27 15:22:45 +0200
committerColin Wilk <colin@wilk.cx>2026-06-27 16:55:53 +0200
commita22ff185f9836023817f9d4f8df3157b948f8cf2 (patch)
treeb51ce1fff12bc245ba024ab9db793bbdd8a8acae /molecule/default
parent2ff66fc090110dcf384e74bc26e73481eb780253 (diff)
downloadansible-role-borgbackup-a22ff185f9836023817f9d4f8df3157b948f8cf2.tar.gz
ansible-role-borgbackup-a22ff185f9836023817f9d4f8df3157b948f8cf2.zip
borg!: support multiple backups to same target
This brings support for multiple backups pointing to the same borg server, different repositories, from the same client. We support this by parsing the SSH authorized key file first and appending allowed repositories to allow independent definitions of the borg targets. So that the decryption_keys do not clash we include the repository name as well as the host in the key. This will lead to new keys being created for existing hosts in the new format. Old Format: {{ combine({inventory_hostname: borg_keys.stdout}) }} New Format: {{ combine({(inventory_hostname ~ '_' ~ borg_repo_name): borg_keys.stdout}) }} If upgrading from an older version that used just the hostname as the key, your existing `decryption_keys.yml` can be manually removed once the new format is also added.
Diffstat (limited to 'molecule/default')
-rw-r--r--molecule/default/tests/test_decryption_keys.py82
1 files changed, 41 insertions, 41 deletions
diff --git a/molecule/default/tests/test_decryption_keys.py b/molecule/default/tests/test_decryption_keys.py
index 227baf0..c772477 100644
--- a/molecule/default/tests/test_decryption_keys.py
+++ b/molecule/default/tests/test_decryption_keys.py
@@ -6,27 +6,27 @@ import pytest
def _get_keys_path():
"""Get decryption_keys.yml path from molecule environment"""
- scenario_dir = os.environ.get("MOLECULE_SCENARIO_DIRECTORY")
+ scenario_dir = os.environ.get('MOLECULE_SCENARIO_DIRECTORY')
if scenario_dir:
- return os.path.join(scenario_dir, "decryption_keys.yml")
-
+ return os.path.join(scenario_dir, 'decryption_keys.yml')
+
test_dir = os.path.dirname(os.path.abspath(__file__))
- return os.path.join(test_dir, "..", "decryption_keys.yml")
+ return os.path.join(test_dir, '..', 'decryption_keys.yml')
def test_decryption_keys_file_exists():
"""Test that decryption_keys.yml exists"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
+ pytest.skip('decryption_keys.yml not yet generated')
def test_decryption_keys_file_permissions():
"""Test that decryption_keys.yml has secure permissions"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
+ pytest.skip('decryption_keys.yml not yet generated')
+
file_stat = os.stat(keys_path)
file_mode = stat.S_IMODE(file_stat.st_mode)
assert file_mode == 0o600, (
@@ -38,15 +38,15 @@ def test_decryption_keys_structure_single_repo():
"""Test single-repo hosts have correct key format"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
- with open(keys_path, "r") as f:
+ pytest.skip('decryption_keys.yml not yet generated')
+
+ with open(keys_path, 'r') as f:
content = f.read()
-
- assert "borg-client_borg-client:" in content, (
+
+ assert 'borg-client_borg-client:' in content, (
"Single repo host should have key named 'hostname_repo_name'"
)
- assert "borg-client-2_borg-client-2:" in content, (
+ assert 'borg-client-2_borg-client-2:' in content, (
"Second single repo host should have key named 'hostname_repo_name'"
)
@@ -55,15 +55,15 @@ def test_decryption_keys_structure_multi_repo():
"""Test multi-instance hosts have correct key format"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
- with open(keys_path, "r") as f:
+ pytest.skip('decryption_keys.yml not yet generated')
+
+ with open(keys_path, 'r') as f:
content = f.read()
-
- assert "borg-client-multi_configs:" in content, (
+
+ assert 'borg-client-multi_configs:' in content, (
"Multi-instance host should have key for 'configs' repo"
)
- assert "borg-client-multi_home-data:" in content, (
+ assert 'borg-client-multi_home-data:' in content, (
"Multi-instance host should have key for 'home-data' repo"
)
@@ -72,14 +72,14 @@ def test_decryption_keys_multi_instance_separate_entries():
"""Test multi-instance hosts have separate keys for each repo"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
- with open(keys_path, "r") as f:
+ pytest.skip('decryption_keys.yml not yet generated')
+
+ with open(keys_path, 'r') as f:
content = f.read()
-
- configs_count = content.count("borg-client-multi_configs:")
- home_data_count = content.count("borg-client-multi_home-data:")
-
+
+ configs_count = content.count('borg-client-multi_configs:')
+ home_data_count = content.count('borg-client-multi_home-data:')
+
assert configs_count == 1, (
f"configs key should appear exactly once, found {configs_count}"
)
@@ -92,13 +92,13 @@ def test_decryption_keys_contain_paper_key_format():
"""Test that decryption keys use borg paper key format"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
- with open(keys_path, "r") as f:
+ pytest.skip('decryption_keys.yml not yet generated')
+
+ with open(keys_path, 'r') as f:
content = f.read()
-
- assert "BORG PAPER KEY" in content, (
- "Decryption keys should contain borg paper key format"
+
+ assert 'BORG PAPER KEY' in content, (
+ 'Decryption keys should contain borg paper key format'
)
@@ -106,17 +106,17 @@ def test_decryption_keys_all_hosts_present():
"""Test that all expected hosts have keys"""
keys_path = _get_keys_path()
if not os.path.exists(keys_path):
- pytest.skip("decryption_keys.yml not yet generated")
-
- with open(keys_path, "r") as f:
+ pytest.skip('decryption_keys.yml not yet generated')
+
+ with open(keys_path, 'r') as f:
content = f.read()
-
+
expected_keys = [
- "borg-client_borg-client:",
- "borg-client-2_borg-client-2:",
- "borg-client-multi_configs:",
- "borg-client-multi_home-data:",
+ 'borg-client_borg-client:',
+ 'borg-client-2_borg-client-2:',
+ 'borg-client-multi_configs:',
+ 'borg-client-multi_home-data:',
]
-
+
for key in expected_keys:
assert key in content, f"Expected key {key} not found in decryption_keys.yml"