2016-09-19 18:09:26 +02:00
|
|
|
{
|
|
|
|
config,
|
|
|
|
pkgs,
|
|
|
|
lib,
|
|
|
|
...
|
|
|
|
}:
|
|
|
|
let
|
|
|
|
cfg = config.services.prometheus.alertmanager;
|
|
|
|
mkConfigFile = pkgs.writeText "alertmanager.yml" (builtins.toJSON cfg.configuration);
|
2018-11-04 16:58:13 +01:00
|
|
|
|
2022-12-21 12:29:48 +01:00
|
|
|
checkedConfig =
|
|
|
|
file:
|
|
|
|
if cfg.checkConfig then
|
2023-10-14 16:45:18 +02:00
|
|
|
pkgs.runCommand "checked-config" { nativeBuildInputs = [ cfg.package ]; } ''
|
2022-12-21 12:29:48 +01:00
|
|
|
ln -s ${file} $out
|
|
|
|
amtool check-config $out
|
|
|
|
''
|
|
|
|
else
|
|
|
|
file;
|
2024-12-10 20:26:33 +01:00
|
|
|
|
2018-11-04 16:58:13 +01:00
|
|
|
alertmanagerYml =
|
|
|
|
let
|
|
|
|
yml =
|
|
|
|
if cfg.configText != null then pkgs.writeText "alertmanager.yml" cfg.configText else mkConfigFile;
|
|
|
|
in
|
|
|
|
checkedConfig yml;
|
2024-12-10 20:26:33 +01:00
|
|
|
|
2018-09-04 23:19:26 +02:00
|
|
|
cmdlineArgs =
|
|
|
|
cfg.extraFlags
|
|
|
|
++ [
|
2020-01-23 13:51:00 +01:00
|
|
|
"--config.file /tmp/alert-manager-substituted.yaml"
|
2018-09-04 23:19:26 +02:00
|
|
|
"--web.listen-address ${cfg.listenAddress}:${toString cfg.port}"
|
|
|
|
"--log.level ${cfg.logLevel}"
|
2020-04-13 18:39:51 +02:00
|
|
|
"--storage.path /var/lib/alertmanager"
|
|
|
|
(toString (map (peer: "--cluster.peer ${peer}:9094") cfg.clusterPeers))
|
2024-08-30 00:47:01 +02:00
|
|
|
]
|
|
|
|
++ (lib.optional (cfg.webExternalUrl != null) "--web.external-url ${cfg.webExternalUrl}")
|
|
|
|
++ (lib.optional (cfg.logFormat != null) "--log.format ${cfg.logFormat}");
|
2016-09-19 18:09:26 +02:00
|
|
|
in
|
|
|
|
{
|
2019-12-10 02:51:19 +01:00
|
|
|
imports = [
|
2024-08-30 00:47:01 +02:00
|
|
|
(lib.mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "user" ]
|
|
|
|
"The alertmanager service is now using systemd's DynamicUser mechanism which obviates a user setting."
|
|
|
|
)
|
|
|
|
(lib.mkRemovedOptionModule [ "services" "prometheus" "alertmanager" "group" ]
|
|
|
|
"The alertmanager service is now using systemd's DynamicUser mechanism which obviates a group setting."
|
|
|
|
)
|
|
|
|
(lib.mkRemovedOptionModule [ "services" "prometheus" "alertmanagerURL" ] ''
|
2019-12-10 02:51:19 +01:00
|
|
|
Due to incompatibility, the alertmanagerURL option has been removed,
|
2022-12-10 20:11:18 +01:00
|
|
|
please use 'services.prometheus.alertmanagers' instead.
|
2019-12-10 02:51:19 +01:00
|
|
|
'')
|
|
|
|
];
|
|
|
|
|
2016-09-19 18:09:26 +02:00
|
|
|
options = {
|
|
|
|
services.prometheus.alertmanager = {
|
2024-08-30 00:47:01 +02:00
|
|
|
enable = lib.mkEnableOption "Prometheus Alertmanager";
|
2016-09-19 18:09:26 +02:00
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
package = lib.mkPackageOption pkgs "prometheus-alertmanager" { };
|
2018-11-04 16:57:47 +01:00
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
configuration = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.attrs;
|
2018-11-04 19:27:43 +01:00
|
|
|
default = null;
|
2016-09-19 18:09:26 +02:00
|
|
|
description = ''
|
|
|
|
Alertmanager configuration as nix attribute set.
|
2024-04-08 11:00:14 +02:00
|
|
|
|
|
|
|
The contents of the resulting config file are processed using envsubst.
|
|
|
|
`$` needs to be escaped as `$$` to be preserved.
|
2016-09-19 18:09:26 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
configText = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.lines;
|
2016-12-22 23:18:39 +01:00
|
|
|
default = null;
|
|
|
|
description = ''
|
|
|
|
Alertmanager configuration as YAML text. If non-null, this option
|
|
|
|
defines the text that is written to alertmanager.yml. If null, the
|
|
|
|
contents of alertmanager.yml is generated from the structured config
|
|
|
|
options.
|
2024-04-08 11:00:14 +02:00
|
|
|
|
|
|
|
The contents of the resulting config file are processed using envsubst.
|
|
|
|
`$` needs to be escaped as `$$` to be preserved.
|
2016-12-22 23:18:39 +01:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
checkConfig = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
2022-12-21 12:29:48 +01:00
|
|
|
default = true;
|
|
|
|
description = ''
|
|
|
|
Check configuration with `amtool check-config`. The call to `amtool` is
|
|
|
|
subject to sandboxing by Nix.
|
|
|
|
|
|
|
|
If you use credentials stored in external files
|
|
|
|
(`environmentFile`, etc),
|
|
|
|
they will not be visible to `amtool`
|
|
|
|
and it will report errors, despite a correct configuration.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
logFormat = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.str;
|
2016-09-19 18:09:26 +02:00
|
|
|
default = null;
|
|
|
|
description = ''
|
|
|
|
If set use a syslog logger or JSON logging.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
logLevel = lib.mkOption {
|
|
|
|
type = lib.types.enum [
|
|
|
|
"debug"
|
|
|
|
"info"
|
|
|
|
"warn"
|
|
|
|
"error"
|
|
|
|
"fatal"
|
|
|
|
];
|
2016-09-19 18:09:26 +02:00
|
|
|
default = "warn";
|
|
|
|
description = ''
|
|
|
|
Only log messages with the given severity or above.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
webExternalUrl = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.str;
|
2016-09-19 18:09:26 +02:00
|
|
|
default = null;
|
|
|
|
description = ''
|
|
|
|
The URL under which Alertmanager is externally reachable (for example, if Alertmanager is served via a reverse proxy).
|
|
|
|
Used for generating relative and absolute links back to Alertmanager itself.
|
|
|
|
If the URL has a path portion, it will be used to prefix all HTTP endoints served by Alertmanager.
|
|
|
|
If omitted, relevant URL components will be derived automatically.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
listenAddress = lib.mkOption {
|
|
|
|
type = lib.types.str;
|
2016-12-27 23:00:15 +01:00
|
|
|
default = "";
|
2016-09-19 18:09:26 +02:00
|
|
|
description = ''
|
2019-02-27 00:59:11 +11:00
|
|
|
Address to listen on for the web interface and API. Empty string will listen on all interfaces.
|
|
|
|
"localhost" will listen on 127.0.0.1 (but not ::1).
|
2016-09-19 18:09:26 +02:00
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
port = lib.mkOption {
|
|
|
|
type = lib.types.port;
|
2016-09-19 18:09:26 +02:00
|
|
|
default = 9093;
|
|
|
|
description = ''
|
|
|
|
Port to listen on for the web interface and API.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
openFirewall = lib.mkOption {
|
|
|
|
type = lib.types.bool;
|
2016-09-19 18:09:26 +02:00
|
|
|
default = false;
|
|
|
|
description = ''
|
|
|
|
Open port in firewall for incoming connections.
|
|
|
|
'';
|
|
|
|
};
|
2018-09-04 23:19:26 +02:00
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
clusterPeers = lib.mkOption {
|
|
|
|
type = lib.types.listOf lib.types.str;
|
2020-04-13 18:39:51 +02:00
|
|
|
default = [ ];
|
|
|
|
description = ''
|
|
|
|
Initial peers for HA cluster.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
extraFlags = lib.mkOption {
|
|
|
|
type = lib.types.listOf lib.types.str;
|
2018-09-04 23:19:26 +02:00
|
|
|
default = [ ];
|
|
|
|
description = ''
|
|
|
|
Extra commandline options when launching the Alertmanager.
|
|
|
|
'';
|
|
|
|
};
|
2020-01-23 13:51:00 +01:00
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
environmentFile = lib.mkOption {
|
|
|
|
type = lib.types.nullOr lib.types.path;
|
2020-01-23 13:51:00 +01:00
|
|
|
default = null;
|
|
|
|
example = "/root/alertmanager.env";
|
|
|
|
description = ''
|
2020-01-24 18:07:24 +01:00
|
|
|
File to load as environment file. Environment variables
|
|
|
|
from this file will be interpolated into the config file
|
|
|
|
using envsubst with this syntax:
|
|
|
|
`$ENVIRONMENT ''${VARIABLE}`
|
2020-01-23 13:51:00 +01:00
|
|
|
'';
|
|
|
|
};
|
2016-09-19 18:09:26 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-08-30 00:47:01 +02:00
|
|
|
config = lib.mkMerge [
|
|
|
|
(lib.mkIf cfg.enable {
|
|
|
|
assertions = lib.singleton {
|
2018-11-04 19:27:43 +01:00
|
|
|
assertion = cfg.configuration != null || cfg.configText != null;
|
|
|
|
message =
|
|
|
|
"Can not enable alertmanager without a configuration. "
|
|
|
|
+ "Set either the `configuration` or `configText` attribute.";
|
|
|
|
};
|
|
|
|
})
|
2024-08-30 00:47:01 +02:00
|
|
|
(lib.mkIf cfg.enable {
|
|
|
|
networking.firewall.allowedTCPPorts = lib.optional cfg.openFirewall cfg.port;
|
2018-11-04 19:27:43 +01:00
|
|
|
|
|
|
|
systemd.services.alertmanager = {
|
|
|
|
wantedBy = [ "multi-user.target" ];
|
2023-10-03 23:23:30 -07:00
|
|
|
wants = [ "network-online.target" ];
|
2020-03-17 22:12:48 +01:00
|
|
|
after = [ "network-online.target" ];
|
2020-01-23 13:51:00 +01:00
|
|
|
preStart = ''
|
2020-01-28 00:32:11 +01:00
|
|
|
${lib.getBin pkgs.envsubst}/bin/envsubst -o "/tmp/alert-manager-substituted.yaml" \
|
|
|
|
-i "${alertmanagerYml}"
|
2020-01-23 13:51:00 +01:00
|
|
|
'';
|
2018-11-04 19:27:43 +01:00
|
|
|
serviceConfig = {
|
2019-04-10 15:03:09 +02:00
|
|
|
ExecStart =
|
|
|
|
"${cfg.package}/bin/alertmanager"
|
2024-08-30 00:47:01 +02:00
|
|
|
+ lib.optionalString (lib.length cmdlineArgs != 0) (
|
|
|
|
" \\\n " + lib.concatStringsSep " \\\n " cmdlineArgs
|
|
|
|
);
|
2018-11-04 19:27:43 +01:00
|
|
|
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
2024-06-24 00:13:04 +01:00
|
|
|
|
|
|
|
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
|
|
|
|
|
|
|
|
CapabilityBoundingSet = [ "" ];
|
|
|
|
DeviceAllow = [ "" ];
|
|
|
|
DynamicUser = true;
|
|
|
|
NoNewPrivileges = true;
|
|
|
|
|
|
|
|
MemoryDenyWriteExecute = true;
|
|
|
|
|
|
|
|
LockPersonality = true;
|
|
|
|
|
|
|
|
ProtectProc = "invisible";
|
|
|
|
ProtectSystem = "strict";
|
|
|
|
ProtectHome = "tmpfs";
|
|
|
|
|
|
|
|
PrivateTmp = true;
|
|
|
|
PrivateDevices = true;
|
|
|
|
PrivateIPC = true;
|
|
|
|
|
|
|
|
ProcSubset = "pid";
|
|
|
|
|
|
|
|
ProtectHostname = true;
|
|
|
|
ProtectClock = true;
|
|
|
|
ProtectKernelTunables = true;
|
|
|
|
ProtectKernelModules = true;
|
|
|
|
ProtectKernelLogs = true;
|
|
|
|
ProtectControlGroups = true;
|
|
|
|
|
|
|
|
Restart = "always";
|
|
|
|
|
|
|
|
RestrictAddressFamilies = [
|
|
|
|
"AF_INET"
|
|
|
|
"AF_INET6"
|
|
|
|
"AF_NETLINK"
|
|
|
|
];
|
|
|
|
RestrictNamespaces = true;
|
|
|
|
RestrictRealtime = true;
|
|
|
|
RestrictSUIDSGID = true;
|
|
|
|
|
|
|
|
StateDirectory = "alertmanager";
|
|
|
|
SystemCallFilter = [
|
|
|
|
"@system-service"
|
|
|
|
"~@cpu-emulation"
|
|
|
|
"~@privileged"
|
|
|
|
"~@reboot"
|
|
|
|
"~@setuid"
|
|
|
|
"~@swap"
|
|
|
|
];
|
|
|
|
|
|
|
|
WorkingDirectory = "/tmp";
|
2018-11-04 19:27:43 +01:00
|
|
|
};
|
2016-09-19 18:09:26 +02:00
|
|
|
};
|
2018-11-04 19:27:43 +01:00
|
|
|
})
|
|
|
|
];
|
2016-09-19 18:09:26 +02:00
|
|
|
}
|