aboutsummaryrefslogtreecommitdiffstats
path: root/molecule/default/tests/test_server_setup.py
blob: 93c319dab89803d84e5908e0c66e4951edf9d50e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""Tests for borg server setup and repository configuration"""

import pytest

testinfra_hosts = ["borg-server", "borg-server-2"]

SERVER_CONFIGS = {
    "borg-server": {
        "user": "borg",
        "home": "/opt/borg",
        "client_repo": "borg-client",
    },
    "borg-server-2": {
        "user": "backupserver",
        "home": "/var/backups",
        "client_repo": "borg-client-2",
    },
}


@pytest.fixture
def config(host):
    return SERVER_CONFIGS[host.backend.hostname]


class TestBorgUser:
    def test_user_exists(self, host, config):
        user = host.user(config["user"])
        assert user.exists
        assert user.home == config["home"]

    def test_home_exists(self, host, config):
        home = host.file(config["home"])
        assert home.exists
        assert home.is_directory
        assert home.user == config["user"]
        assert home.group == config["user"]


class TestBorgSSHSetup:
    def test_ssh_directory_exists(self, host, config):
        ssh_dir = host.file(f"{config['home']}/.ssh")
        assert ssh_dir.exists
        assert ssh_dir.is_directory
        assert ssh_dir.user == config["user"]
        assert ssh_dir.group == config["user"]
        assert ssh_dir.mode == 0o700

    def test_authorized_keys_exists(self, host, config):
        auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys")
        assert auth_keys.exists
        assert auth_keys.user == config["user"]
        assert auth_keys.group == config["user"]
        assert not auth_keys.mode & 0o002

    def test_authorized_keys_has_restrictions(self, host, config):
        auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys")
        content = auth_keys.content_string
        assert "restrict" in content
        assert 'command="borg serve' in content

    def test_authorized_keys_has_repository_restrictions(self, host, config):
        auth_keys = host.file(f"{config['home']}/.ssh/authorized_keys")
        content = auth_keys.content_string
        assert "--restrict-to-repository" in content

    def test_authorized_keys_format_valid(self, host, config):
        auth_keys = host.file(f"{config['home']}/.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(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]}"
            )


class TestBorgRepository:
    def test_repo_directory_exists(self, host, config):
        repo = host.file(f"{config['home']}/{config['client_repo']}")
        assert repo.exists
        assert repo.is_directory
        assert repo.user == config["user"]
        assert repo.group == config["user"]

    def test_repo_initialized(self, host, config):
        c = host.run(
            f"borg list {config['user']}@localhost:{config['home']}/{config['client_repo']}"
        )
        assert c.rc == 0 or "does not exist" not in c.stderr

    def test_repo_has_encryption(self, host, config):
        repo_config = host.file(f"{config['home']}/{config['client_repo']}/config")
        assert repo_config.exists
        content = repo_config.content_string
        assert len(content) > 0

    def test_repo_config_and_data_exist(self, host, config):
        repo_config = host.file(f"{config['home']}/{config['client_repo']}/config")
        assert repo_config.exists

        data = host.file(f"{config['home']}/{config['client_repo']}/data")
        assert data.exists
        assert data.is_directory

    def test_repo_permissions(self, host, config):
        repo = host.file(f"{config['home']}/{config['client_repo']}")
        assert repo.user == config["user"]
        assert repo.group == config["user"]