feat(monitoring): service status lookup

This commit is contained in:
arcnmx 2024-05-31 18:14:37 -07:00
parent f97ab24f47
commit ebfd1f5a9a
12 changed files with 273 additions and 103 deletions

View file

@ -161,11 +161,11 @@
serviceId ? null,
service ? system.exports.services.${serviceName},
portName ? "default",
port ? service.ports.${portName},
network ? "lan",
scheme ? null,
getAddressFor ? "getAddressFor",
}: let
port = service.ports.${portName};
scheme' =
if scheme == null
then port.protocol

View file

@ -28,6 +28,7 @@ in {
};
in {
id = mkAlmostOptionDefault "home";
displayName = mkAlmostOptionDefault "Home Assistant";
nixos = {
serviceAttr = "home-assistant";
assertions = mkIf config.enable [
@ -36,13 +37,14 @@ in {
];
};
defaults.port.listen = mkAlmostOptionDefault "lan";
ports = mapAttrs (_: mapAlmostOptionDefaults) {
ports = {
default = {
port = 8123;
port = mkAlmostOptionDefault 8123;
protocol = "http";
status.enable = true;
};
homekit0 = {
port = 21063;
port = mkAlmostOptionDefault 21063;
transport = "tcp";
};
# TODO: cast udp port range 32768 to 60999

View file

@ -12,6 +12,7 @@ in {
default = {
port = 389;
transport = "tcp";
starttls = true;
};
ssl = {
port = 636;

View file

@ -1,9 +1,61 @@
let
portModule = {lib, ...}: let
inherit (lib.options) mkEnableOption;
portModule = {config, gensokyo-zone, lib, ...}: let
inherit (gensokyo-zone.lib) unmerged;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
in {
options.prometheus = with lib.types; {
exporter.enable = mkEnableOption "prometheus metrics endpoint";
options = with lib.types; {
prometheus = {
exporter.enable = mkEnableOption "prometheus metrics endpoint";
};
status = {
enable = mkEnableOption "status checks";
alert = {
enable = mkEnableOption "health check alerts" // {
default = true;
};
};
gatus = {
enable = mkEnableOption "gatus" // {
default = true;
};
settings = mkOption {
type = unmerged.types.attrs;
};
protocol = mkOption {
type = str;
};
};
};
};
config = {
status.gatus = let
defaultProtocol =
if config.protocol != null then mkOptionDefault config.protocol
else if config.starttls then mkOptionDefault "starttls"
else if config.ssl then mkOptionDefault "tls"
else if config.transport != "unix" then mkOptionDefault config.transport
else mkIf false (throw "unreachable");
in {
protocol = defaultProtocol;
settings = mkMerge [
{
conditions = mkMerge [
(mkIf (config.ssl || config.starttls) (mkOptionDefault [
"[CERTIFICATE_EXPIRATION] > 72h"
]))
(mkOptionDefault [
"[CONNECTED] == true"
])
];
}
(mkIf (config.protocol == "http" || config.protocol == "https") {
conditions = mkOptionDefault [
"[STATUS] == 200"
];
})
];
};
};
};
serviceModule = {
@ -18,6 +70,7 @@ let
inherit (lib.modules) mkOptionDefault;
inherit (lib.attrsets) attrNames filterAttrs;
exporterPorts = filterAttrs (_: port: port.enable && port.prometheus.exporter.enable) config.ports;
statusPorts = filterAttrs (_: port: port.enable && port.status.enable) config.ports;
in {
options = with lib.types; {
prometheus = {
@ -34,14 +87,19 @@ let
};
};
};
status = {
ports = mkOption {
type = listOf str;
};
};
ports = mkOption {
type = attrsOf (submoduleWith {
modules = [portModule];
});
};
};
config.prometheus = {
exporter = {
config = {
prometheus.exporter = {
ports = mkOptionDefault (attrNames exporterPorts);
labels = mapOptionDefaults {
gensokyo_exports_service = config.name;
@ -50,6 +108,9 @@ let
gensokyo_host = system.access.fqdn;
};
};
status = {
ports = mkOptionDefault (attrNames statusPorts);
};
};
};
in
@ -83,7 +144,7 @@ in
protocol = "http";
}
// {
prometheus.exporter.enable = true;
prometheus.exporter.enable = mkAlmostOptionDefault true;
};
});
exporters = mapListToAttrs mkExporter [
@ -99,6 +160,11 @@ in
type = listOf str;
};
};
status = {
services = mkOption {
type = listOf str;
};
};
services = mkOption {
type = attrsOf (submoduleWith {
modules = [serviceModule];
@ -110,6 +176,11 @@ in
in {
exporter.services = mkOptionDefault (attrNames exporterServices);
};
config.exports.status = let
statusServices = filterAttrs (_: service: service.enable && service.status.ports != []) config.exports.services;
in {
services = mkOptionDefault (attrNames statusServices);
};
config.exports.services =
{
prometheus = {config, ...}: {
@ -122,9 +193,10 @@ in
})
];
};
ports.default = mapAlmostOptionDefaults {
port = 9090;
ports.default = {
port = mkAlmostOptionDefault 9090;
protocol = "http";
status.enable = mkAlmostOptionDefault true;
};
};
grafana = {config, ...}: {
@ -138,11 +210,10 @@ in
})
];
};
ports.default = mapAlmostOptionDefaults {
port = 9092;
ports.default = {
port = mkAlmostOptionDefault 9092;
protocol = "http";
} // {
prometheus.exporter.enable = true;
prometheus.exporter.enable = mkAlmostOptionDefault true;
};
};
loki = {config, ...}: {
@ -196,18 +267,15 @@ in
})
];
};
ports.default =
mapAlmostOptionDefaults {
port = 9094;
protocol = "http";
}
// {
prometheus.exporter.enable = true;
};
ports.default = {
port = mkAlmostOptionDefault 9094;
protocol = "http";
prometheus.exporter.enable = mkAlmostOptionDefault true;
};
#ports.grpc = ...
};
gatus = {config, ...}: {
id = mkAlmostOptionDefault "gatus";
id = mkAlmostOptionDefault "status";
nixos = {
serviceAttr = "gatus";
assertions = mkIf config.enable [
@ -217,11 +285,11 @@ in
})
];
};
ports.default =
mapAlmostOptionDefaults {
port = 9095;
protocol = "http";
};
ports.default = {
port = mkAlmostOptionDefault 9095;
protocol = "http";
prometheus.exporter.enable = mkAlmostOptionDefault true;
};
#ports.grpc = ...
};
}

View file

@ -42,6 +42,10 @@
type = bool;
default = false;
};
starttls = mkOption {
type = bool;
default = false;
};
port = mkOption {
type = nullOr int;
};
@ -71,6 +75,10 @@
type = str;
default = name;
};
displayName = mkOption {
type = str;
default = name;
};
id = mkOption {
type = str;
default = config.name;

View file

@ -8,6 +8,7 @@
in {
config.exports.services.zigbee2mqtt = {config, ...}: {
id = mkAlmostOptionDefault "z2m";
displayName = mkAlmostOptionDefault "Zigbee2MQTT";
nixos = {
serviceAttr = "zigbee2mqtt";
assertions = mkIf config.enable [
@ -17,9 +18,10 @@ in {
})
];
};
ports.default = mapAlmostOptionDefaults {
port = 8072;
ports.default = {
port = mkAlmostOptionDefault 8072;
protocol = "http";
status.enable = true;
};
};
}