refactor(gateway): extract the _ vhost agent + dashboard location groups
Step 3 of the hive-gateway.nix vhost cleanup. Lift the /agent/ catch-all (+ its two internal error-page targets) and the catch-all dashboard proxy out of the inline //-chain into agentLocations / dashboardProxyLocation bindings. The default _ server's locations now read as a flat composition of named groups — matrixRedirectLocations // wellKnownLocations // agentLocations // dashboardProxyLocation // <auth optionalAttrs> — instead of a deep nested literal. The auth-401 group stays inline (a self-contained lib.optionalAttrs already). Pure readability refactor, eval-identical: generated virtualHosts toJSON is byte-identical before/after (8888 bytes, diff empty).
This commit is contained in:
parent
90b7d61792
commit
36e5e19d8e
1 changed files with 67 additions and 75 deletions
|
|
@ -643,9 +643,9 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
# `_` (default) server location groups, lifted out of the inline
|
# `_` (default) server location groups, lifted out of the inline
|
||||||
# `//`-chain so the two matrix groups (each with its own `let`)
|
# `//`-chain so each conditional group reads on its own. Composed
|
||||||
# read on their own. Composed into the `_` vhost's `locations`
|
# into the `_` vhost's `locations` below alongside the still-inline
|
||||||
# below alongside the still-inline agent/dashboard/auth groups.
|
# auth-401 group (a self-contained `lib.optionalAttrs`).
|
||||||
|
|
||||||
# `<hive>/matrix/*` → 301 → `matrix.<hive>/$1` (legacy deep-link
|
# `<hive>/matrix/*` → 301 → `matrix.<hive>/$1` (legacy deep-link
|
||||||
# shim during the fluffychat sub-domain move). See `docs/gateway.md`.
|
# shim during the fluffychat sub-domain move). See `docs/gateway.md`.
|
||||||
|
|
@ -707,6 +707,68 @@ in
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# `/agent/` catch-all 404 + the two internal error-page targets it
|
||||||
|
# points at. Per-agent `location /agent/<name>/` blocks live in the
|
||||||
|
# runtime-generated `/run/hive-state/agents.conf` (included via
|
||||||
|
# `extraConfig` on the vhost); nginx longest-prefix-match makes a
|
||||||
|
# real `/agent/<name>/` beat this catch-all. `internal` keeps the
|
||||||
|
# error pages reachable only through nginx's error handling.
|
||||||
|
agentLocations = {
|
||||||
|
"/agent/" = {
|
||||||
|
extraConfig = ''
|
||||||
|
error_page 404 = /__hive_agent_not_found;
|
||||||
|
return 404;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /__hive_agent_not_found" = {
|
||||||
|
extraConfig = ''
|
||||||
|
internal;
|
||||||
|
alias ${agentErrorPagesDir}/not-found.html;
|
||||||
|
default_type text/html;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /__hive_agent_unreachable" = {
|
||||||
|
extraConfig = ''
|
||||||
|
internal;
|
||||||
|
alias ${agentErrorPagesDir}/unreachable.html;
|
||||||
|
default_type text/html;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Everything else proxies to hive-c0re. Upgrade headers stay set so
|
||||||
|
# SSE (`/dashboard/stream`, `/events/stream`) + websocket
|
||||||
|
# (`/screen/ws`) endpoints keep working transparently. When auth is
|
||||||
|
# enabled, nginx's built-in `auth_basic` validates against the
|
||||||
|
# bind-mounted htpasswd; the `=401` error_page points at the
|
||||||
|
# internal unauthorized page (the auth-only location below).
|
||||||
|
dashboardProxyLocation = {
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}";
|
||||||
|
proxyWebsockets = true;
|
||||||
|
extraConfig = ''
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_read_timeout 1d;
|
||||||
|
${lib.optionalString cfg.auth.enable ''
|
||||||
|
auth_basic "${cfg.auth.realm}";
|
||||||
|
# htpasswd file lives in the gateway state dir,
|
||||||
|
# already bind-mounted read-only at /run/hive-state/.
|
||||||
|
# Host path: /var/lib/hyperhive/gateway/gateway.htpasswd
|
||||||
|
auth_basic_user_file /run/hive-state/gateway.htpasswd;
|
||||||
|
# Serve a custom page when credentials are missing or wrong.
|
||||||
|
# `=401` forces the final status to remain 401 so browsers
|
||||||
|
# still present the login dialog on first visit; users who
|
||||||
|
# dismiss the dialog see a page explaining how to add users
|
||||||
|
# with `hivectl gateway create-user`.
|
||||||
|
# The exact-match location below beats `location /` in nginx's
|
||||||
|
# prefix ordering, so the internal subrequest does not loop back
|
||||||
|
# through auth_basic.
|
||||||
|
error_page 401 =401 /__hive_auth_unauthorized;
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
system.stateVersion = "26.05";
|
system.stateVersion = "26.05";
|
||||||
|
|
@ -830,78 +892,8 @@ in
|
||||||
locations =
|
locations =
|
||||||
matrixRedirectLocations
|
matrixRedirectLocations
|
||||||
// wellKnownLocations
|
// wellKnownLocations
|
||||||
//
|
// agentLocations
|
||||||
# `/agent/` catch-all: hits when an operator
|
// dashboardProxyLocation
|
||||||
# requests `/agent/<unknown>/...`. Without this the
|
|
||||||
# request falls through to `/` (c0re dashboard) and
|
|
||||||
# returns 404 with no useful context. Custom 404
|
|
||||||
# page instead. Per-agent `location /agent/<name>/`
|
|
||||||
# blocks live in `/run/hive-state/agents.conf` —
|
|
||||||
# nginx picks them up via the `include` in
|
|
||||||
# `extraConfig` below; the catch-all only matches
|
|
||||||
# names that aren't in that file (nginx longest-
|
|
||||||
# prefix-match: `/agent/atlas/` beats `/agent/`).
|
|
||||||
{
|
|
||||||
"/agent/" = {
|
|
||||||
extraConfig = ''
|
|
||||||
error_page 404 = /__hive_agent_not_found;
|
|
||||||
return 404;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
# Internal static-file locations the error_page
|
|
||||||
# directives above point at. `internal` keeps
|
|
||||||
# operators from hitting the file directly (only
|
|
||||||
# nginx's error-handling can reach it); `alias`
|
|
||||||
# serves the exact file regardless of request URI.
|
|
||||||
"= /__hive_agent_not_found" = {
|
|
||||||
extraConfig = ''
|
|
||||||
internal;
|
|
||||||
alias ${agentErrorPagesDir}/not-found.html;
|
|
||||||
default_type text/html;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
"= /__hive_agent_unreachable" = {
|
|
||||||
extraConfig = ''
|
|
||||||
internal;
|
|
||||||
alias ${agentErrorPagesDir}/unreachable.html;
|
|
||||||
default_type text/html;
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// {
|
|
||||||
# Everything else proxies to hive-c0re. Upgrade
|
|
||||||
# headers stay set so SSE (`/dashboard/stream`,
|
|
||||||
# `/events/stream`) + websocket (`/screen/ws`)
|
|
||||||
# endpoints keep working transparently.
|
|
||||||
# When auth is enabled, nginx's built-in `auth_basic`
|
|
||||||
# validates credentials against the htpasswd file
|
|
||||||
# bind-mounted at `/run/gateway-auth/`. No extra
|
|
||||||
# service or host-side daemon required.
|
|
||||||
"/" = {
|
|
||||||
proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
extraConfig = ''
|
|
||||||
proxy_buffering off;
|
|
||||||
proxy_read_timeout 1d;
|
|
||||||
${lib.optionalString cfg.auth.enable ''
|
|
||||||
auth_basic "${cfg.auth.realm}";
|
|
||||||
# htpasswd file lives in the gateway state dir,
|
|
||||||
# already bind-mounted read-only at /run/hive-state/.
|
|
||||||
# Host path: /var/lib/hyperhive/gateway/gateway.htpasswd
|
|
||||||
auth_basic_user_file /run/hive-state/gateway.htpasswd;
|
|
||||||
# Serve a custom page when credentials are missing or wrong.
|
|
||||||
# `=401` forces the final status to remain 401 so browsers
|
|
||||||
# still present the login dialog on first visit; users who
|
|
||||||
# dismiss the dialog see a page explaining how to add users
|
|
||||||
# with `hivectl gateway create-user`.
|
|
||||||
# The exact-match location below beats `location /` in nginx's
|
|
||||||
# prefix ordering, so the internal subrequest does not loop back
|
|
||||||
# through auth_basic.
|
|
||||||
error_page 401 =401 /__hive_auth_unauthorized;
|
|
||||||
''}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs cfg.auth.enable {
|
// lib.optionalAttrs cfg.auth.enable {
|
||||||
# Internal-only target for the 401 error_page above.
|
# Internal-only target for the 401 error_page above.
|
||||||
# `internal` prevents direct client access; `alias` serves
|
# `internal` prevents direct client access; `alias` serves
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue