diff --git a/nixos/modules/services/monitoring/prometheus/default.nix b/nixos/modules/services/monitoring/prometheus/default.nix index 25385be97043..e7ac12c07d33 100644 --- a/nixos/modules/services/monitoring/prometheus/default.nix +++ b/nixos/modules/services/monitoring/prometheus/default.nix @@ -54,7 +54,7 @@ let rule_files = map (promtoolCheck "check-rules" "rules") (cfg.ruleFiles ++ [ (pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg.rules)) ]); - scrape_configs = cfg.scrapeConfigs; + scrape_configs = filterEmpty cfg.scrapeConfigs; }; generatedPrometheusYml = writePrettyJSON "prometheus.yml" promConfig; @@ -81,7 +81,7 @@ let rule_files = map (prom2toolCheck "check rules" "rules") (cfg2.ruleFiles ++ [ (pkgs.writeText "prometheus.rules" (concatStringsSep "\n" cfg2.rules)) ]); - scrape_configs = cfg2.scrapeConfigs; + scrape_configs = filterEmpty cfg2.scrapeConfigs; alerting = optionalAttrs (cfg2.alertmanagerURL != []) { alertmanagers = [{ static_configs = [{ @@ -108,6 +108,21 @@ let ] ++ optional (cfg2.webExternalUrl != null) "--web.external-url=${cfg2.webExternalUrl}"; + filterEmpty = filterAttrsListRecursive (_n: v: !(v == null || v == [] || v == {})); + filterAttrsListRecursive = pred: x: + if isAttrs x then + listToAttrs ( + concatMap (name: + let v = x.${name}; in + if pred name v then [ + (nameValuePair name (filterAttrsListRecursive pred v)) + ] else [] + ) (attrNames x) + ) + else if isList x then + map (filterAttrsListRecursive pred) x + else x; + promTypes.globalConfig = types.submodule { options = { scrape_interval = mkOption { @@ -237,6 +252,14 @@ let Optional http login credentials for metrics scraping. ''; }; + tls_config = mkOption { + type = types.nullOr promTypes.tls_config; + default = null; + apply = x: mapNullable _filter x; + description = '' + Configures the scrape request's TLS settings. + ''; + }; dns_sd_configs = mkOption { type = types.listOf promTypes.dns_sd_config; default = []; @@ -269,6 +292,14 @@ let List of labeled target groups for this job. ''; }; + ec2_sd_configs = mkOption { + type = types.listOf promTypes.ec2_sd_config; + default = []; + apply = x: map _filter x; + description = '' + List of EC2 service discovery configurations. + ''; + }; relabel_configs = mkOption { type = types.listOf promTypes.relabel_config; default = []; @@ -298,6 +329,96 @@ let }; }; + promTypes.ec2_sd_config = types.submodule { + options = { + region = mkOption { + type = types.str; + description = '' + The AWS Region. + ''; + }; + endpoint = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Custom endpoint to be used. + ''; + }; + access_key = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The AWS API key id. If blank, the environment variable + AWS_ACCESS_KEY_ID is used. + ''; + }; + secret_key = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The AWS API key secret. If blank, the environment variable + AWS_SECRET_ACCESS_KEY is used. + ''; + }; + profile = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Named AWS profile used to connect to the API. + ''; + }; + role_arn = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + AWS Role ARN, an alternative to using AWS API keys. + ''; + }; + refresh_interval = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Refresh interval to re-read the instance list. + ''; + }; + port = mkOption { + type = types.int; + default = 80; + description = '' + The port to scrape metrics from. If using the public IP + address, this must instead be specified in the relabeling + rule. + ''; + }; + filters = mkOption { + type = types.nullOr (types.listOf promTypes.filter); + default = null; + description = '' + Filters can be used optionally to filter the instance list by other criteria. + ''; + }; + }; + }; + + promTypes.filter = types.submodule { + options = { + name = mkOption { + type = types.str; + description = '' + See this list + for the available filters. + ''; + }; + value = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Value of the filter. + ''; + }; + }; + }; + promTypes.dns_sd_config = types.submodule { options = { names = mkOption { @@ -431,6 +552,47 @@ let }; }; + promTypes.tls_config = types.submodule { + options = { + ca_file = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + CA certificate to validate API server certificate with. + ''; + }; + cert_file = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Certificate file for client cert authentication to the server. + ''; + }; + key_file = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + Key file for client cert authentication to the server. + ''; + }; + server_name = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + ServerName extension to indicate the name of the server. + http://tools.ietf.org/html/rfc4366#section-3.1 + ''; + }; + insecure_skip_verify = mkOption { + type = types.bool; + default = false; + description = '' + Disable validation of the server certificate. + ''; + }; + }; + }; + in { options = { services.prometheus = {