The catch-all, the dashboard and the hive-domain vhost were built in vhosts.nix with the listen set, TLS attrs and headers applied by hand. They are declared under services.hyperhive.gateway.vhosts now, so every vhost behind the gateway goes through declared-vhosts.nix. Two gateway-side rules cover what the catch-all needed: a vhost can set securityHeaders = false (the catch-all only returns 444), and `default` is rendered at mkDefault priority so an operator's own default vhost still wins. The matrix discovery locations are unchanged. The rendered nginx vhosts are unchanged.
92 lines
2.9 KiB
Nix
92 lines
2.9 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"
|
|
"securityHeaders"
|
|
];
|
|
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 =
|
|
lib.optionalString declared.securityHeaders cfg.lib.securityHeaders + (own.extraConfig or "");
|
|
}
|
|
// lib.optionalAttrs (own ? default) {
|
|
# At `mkDefault` priority, so an operator can turn this vhost's
|
|
# `default` off with a plain definition.
|
|
default = lib.mkDefault own.default;
|
|
};
|
|
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;
|
|
})
|
|
];
|
|
}
|