{ nodes, lib, config, ... }: with lib; let name = "prometheus"; cfg = config.services.skynet."${name}"; # dont have to worry about any external addresses for this # create a list of either "ip@port" or "" # the ""s then get filtered out by filter_empty exporters = { dns = ( lib.attrsets.mapAttrsToList ( key: value: if value.config.services.skynet.dns.server.enable then "${value.config.deployment.targetHost}:${toString value.config.services.prometheus.exporters.bind.port}" else "" ) nodes ); node = lib.attrsets.mapAttrsToList (key: value: "${value.config.deployment.targetHost}:${toString config.services.prometheus.exporters.node.port}") nodes; }; # clears any invalid entries filter_empty = inputs: (builtins.filter (value: value != "") inputs); in { imports = []; options.services.skynet."${name}" = { server = { enable = mkEnableOption "Prometheus Server"; port = mkOption { type = types.port; default = 9001; }; external.node = mkOption { type = types.listOf types.str; default = []; description = '' To add other nodes outside of nix, specify ip and port that server should listen to here ''; }; }; }; config = mkMerge [ { services.prometheus.exporters.node = { enable = true; openFirewall = true; # most collectors are on by default see https://github.com/prometheus/node_exporter for more options enabledCollectors = ["systemd" "processes"]; }; } (mkIf cfg.server.enable { services.prometheus = { enable = true; port = cfg.server.port; scrapeConfigs = [ { job_name = "node_exporter"; static_configs = [ { targets = filter_empty (exporters.node ++ cfg.server.external.node); } ]; } { job_name = "bind"; static_configs = [ { targets = filter_empty exporters.dns; } ]; } ]; }; }) ]; }