158 lines
4.1 KiB
Nix
158 lines
4.1 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
let
|
|
cfg = config.fudo.services.grafana;
|
|
|
|
datasourceOpts = { name, ... }: {
|
|
options = with types; {
|
|
url = mkOption {
|
|
type = str;
|
|
description = "Datasource URL.";
|
|
};
|
|
|
|
type = mkOption {
|
|
type = enum [ "prometheus" "loki" ];
|
|
description = "Datasource type.";
|
|
default = "prometheus";
|
|
};
|
|
|
|
name = mkOption {
|
|
type = str;
|
|
default = name;
|
|
};
|
|
|
|
default =
|
|
mkEnableOption "Use this datasource as the default while querying.";
|
|
};
|
|
};
|
|
|
|
in {
|
|
options.fudo.services.grafana = with types; {
|
|
enable = mkEnableOption "Enable Grafana server.";
|
|
|
|
state-directory = mkOption {
|
|
type = str;
|
|
description = "Path at which to store server state.";
|
|
};
|
|
|
|
base-url = mkOption {
|
|
type = str;
|
|
description = "Base URL at which the Grafana server is reachable.";
|
|
};
|
|
|
|
admin-password-file = mkOption {
|
|
type = str;
|
|
description = "Path to a file containing the admin user password.";
|
|
};
|
|
|
|
secret-key-file = mkOption {
|
|
type = str;
|
|
description =
|
|
"Path to a file containing a sceret key used for encryption.";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = port;
|
|
description = "Port on which to listen for HTTP requests (on localhost)";
|
|
default = 5402;
|
|
};
|
|
|
|
datasources = mkOption {
|
|
type = attrsOf (submodule datasourceOpts);
|
|
description = "A map of datasources supplied to Grafana.";
|
|
default = { };
|
|
};
|
|
|
|
oauth = let
|
|
oauthOpts.options = {
|
|
hostname = mkOption {
|
|
type = str;
|
|
description = "Host of the OAuth server.";
|
|
};
|
|
|
|
client-id = mkOption {
|
|
type = str;
|
|
description = "Path to file containing the Grafana OAuth client ID.";
|
|
};
|
|
|
|
client-secret = mkOption {
|
|
type = str;
|
|
description =
|
|
"Path to file containing the Grafana OAuth client secret.";
|
|
};
|
|
|
|
slug = mkOption {
|
|
type = str;
|
|
description = "The application slug on the OAuth server.";
|
|
};
|
|
};
|
|
in mkOption {
|
|
type = nullOr (submodule oauthOpts);
|
|
default = null;
|
|
};
|
|
};
|
|
|
|
config = mkIf cfg.enable {
|
|
systemd.tmpfiles.rules = [
|
|
"d ${cfg.state-directory} 0700 ${config.systemd.services.grafana.serviceConfig.User} root - -"
|
|
];
|
|
|
|
services.grafana = {
|
|
enable = true;
|
|
dataDir = "${cfg.state-directory}/data";
|
|
settings = {
|
|
server = {
|
|
root_url = cfg.base-url;
|
|
http_addr = "127.0.0.1";
|
|
http_port = cfg.port;
|
|
protocol = "http";
|
|
};
|
|
|
|
security = {
|
|
admin_password = "$__file{${cfg.admin-password-file}}";
|
|
secret_key = "$__file{${cfg.secret-key-file}}";
|
|
};
|
|
|
|
database = {
|
|
type = "sqlite3";
|
|
path = "${cfg.state-directory}/database.sqlite";
|
|
};
|
|
|
|
auth = mkIf (!isNull cfg.oauth) {
|
|
signout_redirect_url =
|
|
"https://${cfg.oauth.hostname}/application/o/${cfg.oauth.slug}/end-session/";
|
|
oauth_auto_login = true;
|
|
};
|
|
|
|
"auth.generic_oauth" = mkIf (!isNull cfg.oauth) {
|
|
name = "Authentik";
|
|
enabled = true;
|
|
client_id = "$__file{${cfg.oauth.client-id}}";
|
|
client_secret = "$__file{${cfg.oauth.client-secret}}";
|
|
scopes = "openid email profile";
|
|
auth_url = "https://${cfg.oauth.hostname}/application/o/authorize/";
|
|
token_url = "https://${cfg.oauth.hostname}/application/o/token/";
|
|
api_url = "https://${cfg.oauth.hostname}/application/o/userinfo/";
|
|
role_attribute_path = concatStringsSep " || " [
|
|
"contains(groups[*], 'Metrics Admin') && 'Admin'"
|
|
"contains(groups[*], 'Metrics Editor') && 'Editor'"
|
|
"'Viewer'"
|
|
];
|
|
};
|
|
};
|
|
|
|
provision = {
|
|
enable = true;
|
|
datasources.settings.datasources = let
|
|
mkDatasource = ds: {
|
|
editable = false;
|
|
isDefault = ds.default;
|
|
inherit (ds) name type url;
|
|
};
|
|
in map mkDatasource (attrValues cfg.datasources);
|
|
};
|
|
};
|
|
};
|
|
}
|