Watch
0
0
Fork
You've already forked hyperhive
0

add swarm-metrics, an agent CLI for the metrics store

swarm-metrics reads the swarm's VictoriaMetrics from inside an agent
container: query, query-range, series, labels and label-values, each one
GET against the store's Prometheus read API through the gateway, printing
the store's JSON. It authenticates the way swarm-logs does, with the
agent's own queue secret read from bao under the agent's leaf, sent as
a swarm-agent bearer.

On the metrics store's host the read API's auth map gains an agent arm
ahead of the Grafana one. It routes to swarm-metrics-agent-auth, a
swarm-logs-auth instance logged in under the existing swarm-metrics-auth
leaf, whose bao grant now includes swarm/agents/+/queue read. The check is
rate-limited per address like the log store's
(deploy.victoriametrics.agentAuth{Rate,Burst,VerdictTtl}).

nix/agent-modules/metrics.nix installs the wrapped binary when the hive
forwards HIVE_AGENT_METRICS_URL (from swarm.victoriametrics.domain) and a
store address, the same gate as swarm-logs. Adds the base:swarm-metrics
skill and the CLI reference with its freshness check.

Fixes #5395
This commit is contained in:
atlas 2026-10-17 00:55:46 +02:00 • committed by mara
commit e92f118bda
30 changed files with 1417 additions and 88 deletions

View file

@ -672,15 +672,21 @@ let
{
# The read API's check, link by link: every read location names the
# switch with no login redirect (a machine reader would get login HTML
# as a 200), the switch rewrites to the map's pick, a bearer reaches
# the responder's socket, which the unit binds, and anything else goes
# to authelia. vmui is a browser's, so it redirects to the login.
name = "the metrics read API sends a bearer to swarm-metrics-auth and a session to authelia";
# as a 200), the switch rewrites to the map's pick, an agent bearer
# reaches the agents' responder (listed before the catch-all bearer arm,
# since a map takes the first matching regex), any other bearer reaches
# Grafana's, each socket bound by its unit, and anything else goes to
# authelia. vmui is a browser's, so it redirects to the login.
name = "the metrics read API sends an agent bearer to swarm-metrics-agent-auth, another bearer to swarm-metrics-auth and a session to authelia";
ok =
let
l = allLocal.services.nginx.virtualHosts."metrics.t.local".locations;
http = allLocal.services.nginx.appendHttpConfig;
unit = allLocal.systemd.services.swarm-metrics-auth;
agentUnit = allLocal.systemd.services.swarm-metrics-agent-auth;
agentArm = "\"~^Bearer swarm-agent\\.\" /__metrics_agent_auth;";
bearerArm = "\"~^Bearer \" /__metrics_grafana_auth;";
v = allLocal.services.hyperhive.deploy.victoriametrics;
reads = lib.filterAttrs (n: _: lib.hasPrefix "= /api/v1/" n || lib.hasPrefix "^~ /api/v1/" n) l;
in
reads ? "= /api/v1/query_range"
@ -690,7 +696,9 @@ let
&& !(lib.hasInfix "error_page" r.extraConfig)
) (lib.attrValues reads)
&& lib.hasInfix "map \$http_authorization \$swarm_metrics_read_auth_target" http
&& lib.hasInfix "\"~^Bearer \" /__metrics_grafana_auth;" http
&& lib.hasInfix agentArm http
&& lib.hasInfix bearerArm http
&& !(lib.hasInfix bearerArm (lib.head (lib.splitString agentArm http)))
&& lib.hasInfix "default /__metrics_authelia;" http
&&
lib.hasInfix "rewrite ^ \$swarm_metrics_read_auth_target last;"
@ -698,6 +706,18 @@ let
&& lib.hasInfix "internal;" l."= /__metrics_grafana_auth".extraConfig
&& l."= /__metrics_grafana_auth".proxyPass == "http://unix:/run/swarm-metrics-auth/auth.sock:/"
&& lib.hasInfix "--socket /run/swarm-metrics-auth/auth.sock" unit.serviceConfig.ExecStart
&& lib.hasInfix "internal;" l."= /__metrics_agent_auth".extraConfig
&& l."= /__metrics_agent_auth".proxyPass == "http://unix:/run/swarm-metrics-agent-auth/auth.sock:/"
&& lib.hasInfix "--socket /run/swarm-metrics-agent-auth/auth.sock" agentUnit.serviceConfig.ExecStart
&& lib.hasInfix "/bin/swarm-logs-auth " agentUnit.serviceConfig.ExecStart
&& lib.hasInfix "--store-cert-role swarm-metrics-auth" agentUnit.serviceConfig.ExecStart
&& lib.hasInfix "--verdict-ttl ${toString v.agentAuthVerdictTtl}" agentUnit.serviceConfig.ExecStart
&& agentUnit.serviceConfig.LoadCredential == unit.serviceConfig.LoadCredential
&& lib.hasInfix "limit_req_zone $binary_remote_addr zone=swarm_metrics_agent_auth:1m rate=${v.agentAuthRate};" http
&&
lib.hasInfix "limit_req zone=swarm_metrics_agent_auth burst=${toString v.agentAuthBurst} nodelay;"
l."= /__metrics_agent_auth".extraConfig
&& !(lib.hasInfix "limit_req" l."= /__metrics_grafana_auth".extraConfig)
&& lib.hasInfix "auth_request /__metrics_authelia;" l."^~ /vmui/".extraConfig
&& lib.hasInfix "error_page 401 =302" l."^~ /vmui/".extraConfig
&& l."= /__metrics_authelia".proxyPass == "https://auth.t.local/api/authz/auth-request";
@ -884,6 +904,7 @@ let
owners ? swarm-logs-auth
&& owners ? swarm-logs-grafana-auth
&& owners ? swarm-metrics-auth
&& owners ? swarm-metrics-agent-auth
&& !(lib.any (u: hidden u.serviceConfig) (lib.attrValues owners));
}
{