Unverified Commit f5fd09b3 authored by Aaron Andersen's avatar Aaron Andersen Committed by GitHub
Browse files

Merge pull request #231665 from aanderse/nixos/vmalert

nixos/vmalert: init
parents 4c1fb21f d098eec2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ In addition to numerous new and updated packages, this release has the following

- [ivpn](https://www.ivpn.net/), a secure, private VPN with fast WireGuard connections. Available as [services.ivpn](#opt-services.ivpn.enable).

- [vmalert](https://victoriametrics.com/), an alerting engine for VictoriaMetrics. Available as [services.vmalert](#opt-services.vmalert.enable).

- [jellyseerr](https://github.com/Fallenbagel/jellyseerr), a web-based requests manager for Jellyfin, forked from Overseerr. Available as [services.jellyseerr](#opt-services.jellyseerr.enable).

- [kavita](https://kavitareader.com), a self-hosted digital library. Available as [services.kavita](options.html#opt-services.kavita.enable).
+1 −0
Original line number Diff line number Diff line
@@ -777,6 +777,7 @@
  ./services/monitoring/uptime-kuma.nix
  ./services/monitoring/uptime.nix
  ./services/monitoring/vmagent.nix
  ./services/monitoring/vmalert.nix
  ./services/monitoring/vnstat.nix
  ./services/monitoring/zabbix-agent.nix
  ./services/monitoring/zabbix-proxy.nix
+136 −0
Original line number Diff line number Diff line
{ config, pkgs, lib, ... }: with lib;
let
  cfg = config.services.vmalert;

  format = pkgs.formats.yaml {};

  confOpts = concatStringsSep " \\\n" (mapAttrsToList mkLine (filterAttrs (_: v: v != false) cfg.settings));
  confType = with types;
    let
      valueType = oneOf [ bool int path str ];
    in
    attrsOf (either valueType (listOf valueType));

  mkLine = key: value:
    if value == true then "-${key}"
    else if isList value then concatMapStringsSep " " (v: "-${key}=${escapeShellArg (toString v)}") value
    else "-${key}=${escapeShellArg (toString value)}"
  ;
in
{
  # interface
  options.services.vmalert = {
    enable = mkEnableOption (mdDoc "vmalert");

    package = mkOption {
      type = types.package;
      default = pkgs.victoriametrics;
      defaultText = "pkgs.victoriametrics";
      description = mdDoc ''
        The VictoriaMetrics derivation to use.
      '';
    };

    settings = mkOption {
      type = types.submodule {
        freeformType = confType;
        options = {

          "datasource.url" = mkOption {
            type = types.nonEmptyStr;
            example = "http://localhost:8428";
            description = mdDoc ''
              Datasource compatible with Prometheus HTTP API.
            '';
          };

          "notifier.url" = mkOption {
            type = with types; listOf nonEmptyStr;
            default = [];
            example = [ "http://127.0.0.1:9093" ];
            description = mdDoc ''
              Prometheus Alertmanager URL. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability.
            '';
          };

          "rule" = mkOption {
            type = with types; listOf path;
            description = mdDoc ''
              Path to the files with alerting and/or recording rules.

              ::: {.note}
              Consider using the {option}`services.vmalert.rules` option as a convenient alternative for declaring rules
              directly in the `nix` language.
              :::
            '';
          };

        };
      };
      default = { };
      example = {
        "datasource.url" = "http://localhost:8428";
        "datasource.disableKeepAlive" = true;
        "datasource.showURL" = false;
        "rule" = [
          "http://<some-server-addr>/path/to/rules"
          "dir/*.yaml"
        ];
      };
      description = mdDoc ''
        `vmalert` configuration, passed via command line flags. Refer to
        <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#configuration>
        for details on supported values.
      '';
    };

    rules = mkOption {
      type = format.type;
      default = {};
      example = {
        group = [
          { name = "TestGroup";
            rules = [
              { alert = "ExampleAlertAlwaysFiring";
                expr = ''
                  sum by(job)
                  (up == 1)
                '';
              }
            ];
          }
        ];
      };
      description = mdDoc ''
        A list of the given alerting or recording rules against configured `"datasource.url"` compatible with
        Prometheus HTTP API for `vmalert` to execute. Refer to
        <https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/app/vmalert/README.md#rules>
        for details on supported values.
      '';
    };
  };

  # implementation
  config = mkIf cfg.enable {

    environment.etc."vmalert/rules.yml".source = format.generate "rules.yml" cfg.rules;

    services.vmalert.settings.rule = [
      "/etc/vmalert/rules.yml"
    ];

    systemd.services.vmalert = {
      description = "vmalert service";
      wantedBy = [ "multi-user.target" ];
      after = [ "network.target" ];
      reloadTriggers = [ config.environment.etc."vmalert/rules.yml".source ];

      serviceConfig = {
        DynamicUser = true;
        Restart = "on-failure";
        ExecStart = "${cfg.package}/bin/vmalert ${confOpts}";
        ExecReload = ''${pkgs.coreutils}/bin/kill -SIGHUP "$MAINPID"'';
      };
    };
  };
}