mirror of
https://github.com/SebastianStork/nixos-config.git
synced 2026-03-22 21:19:07 +01:00
Compare commits
2 commits
7557252b22
...
e2f312b2c5
| Author | SHA1 | Date | |
|---|---|---|---|
| e2f312b2c5 | |||
| e69e9c8491 |
12 changed files with 37 additions and 33 deletions
|
|
@ -11,8 +11,11 @@
|
|||
|
||||
genAttrs = f: names: lib.genAttrs names f;
|
||||
|
||||
mkInvalidConfigMessage = subject: reason: "Invalid configuration for ${subject}: ${reason}.";
|
||||
|
||||
mkUnprotectedMessage =
|
||||
name: "${name} should only be exposed on private networks; access control isn't yet configured";
|
||||
name:
|
||||
self.lib.mkInvalidConfigMessage name "the service must use a private domain until access control is configured";
|
||||
|
||||
relativePath = path: path |> toString |> lib.removePrefix "${self}/";
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ in
|
|||
systemd.user.services.ntfy-client = {
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
Unit = {
|
||||
Description = "ntfy client subscriber";
|
||||
Description = "ntfy client subscription";
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
After = [ "graphical-session.target" ];
|
||||
X-Restart-Triggers = [ config.xdg.configFile."ntfy/client.yml".source ];
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ in
|
|||
default = "${self}/users/${config.home.username}/@${osConfig.networking.hostName}/secrets.json";
|
||||
};
|
||||
secretsData = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
type = lib.types.attrs;
|
||||
default = cfg.secretsFile |> lib.readFile |> lib.strings.fromJSON;
|
||||
};
|
||||
};
|
||||
|
|
@ -43,7 +43,7 @@ in
|
|||
|> lib.attrNames
|
||||
|> lib.map (secretPath: {
|
||||
assertion = cfg.secretsData |> lib.hasAttrByPath (secretPath |> lib.splitString "/");
|
||||
message = "Sops secret `${secretPath}` is used in a module but not defined in secrets.json";
|
||||
message = self.lib.mkInvalidConfigMessage "SOPS secret `${secretPath}`" "it is used in a module but not defined in `secrets.json`";
|
||||
})
|
||||
)
|
||||
++ (
|
||||
|
|
@ -51,7 +51,7 @@ in
|
|||
|> lib.mapAttrsToListRecursive (path: _: path |> lib.concatStringsSep "/")
|
||||
|> lib.map (secretPath: {
|
||||
assertion = config.sops.secrets |> lib.hasAttr secretPath;
|
||||
message = "Sops secret `${secretPath}` is defined in secrets.json but not used in any module";
|
||||
message = self.lib.mkInvalidConfigMessage "SOPS secret `${secretPath}`" "it is defined in `secrets.json` but not used in any module";
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ in
|
|||
};
|
||||
|
||||
nodes = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default =
|
||||
allHosts
|
||||
|> lib.attrValues
|
||||
|
|
@ -31,7 +31,7 @@ in
|
|||
readOnly = true;
|
||||
};
|
||||
peers = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
type = lib.types.listOf lib.types.attrs;
|
||||
default = cfg.nodes |> lib.filter (node: node.hostName != cfg.hostName);
|
||||
readOnly = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ in
|
|||
};
|
||||
|
||||
dnsServers = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
type = lib.types.listOf lib.types.nonEmptyStr;
|
||||
default =
|
||||
allHosts
|
||||
|> lib.attrValues
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
config,
|
||||
self,
|
||||
lib,
|
||||
allHosts,
|
||||
...
|
||||
|
|
@ -38,7 +39,7 @@ in
|
|||
|> lib.filter (name: name != "system")
|
||||
|> lib.map (name: {
|
||||
assertion = cfg.collect.metrics.${name} -> config.services.${name}.enable;
|
||||
message = "Alloy cannot collect `${name}` metrics without the `${name}` service";
|
||||
message = self.lib.mkInvalidConfigMessage "Alloy metric collection for `${name}`" "the `${name}` service is not enabled";
|
||||
});
|
||||
|
||||
services.alloy = {
|
||||
|
|
|
|||
|
|
@ -91,11 +91,11 @@ in
|
|||
|> lib.concatMap (vHost: [
|
||||
{
|
||||
assertion = (vHost.port == null) || (vHost.files == null);
|
||||
message = "Caddy virtual host `${vHost.domain}` cannot set both `port` and `files`";
|
||||
message = self.lib.mkInvalidConfigMessage "Caddy virtual host `${vHost.domain}`" "`port` and `files` cannot be set at the same time";
|
||||
}
|
||||
{
|
||||
assertion = (vHost.port != null) || (vHost.files != null) || (vHost.extraConfig != null);
|
||||
message = "Caddy virtual host `${vHost.domain}` must set at least one of `port`, `files` or `extraConfig`";
|
||||
message = self.lib.mkInvalidConfigMessage "Caddy virtual host `${vHost.domain}`" "one of `port`, `files` or `extraConfig` must be set";
|
||||
}
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ in
|
|||
config = lib.mkIf cfg.enable {
|
||||
assertions = lib.singleton {
|
||||
assertion = netCfg.overlay.isLighthouse -> cfg.advertise.address != null;
|
||||
message = "`${netCfg.hostName}` is a Nebula lighthouse, but `underlay.isPublic` or `overlay.advertise.address` are not set. Lighthouses must be publicly reachable.";
|
||||
message = self.lib.mkInvalidConfigMessage "Nebula lighthouse `${netCfg.hostName}`" "`underlay.isPublic` must be enabled or `services.nebula.advertise.address` must be set so the host is publicly reachable";
|
||||
};
|
||||
|
||||
sops.secrets."nebula/host-key" = lib.mkIf (cfg.privateKeyFile == null) {
|
||||
|
|
|
|||
|
|
@ -96,10 +96,10 @@ in
|
|||
expr = ''absent_over_time(up{instance="${hostName}", job="node"}[2m])'';
|
||||
labels.severity = "critical";
|
||||
annotations = {
|
||||
summary = "${hostName} is DOWN";
|
||||
summary_resolved = "${hostName} is up again";
|
||||
description = "No metrics received for over 2 minutes.";
|
||||
description_resolved = "Metrics are being received again.";
|
||||
summary = "Host ${hostName} is down";
|
||||
summary_resolved = "Host ${hostName} is up again";
|
||||
description = "Prometheus has not received node metrics from ${hostName} for 2 minutes.";
|
||||
description_resolved = "Prometheus is receiving node metrics from ${hostName} again.";
|
||||
};
|
||||
})
|
||||
)
|
||||
|
|
@ -109,20 +109,20 @@ in
|
|||
expr = ''up{job=~"prometheus|alertmanager"} == 0'';
|
||||
for = "2m";
|
||||
annotations = {
|
||||
summary = "{{ $labels.job | title }} on {{ $labels.instance }} is DOWN";
|
||||
summary_resolved = "{{ $labels.job | title }} on {{ $labels.instance }} is up again";
|
||||
description = "Unresponsive for over 2 minutes.";
|
||||
description_resolved = "Responding normally.";
|
||||
summary = "Service {{ $labels.job | title }} on {{ $labels.instance }} is down";
|
||||
summary_resolved = "Service {{ $labels.job | title }} on {{ $labels.instance }} is up again";
|
||||
description = "Prometheus has not received scrape data for 2 minutes.";
|
||||
description_resolved = "Prometheus is receiving scrape data again.";
|
||||
};
|
||||
}
|
||||
{
|
||||
alert = "CominDeploymentFailed";
|
||||
expr = ''comin_deployment_info{status!="done"}'';
|
||||
annotations = {
|
||||
summary = "{{ $labels.instance }} deployment failed";
|
||||
summary_resolved = "{{ $labels.instance }} deployment recovered";
|
||||
description = "Deployment is not reaching \"done\" status.";
|
||||
description_resolved = "Deployment completed successfully.";
|
||||
summary = "Deployment on {{ $labels.instance }} failed";
|
||||
summary_resolved = "Deployment on {{ $labels.instance }} succeeded again";
|
||||
description = "Comin reports a deployment status other than \"done\".";
|
||||
description_resolved = "Comin reports the deployment status as \"done\" again.";
|
||||
};
|
||||
}
|
||||
{
|
||||
|
|
@ -130,10 +130,10 @@ in
|
|||
expr = "count(count by (commit_id) (comin_deployment_info)) > 1";
|
||||
for = "10m";
|
||||
annotations = {
|
||||
summary = "Hosts are running different commits";
|
||||
summary_resolved = "All hosts are running the same commit again";
|
||||
description = "Possibly a failed deployment or incompatible configurations.";
|
||||
description_resolved = "All hosts are in sync.";
|
||||
summary = "Deployment commits are out of sync";
|
||||
summary_resolved = "Deployment commits are in sync again";
|
||||
description = "Comin reports different deployed commits across hosts.";
|
||||
description_resolved = "Comin reports the same deployed commit across all hosts again.";
|
||||
};
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ in
|
|||
default = [ ];
|
||||
};
|
||||
extraConfig = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.anything;
|
||||
type = lib.types.attrs;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ in
|
|||
|
||||
systemd.services = {
|
||||
"healthcheck-ping@" = {
|
||||
description = "Pings healthcheck (%i)";
|
||||
description = "Ping Healthchecks for %i";
|
||||
serviceConfig.Type = "oneshot";
|
||||
scriptArgs = "%i";
|
||||
script = ''
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ in
|
|||
default = "${self}/hosts/${config.networking.hostName}/secrets.json";
|
||||
};
|
||||
secretsData = lib.mkOption {
|
||||
type = lib.types.anything;
|
||||
type = lib.types.attrs;
|
||||
default = cfg.secretsFile |> lib.readFile |> lib.strings.fromJSON;
|
||||
};
|
||||
};
|
||||
|
|
@ -41,7 +41,7 @@ in
|
|||
|> lib.attrNames
|
||||
|> lib.map (secretPath: {
|
||||
assertion = cfg.secretsData |> lib.hasAttrByPath (secretPath |> lib.splitString "/");
|
||||
message = "Sops secret `${secretPath}` is used in a module but not defined in secrets.json";
|
||||
message = self.lib.mkInvalidConfigMessage "SOPS secret `${secretPath}`" "it is used in a module but not defined in `secrets.json`";
|
||||
})
|
||||
)
|
||||
++ (
|
||||
|
|
@ -49,7 +49,7 @@ in
|
|||
|> lib.mapAttrsToListRecursive (path: _: path |> lib.concatStringsSep "/")
|
||||
|> lib.map (secretPath: {
|
||||
assertion = config.sops.secrets |> lib.hasAttr secretPath;
|
||||
message = "Sops secret `${secretPath}` is defined in secrets.json but not used in any module";
|
||||
message = self.lib.mkInvalidConfigMessage "SOPS secret `${secretPath}`" "it is defined in `secrets.json` but not used in any module";
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue