Watch
0
0
Fork
You've already forked hyperhive
0

service urls carry no gateway port, httpsPort is listen-only

This commit is contained in:
atlas 2026-10-25 02:00:20 +02:00 • committed by mara
commit 19680a8b78
25 changed files with 105 additions and 143 deletions

View file

@ -24,8 +24,7 @@
# ./glue-swarm-otel-oidc-client.nix), and `deploy.swarm-otel.enable` only says it
# runs HERE. The endpoint is its swarm-service name through the gateway, never a
# loopback literal, with no trailing slash: the http exporter appends
# `/v1/metrics` and the gateway route strips `/${producerName}`. The port suffix
# is elided on 443, as in ./swarm-bao.nix.
# `/v1/metrics` and the gateway route strips `/${producerName}`.
# `SWARM_CONTROLLER_OTEL_AUDIENCE` is the audience ./glue-controller-oidc-client.nix
# registers and ./swarm-otel.nix's `oidc/${producerName}` authenticator checks.
{
@ -38,9 +37,6 @@ let
deployCfg = hyperhiveCfg.deploy;
otelSwarmCfg = hyperhiveCfg.swarm.otel;
queueClientId = hyperhiveCfg.swarm.controller.queueClientId;
gatewayPortSuffix = lib.optionalString (
hyperhiveCfg.gateway.httpsPort != 443
) ":${toString hyperhiveCfg.gateway.httpsPort}";
in
{
config = lib.mkIf deployCfg.swarm-controller.enable (
@ -53,7 +49,7 @@ in
})
{
systemd.services.swarm-controller.environment = {
OTEL_EXPORTER_OTLP_ENDPOINT = "https://${otelSwarmCfg.domain}${gatewayPortSuffix}/${otelSwarmCfg.producerName}";
OTEL_EXPORTER_OTLP_ENDPOINT = "https://${otelSwarmCfg.domain}/${otelSwarmCfg.producerName}";
SWARM_CONTROLLER_OTEL_AUDIENCE = queueClientId;
};
}

View file

@ -23,12 +23,7 @@ let
gatewayCfg = hyperhiveCfg.gateway;
matrixCfg = hyperhiveCfg.swarm.matrix;
publicPort = gatewayCfg.httpsPort;
# The canonical 443 elides the port; see `docs/networking/gateway.md`
# ("Self-signed TLS").
homeserverUrl = "https://${matrixCfg.gatewayHost}${
lib.optionalString (publicPort != 443) ":${toString publicPort}"
}";
homeserverUrl = "https://${matrixCfg.gatewayHost}";
in
{
config =
@ -73,7 +68,7 @@ in
"= /.well-known/matrix/server" = {
extraConfig = ''
default_type application/json;
return 200 '{"m.server":"${matrixCfg.gatewayHost}:${toString publicPort}"}';
return 200 '{"m.server":"${matrixCfg.gatewayHost}:443"}';
'';
};
};

View file

@ -19,10 +19,6 @@ let
# Dashboard SPA dist, static-served by nginx.
dashboardDist = "${hyperhiveCfg.c0re.servedFrontend}/dashboard";
# The canonical 443 elides the port; see `docs/networking/gateway.md`
# ("Self-signed TLS").
publicPortSuffix = if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}";
# `/agent/` catch-all 404 + the two internal error-page targets it
# points at. Per-agent `location /agent/<name>/` blocks live in the
# runtime-generated `/var/lib/hive-gateway/conf/agents.conf` (included via
@ -205,7 +201,7 @@ in
# lands.
${hyperhiveCfg.domain} = {
locations."/".extraConfig = ''
return 301 https://${dashboardDomain}${publicPortSuffix}$request_uri;
return 301 https://${dashboardDomain}$request_uri;
'';
};
};

View file

