at 23.11-pre 14 kB view raw
1{ lib, pkgs, config, options, ... }: 2 3let 4 cfg = config.services.nifi; 5 opt = options.services.nifi; 6 7 env = { 8 NIFI_OVERRIDE_NIFIENV = "true"; 9 NIFI_HOME = "/var/lib/nifi"; 10 NIFI_PID_DIR = "/run/nifi"; 11 NIFI_LOG_DIR = "/var/log/nifi"; 12 }; 13 14 envFile = pkgs.writeText "nifi.env" (lib.concatMapStrings (s: s + "\n") ( 15 (lib.concatLists (lib.mapAttrsToList (name: value: 16 if value != null then [ 17 "${name}=\"${toString value}\"" 18 ] else [] 19 ) env)))); 20 21 nifiEnv = pkgs.writeShellScriptBin "nifi-env" '' 22 set -a 23 source "${envFile}" 24 eval -- "\$@" 25 ''; 26 27in { 28 options = { 29 services.nifi = { 30 enable = lib.mkEnableOption (lib.mdDoc "Apache NiFi"); 31 32 package = lib.mkOption { 33 type = lib.types.package; 34 default = pkgs.nifi; 35 defaultText = lib.literalExpression "pkgs.nifi"; 36 description = lib.mdDoc "Apache NiFi package to use."; 37 }; 38 39 user = lib.mkOption { 40 type = lib.types.str; 41 default = "nifi"; 42 description = lib.mdDoc "User account where Apache NiFi runs."; 43 }; 44 45 group = lib.mkOption { 46 type = lib.types.str; 47 default = "nifi"; 48 description = lib.mdDoc "Group account where Apache NiFi runs."; 49 }; 50 51 enableHTTPS = lib.mkOption { 52 type = lib.types.bool; 53 default = true; 54 description = lib.mdDoc "Enable HTTPS protocol. Don`t use in production."; 55 }; 56 57 listenHost = lib.mkOption { 58 type = lib.types.str; 59 default = if cfg.enableHTTPS then "0.0.0.0" else "127.0.0.1"; 60 defaultText = lib.literalExpression '' 61 if config.${opt.enableHTTPS} 62 then "0.0.0.0" 63 else "127.0.0.1" 64 ''; 65 description = lib.mdDoc "Bind to an ip for Apache NiFi web-ui."; 66 }; 67 68 listenPort = lib.mkOption { 69 type = lib.types.int; 70 default = if cfg.enableHTTPS then 8443 else 8080; 71 defaultText = lib.literalExpression '' 72 if config.${opt.enableHTTPS} 73 then "8443" 74 else "8000" 75 ''; 76 description = lib.mdDoc "Bind to a port for Apache NiFi web-ui."; 77 }; 78 79 proxyHost = lib.mkOption { 80 type = lib.types.nullOr lib.types.str; 81 default = if cfg.enableHTTPS then "0.0.0.0" else null; 82 defaultText = lib.literalExpression '' 83 if config.${opt.enableHTTPS} 84 then "0.0.0.0" 85 else null 86 ''; 87 description = lib.mdDoc "Allow requests from a specific host."; 88 }; 89 90 proxyPort = lib.mkOption { 91 type = lib.types.nullOr lib.types.int; 92 default = if cfg.enableHTTPS then 8443 else null; 93 defaultText = lib.literalExpression '' 94 if config.${opt.enableHTTPS} 95 then "8443" 96 else null 97 ''; 98 description = lib.mdDoc "Allow requests from a specific port."; 99 }; 100 101 initUser = lib.mkOption { 102 type = lib.types.nullOr lib.types.str; 103 default = null; 104 description = lib.mdDoc "Initial user account for Apache NiFi. Username must be at least 4 characters."; 105 }; 106 107 initPasswordFile = lib.mkOption { 108 type = lib.types.nullOr lib.types.path; 109 default = null; 110 example = "/run/keys/nifi/password-nifi"; 111 description = lib.mdDoc "nitial password for Apache NiFi. Password must be at least 12 characters."; 112 }; 113 114 initJavaHeapSize = lib.mkOption { 115 type = lib.types.nullOr lib.types.int; 116 default = null; 117 example = 1024; 118 description = lib.mdDoc "Set the initial heap size for the JVM in MB."; 119 }; 120 121 maxJavaHeapSize = lib.mkOption { 122 type = lib.types.nullOr lib.types.int; 123 default = null; 124 example = 2048; 125 description = lib.mdDoc "Set the initial heap size for the JVM in MB."; 126 }; 127 }; 128 }; 129 130 config = lib.mkIf cfg.enable { 131 assertions = [ 132 { assertion = cfg.initUser!=null || cfg.initPasswordFile==null; 133 message = '' 134 <option>services.nifi.initUser</option> needs to be set if <option>services.nifi.initPasswordFile</option> enabled. 135 ''; 136 } 137 { assertion = cfg.initUser==null || cfg.initPasswordFile!=null; 138 message = '' 139 <option>services.nifi.initPasswordFile</option> needs to be set if <option>services.nifi.initUser</option> enabled. 140 ''; 141 } 142 { assertion = cfg.proxyHost==null || cfg.proxyPort!=null; 143 message = '' 144 <option>services.nifi.proxyPort</option> needs to be set if <option>services.nifi.proxyHost</option> value specified. 145 ''; 146 } 147 { assertion = cfg.proxyHost!=null || cfg.proxyPort==null; 148 message = '' 149 <option>services.nifi.proxyHost</option> needs to be set if <option>services.nifi.proxyPort</option> value specified. 150 ''; 151 } 152 { assertion = cfg.initJavaHeapSize==null || cfg.maxJavaHeapSize!=null; 153 message = '' 154 <option>services.nifi.maxJavaHeapSize</option> needs to be set if <option>services.nifi.initJavaHeapSize</option> value specified. 155 ''; 156 } 157 { assertion = cfg.initJavaHeapSize!=null || cfg.maxJavaHeapSize==null; 158 message = '' 159 <option>services.nifi.initJavaHeapSize</option> needs to be set if <option>services.nifi.maxJavaHeapSize</option> value specified. 160 ''; 161 } 162 ]; 163 164 warnings = lib.optional (cfg.enableHTTPS==false) '' 165 Please do not disable HTTPS mode in production. In this mode, access to the nifi is opened without authentication. 166 ''; 167 168 systemd.tmpfiles.rules = [ 169 "d '/var/lib/nifi/conf' 0750 ${cfg.user} ${cfg.group}" 170 "L+ '/var/lib/nifi/lib' - - - - ${cfg.package}/lib" 171 ]; 172 173 174 systemd.services.nifi = { 175 description = "Apache NiFi"; 176 after = [ "network.target" ]; 177 wantedBy = [ "multi-user.target" ]; 178 179 environment = env; 180 path = [ pkgs.gawk ]; 181 182 serviceConfig = { 183 Type = "forking"; 184 PIDFile = "/run/nifi/nifi.pid"; 185 ExecStartPre = pkgs.writeScript "nifi-pre-start.sh" '' 186 #!/bin/sh 187 umask 077 188 test -f '/var/lib/nifi/conf/authorizers.xml' || (cp '${cfg.package}/share/nifi/conf/authorizers.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/authorizers.xml') 189 test -f '/var/lib/nifi/conf/bootstrap.conf' || (cp '${cfg.package}/share/nifi/conf/bootstrap.conf' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/bootstrap.conf') 190 test -f '/var/lib/nifi/conf/bootstrap-hashicorp-vault.conf' || (cp '${cfg.package}/share/nifi/conf/bootstrap-hashicorp-vault.conf' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/bootstrap-hashicorp-vault.conf') 191 test -f '/var/lib/nifi/conf/bootstrap-notification-services.xml' || (cp '${cfg.package}/share/nifi/conf/bootstrap-notification-services.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/bootstrap-notification-services.xml') 192 test -f '/var/lib/nifi/conf/logback.xml' || (cp '${cfg.package}/share/nifi/conf/logback.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/logback.xml') 193 test -f '/var/lib/nifi/conf/login-identity-providers.xml' || (cp '${cfg.package}/share/nifi/conf/login-identity-providers.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/login-identity-providers.xml') 194 test -f '/var/lib/nifi/conf/nifi.properties' || (cp '${cfg.package}/share/nifi/conf/nifi.properties' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/nifi.properties') 195 test -f '/var/lib/nifi/conf/stateless-logback.xml' || (cp '${cfg.package}/share/nifi/conf/stateless-logback.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/stateless-logback.xml') 196 test -f '/var/lib/nifi/conf/stateless.properties' || (cp '${cfg.package}/share/nifi/conf/stateless.properties' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/stateless.properties') 197 test -f '/var/lib/nifi/conf/state-management.xml' || (cp '${cfg.package}/share/nifi/conf/state-management.xml' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/state-management.xml') 198 test -f '/var/lib/nifi/conf/zookeeper.properties' || (cp '${cfg.package}/share/nifi/conf/zookeeper.properties' '/var/lib/nifi/conf/' && chmod 0640 '/var/lib/nifi/conf/zookeeper.properties') 199 test -d '/var/lib/nifi/docs/html' || (mkdir -p /var/lib/nifi/docs && cp -r '${cfg.package}/share/nifi/docs/html' '/var/lib/nifi/docs/html') 200 ${lib.optionalString ((cfg.initUser != null) && (cfg.initPasswordFile != null)) '' 201 awk -F'[<|>]' '/property name="Username"/ {if ($3!="") f=1} END{exit !f}' /var/lib/nifi/conf/login-identity-providers.xml || ${cfg.package}/bin/nifi.sh set-single-user-credentials ${cfg.initUser} $(cat ${cfg.initPasswordFile}) 202 ''} 203 ${lib.optionalString (cfg.enableHTTPS == false) '' 204 sed -i /var/lib/nifi/conf/nifi.properties \ 205 -e 's|nifi.remote.input.secure=.*|nifi.remote.input.secure=false|g' \ 206 -e 's|nifi.web.http.host=.*|nifi.web.http.host=${cfg.listenHost}|g' \ 207 -e 's|nifi.web.http.port=.*|nifi.web.http.port=${(toString cfg.listenPort)}|g' \ 208 -e 's|nifi.web.https.host=.*|nifi.web.https.host=|g' \ 209 -e 's|nifi.web.https.port=.*|nifi.web.https.port=|g' \ 210 -e 's|nifi.security.keystore=.*|nifi.security.keystore=|g' \ 211 -e 's|nifi.security.keystoreType=.*|nifi.security.keystoreType=|g' \ 212 -e 's|nifi.security.truststore=.*|nifi.security.truststore=|g' \ 213 -e 's|nifi.security.truststoreType=.*|nifi.security.truststoreType=|g' \ 214 -e '/nifi.security.keystorePasswd/s|^|#|' \ 215 -e '/nifi.security.keyPasswd/s|^|#|' \ 216 -e '/nifi.security.truststorePasswd/s|^|#|' 217 ''} 218 ${lib.optionalString (cfg.enableHTTPS == true) '' 219 sed -i /var/lib/nifi/conf/nifi.properties \ 220 -e 's|nifi.remote.input.secure=.*|nifi.remote.input.secure=true|g' \ 221 -e 's|nifi.web.http.host=.*|nifi.web.http.host=|g' \ 222 -e 's|nifi.web.http.port=.*|nifi.web.http.port=|g' \ 223 -e 's|nifi.web.https.host=.*|nifi.web.https.host=${cfg.listenHost}|g' \ 224 -e 's|nifi.web.https.port=.*|nifi.web.https.port=${(toString cfg.listenPort)}|g' \ 225 -e 's|nifi.security.keystore=.*|nifi.security.keystore=./conf/keystore.p12|g' \ 226 -e 's|nifi.security.keystoreType=.*|nifi.security.keystoreType=PKCS12|g' \ 227 -e 's|nifi.security.truststore=.*|nifi.security.truststore=./conf/truststore.p12|g' \ 228 -e 's|nifi.security.truststoreType=.*|nifi.security.truststoreType=PKCS12|g' \ 229 -e '/nifi.security.keystorePasswd/s|^#\+||' \ 230 -e '/nifi.security.keyPasswd/s|^#\+||' \ 231 -e '/nifi.security.truststorePasswd/s|^#\+||' 232 ''} 233 ${lib.optionalString ((cfg.enableHTTPS == true) && (cfg.proxyHost != null) && (cfg.proxyPort != null)) '' 234 sed -i /var/lib/nifi/conf/nifi.properties \ 235 -e 's|nifi.web.proxy.host=.*|nifi.web.proxy.host=${cfg.proxyHost}:${(toString cfg.proxyPort)}|g' 236 ''} 237 ${lib.optionalString ((cfg.enableHTTPS == false) || (cfg.proxyHost == null) && (cfg.proxyPort == null)) '' 238 sed -i /var/lib/nifi/conf/nifi.properties \ 239 -e 's|nifi.web.proxy.host=.*|nifi.web.proxy.host=|g' 240 ''} 241 ${lib.optionalString ((cfg.initJavaHeapSize != null) && (cfg.maxJavaHeapSize != null))'' 242 sed -i /var/lib/nifi/conf/bootstrap.conf \ 243 -e 's|java.arg.2=.*|java.arg.2=-Xms${(toString cfg.initJavaHeapSize)}m|g' \ 244 -e 's|java.arg.3=.*|java.arg.3=-Xmx${(toString cfg.maxJavaHeapSize)}m|g' 245 ''} 246 ${lib.optionalString ((cfg.initJavaHeapSize == null) && (cfg.maxJavaHeapSize == null))'' 247 sed -i /var/lib/nifi/conf/bootstrap.conf \ 248 -e 's|java.arg.2=.*|java.arg.2=-Xms512m|g' \ 249 -e 's|java.arg.3=.*|java.arg.3=-Xmx512m|g' 250 ''} 251 ''; 252 ExecStart = "${cfg.package}/bin/nifi.sh start"; 253 ExecStop = "${cfg.package}/bin/nifi.sh stop"; 254 # User and group 255 User = cfg.user; 256 Group = cfg.group; 257 # Runtime directory and mode 258 RuntimeDirectory = "nifi"; 259 RuntimeDirectoryMode = "0750"; 260 # State directory and mode 261 StateDirectory = "nifi"; 262 StateDirectoryMode = "0750"; 263 # Logs directory and mode 264 LogsDirectory = "nifi"; 265 LogsDirectoryMode = "0750"; 266 # Proc filesystem 267 ProcSubset = "pid"; 268 ProtectProc = "invisible"; 269 # Access write directories 270 ReadWritePaths = [ cfg.initPasswordFile ]; 271 UMask = "0027"; 272 # Capabilities 273 CapabilityBoundingSet = ""; 274 # Security 275 NoNewPrivileges = true; 276 # Sandboxing 277 ProtectSystem = "strict"; 278 ProtectHome = true; 279 PrivateTmp = true; 280 PrivateDevices = true; 281 PrivateIPC = true; 282 PrivateUsers = true; 283 ProtectHostname = true; 284 ProtectClock = true; 285 ProtectKernelTunables = true; 286 ProtectKernelModules = true; 287 ProtectKernelLogs = true; 288 ProtectControlGroups = true; 289 RestrictAddressFamilies = [ "AF_INET AF_INET6" ]; 290 RestrictNamespaces = true; 291 LockPersonality = true; 292 MemoryDenyWriteExecute = false; 293 RestrictRealtime = true; 294 RestrictSUIDSGID = true; 295 RemoveIPC = true; 296 PrivateMounts = true; 297 # System Call Filtering 298 SystemCallArchitectures = "native"; 299 SystemCallFilter = [ "~@cpu-emulation @debug @keyring @memlock @mount @obsolete @resources @privileged @setuid" "@chown" ]; 300 }; 301 }; 302 303 users.users = lib.mkMerge [ 304 (lib.mkIf (cfg.user == "nifi") { 305 nifi = { 306 group = cfg.group; 307 isSystemUser = true; 308 home = cfg.package; 309 }; 310 }) 311 (lib.attrsets.setAttrByPath [ cfg.user "packages" ] [ cfg.package nifiEnv ]) 312 ]; 313 314 users.groups = lib.optionalAttrs (cfg.group == "nifi") { 315 nifi = { }; 316 }; 317 }; 318}