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