@ -83,12 +83,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.hive-forge` in
# ../swarm-otel-service.nix declares, as a client of its own rather than the
# login source's. The port suffix is elided on 443, as in ../swarm-bao.nix.
# login source's.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${config.services.hyperhive.swarm.otel.domain}${gatewayPortSuffix}/hive-forge";
forwarderEndpoint = "https://${config.services.hyperhive.swarm.otel.domain}/hive-forge";
forwarderUnit = "swarm-journal-forwarder-oidc";
# In the host netns: distinct from every other collector's there, which the
# assertion below checks.
@ -115,15 +112,11 @@ let
# gateway vhost server-name, so ROOT_URL just uses it directly. The
# gateway always terminates TLS (self-signed is the implicit floor when
# neither `tls.certDir` nor ACME is configured), so the forge is always
# advertised over `https` on `httpsPort` — the canonical 443 elides the
# port suffix. Operators can still override via `cfg.rootUrl` for
# bespoke shapes. Both bindings are duplicated in ./service.nix, which
# builds `sso.redirectUri` from them; keep the two equal.
defaultRootUrl =
let
portSuffix = if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}";
in
"https://${cfg.domain}${portSuffix}/";
# advertised as plain `https://<domain>/`. Operators can still override via
# `cfg.rootUrl` for bespoke shapes. Both bindings are duplicated in
# ./service.nix, which builds `sso.redirectUri` from them; keep the two
# equal.
defaultRootUrl = "https://${cfg.domain}/";
effectiveRootUrl = if cfg.rootUrl != null then cfg.rootUrl else defaultRootUrl;
# `actionsFromSelf` resolves `uses:` against this forge, which then has to

View file

@ -8,7 +8,6 @@
}:
let
cfg = config.services.hyperhive.swarm.forge;
gatewayCfg = config.services.hyperhive.gateway;
swarmDomain = config.services.hyperhive.swarm.domain;
# Forgejo's name for the login source. Duplicated in ./default.nix, which
@ -22,11 +21,7 @@ let
# Forgejo's `ROOT_URL`, duplicated from ./default.nix, which documents its
# shape.
defaultRootUrl =
let
portSuffix = if gatewayCfg.httpsPort == 443 then "" else ":${toString gatewayCfg.httpsPort}";
in
"https://${cfg.domain}${portSuffix}/";
defaultRootUrl = "https://${cfg.domain}/";
effectiveRootUrl = if cfg.rootUrl != null then cfg.rootUrl else defaultRootUrl;
in
{
@ -117,8 +112,8 @@ in
(default), `ROOT_URL` is `https://''${cfg.domain}/`. The gateway
always terminates TLS (self-signed is the implicit floor when no
`gateway.tls.certDir` / ACME is set), so the forge is always
advertised over https. A non-canonical `gateway.httpsPort` is
appended as `:<port>`.
advertised over https, on the default port. A gateway that listens
on another `gateway.httpsPort` does not change this URL.
Set this only for a genuinely bespoke shape (e.g. an external
reverse proxy on a different host/path). Must end with `/` per
@ -159,12 +154,6 @@ in
than a knob. The glue that registers this client wherever
authelia runs reads it from here instead of restating the
format.
⚠️ With {option}`services.hyperhive.swarm.forge.rootUrl` unset,
`ROOT_URL` follows the gateway's `httpsPort`, which is
per-host. An authelia host that is not the forge's host renders
the forge's callback only if the two agree on it; set `rootUrl`
if they do not.
'';
};
# The secret half is fetched from the swarm secret store on the host

View file

@ -307,10 +307,15 @@ in
default = 443;
example = 8443;
description = ''
TCP port for the TLS-terminated vhosts. Default 443. The gateway
always terminates TLS (self-signed is the implicit floor when no
`tls.certDir` / ACME is configured), so this port is always active
alongside the plain-http `port`.
TCP port nginx listens on for the TLS-terminated vhosts, and the one
`openFirewall` opens. Default 443. The gateway always terminates TLS
(self-signed is the implicit floor when no `tls.certDir` / ACME is
configured), so this port is always active alongside the plain-http
`port`.
Listen-only: it does not change any URL. Every swarm service URL is
`https://<domain>` with no port, so clients reach the services on 443
whatever this is set to.
'';
};

