1import ./make-test-python.nix (
2 { lib, pkgs, ... }:
3 {
4 name = "systemd-journal-gateway";
5 meta = with pkgs.lib.maintainers; {
6 maintainers = [
7 minijackson
8 raitobezarius
9 ];
10 };
11
12 # Named client for coherence with the systemd-journal-upload test, and for
13 # certificate validation
14 nodes.client = {
15 services.journald.gateway = {
16 enable = true;
17 cert = "/run/secrets/client/cert.pem";
18 key = "/run/secrets/client/key.pem";
19 trust = "/run/secrets/ca.cert.pem";
20 };
21 };
22
23 testScript = ''
24 import json
25 import subprocess
26 import tempfile
27
28 tmpdir_o = tempfile.TemporaryDirectory()
29 tmpdir = tmpdir_o.name
30
31 def generate_pems(domain: str):
32 subprocess.run(
33 [
34 "${pkgs.minica}/bin/minica",
35 "--ca-key=ca.key.pem",
36 "--ca-cert=ca.cert.pem",
37 f"--domains={domain}",
38 ],
39 cwd=str(tmpdir),
40 )
41
42 with subtest("Creating keys and certificates"):
43 generate_pems("server")
44 generate_pems("client")
45
46 client.wait_for_unit("multi-user.target")
47
48 def copy_pem(file: str):
49 machine.copy_from_host(source=f"{tmpdir}/{file}", target=f"/run/secrets/{file}")
50 machine.succeed(f"chmod 600 /run/secrets/{file} && chown systemd-journal-gateway /run/secrets/{file}")
51
52 with subtest("Copying keys and certificates"):
53 machine.succeed("mkdir -p /run/secrets/{client,server}")
54 copy_pem("server/cert.pem")
55 copy_pem("server/key.pem")
56 copy_pem("client/cert.pem")
57 copy_pem("client/key.pem")
58 copy_pem("ca.cert.pem")
59
60 client.wait_for_unit("multi-user.target")
61
62 curl = '${pkgs.curl}/bin/curl'
63 accept_json = '--header "Accept: application/json"'
64 cacert = '--cacert /run/secrets/ca.cert.pem'
65 cert = '--cert /run/secrets/server/cert.pem'
66 key = '--key /run/secrets/server/key.pem'
67 base_url = 'https://client:19531'
68
69 curl_cli = f"{curl} {accept_json} {cacert} {cert} {key} --fail"
70
71 machine_info = client.succeed(f"{curl_cli} {base_url}/machine")
72 assert json.loads(machine_info)["hostname"] == "client", "wrong machine name"
73
74 # The HTTP request should have started the gateway service, triggered by
75 # the .socket unit
76 client.wait_for_unit("systemd-journal-gatewayd.service")
77
78 identifier = "nixos-test"
79 message = "Hello from NixOS test infrastructure"
80
81 client.succeed(f"systemd-cat --identifier={identifier} <<< '{message}'")
82
83 # max-time is a workaround against a bug in systemd-journal-gatewayd where
84 # if TLS is enabled, the connection is never closed. Since it will timeout,
85 # we ignore the return code.
86 entries = client.succeed(
87 f"{curl_cli} --max-time 5 {base_url}/entries?SYSLOG_IDENTIFIER={identifier} || true"
88 )
89
90 # Number of entries should be only 1
91 added_entry = json.loads(entries)
92 assert added_entry["SYSLOG_IDENTIFIER"] == identifier and added_entry["MESSAGE"] == message, "journal entry does not correspond"
93 '';
94 }
95)