diff --git a/secrets.nix b/secrets.nix index 8e83190..caca9dc 100644 --- a/secrets.nix +++ b/secrets.nix @@ -9,6 +9,7 @@ let hydra-ssh-key-priv = [ machines.bagel-box ]; netbox-environment = [ machines.meta01 ]; mimir-environment = [ machines.meta01 ]; + mimir-webhook-url = [ machines.meta01 ]; grafana-oauth-secret = [ machines.meta01 ]; loki-environment = [ machines.meta01 ]; gerrit-prometheus-bearer-token = [ machines.gerrit01 machines.meta01 ]; diff --git a/secrets/mimir-webhook-url.age b/secrets/mimir-webhook-url.age new file mode 100644 index 0000000..b492d7d Binary files /dev/null and b/secrets/mimir-webhook-url.age differ diff --git a/services/monitoring/default.nix b/services/monitoring/default.nix index 1431b36..e972a3c 100644 --- a/services/monitoring/default.nix +++ b/services/monitoring/default.nix @@ -3,5 +3,6 @@ ./exporters ./lgtm ./agent.nix + ./hookshot-adapter ]; } \ No newline at end of file diff --git a/services/monitoring/hookshot-adapter/default.nix b/services/monitoring/hookshot-adapter/default.nix new file mode 100644 index 0000000..000c70e --- /dev/null +++ b/services/monitoring/hookshot-adapter/default.nix @@ -0,0 +1,30 @@ +{ + config, + lib, + pkgs, + ... +}: +let + cfg = config.bagel.services.alertmanager-hookshot-adapter; + inherit (lib) mkEnableOption mkIf; + package = pkgs.callPackage ./package.nix {}; +in +{ + options.bagel.services.alertmanager-hookshot-adapter.enable = mkEnableOption "alertmanager to matrix-hookshot adapter"; + + config = mkIf cfg.enable { + systemd.services.alertmanager-hookshot-adapter = { + wantedBy = ["multi-user.target"]; + wants = ["network-online.target"]; + after = ["network-online.target"]; + environment = { + PORT = "9100"; + UPSTREAM = "https://alerts.forkos.org/webhook"; + }; + serviceConfig = { + ExecStart = lib.getExe package; + DynamicUser = true; + }; + }; + }; +} diff --git a/services/monitoring/hookshot-adapter/package.json b/services/monitoring/hookshot-adapter/package.json new file mode 100644 index 0000000..4919b67 --- /dev/null +++ b/services/monitoring/hookshot-adapter/package.json @@ -0,0 +1,23 @@ +{ + "name": "alertmanager-hookshot-adapter", + "version": "1.0.0", + "description": "Adapter between alertmanager webhooks and the Matrix Hookshot Apapter", + "main": "index.ts", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/hm-edu/alertmanager-hookshot-adapter" + }, + "dependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.11.20", + "dotenv": "^16.4.5", + "express": "^4.18.2", + "node-fetch": "^3.3.2", + "typescript": "^5.3.3", + "winston": "^3.13.0" + }, + "scripts": { + "build": "npx tsc" + } +} diff --git a/services/monitoring/hookshot-adapter/package.nix b/services/monitoring/hookshot-adapter/package.nix new file mode 100644 index 0000000..68208e9 --- /dev/null +++ b/services/monitoring/hookshot-adapter/package.nix @@ -0,0 +1,40 @@ +{ + lib, + mkYarnPackage, + fetchFromGitHub, + fetchYarnDeps, + makeWrapper, + nodejs, +}: + +mkYarnPackage rec { + pname = "alertmanager-hookshot-adapter"; + version = "1.9.1"; + + src = fetchFromGitHub { + owner = "hm-edu"; + repo = "alertmanager-hookshot-adapter"; + rev = "v${version}"; + hash = "sha256-KTk70zFA1tymmR8AYrAl2XIyA+SPs5Uksd6Z3kvUb+o="; + }; + + packageJSON = ./package.json; + + offlineCache = fetchYarnDeps { + yarnLock = "${src}/yarn.lock"; + hash = "sha256-LU25cXB+0DdcHRzKQ1hjQIVntarqPOUXZTgcw6lvLRM="; + }; + + buildPhase = '' + yarn build + ''; + + nativeBuildInputs = [ makeWrapper ]; + + postInstall = '' + makeWrapper ${lib.getExe nodejs} $out/bin/alertmanager-hookshot-adapter \ + --add-flags $out/libexec/alertmanager-hookshot-adapter/deps/alertmanager-hookshot-adapter/dist/index.js + ''; + + meta.mainProgram = "alertmanager-hookshot-adapter"; +} diff --git a/services/monitoring/lgtm/mimir.nix b/services/monitoring/lgtm/mimir.nix index 14a67a2..8f571da 100644 --- a/services/monitoring/lgtm/mimir.nix +++ b/services/monitoring/lgtm/mimir.nix @@ -20,6 +20,7 @@ in owner = "nginx"; }; mimir-environment.file = ../../../secrets/mimir-environment.age; + mimir-webhook-url.file = ../../../secrets/mimir-webhook-url.age; }; services.mimir = { @@ -75,6 +76,11 @@ in receivers = [ { name = "matrix"; + webhook_configs = [{ + # Mimir can't expand environment variables in external config files, + # so work around it. + url_file = "/run/credentials/mimir.service/webhook-url"; + }]; } ]; }; @@ -91,7 +97,10 @@ in # Avoid that by ensuring it starts after the network is set up. wants = [ "network-online.target" ]; after = ["network-online.target"]; - serviceConfig.EnvironmentFile = [ config.age.secrets.mimir-environment.path ]; + serviceConfig = { + EnvironmentFile = [ config.age.secrets.mimir-environment.path ]; + LoadCredential = [ "webhook-url:${config.age.secrets.mimir-webhook-url.path}" ]; + }; }; services.nginx = { @@ -111,5 +120,6 @@ in }; bagel.monitoring.grafana-agent.exporters.mimir.port = 9009; + bagel.services.alertmanager-hookshot-adapter.enable = true; }; }