View file

@ -123,14 +123,10 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.hive-matrix` in
# ./swarm-otel-service.nix declares, as a client of its own rather than the
# homeserver login's. The port suffix is elided on 443, as in
# ./swarm-bao.nix. It reads its client secret with matrix-ctl's identity,
# homeserver login's. It reads its client secret with matrix-ctl's identity,
# bound in above: one identity for the whole container.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${config.services.hyperhive.swarm.otel.domain}${gatewayPortSuffix}/hive-matrix";
forwarderEndpoint = "https://${config.services.hyperhive.swarm.otel.domain}/hive-matrix";
# Loopback in the container's own netns, and distinct from the other service
# containers' forwarders all the same.
forwarderTelemetryPort = 8899;

View file

@ -201,13 +201,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-authelia` in
# ./swarm-otel-service.nix declares, as a client of its own. The port suffix
# is elided on 443, as in ./swarm-bao.nix.
# ./swarm-otel-service.nix declares, as a client of its own.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}${gatewayPortSuffix}/${cfg.machine}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}/${cfg.machine}";
# Loopback port of the forwarder's own metrics, inside the container's netns:
# no other collector shares it. The module requires a value.
forwarderTelemetryPort = 8901;

View file

@ -1442,11 +1442,7 @@ let
# wrong. The path selects WHICH receiver: this container is a swarm-level
# producer and not a hive, so it is the swarm tier's own route, the same one
# ./glue-controller-env.nix exports to. `/` on that vhost answers 404.
#
# The port suffix follows ./hive-forge/default.nix: elided on the canonical
# 443 so this renders byte for byte like the tier's other two consumers of
# this name, present when an operator moved the gateway's TLS port.
otelFirstHop = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${swarmOtelCfg.storeProducerName}";
otelFirstHop = "https://${swarmOtelCfg.domain}/${swarmOtelCfg.storeProducerName}";
# The forwarder's own credential, and the three names it takes on the way
# in. The shape is ./swarm-otel.nix's `swarm-bao-otel-oidc` — the unit that
@ -1498,11 +1494,6 @@ let
};
swarmOtelCfg = hyperhiveCfg.swarm.otel;
gatewayPortSuffix =
let
p = hyperhiveCfg.gateway.httpsPort;
in
lib.optionalString (p != 443) ":${toString p}";
# Non-zero is what SERVES the endpoint at all — the switch is a duration, not
# a boolean, so a zero here is an openbao that answers 404 on a listener

View file

@ -43,13 +43,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-builder` in
# ./swarm-otel-service.nix declares, by the collector's gateway name. The
# port suffix is elided on 443, as in ./swarm-bao.nix.
# ./swarm-otel-service.nix declares, by the collector's gateway name.
swarmOtelCfg = hyperhiveCfg.swarm.otel;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback in the container's own netns, and distinct from the other service
# containers' forwarders all the same.

View file

@ -31,12 +31,8 @@ let
clientId = hyperhiveCfg.swarm.ci-metrics.clientId;
# The route `serviceProducers.swarm-ci-metrics` in ./swarm-otel-service.nix
# declares, by the collector's gateway name. The port suffix is elided on
# 443, as in ./swarm-builder.nix.
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
otlpEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${unit}";
# declares, by the collector's gateway name.
otlpEndpoint = "https://${swarmOtelCfg.domain}/${unit}";
haveClientIdentity =
baoDeploy.ciMetricsClientCertFile != null && baoDeploy.ciMetricsClientKeyFile != null;

View file

@ -63,14 +63,10 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-ci-runner` in
# ./swarm-otel-service.nix declares. The port suffix is elided on 443, as in
# ./swarm-bao.nix.
# ./swarm-otel-service.nix declares.
swarmOtelCfg = config.services.hyperhive.swarm.otel;
forwarderClientId = config.services.hyperhive.swarm.ci-runner.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
forwarderTokenUrl = "${toString config.services.hyperhive.swarm.authelia.url}/api/oidc/token";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback in the container's own netns, and distinct from the other service

