swarm-nats-auth: accept the agent suffix it ships as its default
`--agent-client-suffix` takes a value that opens with `-`, and clap reads one space-separated as a short-flag cluster. `swarm-nats.nix` passes it that way, so the responder aborted at startup on `unexpected argument '-a'`. A responder that never subscribes is not a degraded queue. `auth_callout` is fail-closed by design, so the server denies every client, and each denial arrives as `authorization violation` on the client — naming nothing, on a process that is itself healthy. Two unrelated daemons reported it at once and neither was at fault. The option's own `default_value` is `-agent`, so the binary could not accept the value it ships. Fixing the module's call site instead would leave that true for anyone running it by hand. The three tests parse argument vectors rather than assert on a struct: one is the literal vector the unit builds, one is the control that an ordinary value goes through the same flag, and one pins the default against the module.
This commit is contained in:
parent
45e73f8636
commit
8104e5e018
1 changed files with 77 additions and 1 deletions
|
|
@ -94,7 +94,11 @@ struct Args {
|
|||
/// A suffix on the hive's id rather than a prefix of its own, because
|
||||
/// `agent-<name>` reads as *the agent called `<name>`* — the one thing
|
||||
/// this identity does not carry.
|
||||
#[arg(long, default_value = "-agent")]
|
||||
///
|
||||
/// A suffix starts with `-`, so it has to be accepted as a value rather
|
||||
/// than read as a short-flag cluster — without this the default below
|
||||
/// cannot be passed back in on the command line that produced it.
|
||||
#[arg(long, default_value = "-agent", allow_hyphen_values = true)]
|
||||
agent_client_suffix: String,
|
||||
|
||||
/// Client ids allowed to read every hive's status. Repeatable. The
|
||||
|
|
@ -275,3 +279,75 @@ async fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
anyhow::bail!("subscription to {AUTH_SUBJECT} ended")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// The argument vector `swarm-nats.nix` actually builds, in the form it
|
||||
/// builds it: every flag space-separated, and the suffix's value opening
|
||||
/// with `-`. Read as a short-flag cluster it aborts before `main` runs,
|
||||
/// and a responder that never starts denies every client — which reaches
|
||||
/// the operator as `authorization violation` on an unrelated process.
|
||||
#[test]
|
||||
fn the_units_own_argument_vector_parses() {
|
||||
let args = Args::try_parse_from([
|
||||
"swarm-nats-auth",
|
||||
"--user-seed-file",
|
||||
"/run/credentials/callout-user.seed",
|
||||
"--issuer-seed-file",
|
||||
"/run/credentials/issuer.seed",
|
||||
"--client-secret-file",
|
||||
"/run/credentials/oidc-client.secret",
|
||||
"--introspection-url",
|
||||
"https://auth.example/api/oidc/introspection",
|
||||
"--hive-client-prefix",
|
||||
"hive-",
|
||||
"--agent-client-suffix",
|
||||
"-agent",
|
||||
])
|
||||
.expect("the unit's own argument vector must parse");
|
||||
assert_eq!(args.agent_client_suffix, "-agent");
|
||||
}
|
||||
|
||||
/// The control for the case above: an ordinary value parses through the
|
||||
/// same flag, so a failure there is about the leading `-` and not about
|
||||
/// the argument being unknown.
|
||||
#[test]
|
||||
fn an_agent_suffix_without_a_leading_dash_parses_too() {
|
||||
let args = Args::try_parse_from([
|
||||
"swarm-nats-auth",
|
||||
"--user-seed-file",
|
||||
"/run/credentials/callout-user.seed",
|
||||
"--issuer-seed-file",
|
||||
"/run/credentials/issuer.seed",
|
||||
"--client-secret-file",
|
||||
"/run/credentials/oidc-client.secret",
|
||||
"--introspection-url",
|
||||
"https://auth.example/api/oidc/introspection",
|
||||
"--agent-client-suffix",
|
||||
"agent",
|
||||
])
|
||||
.expect("an ordinary suffix must parse");
|
||||
assert_eq!(args.agent_client_suffix, "agent");
|
||||
}
|
||||
|
||||
/// The default is the value the deployment passes, so the two cannot
|
||||
/// drift into disagreeing about what an agent client is called.
|
||||
#[test]
|
||||
fn the_default_suffix_is_what_the_module_passes() {
|
||||
let args = Args::try_parse_from([
|
||||
"swarm-nats-auth",
|
||||
"--user-seed-file",
|
||||
"/run/credentials/callout-user.seed",
|
||||
"--issuer-seed-file",
|
||||
"/run/credentials/issuer.seed",
|
||||
"--client-secret-file",
|
||||
"/run/credentials/oidc-client.secret",
|
||||
"--introspection-url",
|
||||
"https://auth.example/api/oidc/introspection",
|
||||
])
|
||||
.expect("the required flags alone must parse");
|
||||
assert_eq!(args.agent_client_suffix, "-agent");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue