fix(#3554): push to the swarm's stores by domain, authenticated
The collector's store exporters were gated on deploy.victoriametrics.enable /
deploy.victorialogs.enable — options that say "this host RUNS the store", not
"the swarm has one". A collector that did not share a host with the stores
rendered no exporter at all and dropped everything it received, from every
hive, silently: an absent exporter is not an error.
mara ruled the premise rather than the mechanism ("the swarm always has a
store"), so there is no gate and no new option for that. Both exporters are
unconditional and address the stores by domain, per the cross-host rule from
the OIDC client and secret-delivery unit #3517 already built. The logs exporter
had the identical bug and is fixed here too.
Both stores gained a machine ingest route, required in the same change: the
exporter now targets https://logs.<domain>/insert/..., and that vhost is
browser-shaped, so shipping the collector half alone would have regressed logs
ingestion that works today. Neither ingest location carries
`error_page 401 =302` — a pusher handed a redirect follows it and POSTs at a
login page, which answers 200.
Whether the collector authenticates follows the CREDENTIAL, never another
service's placement: `clientSecretFile` is a nullable option, and the delivery
unit — the one thing here that may know where authelia runs, since it copies
out of its container — sets it by mkDefault. An earlier revision gated this on
deploy.authelia.enable directly, which put a different service's co-location in
the collector's own config.
Also removed rather than relaxed: the assertion that this collector has
"somewhere to send". It read the store's per-host enable, so it rejected at
eval exactly the deployment reaching the stores by domain exists for.
Deliberately not replaced with an authentication assertion — a collector on a
host of its own is a supported shape, and refusing to build it would make this
fix illegal where the bug bites hardest.
Knock-on worth review: collectLogs is now always satisfied, so journald
collection is unconditional.
Config shape validated against otelcol-contrib 0.151.0 `validate`, with a
bogus-key control confirming the validator checks the extension schema.
module-eval: 31 properties.
This commit is contained in:
parent
a3612f5168
commit
5478e0bf67
4 changed files with 446 additions and 181 deletions
|
|
@ -18,9 +18,12 @@
|
|||
# rationale (forceSSL is load-bearing there too: authelia answers a plain-http
|
||||
# auth subrequest with 400, which `auth_request` cannot interpret as anything
|
||||
# but a broken check). The store's own listener stays loopback-only and
|
||||
# unauthenticated exactly as before — the collector still writes to it
|
||||
# directly, never through this vhost — so this adds a new authenticated front
|
||||
# door without touching the existing write path at all.
|
||||
# unauthenticated, and the vhost is now the ONLY way in from outside: the
|
||||
# collector pushes through it too, at its own `= /insert/...` location, because
|
||||
# a swarm has one log store and the collector need not share a host with it.
|
||||
# ⚠️ That ingest location deliberately does not carry `swarmAuthRequest` — a
|
||||
# pusher handed its `error_page 401 =302` follows the redirect and POSTs at a
|
||||
# login page, which answers 200. See the location itself.
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
|
|
@ -177,6 +180,27 @@ in
|
|||
proxyPass = "http://127.0.0.1:${toString cfg.port}/";
|
||||
extraConfig = swarmAuthRequest;
|
||||
};
|
||||
|
||||
# The swarm collector's ingest route. `=` so it outranks the `/`
|
||||
# prefix above — without a more specific location it would ride that
|
||||
# catch-all, and that is the whole hazard here.
|
||||
#
|
||||
# ⚠️ Deliberately NOT `swarmAuthRequest`. That block ends in
|
||||
# `error_page 401 =302`, which is right for a browser and wrong for a
|
||||
# pusher: handed a redirect it follows the redirect and POSTs its
|
||||
# batch at a login page, which answers 200. Ingest then reports
|
||||
# healthy while storing nothing. A machine route lets the 401 reach
|
||||
# the client unchanged.
|
||||
#
|
||||
# `auth_request` does not inherit across sibling locations (see the
|
||||
# note on `swarmAuthRequest` above), so naming it here is required
|
||||
# rather than redundant.
|
||||
"= /insert/opentelemetry/v1/logs" = {
|
||||
proxyPass = "http://127.0.0.1:${toString cfg.port}/insert/opentelemetry/v1/logs";
|
||||
extraConfig = ''
|
||||
auth_request /__hive_authelia;
|
||||
'';
|
||||
};
|
||||
# The subrequest itself — same target, same header set, same
|
||||
# reasoning as `swarm-ui.nix`'s own copy (measured against the
|
||||
# pinned authelia binary, not copied from an example).
|
||||
|
|
@ -261,6 +285,8 @@ in
|
|||
# code is not evidence.
|
||||
#
|
||||
# ⚠️ Like the metrics store's, that endpoint is unauthenticated — which is
|
||||
# why `listenAddress` above is loopback, why the collector is the only
|
||||
# writer, and why this module declares no gateway vhost.
|
||||
# why `listenAddress` above is loopback and why nothing reaches it except
|
||||
# through the gateway, where the ingest route is authenticated. (This module
|
||||
# does declare a vhost; the line that used to say otherwise was already
|
||||
# wrong before the collector started pushing through it.)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue