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