grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / monitoring / zabbix-agent.nix
blobb3850baa738b3cc59820144d820615fe605de18a
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.zabbixAgent;
6   inherit (lib) mkDefault mkEnableOption mkPackageOption mkIf mkMerge mkOption;
7   inherit (lib) attrValues concatMapStringsSep literalExpression optionalString types;
8   inherit (lib.generators) toKeyValue;
10   user = "zabbix-agent";
11   group = "zabbix-agent";
13   moduleEnv = pkgs.symlinkJoin {
14     name = "zabbix-agent-module-env";
15     paths = attrValues cfg.modules;
16   };
18   configFile = pkgs.writeText "zabbix_agent.conf" (toKeyValue { listsAsDuplicateKeys = true; } cfg.settings);
23   imports = [
24     (lib.mkRemovedOptionModule [ "services" "zabbixAgent" "extraConfig" ] "Use services.zabbixAgent.settings instead.")
25   ];
27   # interface
29   options = {
31     services.zabbixAgent = {
32       enable = mkEnableOption "the Zabbix Agent";
34       package = mkPackageOption pkgs [ "zabbix" "agent" ] { };
36       extraPackages = mkOption {
37         type = types.listOf types.package;
38         default = with pkgs; [ nettools ];
39         defaultText = literalExpression "with pkgs; [ nettools ]";
40         example = literalExpression "with pkgs; [ nettools mysql ]";
41         description = ''
42           Packages to be added to the Zabbix {env}`PATH`.
43           Typically used to add executables for scripts, but can be anything.
44         '';
45       };
47       modules = mkOption {
48         type = types.attrsOf types.package;
49         description = "A set of modules to load.";
50         default = {};
51         example = literalExpression ''
52           {
53             "dummy.so" = pkgs.stdenv.mkDerivation {
54               name = "zabbix-dummy-module-''${cfg.package.version}";
55               src = cfg.package.src;
56               buildInputs = [ cfg.package ];
57               sourceRoot = "zabbix-''${cfg.package.version}/src/modules/dummy";
58               installPhase = '''
59                 mkdir -p $out/lib
60                 cp dummy.so $out/lib/
61               ''';
62             };
63           }
64         '';
65       };
67       server = mkOption {
68         type = types.str;
69         description = ''
70           The IP address or hostname of the Zabbix server to connect to.
71         '';
72       };
74       listen = {
75         ip = mkOption {
76           type = types.str;
77           default = "0.0.0.0";
78           description = ''
79             List of comma delimited IP addresses that the agent should listen on.
80           '';
81         };
83         port = mkOption {
84           type = types.port;
85           default = 10050;
86           description = ''
87             Agent will listen on this port for connections from the server.
88           '';
89         };
90       };
92       openFirewall = mkOption {
93         type = types.bool;
94         default = false;
95         description = ''
96           Open ports in the firewall for the Zabbix Agent.
97         '';
98       };
100       settings = mkOption {
101         type = with types; attrsOf (oneOf [ int str (listOf str) ]);
102         default = {};
103         description = ''
104           Zabbix Agent configuration. Refer to
105           <https://www.zabbix.com/documentation/current/manual/appendix/config/zabbix_agentd>
106           for details on supported values.
107         '';
108         example = {
109           Hostname = "example.org";
110           DebugLevel = 4;
111         };
112       };
114     };
116   };
118   # implementation
120   config = mkIf cfg.enable {
122     services.zabbixAgent.settings = mkMerge [
123       {
124         LogType = "console";
125         Server = cfg.server;
126         ListenPort = cfg.listen.port;
127       }
128       (mkIf (cfg.modules != {}) {
129         LoadModule = builtins.attrNames cfg.modules;
130         LoadModulePath = "${moduleEnv}/lib";
131       })
133       # the default value for "ListenIP" is 0.0.0.0 but zabbix agent 2 cannot accept configuration files which
134       # explicitly set "ListenIP" to the default value...
135       (mkIf (cfg.listen.ip != "0.0.0.0") { ListenIP = cfg.listen.ip; })
136     ];
138     networking.firewall = mkIf cfg.openFirewall {
139       allowedTCPPorts = [ cfg.listen.port ];
140     };
142     users.users.${user} = {
143       description = "Zabbix Agent daemon user";
144       inherit group;
145       isSystemUser = true;
146     };
148     users.groups.${group} = { };
150     systemd.services.zabbix-agent = {
151       description = "Zabbix Agent";
153       wantedBy = [ "multi-user.target" ];
155       # https://www.zabbix.com/documentation/current/manual/config/items/userparameters
156       # > User parameters are commands executed by Zabbix agent.
157       # > /bin/sh is used as a command line interpreter under UNIX operating systems.
158       path = with pkgs; [ bash "/run/wrappers" ] ++ cfg.extraPackages;
160       serviceConfig = {
161         ExecStart = "@${cfg.package}/sbin/zabbix_agentd zabbix_agentd -f --config ${configFile}";
162         Restart = "always";
163         RestartSec = 2;
165         User = user;
166         Group = group;
167         PrivateTmp = true;
168       };
169     };
171   };