python312Packages.flask-allowed-hosts: 1.1.2 -> 1.2.0 (#361132)
[NixPkgs.git] / nixos / modules / services / web-apps / icingaweb2 / icingaweb2.nix
blob862ba730abfc587b7fb839c32874d46c33c4a003
1 { config, lib, pkgs, ... }: with lib; let
2   cfg = config.services.icingaweb2;
3   fpm = config.services.phpfpm.pools.${poolName};
4   poolName = "icingaweb2";
6   defaultConfig = {
7     global = {
8       module_path = "${pkgs.icingaweb2}/modules";
9     };
10   };
11 in {
12   meta.maintainers = teams.helsinki-systems.members;
14   options.services.icingaweb2 = with types; {
15     enable = mkEnableOption "the icingaweb2 web interface";
17     pool = mkOption {
18       type = str;
19       default = poolName;
20       description = ''
21          Name of existing PHP-FPM pool that is used to run Icingaweb2.
22          If not specified, a pool will automatically created with default values.
23       '';
24     };
26     libraryPaths = mkOption {
27       type = attrsOf package;
28       default = { };
29       description = ''
30         Libraries to add to the Icingaweb2 library path.
31         The name of the attribute is the name of the library, the value
32         is the package to add.
33       '';
34     };
36     virtualHost = mkOption {
37       type = nullOr str;
38       default = "icingaweb2";
39       description = ''
40         Name of the nginx virtualhost to use and setup. If null, no virtualhost is set up.
41       '';
42     };
44     timezone = mkOption {
45       type = str;
46       default = "UTC";
47       example = "Europe/Berlin";
48       description = "PHP-compliant timezone specification";
49     };
51     modules = {
52       doc.enable = mkEnableOption "the icingaweb2 doc module";
53       migrate.enable = mkEnableOption "the icingaweb2 migrate module";
54       setup.enable = mkEnableOption "the icingaweb2 setup module";
55       test.enable = mkEnableOption "the icingaweb2 test module";
56       translation.enable = mkEnableOption "the icingaweb2 translation module";
57     };
59     modulePackages = mkOption {
60       type = attrsOf package;
61       default = {};
62       example = literalExpression ''
63         {
64           "snow" = icingaweb2Modules.theme-snow;
65         }
66       '';
67       description = ''
68         Name-package attrset of Icingaweb 2 modules packages to enable.
70         If you enable modules manually (e.g. via the web ui), they will not be touched.
71       '';
72     };
74     generalConfig = mkOption {
75       type = nullOr attrs;
76       default = null;
77       example = {
78         general = {
79           showStacktraces = 1;
80           config_resource = "icingaweb_db";
81         };
82         logging = {
83           log = "syslog";
84           level = "CRITICAL";
85         };
86       };
87       description = ''
88         config.ini contents.
89         Will automatically be converted to a .ini file.
90         If you don't set global.module_path, the module will take care of it.
92         If the value is null, no config.ini is created and you can
93         modify it manually (e.g. via the web interface).
94         Note that you need to update module_path manually.
95       '';
96     };
98     resources = mkOption {
99       type = nullOr attrs;
100       default = null;
101       example = {
102         icingaweb_db = {
103           type = "db";
104           db = "mysql";
105           host = "localhost";
106           username = "icingaweb2";
107           password = "icingaweb2";
108           dbname = "icingaweb2";
109         };
110       };
111       description = ''
112         resources.ini contents.
113         Will automatically be converted to a .ini file.
115         If the value is null, no resources.ini is created and you can
116         modify it manually (e.g. via the web interface).
117         Note that if you set passwords here, they will go into the nix store.
118       '';
119     };
121     authentications = mkOption {
122       type = nullOr attrs;
123       default = null;
124       example = {
125         icingaweb = {
126           backend = "db";
127           resource = "icingaweb_db";
128         };
129       };
130       description = ''
131         authentication.ini contents.
132         Will automatically be converted to a .ini file.
134         If the value is null, no authentication.ini is created and you can
135         modify it manually (e.g. via the web interface).
136       '';
137     };
139     groupBackends = mkOption {
140       type = nullOr attrs;
141       default = null;
142       example = {
143         icingaweb = {
144           backend = "db";
145           resource = "icingaweb_db";
146         };
147       };
148       description = ''
149         groups.ini contents.
150         Will automatically be converted to a .ini file.
152         If the value is null, no groups.ini is created and you can
153         modify it manually (e.g. via the web interface).
154       '';
155     };
157     roles = mkOption {
158       type = nullOr attrs;
159       default = null;
160       example = {
161         Administrators = {
162           users = "admin";
163           permissions = "*";
164         };
165       };
166       description = ''
167         roles.ini contents.
168         Will automatically be converted to a .ini file.
170         If the value is null, no roles.ini is created and you can
171         modify it manually (e.g. via the web interface).
172       '';
173     };
174   };
176   config = mkIf cfg.enable {
177     services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
178       ${poolName} = {
179         user = "icingaweb2";
180         phpEnv = {
181           ICINGAWEB_LIBDIR = toString (pkgs.linkFarm "icingaweb2-libdir" (mapAttrsToList (name: path: { inherit name path; }) cfg.libraryPaths));
182         };
183         phpPackage = pkgs.php.withExtensions ({ enabled, all }: [ all.imagick ] ++ enabled);
184         phpOptions = ''
185           date.timezone = "${cfg.timezone}"
186         '';
187         settings = mapAttrs (name: mkDefault) {
188           "listen.owner" = "nginx";
189           "listen.group" = "nginx";
190           "listen.mode" = "0600";
191           "pm" = "dynamic";
192           "pm.max_children" = 75;
193           "pm.start_servers" = 2;
194           "pm.min_spare_servers" = 2;
195           "pm.max_spare_servers" = 10;
196         };
197       };
198     };
200     services.icingaweb2.libraryPaths = {
201       ipl = pkgs.icingaweb2-ipl;
202       thirdparty = pkgs.icingaweb2-thirdparty;
203     };
205     systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ];
207     services.nginx = {
208       enable = true;
209       virtualHosts = mkIf (cfg.virtualHost != null) {
210         ${cfg.virtualHost} = {
211           root = "${pkgs.icingaweb2}/public";
213           extraConfig = ''
214             index index.php;
215             try_files $1 $uri $uri/ /index.php$is_args$args;
216           '';
218           locations."~ ..*/.*.php$".extraConfig = ''
219             return 403;
220           '';
222           locations."~ ^/index.php(.*)$".extraConfig = ''
223             fastcgi_intercept_errors on;
224             fastcgi_index index.php;
225             include ${config.services.nginx.package}/conf/fastcgi.conf;
226             try_files $uri =404;
227             fastcgi_split_path_info ^(.+\.php)(/.+)$;
228             fastcgi_pass unix:${fpm.socket};
229             fastcgi_param SCRIPT_FILENAME ${pkgs.icingaweb2}/public/index.php;
230           '';
231         };
232       };
233     };
235     # /etc/icingaweb2
236     environment.etc = let
237       doModule = name: optionalAttrs (cfg.modules.${name}.enable) { "icingaweb2/enabledModules/${name}".source = "${pkgs.icingaweb2}/modules/${name}"; };
238     in {}
239       # Module packages
240       // (mapAttrs' (k: v: nameValuePair "icingaweb2/enabledModules/${k}" { source = v; }) cfg.modulePackages)
241       # Built-in modules
242       // doModule "doc"
243       // doModule "migrate"
244       // doModule "setup"
245       // doModule "test"
246       // doModule "translation"
247       # Configs
248       // optionalAttrs (cfg.generalConfig != null) { "icingaweb2/config.ini".text = generators.toINI {} (defaultConfig // cfg.generalConfig); }
249       // optionalAttrs (cfg.resources != null) { "icingaweb2/resources.ini".text = generators.toINI {} cfg.resources; }
250       // optionalAttrs (cfg.authentications != null) { "icingaweb2/authentication.ini".text = generators.toINI {} cfg.authentications; }
251       // optionalAttrs (cfg.groupBackends != null) { "icingaweb2/groups.ini".text = generators.toINI {} cfg.groupBackends; }
252       // optionalAttrs (cfg.roles != null) { "icingaweb2/roles.ini".text = generators.toINI {} cfg.roles; };
254     # User and group
255     users.groups.icingaweb2 = {};
256     users.users.icingaweb2 = {
257       description = "Icingaweb2 service user";
258       group = "icingaweb2";
259       isSystemUser = true;
260     };
261   };