From 6048978a33b8e4d5fa8e65711c26490b8a60de4d Mon Sep 17 00:00:00 2001 From: niten Date: Sat, 15 Jan 2022 06:41:50 -0800 Subject: [PATCH] Add special metric srv records --- lib/fudo/grafana.nix | 106 +++++++++++++++++++--------------- lib/lib/dns.nix | 11 ++++ lib/types/zone-definition.nix | 38 ++++++++++-- 3 files changed, 106 insertions(+), 49 deletions(-) diff --git a/lib/fudo/grafana.nix b/lib/fudo/grafana.nix index 6bed0e5..7aaa45d 100644 --- a/lib/fudo/grafana.nix +++ b/lib/fudo/grafana.nix @@ -1,35 +1,13 @@ # NOTE: this assumes that postgres is running locally. -{ config, lib, pkgs, ... }: +{ config, lib, pkgs, ... } @ toplevel: with lib; let cfg = config.fudo.grafana; - fudo-cfg = config.fudo.common; - database-name = "grafana"; - database-user = "grafana"; - - databaseOpts = { ... }: { - options = { - name = mkOption { - type = types.str; - description = "Database name."; - }; - hostname = mkOption { - type = types.str; - description = "Hostname of the database server."; - }; - user = mkOption { - type = types.str; - description = "Database username."; - }; - password-file = mkOption { - type = types.path; - description = "File containing the database user's password."; - }; - }; - }; + hostname = config.instance.hostname; + domain-name = config.fudo.hosts.${hostname}.domain; in { @@ -37,45 +15,82 @@ in { enable = mkEnableOption "Fudo Metrics Display Service"; hostname = mkOption { - type = types.str; + type = str; description = "Grafana site hostname."; example = "fancy-graphs.fudo.org"; }; - smtp-username = mkOption { - type = types.str; - description = "Username with which to send email."; + smtp = { + username = mkOption { + type = str; + description = "Username with which to send email."; + default = "metrics"; + }; + + password-file = mkOption { + type = str; + description = "Path to a file containing the email user's password."; + }; + + hostname = mkOption { + type = str; + description = "Mail server hostname."; + default = "mail.${domain-name}"; + }; + + email = mkOption { + type = str; + description = "Address from which mail will be sent (i.e. 'from' address)."; + default = "${toplevel.config.fudo.grafana.smtp.username}@${domain-name}"; + }; }; - smtp-password-file = mkOption { - type = types.path; - description = "Path to a file containing the email user's password."; - }; - - database = mkOption { - type = (types.submodule databaseOpts); - description = "Grafana database configuration."; + database = { + name = mkOption { + type = str; + description = "Database name."; + default = "grafana"; + }; + hostname = mkOption { + type = str; + description = "Hostname of the database server."; + default = "localhost"; + }; + user = mkOption { + type = str; + description = "Database username."; + default = "grafana"; + }; + password-file = mkOption { + type = str; + description = "File containing the database user's password."; + }; }; admin-password-file = mkOption { - type = types.path; + type = str; description = "Path to a file containing the admin user's password."; }; secret-key-file = mkOption { - type = types.path; + type = str; description = "Path to a file containing the server's secret key, used for signatures."; }; - prometheus-host = mkOption { - type = types.str; - description = "The URL of the prometheus data source."; + prometheus-hosts = mkOption { + type = listOf str; + description = "A list of URLs to prometheus data sources."; + default = []; + }; + + state-directory = mkOption { + type = str; + description = "Directory at which to store Grafana state data."; + default = "/var/lib/grafana"; }; }; config = mkIf cfg.enable { - security.acme.certs.${cfg.hostname}.email = fudo-cfg.admin-email; - services.nginx = { enable = true; @@ -105,8 +120,9 @@ in { addr = "127.0.0.1"; protocol = "http"; port = 3000; - domain = "${cfg.hostname}"; + domain = cfg.hostname; rootUrl = "https://${cfg.hostname}/"; + dataDir = cfg.state-directory; security = { adminPasswordFile = cfg.admin-password-file; diff --git a/lib/lib/dns.nix b/lib/lib/dns.nix index 4adcf9b..aa2789e 100644 --- a/lib/lib/dns.nix +++ b/lib/lib/dns.nix @@ -60,6 +60,15 @@ let makeSrvProtocolRecords = protocol: services: join-lines (mapAttrsToList (makeSrvRecords protocol) services); + makeMetricRecords = metric-type: records: + join-lines + (map (record: + "${metric-type}._metrics._tcp IN SRV ${ + toString record.priority + } ${ + toString record.weight + } ${record.host}.") records); + srvRecordOpts = with types; { options = { weight = mkOption { @@ -140,6 +149,8 @@ let ${join-lines (mapAttrsToList makeSrvProtocolRecords zone.srv-records)} + ${join-lines (mapAttrsToList makeMetricRecords zone.metric-records)} + $TTL ${zone.host-record-ttl} ${join-lines (mapAttrsToList hostRecords zone.hosts)} diff --git a/lib/types/zone-definition.nix b/lib/types/zone-definition.nix index fc8dc6c..9fdddd3 100644 --- a/lib/types/zone-definition.nix +++ b/lib/types/zone-definition.nix @@ -62,15 +62,45 @@ let description = "SRV records for the network."; example = { tcp = { - kerberos = { - port = 88; - host = "krb-host.my-domain.com"; - }; + kerberos = [ + { + port = 88; + host = "krb-host.my-domain.com"; + } + { + port = 88; + host = "krb-host2.my-domain.com"; + } + ]; }; }; default = { }; }; + metric-records = mkOption { + type = attrsOf (listOf (submodule srvRecordOpts)); + description = "Map of metric type to list of SRV host records."; + example = { + node = [ + { + host = "my-host.my-domain.com"; + port = 443; + } + { + host = "my-host2.my-domain.com"; + port = 443; + } + ]; + rspamd = [ + { + host = "mail-host.my-domain.com"; + port = 443; + } + ]; + }; + default = { }; + }; + aliases = mkOption { type = attrsOf str; default = { };