From 85e626ad63acf1a9ac2ba83c8110a7d5d2ca1f1c Mon Sep 17 00:00:00 2001
From: Florian Sesser <florian@private.storage>
Date: Thu, 30 Sep 2021 11:43:03 +0000
Subject: [PATCH] Make Grafana read the Slack Alerter URL from its environment

Unfortunately still prints a bold warning on deployment.
---
 morph/grid/local/grid.nix                     |  2 +-
 .../local/private-keys/grafanaEnvironment     |  2 ++
 morph/lib/customize-monitoring.nix            | 24 +++++++++++++++----
 nixos/modules/monitoring/server/grafana.nix   | 24 +++++++++++++------
 4 files changed, 39 insertions(+), 13 deletions(-)
 create mode 100644 morph/grid/local/private-keys/grafanaEnvironment

diff --git a/morph/grid/local/grid.nix b/morph/grid/local/grid.nix
index 75d0d7fd..10243cea 100644
--- a/morph/grid/local/grid.nix
+++ b/morph/grid/local/grid.nix
@@ -108,7 +108,7 @@ let
         inherit hostsMap vpnClientIPs nodeExporterTargets paymentExporterTargets;
         inherit (grid-config) letsEncryptAdminEmail;
         googleOAuthClientID = grid-config.monitoringGoogleOAuthClientID;
-        # slackAlertChannelSecretUrl = lib.readFile ;
+        enableSlackAlert = true;
         monitoringvpnIPv4 = "172.23.23.1";
         stateVersion = "19.09";
       })
diff --git a/morph/grid/local/private-keys/grafanaEnvironment b/morph/grid/local/private-keys/grafanaEnvironment
new file mode 100644
index 00000000..cb7dd1ae
--- /dev/null
+++ b/morph/grid/local/private-keys/grafanaEnvironment
@@ -0,0 +1,2 @@
+SLACKURL=https://hooks.slack.com/services/x/y/z
+
diff --git a/morph/lib/customize-monitoring.nix b/morph/lib/customize-monitoring.nix
index b3b21740..8faffad2 100644
--- a/morph/lib/customize-monitoring.nix
+++ b/morph/lib/customize-monitoring.nix
@@ -32,9 +32,10 @@
   # logins to Grafana.
 , googleOAuthClientID
 
-  # A (secret) Slack URL to post alerts to.  Make one for your Slack channel
-  # at https://www.slack.com/apps/A0F7XDUAZ.
-, slackAlertChannelSecretUrl ? ""
+  # Whether or not to enable slack alerting. Expects a SLACKURL environment
+  # variable with the secret URL. Get the secret URL for your Slack at
+  # https://www.slack.com/apps/A0F7XDUAZ.
+, enableSlackAlert ? false
 
   # A string giving the NixOS state version for the system.
 , stateVersion
@@ -75,12 +76,25 @@ in {
           action = ["sudo" "systemctl" "restart" "grafana.service"];
         };
       };
+    grafanaEnvironment =
+      if !enableSlackAlert
+      then {}
+      else {
+        "grafanaEnvironment" = {
+          source = "${privateKeyPath}/grafanaEnvironment";
+          destination = "/run/keys/grafanaEnvironment";
+          owner.user = config.systemd.services.grafana.serviceConfig.User;
+          owner.group = config.users.users.grafana.group;
+          permissions = "0400";
+          action = ["sudo" "systemctl" "restart" "grafana.service"];
+        };
+      };
     monitoringvpn = {
       "monitoringvpn-private-key".source = "${privateKeyPath}/monitoringvpn/server.key";
       "monitoringvpn-preshared-key".source = "${privateKeyPath}/monitoringvpn/preshared.key";
     };
     in
-      grafanaSSO // monitoringvpn;
+      grafanaSSO // grafanaEnvironment // monitoringvpn;
 
   networking.hosts = hostsMap;
 
@@ -100,7 +114,7 @@ in {
   services.private-storage.monitoring.grafana = {
     inherit letsEncryptAdminEmail;
     inherit googleOAuthClientID;
-    inherit slackAlertChannelSecretUrl;
+    inherit enableSlackAlert;
     domain = "${config.networking.hostName}.${config.networking.domain}";
   };
 
diff --git a/nixos/modules/monitoring/server/grafana.nix b/nixos/modules/monitoring/server/grafana.nix
index 3765983f..1d2052dd 100644
--- a/nixos/modules/monitoring/server/grafana.nix
+++ b/nixos/modules/monitoring/server/grafana.nix
@@ -62,11 +62,18 @@ in {
       default = /run/keys/grafana-admin.password;
       description = "A file containing the password for the Grafana Admin account.";
     };
-    slackAlertChannelSecretUrl = lib.mkOption
-    { type = lib.types.str;
-      default = "";
-      example = lib.literalExample "https://hooks.slack.com/services/x/y/z";
-      description = "If set, enables the slack alerter. Don't commit a secret URL to the repo, use readFile instead.";
+    enableSlackAlert = lib.mkOption
+    { type = lib.types.bool;
+      default = false;
+      description = ''
+        Enables the slack alerter. Expects a $SLACKURL environment
+        variable with the secret URL in grafanaEnvironmentFile.
+      '';
+    };
+    grafanaEnvironmentFile = lib.mkOption
+    { type = lib.types.path;
+      default = /run/keys/grafanaEnvironment;
+      description = "Where to find the Grafana Systemd EnvironmentFile.";
     };
   };
 
@@ -74,6 +81,8 @@ in {
     # Port 80 for ACME ssl retrieval only. 443 for nginx -> grafana.
     networking.firewall.allowedTCPPorts = [ 80 443 ];
 
+    systemd.services.grafana.serviceConfig.EnvironmentFile = cfg.grafanaEnvironmentFile;
+
     services.grafana = {
       enable = true;
       domain = cfg.domain;
@@ -128,17 +137,18 @@ in {
           options.path = ./grafana-dashboards;
         }];
         # See https://grafana.com/docs/grafana/latest/administration/provisioning/#example-alert-notification-channels-config-file
-        notifiers = [ ] ++ (lib.optionals ("" != cfg.slackAlertChannelSecretUrl) [{
+        notifiers = [ ] ++ (lib.optionals (cfg.enableSlackAlert) [{
           uid = "slack-notifier-1";
           name = "Slack";
           type = "slack";
           is_default = true;
           send_reminder = false;
           settings = {
+            username = "${cfg.domain}";
             uploadImage = true;
           };
           secure_settings = {
-            url = cfg.slackAlertChannelSecretUrl;
+            url = "$SLACKURL";
           };
         }]);
       };
-- 
GitLab