View file

@ -46,13 +46,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-claude-login` in
# ./swarm-otel-service.nix declares, by the collector's gateway name. The
# port suffix is elided on 443, as in ./swarm-bao.nix.
# ./swarm-otel-service.nix declares, by the collector's gateway name.
swarmOtelCfg = hyperhiveCfg.swarm.otel;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback in the container's own netns, and distinct from the other service
# containers' forwarders all the same.

View file

@ -306,12 +306,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-grafana` in
# ./swarm-otel-service.nix declares, as a client of its own rather than the
# browser login's. The port suffix is elided on 443, as in ./swarm-bao.nix.
# browser login's.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}${gatewayPortSuffix}/${cfg.machine}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}/${cfg.machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback port of the forwarder's own metrics, inside the container's netns:
# no other collector shares it. The module requires a value.

View file

@ -27,13 +27,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-nats` in
# ./swarm-otel-service.nix declares, by the collector's gateway name. The
# port suffix is elided on 443, as in ./swarm-bao.nix.
# ./swarm-otel-service.nix declares, by the collector's gateway name.
swarmOtelCfg = config.services.hyperhive.swarm.otel;
gatewayPortSuffix = lib.optionalString (
config.services.hyperhive.gateway.httpsPort != 443
) ":${toString config.services.hyperhive.gateway.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
tlsCfg = config.services.hyperhive.deploy.hive-controller.tls;
gatewayCfg = config.services.hyperhive.gateway;

View file

@ -38,10 +38,7 @@ let
# collector, the route `serviceProducers.swarm-notify-router` in
# ./swarm-otel-service.nix declares, as ./swarm-claude-login.nix does.
swarmOtelCfg = hyperhiveCfg.swarm.otel;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback in the container's own netns, and distinct from the other service
# containers' forwarders all the same.

View file

@ -48,13 +48,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-review-classifier` in
# ./swarm-otel-service.nix declares, by the collector's gateway name. The
# port suffix is elided on 443, as in ./swarm-bao.nix.
# ./swarm-otel-service.nix declares, by the collector's gateway name.
swarmOtelCfg = hyperhiveCfg.swarm.otel;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}${gatewayPortSuffix}/${machine}";
forwarderEndpoint = "https://${swarmOtelCfg.domain}/${machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# Loopback in the container's own netns, and distinct from the other service
# containers' forwarders all the same.

View file

@ -83,13 +83,9 @@ let
# The container's journal forwarder pushes to its own receiver on the swarm
# collector, the route `serviceProducers.swarm-victorialogs` in
# ./swarm-otel-service.nix declares. The port suffix is elided on 443, as in
# ./swarm-bao.nix.
# ./swarm-otel-service.nix declares.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}${gatewayPortSuffix}/${cfg.machine}";
forwarderEndpoint = "https://${hyperhiveCfg.swarm.otel.domain}/${cfg.machine}";
forwarderUnit = "swarm-journal-forwarder-oidc";
# In the host netns: distinct from every other collector's there, which the
# assertion below checks.

View file

@ -149,9 +149,6 @@ let
# The client secret is fetched on the host, under the responder's store
# identity, and bound in read-only: the container cannot reach the store.
forwarderClientId = cfg.otel.clientId;
gatewayPortSuffix = lib.optionalString (
gatewayCfg.httpsPort != 443
) ":${toString gatewayCfg.httpsPort}";
otelDomain = hyperhiveCfg.swarm.otel.domain;
autheliaDomain = hyperhiveCfg.swarm.authelia.domain;
@ -177,7 +174,7 @@ let
}
location ^~ /${cfg.machine}/ {
proxy_pass https://${otelDomain}${gatewayPortSuffix};
proxy_pass https://${otelDomain};
${gatewayCfg.lib.verifiedProxyTo otelDomain}
}