204 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| {
 | |
|   pkgs,
 | |
|   config,
 | |
|   lib,
 | |
|   ...
 | |
| }: let
 | |
|   inherit (lib) types mkOption mkDefault;
 | |
|   yaml = pkgs.formats.yaml {};
 | |
| in {
 | |
|   options = {
 | |
|     services.prometheus = {
 | |
|       extraExporters = mkOption {
 | |
|         type = types.attrsOf (types.submodule {
 | |
|           options = {
 | |
|             port = mkOption {
 | |
|               type = types.int;
 | |
|               description = "The port on which this exporter listens.";
 | |
|             };
 | |
|             listenAddress = mkOption {
 | |
|               type = types.str;
 | |
|               default = "127.0.0.1";
 | |
|               description = "Address to listen on.";
 | |
|             };
 | |
|             serviceOpts = mkOption {
 | |
|               type = types.attrs;
 | |
|               description = "An attrset to be merged with the exporter's systemd service.";
 | |
|             };
 | |
|           };
 | |
|         });
 | |
|       };
 | |
|     };
 | |
| 
 | |
|     services.victoriametrics.scrapeConfigs = mkOption {
 | |
|       type = types.attrsOf (types.submodule ({
 | |
|         name,
 | |
|         self,
 | |
|         ...
 | |
|       }: {
 | |
|         options = {
 | |
|           job_name = mkOption {
 | |
|             type = types.str;
 | |
|             default = name;
 | |
|           };
 | |
| 
 | |
|           extraSettings = mkOption {
 | |
|             type = types.anything;
 | |
|             description = ''
 | |
|               Other settings to set for this scrape config.
 | |
|             '';
 | |
|             default = {};
 | |
|           };
 | |
| 
 | |
|           targets = mkOption {
 | |
|             type = types.listOf types.str;
 | |
|             description = lib.mdDoc ''
 | |
|               Addresses scrape targets for this config listen on.
 | |
| 
 | |
|               Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
 | |
|             '';
 | |
|             default = [];
 | |
|           };
 | |
| 
 | |
|           static_configs = mkOption {
 | |
|             default = [];
 | |
|             type = types.listOf (types.submodule {
 | |
|               options = {
 | |
|                 targets = mkOption {
 | |
|                   type = types.listOf types.str;
 | |
|                   description = lib.mdDoc ''
 | |
|                     The addresses scrape targets for this config listen on.
 | |
| 
 | |
|                     Must in `listenAddress:port` format.
 | |
|                   '';
 | |
|                 };
 | |
|                 labels = mkOption {
 | |
|                   type = types.attrsOf types.str;
 | |
|                   description = lib.mdDoc ''
 | |
|                     Labels to apply to all targets defined for this static config.
 | |
|                   '';
 | |
|                   default = {};
 | |
|                 };
 | |
|               };
 | |
|             });
 | |
|           };
 | |
|         };
 | |
|       }));
 | |
|     };
 | |
|   };
 | |
| 
 | |
|   config = {
 | |
|     systemd.services = lib.mkMerge [
 | |
|       (lib.mapAttrs' (name: exporter:
 | |
|         lib.nameValuePair "prometheus-${name}-exporter" (lib.mkMerge [
 | |
|           {
 | |
|             # Shamelessly copied from upstream because the upstream
 | |
|             # module is an intractable mess
 | |
|             wantedBy = ["multi-user.target"];
 | |
|             after = ["network.target"];
 | |
|             serviceConfig.Restart = mkDefault "always";
 | |
|             serviceConfig.PrivateTmp = mkDefault true;
 | |
|             serviceConfig.WorkingDirectory = mkDefault /tmp;
 | |
|             serviceConfig.DynamicUser = mkDefault true;
 | |
|             # Hardening
 | |
|             serviceConfig.CapabilityBoundingSet = mkDefault [""];
 | |
|             serviceConfig.DeviceAllow = [""];
 | |
|             serviceConfig.LockPersonality = true;
 | |
|             serviceConfig.MemoryDenyWriteExecute = true;
 | |
|             serviceConfig.NoNewPrivileges = true;
 | |
|             serviceConfig.PrivateDevices = mkDefault true;
 | |
|             serviceConfig.ProtectClock = mkDefault true;
 | |
|             serviceConfig.ProtectControlGroups = true;
 | |
|             serviceConfig.ProtectHome = true;
 | |
|             serviceConfig.ProtectHostname = true;
 | |
|             serviceConfig.ProtectKernelLogs = true;
 | |
|             serviceConfig.ProtectKernelModules = true;
 | |
|             serviceConfig.ProtectKernelTunables = true;
 | |
|             serviceConfig.ProtectSystem = mkDefault "strict";
 | |
|             serviceConfig.RemoveIPC = true;
 | |
|             serviceConfig.RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
 | |
|             serviceConfig.RestrictNamespaces = true;
 | |
|             serviceConfig.RestrictRealtime = true;
 | |
|             serviceConfig.RestrictSUIDSGID = true;
 | |
|             serviceConfig.SystemCallArchitectures = "native";
 | |
|             serviceConfig.UMask = "0077";
 | |
|           }
 | |
|           exporter.serviceOpts
 | |
|         ]))
 | |
|       config.services.prometheus.extraExporters)
 | |
| 
 | |
|       {
 | |
|         vmagent-scrape-exporters = let
 | |
|           listenAddress = config.services.victoriametrics.listenAddress;
 | |
|           vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
 | |
|           promscrape = yaml.generate "prometheus.yml" {
 | |
|             scrape_configs = lib.mapAttrsToList (_: scrape:
 | |
|               lib.recursiveUpdate {
 | |
|                 inherit (scrape) job_name;
 | |
|                 static_configs =
 | |
|                   scrape.static_configs
 | |
|                   ++ lib.optional (scrape.targets != []) {targets = scrape.targets;};
 | |
|               }
 | |
|               scrape.extraSettings)
 | |
|             config.services.victoriametrics.scrapeConfigs;
 | |
|           };
 | |
|         in {
 | |
|           enable = true;
 | |
|           path = [pkgs.victoriametrics];
 | |
|           wantedBy = ["multi-user.target"];
 | |
|           after = ["network.target" "victoriametrics.service"];
 | |
|           serviceConfig = {
 | |
|             ExecStart = [
 | |
|               (lib.concatStringsSep " " [
 | |
|                 "${pkgs.victoriametrics}/bin/vmagent"
 | |
|                 "-promscrape.config=${promscrape}"
 | |
|                 "-remoteWrite.url=http://${vmAddr}/api/v1/write"
 | |
|                 "-remoteWrite.tmpDataPath=%t/vmagent"
 | |
|               ])
 | |
|             ];
 | |
|             SupplementaryGroups = "metrics";
 | |
| 
 | |
|             DynamicUser = true;
 | |
|             RuntimeDirectory = "vmagent";
 | |
|             CapabilityBoundingSet = [""];
 | |
|             DeviceAllow = [""];
 | |
|             LockPersonality = true;
 | |
|             MemoryDenyWriteExecute = true;
 | |
|             NoNewPrivileges = true;
 | |
|             PrivateDevices = true;
 | |
|             ProtectClock = true;
 | |
|             ProtectControlGroups = true;
 | |
|             ProtectHome = true;
 | |
|             ProtectHostname = true;
 | |
|             ProtectKernelLogs = true;
 | |
|             ProtectKernelModules = true;
 | |
|             ProtectKernelTunables = true;
 | |
|             ProtectSystem = "strict";
 | |
|             RemoveIPC = true;
 | |
|             RestrictAddressFamilies = ["AF_INET" "AF_INET6"];
 | |
|             RestrictNamespaces = true;
 | |
|             RestrictRealtime = true;
 | |
|             RestrictSUIDSGID = true;
 | |
|             SystemCallArchitectures = "native";
 | |
|             UMask = "0077";
 | |
|           };
 | |
|         };
 | |
|       }
 | |
|     ];
 | |
| 
 | |
|     users.groups.metrics = {};
 | |
| 
 | |
|     services.victoriametrics.scrapeConfigs = let
 | |
|       allExporters =
 | |
|         lib.mapAttrs (name: exporter: {
 | |
|           inherit (exporter) listenAddress port;
 | |
|         }) ((lib.filterAttrs (_: exporter: builtins.isAttrs exporter && exporter.enable)
 | |
|           config.services.prometheus.exporters)
 | |
|         // config.services.prometheus.extraExporters);
 | |
|     in
 | |
|       lib.mapAttrs (_: exporter: {
 | |
|         targets = ["${exporter.listenAddress}:${toString exporter.port}"];
 | |
|       })
 | |
|       allExporters;
 | |
|   };
 | |
| }
 |