at 23.11-pre 7.8 kB view raw
1{ config, lib, pkgs, buildEnv, ... }: 2 3with lib; 4 5let 6 cfg = config.services.peering-manager; 7 configFile = pkgs.writeTextFile { 8 name = "configuration.py"; 9 text = '' 10 ALLOWED_HOSTS = ['*'] 11 DATABASE = { 12 'NAME': 'peering-manager', 13 'USER': 'peering-manager', 14 'HOST': '/run/postgresql', 15 } 16 17 # Redis database settings. Redis is used for caching and for queuing background tasks such as webhook events. A separate 18 # configuration exists for each. Full connection details are required in both sections, and it is strongly recommended 19 # to use two separate database IDs. 20 REDIS = { 21 'tasks': { 22 'UNIX_SOCKET_PATH': '${config.services.redis.servers.peering-manager.unixSocket}', 23 'DATABASE': 0, 24 }, 25 'caching': { 26 'UNIX_SOCKET_PATH': '${config.services.redis.servers.peering-manager.unixSocket}', 27 'DATABASE': 1, 28 } 29 } 30 31 with open("${cfg.secretKeyFile}", "r") as file: 32 SECRET_KEY = file.readline() 33 '' + lib.optionalString (cfg.peeringdbApiKeyFile != null) '' 34 with open("${cfg.peeringdbApiKeyFile}", "r") as file: 35 PEERINGDB_API_KEY = file.readline() 36 '' + '' 37 38 ${cfg.extraConfig} 39 ''; 40 }; 41 pkg = (pkgs.peering-manager.overrideAttrs (old: { 42 postInstall = '' 43 ln -s ${configFile} $out/opt/peering-manager/peering_manager/configuration.py 44 '' + optionalString cfg.enableLdap '' 45 ln -s ${cfg.ldapConfigPath} $out/opt/peering-manager/peering_manager/ldap_config.py 46 ''; 47 })).override { 48 inherit (cfg) plugins; 49 }; 50 peeringManagerManageScript = with pkgs; (writeScriptBin "peering-manager-manage" '' 51 #!${stdenv.shell} 52 export PYTHONPATH=${pkg.pythonPath} 53 sudo -u peering-manager ${pkg}/bin/peering-manager "$@" 54 ''); 55 56in { 57 options.services.peering-manager = { 58 enable = mkOption { 59 type = lib.types.bool; 60 default = false; 61 description = lib.mdDoc '' 62 Enable Peering Manager. 63 64 This module requires a reverse proxy that serves `/static` separately. 65 See this [example](https://github.com/peering-manager-community/peering-manager/blob/develop/contrib/nginx.conf/) on how to configure this. 66 ''; 67 }; 68 69 listenAddress = mkOption { 70 type = types.str; 71 default = "[::1]"; 72 description = lib.mdDoc '' 73 Address the server will listen on. 74 ''; 75 }; 76 77 port = mkOption { 78 type = types.port; 79 default = 8001; 80 description = lib.mdDoc '' 81 Port the server will listen on. 82 ''; 83 }; 84 85 plugins = mkOption { 86 type = types.functionTo (types.listOf types.package); 87 default = _: []; 88 defaultText = literalExpression '' 89 python3Packages: with python3Packages; []; 90 ''; 91 description = lib.mdDoc '' 92 List of plugin packages to install. 93 ''; 94 }; 95 96 secretKeyFile = mkOption { 97 type = types.path; 98 description = lib.mdDoc '' 99 Path to a file containing the secret key. 100 ''; 101 }; 102 103 peeringdbApiKeyFile = mkOption { 104 type = with types; nullOr path; 105 default = null; 106 description = lib.mdDoc '' 107 Path to a file containing the PeeringDB API key. 108 ''; 109 }; 110 111 extraConfig = mkOption { 112 type = types.lines; 113 default = ""; 114 description = lib.mdDoc '' 115 Additional lines of configuration appended to the `configuration.py`. 116 See the [documentation](https://peering-manager.readthedocs.io/en/stable/configuration/optional-settings/) for more possible options. 117 ''; 118 }; 119 120 enableLdap = mkOption { 121 type = types.bool; 122 default = false; 123 description = lib.mdDoc '' 124 Enable LDAP-Authentication for Peering Manager. 125 126 This requires a configuration file being pass through `ldapConfigPath`. 127 ''; 128 }; 129 130 ldapConfigPath = mkOption { 131 type = types.path; 132 description = lib.mdDoc '' 133 Path to the Configuration-File for LDAP-Authentication, will be loaded as `ldap_config.py`. 134 See the [documentation](https://peering-manager.readthedocs.io/en/stable/setup/6-ldap/#configuration) for possible options. 135 ''; 136 }; 137 }; 138 139 config = mkIf cfg.enable { 140 services.peering-manager.plugins = mkIf cfg.enableLdap (ps: [ ps.django-auth-ldap ]); 141 142 system.build.peeringManagerPkg = pkg; 143 144 services.redis.servers.peering-manager.enable = true; 145 146 services.postgresql = { 147 enable = true; 148 ensureDatabases = [ "peering-manager" ]; 149 ensureUsers = [ 150 { 151 name = "peering-manager"; 152 ensurePermissions = { 153 "DATABASE \"peering-manager\"" = "ALL PRIVILEGES"; 154 }; 155 } 156 ]; 157 }; 158 159 environment.systemPackages = [ peeringManagerManageScript ]; 160 161 systemd.targets.peering-manager = { 162 description = "Target for all Peering Manager services"; 163 wantedBy = [ "multi-user.target" ]; 164 after = [ "network-online.target" "redis-peering-manager.service" ]; 165 }; 166 167 systemd.services = let 168 defaultServiceConfig = { 169 WorkingDirectory = "/var/lib/peering-manager"; 170 User = "peering-manager"; 171 Group = "peering-manager"; 172 StateDirectory = "peering-manager"; 173 StateDirectoryMode = "0750"; 174 Restart = "on-failure"; 175 }; 176 in { 177 peering-manager-migration = { 178 description = "Peering Manager migrations"; 179 wantedBy = [ "peering-manager.target" ]; 180 181 environment = { 182 PYTHONPATH = pkg.pythonPath; 183 }; 184 185 serviceConfig = defaultServiceConfig // { 186 Type = "oneshot"; 187 ExecStart = '' 188 ${pkg}/bin/peering-manager migrate 189 ''; 190 }; 191 }; 192 193 peering-manager = { 194 description = "Peering Manager WSGI Service"; 195 wantedBy = [ "peering-manager.target" ]; 196 after = [ "peering-manager-migration.service" ]; 197 198 preStart = '' 199 ${pkg}/bin/peering-manager remove_stale_contenttypes --no-input 200 ''; 201 202 environment = { 203 PYTHONPATH = pkg.pythonPath; 204 }; 205 206 serviceConfig = defaultServiceConfig // { 207 ExecStart = '' 208 ${pkg.python.pkgs.gunicorn}/bin/gunicorn peering_manager.wsgi \ 209 --bind ${cfg.listenAddress}:${toString cfg.port} \ 210 --pythonpath ${pkg}/opt/peering-manager 211 ''; 212 }; 213 }; 214 215 peering-manager-rq = { 216 description = "Peering Manager Request Queue Worker"; 217 wantedBy = [ "peering-manager.target" ]; 218 after = [ "peering-manager.service" ]; 219 220 environment = { 221 PYTHONPATH = pkg.pythonPath; 222 }; 223 224 serviceConfig = defaultServiceConfig // { 225 ExecStart = '' 226 ${pkg}/bin/peering-manager rqworker high default low 227 ''; 228 }; 229 }; 230 231 peering-manager-housekeeping = { 232 description = "Peering Manager housekeeping job"; 233 after = [ "peering-manager.service" ]; 234 235 environment = { 236 PYTHONPATH = pkg.pythonPath; 237 }; 238 239 serviceConfig = defaultServiceConfig // { 240 Type = "oneshot"; 241 ExecStart = '' 242 ${pkg}/bin/peering-manager housekeeping 243 ''; 244 }; 245 }; 246 }; 247 248 systemd.timers.peering-manager-housekeeping = { 249 description = "Run Peering Manager housekeeping job"; 250 wantedBy = [ "timers.target" ]; 251 252 timerConfig = { 253 OnCalendar = "daily"; 254 }; 255 }; 256 257 users.users.peering-manager = { 258 home = "/var/lib/peering-manager"; 259 isSystemUser = true; 260 group = "peering-manager"; 261 }; 262 users.groups.peering-manager = {}; 263 users.groups."${config.services.redis.servers.peering-manager.user}".members = [ "peering-manager" ]; 264 }; 265}