feat: add declarative status page

This commit is contained in:
Julien Malka 2025-01-18 00:25:18 +01:00
parent f3ba2a1c8b
commit 718128596f
Signed by: Luj
GPG key ID: 6FC74C847011FD83
10 changed files with 101 additions and 40 deletions

View file

@ -175,9 +175,9 @@
"type": "Git",
"fetchType": "git",
"branch": "truly-deterministic",
"revision": "caf3169829647809805caaf968c8c0d4015ef187",
"revision": "78564e5f2c4fad5175f709560e6ee75d30115b22",
"url": "https://git.dgnum.eu/Luj/stateless-uptime-kuma.git",
"hash": "sha256-tux43mzd1rrlpTEhcQ9PiJBse9+SGEcWY/9F8cxX+Po=",
"hash": "sha256-I5uHrQvwKvJMFSOJfEZRZyc5ZElD0tCGfFVDaBfcLNM=",
"submodules": false
},
"unstable": {

View file

@ -68,4 +68,35 @@ in
config.machine.meta.ips.public.ipv6
];
machine.meta.probes.monitors."s3.luj.fr - IPv4".accepted_statuscodes = [ "403" ];
machine.meta.probes.monitors."s3.luj.fr - IPv6".accepted_statuscodes = [ "403" ];
machine.meta.probes.monitors."cdn.luj.fr - IPv4".accepted_statuscodes = [ "404" ];
machine.meta.probes.monitors."cdn.luj.fr - IPv6".accepted_statuscodes = [ "404" ];
machine.meta.probes.monitors = {
"luj.fr - IPv4" = {
url = "https://${config.machine.meta.ips.public.ipv4}";
type = "http";
accepted_statuscodes = [ "200-299" ];
notificationIDList = [ 1 ];
headers = ''
{
"Host": "luj.fr"
}
'';
};
"luj.fr - IPv6" = {
url = "https://[${config.machine.meta.ips.public.ipv6}]";
type = "http";
accepted_statuscodes = [ "200-299" ];
notificationIDList = [ 1 ];
headers = ''
{
"Host": "luj.fr"
}
'';
};
};
}

View file

@ -122,8 +122,8 @@
security.acme.certs."ca.luj".server = lib.mkForce "https://127.0.0.1:8444/acme/acme/directory";
machine.meta.monitors."ca.luj - IPv4".url = lib.mkForce "https://100.100.45.14/health";
machine.meta.monitors."ca.luj - IPv6".url = lib.mkForce "https://[fd7a:115c:a1e0::e]/health";
machine.meta.probes.monitors."ca.luj - IPv4".url = lib.mkForce "https://100.100.45.14/health";
machine.meta.probes.monitors."ca.luj - IPv6".url = lib.mkForce "https://[fd7a:115c:a1e0::e]/health";
systemd.services."step-ca".after = [ "keycloak.service" ];

View file

@ -101,30 +101,8 @@ lib.mkMerge [
networking.firewall.allowedUDPPorts = [ 53 ];
networking.firewall.allowedTCPPorts = [ 53 ];
machine.meta.zones."luj.fr".TXT = [ "homepage.luj.luj-static.page" ];
machine.meta.monitors = {
"luj.fr - IPv4" = {
url = "https://${config.machine.meta.ips.public.ipv4}";
type = "http";
accepted_statuscodes = [ "200-299" ];
headers = ''
{
"Host": "luj.fr"
}
'';
};
"luj.fr - IPv6" = {
url = "https://[${config.machine.meta.ips.public.ipv6}]";
type = "http";
accepted_statuscodes = [ "200-299" ];
headers = ''
{
"Host": "luj.fr"
}
'';
};
};
# Page server disabled for now
#machine.meta.zones."luj.fr".TXT = [ "homepage.luj.luj-static.page" ];
}

View file

