diff --git a/morph/lib/monitoring.nix b/morph/lib/monitoring.nix index a5f2575aaef5fca0cf15f5d125981f150a0f20a3..c4d8bcdb87c0386d4ca59ee30676e9c292f8fd6b 100644 --- a/morph/lib/monitoring.nix +++ b/morph/lib/monitoring.nix @@ -174,10 +174,15 @@ in { nginxExporterTargets = []; }; - services.private-storage.monitoring.grafana = { + grafana = { inherit (cfg) googleOAuthClientID enableSlackAlert enableZulipAlert; inherit letsEncryptAdminEmail; domains = cfg.monitoringDomains; + prometheusUrl = "http://localhost:9090/"; + lokiUrl = "http://localhost:3100/"; + googleOAuthClientSecretFile = /run/keys/grafana-google-sso.secret; + adminPasswordFile = /run/keys/grafana-admin.password; + metricsAllowedIp = "${monitoringvpnIPv4}/24"; }; services.private-storage.monitoring.exporters.node.enable = true; diff --git a/nixos/modules/monitoring/server/grafana.nix b/nixos/modules/monitoring/server/grafana.nix index 5299829ccc7fec081e9ccb4f0e41c66daa8a0251..6e78f53f5bef77c6fe737f8202e0abf39459cd28 100644 --- a/nixos/modules/monitoring/server/grafana.nix +++ b/nixos/modules/monitoring/server/grafana.nix @@ -6,26 +6,26 @@ { config, lib, ... }: let - cfg = config.services.private-storage.monitoring.grafana; + cfg = config.grafana; in { - options.services.private-storage.monitoring.grafana = { + options.grafana = { domains = lib.mkOption { type = lib.types.listOf lib.types.str; - example = [ "grafana.grid.private.storage" ]; + example = [ "grafana.example.com" ]; description = "The domain names at which the server is reachable."; }; prometheusUrl = lib.mkOption { type = lib.types.str; example = "http://prometheus:9090/"; - default = "http://localhost:9090/"; + default = ""; description = "The URL of the Prometheus host to access"; }; lokiUrl = lib.mkOption { type = lib.types.str; example = "http://loki:3100/"; - default = "http://localhost:3100/"; + default = ""; description = "The URL of the Loki host to access"; }; letsEncryptAdminEmail = lib.mkOption @@ -35,22 +35,28 @@ in { operational contact for the service's TLS certificate. ''; }; + allowAnonymousViewers = lib.mkOption + { type = lib.types.bool; + default = false; + description = '' + Allow read access w/o any authentication. + ''; + }; googleOAuthClientID = lib.mkOption { type = lib.types.str; example = "grafana-staging-345678"; - default = "replace-by-your-client-id-or-set-empty-string-for-anonymous-access"; - description = "The GSuite OAuth2 SSO Client ID. Empty string turns SSO auth off and anonymous (free for all) access on."; + default = ""; + description = "The GSuite OAuth2 SSO Client ID."; }; googleOAuthClientSecretFile = lib.mkOption { type = lib.types.path; - example = /var/secret/monitoring-gsuite-client-secret; - default = /run/keys/grafana-google-sso.secret; + example = /var/secret/grafana-gsuite-client-secret; + default = ""; description = "The path to the GSuite SSO secret file."; }; adminPasswordFile = lib.mkOption { type = lib.types.path; - example = "/var/secret/monitoring-admin-password"; - default = /run/keys/grafana-admin.password; + example = "/run/secrets/grafana-admin-password"; description = "A file containing the password for the Grafana Admin account."; }; enableSlackAlert = lib.mkOption @@ -83,6 +89,12 @@ in { Where to find the file that containts the Zulip URL. ''; }; + metricsAllowedIp = lib.mkOption + { type = lib.types.str; + example = "192.168.0.0/24"; + default = "0.0.0.0/0"; + description = "The IP subnet allowd to access metrics"; + }; }; config = @@ -123,13 +135,13 @@ in { # The auth sections since NixOS 22.11 are named a bit funky with a dot in the name # # https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/grafana/#anonymous-authentication - # https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/google/ - "auth.anonymous" = lib.mkIf (cfg.googleOAuthClientID == "") { + "auth.anonymous" = lib.mkIf (cfg.allowAnonymousViewers) { enabled = true; - org_role = "Admin"; + org_role = "Viewer"; org_name = "Main Org."; }; - "auth.google" = lib.mkIf (cfg.googleOAuthClientID != "") { + # https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/google/ + "auth.google" = lib.mkIf (cfg.googleOAuthClientID != "" && cfg.googleOAuthClientSecretFile != "") { enabled = true; # Grafana considers it "sign up" to let in a user it has # never seen before. @@ -148,20 +160,21 @@ in { provision = { enable = true; # See https://grafana.com/docs/grafana/latest/administration/provisioning/#datasources - datasources.settings.datasources = [{ + datasources.settings.datasources = + [ ] ++ (lib.optionals (cfg.prometheusUrl != "") [{ name = "Prometheus"; type = "prometheus"; uid = "LocalPrometheus"; access = "proxy"; url = cfg.prometheusUrl; isDefault = true; - } { + }]) ++ (lib.optionals (cfg.lokiUrl != "") [{ name = "Loki"; type = "loki"; uid = "LocalLoki"; access = "proxy"; url = cfg.lokiUrl; - }]; + }]); # See https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards dashboards.settings.providers = [{ name = "provisioned"; @@ -221,10 +234,9 @@ in { proxyWebsockets = true; }; locations."/metrics" = { - # Only allow our monitoringvpn subnet - # And localhost since we're the monitoring server currently + # Only allow localhost and a for now extraConfig = '' - allow ${config.grid.monitoringvpnIPv4}/24; + allow ${toString cfg.metricsAllowedIp}; allow 127.0.0.1; allow ::1; deny all;