hive-agent: read the per-agent queue secret from bao in process
The harness now reads swarm/agents/<agent>/queue from the store itself, under the agent's own store certificate, and holds it in memory only. It reads once before the first connect and again on every reconnect attempt (async-nats `ConnectOptions::with_auth_callback`), so an agent whose secret was re-minted reconnects with the new value instead of being refused until the container restarts. hive-agent-queue-credential.service, the /run file it wrote, and HIVE_AGENT_QUEUE_AGENT_SECRET_FILE are gone; queue-identity.nix now hands hive-agent.service the store address, its certificate paths and the agent name. A failed or empty read before the first connect still falls back to the hive's shared client. Each read is bounded by a 10s timeout, and retries wait out the existing reconnect backoff (500ms doubling, capped at 60s). Closes #4783
This commit is contained in:
parent
f7437a4773
commit
ccb5bd3b38
10 changed files with 770 additions and 529 deletions
|
|
@ -827,20 +827,36 @@ pub async fn connect(cfg: QueueConfig) -> Result<async_nats::Client, Error> {
|
|||
Ok(client)
|
||||
}
|
||||
|
||||
/// Connect presenting a fixed `token`, as an agent presents its own queue
|
||||
/// credential. Reconnects present the same token.
|
||||
/// Connect presenting the token `token` resolves to, as an agent presents its
|
||||
/// own queue credential.
|
||||
///
|
||||
/// `token` runs once per connection attempt, reconnects included, so a
|
||||
/// credential replaced at its source is presented on the next attempt. An
|
||||
/// `Err` from it fails that attempt, and the next one waits out the same
|
||||
/// backoff as a refused connect.
|
||||
///
|
||||
/// Unlike [`connect`], the first attempt must succeed: a refused or failed
|
||||
/// connect is returned rather than retried in the background, so the caller
|
||||
/// can fall back to another credential. `ca_file` is the queue's trust anchor,
|
||||
/// as [`QueueConfig::ca_file`].
|
||||
pub async fn connect_with_token(
|
||||
pub async fn connect_with_token<F, Fut>(
|
||||
url: &str,
|
||||
ca_file: Option<&std::path::Path>,
|
||||
token: String,
|
||||
) -> Result<async_nats::Client, Error> {
|
||||
let mut options =
|
||||
async_nats::ConnectOptions::with_token(token).reconnect_delay_callback(reconnect_delay);
|
||||
token: F,
|
||||
) -> Result<async_nats::Client, Error>
|
||||
where
|
||||
F: Fn() -> Fut + Send + Sync + 'static,
|
||||
Fut: Future<Output = Result<String, String>> + Send + Sync + 'static,
|
||||
{
|
||||
let mut options = async_nats::ConnectOptions::with_auth_callback(move |_nonce| {
|
||||
let token = token();
|
||||
async move {
|
||||
let mut auth = async_nats::Auth::new();
|
||||
auth.token = Some(token.await.map_err(async_nats::AuthError::new)?);
|
||||
Ok(auth)
|
||||
}
|
||||
})
|
||||
.reconnect_delay_callback(reconnect_delay);
|
||||
if let Some(path) = ca_file {
|
||||
options = options.add_root_certificates(path.to_path_buf());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue