swarm: read the agent queue credential out of the store onto the hive host
The publisher on the authelia host has been writing `secret/swarm/hives/<hive>/queue/agent` — the OIDC client secret agent containers present to the swarm queue, plus the client id it belongs to — and nothing read it. This is the reader: a oneshot `swarm-bao-queue-agent` that logs in with the host's certificate and lands the two fields as two files under `deploy.hive-controller.queue.agentCredentialDir`, the secret `0600` and the client id `0644`. Two files rather than one because that is the consumer's shape: `swarm_queue_client::QueueConfig::from_env` takes the secret as a path and the client id as a value, so the split here is what keeps the next slice from parsing anything. Same shape as the store's first reader, `glue-matrix-bao-token.nix` — a cert login that fails loudly under `Restart=on-failure` because every state it fails on is one a retry fixes, then reads that degrade quietly because no retry turns "no value there" into a value. Unlike the matrix token there is no local fallback and none is possible, so absent files mean this hive's agents do not connect, which is the ordinary state of a swarm before the publisher has run. Nothing consumes the files yet and this unit is ordered `Before=` nothing. The next slice bind-mounts them into agent containers through hive-c0re and adds the ordering edge along with them. Refs #3805
This commit is contained in:
parent
14305255f0
commit
b8157cb08e
4 changed files with 289 additions and 7 deletions
|
|
@ -1164,6 +1164,57 @@ let
|
|||
# which no grant covers.
|
||||
&& !(lib.hasInfix "secret/swarm/matrix/" s);
|
||||
}
|
||||
{
|
||||
# The store's second reader, and the gate that decides it exists is the
|
||||
# certificate rather than anything about agents: containers are created
|
||||
# at runtime, so there is no static "this hive runs agents" fact to ask.
|
||||
name = "a hive that names a client identity reads its agent queue credential";
|
||||
ok = baoRemoteReader.systemd.services ? swarm-bao-queue-agent;
|
||||
}
|
||||
{
|
||||
# Absence arm, and what makes the one above able to fail: with no leaf
|
||||
# this unit would fail a TLS handshake on every boot, so it must not
|
||||
# exist at all rather than retry its way through the start limit.
|
||||
name = "a hive with no store identity renders no queue credential reader";
|
||||
ok = !(matrixNoBaoIdentity.systemd.services ? swarm-bao-queue-agent);
|
||||
}
|
||||
{
|
||||
# Same 403-not-a-miss reason as the matrix arm above, against the path
|
||||
# `swarm_secret_client::queue::agent_client_path` builds from the same
|
||||
# pieces. The negative arm is the rename this one is exposed to: a
|
||||
# credential named for the queue rather than for the hive that presents
|
||||
# it reads as correct and is refused on every boot.
|
||||
name = "the agent queue credential path sits inside the prefix the reader is granted";
|
||||
ok =
|
||||
let
|
||||
s = baoRemoteReader.systemd.services.swarm-bao-queue-agent.script;
|
||||
in
|
||||
lib.hasInfix "secret/swarm/hives/h1/queue/agent" s && !(lib.hasInfix "secret/swarm/queue/" s);
|
||||
}
|
||||
{
|
||||
# The unit's output is the option's value, not a literal that agrees with
|
||||
# it today: an operator moving the directory has to move both files. The
|
||||
# prefix is asserted too because `hasInfix ""` is true — an option
|
||||
# renamed out from under this arm would otherwise read empty and pass.
|
||||
name = "the queue credential reader writes both files under the directory its option names";
|
||||
ok =
|
||||
let
|
||||
m = baoRemoteReader;
|
||||
dir = toString m.services.hyperhive.deploy.hive-controller.queue.agentCredentialDir;
|
||||
s = m.systemd.services.swarm-bao-queue-agent.script;
|
||||
in
|
||||
lib.hasPrefix "/var/lib/" dir
|
||||
&& lib.hasInfix "${dir}/secret" s
|
||||
&& lib.hasInfix "${dir}/client_id" s;
|
||||
}
|
||||
{
|
||||
# A reader off the store's host is a reader whose journal is the only
|
||||
# record of why a hive's agents never connected, so the collector has to
|
||||
# be told the unit exists. Nothing else can say it: the store's module
|
||||
# does not know who holds a certificate.
|
||||
name = "the queue credential reader's journal reaches the collector";
|
||||
ok = builtins.elem "swarm-bao-queue-agent" baoRemoteReader.services.hyperhive.swarm.otel.journaldUnits;
|
||||
}
|
||||
{
|
||||
# The doctrine three glue files state, as a property a rewrite has to
|
||||
# keep: a client is defined by holding a certificate the store accepts,
|
||||
|
|
|
|||
Loading…
Reference in a new issue