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:
parent
1e8c398132
commit
e92f118bda
30 changed files with 1417 additions and 88 deletions
|
|
@ -41,19 +41,23 @@ let
|
|||
|
||||
agentNoBao = shared.agentBare;
|
||||
|
||||
# `swarm-logs` authenticates with the agent's queue secret from the store, so
|
||||
# the store address gates it beside the query URL.
|
||||
# `swarm-logs` and `swarm-metrics` authenticate with the agent's queue secret
|
||||
# from the store, so the store address gates each beside its store URL.
|
||||
logsUrl = "https://logs.t.local/select/logsql/query";
|
||||
metricsUrl = "https://metrics.t.local";
|
||||
agentLogs = agentWith {
|
||||
services.hyperhive.agent.bao.addr = "https://bao.t.local:8200";
|
||||
services.hyperhive.agent.logs.queryUrl = logsUrl;
|
||||
services.hyperhive.agent.metrics.url = metricsUrl;
|
||||
};
|
||||
agentLogsNoBao = agentWith { services.hyperhive.agent.logs.queryUrl = logsUrl; };
|
||||
swarmLogsIn =
|
||||
machine:
|
||||
lib.findFirst (
|
||||
p: (p.name or "") == "swarm-logs-configured"
|
||||
) null machine.environment.systemPackages;
|
||||
agentLogsNoBao = agentWith {
|
||||
services.hyperhive.agent.logs.queryUrl = logsUrl;
|
||||
services.hyperhive.agent.metrics.url = metricsUrl;
|
||||
};
|
||||
configuredIn =
|
||||
name: machine: lib.findFirst (p: (p.name or "") == name) null machine.environment.systemPackages;
|
||||
swarmLogsIn = configuredIn "swarm-logs-configured";
|
||||
swarmMetricsIn = configuredIn "swarm-metrics-configured";
|
||||
|
||||
agentBaoIdentity = machine: machine.systemd.services.hive-agent-bao-identity;
|
||||
cases = [
|
||||
|
|
@ -80,6 +84,27 @@ let
|
|||
name = "an agent with a log store but no secret store gets no swarm-logs";
|
||||
ok = swarmLogsIn agentLogsNoBao == null && swarmLogsIn agentLogs != null;
|
||||
}
|
||||
{
|
||||
# The same store identity as `swarm-logs`, and the store's origin.
|
||||
name = "swarm-metrics is wrapped with the agent's own store identity";
|
||||
ok =
|
||||
let
|
||||
w = (swarmMetricsIn agentLogs).buildCommand;
|
||||
a = agentLogs.services.hyperhive.agent;
|
||||
set = k: v: lib.hasInfix "--set ${k} ${lib.escapeShellArg v}" w;
|
||||
in
|
||||
set "HIVE_AGENT_METRICS_URL" metricsUrl
|
||||
&& set "HIVE_AGENT_NAME" a.user.name
|
||||
&& set "BAO_ADDR" "https://bao.t.local:8200"
|
||||
&& set "BAO_CLIENT_CERT" a.bao.clientCertFile
|
||||
&& set "BAO_CLIENT_KEY" a.bao.clientKeyFile
|
||||
&& set "BAO_CACERT" "/run/credentials/hive-agent.service/hive-agent-bao-server-ca";
|
||||
}
|
||||
{
|
||||
# A metrics URL with nothing to authenticate as installs nothing.
|
||||
name = "an agent with a metrics store but no secret store gets no swarm-metrics";
|
||||
ok = swarmMetricsIn agentLogsNoBao == null && swarmMetricsIn agentLogs != null;
|
||||
}
|
||||
{
|
||||
# Both ids or neither: the secret authenticates nobody without the id it
|
||||
# belongs to, and `swarm-logs` reads both.
|
||||
|
|
|
|||
Loading…
Reference in a new issue