summaryrefslogtreecommitdiffstats
path: root/nixos/tests/nezha.nix
blob: 924cfc1d8300d85a82ce354afadf3f23a2203bef (plain)
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
{ lib, pkgs, ... }:
let
  agent_host = "agent.test";
  dashboard_host = "dashboard.test";

  agentSecret = pkgs.writeText "fakeagentsecret" "fakeagentsecret";

  hosts = {
    "${agent_host}" = "192.168.0.2";
    "${dashboard_host}" = "192.168.0.1";
  };
  hostsEntries = lib.mapAttrs' (k: v: {
    name = v;
    value = lib.singleton k;
  }) hosts;
in
{
  name = "nezha";

  meta.maintainers = with lib.maintainers; [ moraxyc ];

  containers = {
    agent = _: {
      networking = {
        hostName = builtins.elemAt (lib.splitString "." agent_host) 0;
        domain = builtins.elemAt (lib.splitString "." agent_host) 1;
        firewall.enable = false;
        hosts = hostsEntries;
        useDHCP = false;
        interfaces.eth1.ipv4.addresses = lib.singleton {
          address = hosts."${agent_host}";
          prefixLength = 24;
        };
      };
      services.nezha-agent = {
        enable = true;
        debug = true;
        genUuid = true;
        settings = {
          server = hosts."${dashboard_host}" + ":80";
        };
        clientSecretFile = agentSecret;
      };
    };

    dashboard =
      { pkgs, ... }:
      {
        networking = {
          firewall.enable = false;
          hosts = hostsEntries;
          useDHCP = false;
          interfaces.eth1.ipv4.addresses = lib.singleton {
            address = hosts."${dashboard_host}";
            prefixLength = 24;
          };
        };
        services.nezha = {
          enable = true;
          debug = true;
          settings = {
            listenhost = "0.0.0.0";
            # Test CAP_NET_BIND_SERVICE
            listenport = 80;
          };
          mutableConfig = true;
          jwtSecretFile = pkgs.writeText "fakejwt" "fakejwt";
          agentSecretFile = agentSecret;
        };
      };
  };

  testScript = ''
    import json

    with subtest("Wait for services and network"):
        dashboard.wait_for_unit("nezha.service")
        agent.wait_for_unit("nezha-agent.service")
        dashboard.wait_for_open_port(80)
        dashboard.wait_for_unit("network.target")
        agent.wait_for_unit("network.target")
        agent.succeed("curl --fail --max-time 10 http://dashboard.test/")

    with subtest("Test mutableConfig"):
        dashboard.succeed("systemctl stop nezha")
        dashboard.succeed("""
          echo '{"sitename": "Nezha on NixOS"}' > /etc/nezha/config.yaml
        """)
        dashboard.succeed("systemctl start nezha")
        dashboard.wait_for_unit("nezha.service")
        dashboard.wait_for_open_port(80)
        result = json.loads(agent.succeed("""
            curl --fail -X POST --json '{ "username": "admin", "password": "admin"}' \
              'http://dashboard.test/api/v1/login'
        """))
        token = result['data']['token']
        result = json.loads(agent.succeed(f"""
          curl --fail -X GET --header 'Authorization: Bearer {token}' \
            'http://dashboard.test/api/v1/setting'
        """))
        assert "Nezha on NixOS" == result['data']['config']['site_name']

    with subtest("Verify connection and uuid"):
        uuid = agent.succeed(
            "${lib.getExe' pkgs.util-linux "uuidgen"} --md5 -n @dns -N ${agent_host}"
        )
        # remove unprintable characters
        uuid = "".join([char for char in uuid if char.isprintable()])
        agent.wait_until_succeeds(f"""
          curl --fail -X GET --header 'Authorization: Bearer {token}' \
            'http://dashboard.test/api/v1/server' | grep {uuid}
        """)
  '';
}