@ -8,15 +8,20 @@
}:
let
probesFromConfig = lib.mkMerge (
lib.mapAttrsToList (_: value: value.config.machine.meta.monitors) nixosConfigurations
monitorsFromConfig = lib.mkMerge (
lib.mapAttrsToList (_: value: value.config.machine.meta.probes.monitors) nixosConfigurations
);
pagesFromConfig = lib.mkMerge (
lib.mapAttrsToList (_: value: value.config.machine.meta.probes.status_pages) nixosConfigurations
);
in
{
services.uptime-kuma = {
enable = true;
package = pkgs.uptime-kuma-beta;
package = pkgs.unstable.uptime-kuma;
settings = {
NODE_EXTRA_CA_CERTS = "/etc/ssl/certs/ca-certificates.crt";
};
@ -31,14 +36,16 @@ in
};
};
age.secrets."stateless-uptime-kuma-password".file = ../../secrets/stateless-uptime-kuma-password.age;
age.secrets."stateless-uptime-kuma-password".file =
../../secrets/stateless-uptime-kuma-password.age;
nixpkgs.overlays = [
(import "${inputs.stateless-uptime-kuma}/overlay.nix")
];
statelessUptimeKuma = {
enableService = true;
probesConfig.monitors = probesFromConfig;
probesConfig.monitors = monitorsFromConfig;
probesConfig.status_pages = pagesFromConfig;
extraFlags = [
"-s"
"-v DEBUG"

View file

@ -60,7 +60,8 @@
services.openssh.enable = true;
programs.ssh.knownHosts."darwin-build-box.winter.cafe".publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB0io9E0eXiDIEHvsibXOxOPveSjUPIr1RnNKbUkw3fD";
programs.ssh.knownHosts."darwin-build-box.winter.cafe".publicKey =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB0io9E0eXiDIEHvsibXOxOPveSjUPIr1RnNKbUkw3fD";
services.nginx.virtualHosts."photos.julienmalka.me" = {
enableACME = true;
@ -131,8 +132,8 @@
root = "/home/gitlab-runner/artifacts";
};
machine.meta.monitors."phd.julienmalka.me - IPv4".accepted_statuscodes = [ "401" ];
machine.meta.monitors."phd.julienmalka.me - IPv6".accepted_statuscodes = [ "401" ];
machine.meta.probes.monitors."phd.julienmalka.me - IPv4".accepted_statuscodes = [ "401" ];
machine.meta.probes.monitors."phd.julienmalka.me - IPv6".accepted_statuscodes = [ "401" ];
systemd.services.nginx.serviceConfig.ProtectHome = "read-only";
systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/home/gitlab-runner/artifacts" ];

View file

@ -45,6 +45,10 @@ in
);
inherit (cfg) user group;
};
machine.meta.probes.monitors."jackett.luj - IPv4".accepted_statuscodes = [ "400" ];
machine.meta.probes.monitors."jackett.luj - IPv6".accepted_statuscodes = [ "400" ];
}
(mkIf cfg.nginx.enable (mkVPNSubdomain cfg.nginx.subdomain port))

View file

@ -43,9 +43,27 @@
default = with profiles; [ base ];
};
monitors = mkOption {
default = { };
type = types.attrsOf (pkgs.formats.json { }).type;
probes = {
monitors = lib.mkOption {
type = types.attrsOf (pkgs.formats.json { }).type;
default = { };
};
tags = lib.mkOption {
type = types.attrsOf (pkgs.formats.json { }).type;
default = { };
};
notifications = lib.mkOption {
type = types.attrsOf (pkgs.formats.json { }).type;
default = { };
};
status_pages = lib.mkOption {
type = types.attrsOf (pkgs.formats.json { }).type;
default = { };
};
settings = lib.mkOption {
type = types.attrsOf (pkgs.formats.json { }).type;
default = { };
};
};
defaultInterface = mkOption {

View file

@ -59,7 +59,7 @@ in
'';
systemConfig = _: {
machine.meta.monitors = lib.mkIf (name != "default") {
machine.meta.probes.monitors = lib.mkIf (name != "default") {
"${name} - IPv4" = {
url = "https://${
if (hasSuffix "luj" name) then
@ -69,6 +69,7 @@ in
}";
type = "http";
accepted_statuscodes = [ "200-299" ];
notificationIDList = [ 1 ];
headers = ''
{
"Host": "${name}"
@ -84,6 +85,7 @@ in
}]";
type = "http";
accepted_statuscodes = [ "200-299" ];
notificationIDList = [ 1 ];
headers = ''
{
"Host": "${name}"

View file

@ -123,4 +123,24 @@
VfXtULncAiEA2gmqdr+ugFz5tvPdKwanroTiMTUMhhCRYVlQlyTApyQ=
-----END CERTIFICATE-----''
];
machine.meta.probes = {
status_pages."public" = {
title = "Public Services";
description = "State of my public infrastructure";
showTags = false;
publicGroupList =
lib.optionals ((builtins.length (lib.attrNames config.machine.meta.probes.monitors)) > 0)
[
{
name = config.networking.hostName;
weight = 1;
monitorList = builtins.filter (e: (lib.hasInfix ".luj.fr" e) || !(lib.hasInfix ".luj" e)) (
lib.attrNames config.machine.meta.probes.monitors
);
}
];
};
};
}