main
 1{
 2  den,
 3  lib,
 4  ...
 5}: let
 6  # Tailnet MagicDNS base domain; reverse proxy entries use it as a suffix.
 7  tailnetDomain = "net.trin.one";
 8in {
 9  den.quirks.reverseProxy.description = ''
10    Reverse proxy site entries collected from aspects (host)
11
12    Example:
13      domain = {
14        port = 8080; # Port the service listen
15        path = "/foo/bar" # Path to reverse proxy to
16        stripPath = false; # Whether to strip path prefix ("/foo/bar")
17        upstream = "/"; Path to reverse proxy from
18        prefer = "direct"; # Connection policy override: null (host default), "direct" or "tailscale"
19        maxSize = "16MiB"; # Set request_body.max_size in Caddyfile
20      }
21  '';
22
23  den.aspects.services.caddy.tailnetDomain = tailnetDomain;
24
25  den.policies.collect-reverse-proxy = _: let
26    inherit (den.lib.policy) pipe;
27  in [
28    (pipe.from "reverseProxy" [
29      (pipe.collectAll ({host, ...}: true))
30      (pipe.transform (value: (lib.mapAttrs
31        (domain: conf: conf // {tailscale = lib.hasSuffix ".${tailnetDomain}" domain;})
32        value)))
33      pipe.withProvenance
34    ])
35  ];
36
37  den.schema.host.includes = [den.policies.collect-reverse-proxy];
38}