Watch
0
0
Fork
You've already forked hyperhive
0

swarm-controller: mint each agent's forge token and store it in bao

A MintAgentForgeToken node mints a fixed-name swarm-agent token with the
admin API, keeps it when the stored value's last eight and the normalised
scopes match the forge's list, and otherwise deletes and re-creates it.
The token is stored at swarm/agents/<agent>/forge-token. Agent creation
inserts the node, and a pass at start and every five minutes inserts it
for every agent holding a store identity whose token is missing or stale.

Refs #3782
This commit is contained in:
atlas 2026-09-24 16:29:04 +02:00 • committed by mara
commit 52c8c0b0de
7 changed files with 977 additions and 4 deletions

View file

@ -96,6 +96,23 @@ pub fn agent_object_name(agent: &str) -> Result<String, Error> {
Ok(format!("{AGENT_PREFIX}{agent}"))
}
/// The agents among `names`, a listing of cert-auth roles: the inverse of
/// [`agent_object_name`], for a caller that needs the set of agents holding a
/// store identity.
///
/// A name that carries the prefix but whose suffix is not a legal segment is
/// dropped rather than returned: [`agent_object_name`] could not have produced
/// it, so it is not an agent this crate minted.
#[must_use]
pub fn agents_from_role_names(names: &[String]) -> Vec<String> {
names
.iter()
.filter_map(|name| name.strip_prefix(AGENT_PREFIX))
.filter(|agent| checked_segment("agent", agent).is_ok())
.map(str::to_owned)
.collect()
}
/// One read stanza. The only shape this module emits, so "read-only" is a
/// property of the renderer rather than of each call site.
fn read_stanza(path: &str) -> String {
@ -595,4 +612,33 @@ mod tests {
let expected_queue_path = crate::queue::agent_client_path("pr1ma").expect("legal");
assert!(p.contains(&expected_queue_path));
}
#[test]
fn only_agent_roles_come_back_and_without_their_prefix() {
let roles: Vec<String> = [
"hive-agent-atlas",
"hive-pr1ma",
"swarm-controller",
"hive-agent-argus",
]
.map(str::to_owned)
.to_vec();
assert_eq!(agents_from_role_names(&roles), ["atlas", "argus"]);
}
#[test]
fn a_role_agent_object_name_could_not_have_produced_is_dropped() {
// An empty suffix and one carrying a dot are both names the prefix
// matches and no agent can have.
let roles: Vec<String> = ["hive-agent-", "hive-agent-a.b", "hive-agent-ok"]
.map(str::to_owned)
.to_vec();
assert_eq!(agents_from_role_names(&roles), ["ok"]);
}
#[test]
fn the_listing_inverts_agent_object_name() {
let name = agent_object_name("atlas").expect("legal");
assert_eq!(agents_from_role_names(&[name]), ["atlas"]);
}
}