at main 5.0 kB view raw
1# Copyright (c) 2023 soopyc 2# Permission is given to copy and use under the terms of Apache 2.0. 3# 4# you may copy-paste this entire file to anywhere else. just keep the comments. 5# see /docs/src/utils/ for a usage guide 6{ 7 inputs, 8 system, 9 ... 10}: 11let 12 pkgs = inputs.nixpkgs.legacyPackages.${system}; 13 lib = pkgs.lib; 14in 15rec { 16 mkVhost = 17 opts: 18 lib.mkMerge [ 19 { 20 forceSSL = lib.mkDefault true; 21 useACMEHost = lib.mkDefault "global.c.soopy.moe"; 22 kTLS = lib.mkDefault true; 23 quic = lib.mkDefault true; 24 25 locations."/_cgi/error/" = { 26 alias = "${inputs.mystia.packages.${system}.staticly}/nginx_error_pages/"; 27 }; 28 29 # To override, mkForce {} 30 locations."= /robots.txt" = mkNginxFile { 31 filename = "robots.txt"; 32 content = '' 33 # Please stop hammering and/or scraping our services. 34 User-Agent: * 35 Disallow: / 36 ''; 37 }; 38 39 extraConfig = '' 40 error_page 503 /_cgi/error/503.html; 41 error_page 502 /_cgi/error/502.html; 42 error_page 404 /_cgi/error/404.html; 43 add_header strict-transport-security "max-age=63072000; includeSubDomains; preload" always; 44 add_header alt-svc 'h3=":443";ma=86400' always; 45 ''; 46 } 47 opts 48 ]; 49 50 mkSimpleProxy = 51 { 52 protocol ? "http", 53 host ? "localhost", 54 port ? null, 55 socketPath ? null, 56 location ? "/", 57 websockets ? false, 58 extraConfig ? { }, 59 }: 60 assert lib.assertMsg ( 61 port != null || socketPath != null 62 ) "one of port or socketPath must be specified"; 63 # i dislike logic gates 64 assert lib.assertMsg ( 65 !(port != null && socketPath != null) 66 ) "only one of port or socketPath may be specified at the same time"; 67 assert lib.assertMsg ( 68 socketPath != null -> host == "localhost" 69 ) "setting host has no effect when socketPath is set"; 70 assert lib.assertMsg (port != null -> builtins.isInt port) "port must be an integer if specified"; 71 mkVhost ( 72 lib.mkMerge [ 73 extraConfig 74 { 75 locations."${location}" = { 76 proxyPass = 77 "${protocol}://" 78 + (if (socketPath == null) then "${host}:${builtins.toString port}" else "unix:${socketPath}"); 79 proxyWebsockets = websockets; 80 }; 81 } 82 ] 83 ); 84 85 setupSecrets = 86 _config: 87 { 88 namespace ? ( 89 lib.warn "secret namespace left as default, which is empty. it is encouraged to set a namespace for easier secret management. to override, explicitly set this to an empty value." "" 90 ), 91 secrets, 92 config ? { }, 93 }: 94 let 95 _r_ns = namespace + lib.optionalString (lib.stringLength namespace != 0) "/"; 96 check = 97 path: 98 assert lib.assertMsg (lib.elem path secrets) 99 "secret path `${path}` is not defined in namespace `${namespace}`. (resolved to: ${_r_ns}${path})"; 100 path; 101 getRealPath = path: _r_ns + check path; 102 in 103 builtins.addErrorContext "while setting up secrets with namespace ${namespace}" { 104 generate = { 105 sops.secrets = genSecrets namespace secrets config; 106 }; # i love trolling 107 get = path: _config.sops.secrets.${getRealPath path}.path; 108 109 placeholder = path: _config.sops.placeholder.${getRealPath path}; 110 getTemplate = file: _config.sops.templates.${file}.path; 111 mkTemplate = 112 file: content: 113 builtins.addErrorContext "while generating sops template ${file}" { 114 sops.templates.${file} = { 115 inherit content; 116 } 117 // (builtins.removeAttrs config [ "content" ]); 118 # // (lib.optionalAttrs (builtins.hasAttr "owner" config) {inherit (config) owner;}) 119 # // (lib.optionalAttrs (builtins.hasAttr "group" config) {inherit (config) group;}); 120 }; 121 }; 122 123 genSecrets = 124 namespace: files: value: 125 lib.genAttrs (map ( 126 x: namespace + lib.optionalString (lib.stringLength namespace != 0) "/" + x 127 ) files) (_: value); 128 129 mkNginxFile = 130 { 131 filename ? "index.html", 132 content, 133 }: 134 builtins.addErrorContext "while creating a static nginx file ${filename}" ( 135 let 136 contentDir = 137 assert lib.assertMsg ( 138 builtins.typeOf content == "string" 139 ) "content must be a string, got `${builtins.typeOf content}`"; 140 builtins.toString (pkgs.writeTextDir filename content) + "/"; 141 in 142 { 143 alias = contentDir; 144 tryFiles = "${filename} =500"; # if it can't find the file something has gone wrong. 145 } 146 ); 147 148 mkNginxJSON = 149 filename: attrset: 150 builtins.addErrorContext "while creating a static nginx JSON file ${filename}" ( 151 assert lib.assertMsg ( 152 builtins.typeOf attrset == "set" 153 ) "expected argument type `set`, got `${builtins.typeOf attrset}` instead."; 154 mkNginxFile { 155 inherit filename; 156 content = builtins.toJSON attrset; 157 } 158 ); 159}