Watch
0
0
Fork
You've already forked hyperhive
0
hyperhive/nix/host-modules/hive-gateway/declared-vhosts.nix
atlas ddb583cc22 gateway: service modules declare their vhost under gateway.vhosts
Ten service modules (forge, matrix chat, authelia, grafana, otel, nats,
swarm-ui, victorialogs, victoriametrics, bao UI) wrote
services.nginx.virtualHosts themselves, each applying the gateway's
listen set, per-name TLS attrs and security headers by hand. They now
declare services.hyperhive.gateway.vhosts.<name> with only their own
locations and options; ./declared-vhosts.nix renders it into the nginx
vhost with listen, TLS and headers added.

An eval assertion refuses a declared vhost that sets listen, addSSL,
onlySSL, enableACME, useACMEHost, sslCertificate or sslCertificateKey,
and one declared while the gateway is off. nats' own leaf is the new
`certificate` field. The rendered nginx vhosts are unchanged.
2026-10-16 12:47:03 +02:00

85 lines
2.6 KiB
Nix

# Renders `services.hyperhive.gateway.vhosts` into
# `services.nginx.virtualHosts`: each declared vhost keeps what its module
# wrote and gets the gateway's `listen`, the TLS attributes for its name and
# the security headers.
#
# Its own module rather than part of ./default.nix because the
# "declared while the gateway is off" assertion has to hold when
# `gateway.enable` is false, where ./default.nix defines nothing.
{ lib, config, ... }:
let
cfg = config.services.hyperhive.gateway;
# What the gateway owns on a vhost. A declared vhost naming one of these
# fails the eval.
gatewayOwned = [
"listen"
"addSSL"
"onlySSL"
"enableACME"
"useACMEHost"
"sslCertificate"
"sslCertificateKey"
];
offenders = lib.concatMap (
name: map (attr: "${name}.${attr}") (lib.filter (a: cfg.vhosts.${name} ? ${a}) gatewayOwned)
) (lib.attrNames cfg.vhosts);
render =
name: declared:
let
own = removeAttrs declared [
"_module"
"certificate"
];
base =
if declared.certificate != null then
{
sslCertificate = declared.certificate.cert;
sslCertificateKey = declared.certificate.key;
}
else
cfg.lib.tlsFor name;
# nixos asserts on a vhost declaring both `addSSL` and `forceSSL`.
tls = if own.forceSSL or false then removeAttrs base [ "addSSL" ] else base;
in
tls
// own
// {
listen = cfg.lib.listen;
extraConfig = cfg.lib.securityHeaders + (own.extraConfig or "");
};
in
{
config = lib.mkMerge [
{
assertions = [
{
assertion = cfg.enable || cfg.vhosts == { };
message = ''
services.hyperhive.gateway.vhosts declares ${lib.concatStringsSep ", " (lib.attrNames cfg.vhosts)}
while services.hyperhive.gateway.enable is false, so nothing
would serve them. Enable the gateway, or drop the service that
declares the vhost.
'';
}
{
assertion = offenders == [ ];
message = ''
services.hyperhive.gateway.vhosts sets attributes the gateway owns:
${lib.concatStringsSep ", " offenders}
The gateway sets the listen set and the TLS attributes of every
vhost it fronts. Declare only the vhost's own locations and
options; to serve a certificate the gateway does not pick, set
`certificate` on the vhost.
'';
}
];
}
(lib.mkIf cfg.enable {
services.nginx.virtualHosts = lib.mapAttrs render cfg.vhosts;
})
];
}