link_assistant_router/cli/configure.rs
1//! `router configure <client>` — the one name for permanent client setup.
2//!
3//! Pointing a client at the router permanently is the first thing an operator
4//! does after standing a deployment up, and it had no single name. Two
5//! commands wrote the same file and disagreed on almost everything else: the
6//! address (`clients setup` used this CLI's own `--host`/`--port` default even
7//! with a server selected), the credential (`with --global` stored none and
8//! told the user to go set an environment variable), how to reverse it, and
9//! which clients it worked for. `configure` exists in the codebase — it is
10//! what both paths call — but was not a name a user could type (issue #296).
11
12use clap::Args;
13
14use super::AuthTarget;
15use crate::clients::ClientKind;
16
17/// Point a client at the router permanently.
18#[derive(Clone, Debug, Args)]
19pub struct ConfigureArgs {
20 /// Client to configure. Omit when `--all` is given.
21 #[arg(value_enum, required_unless_present = "all")]
22 pub client: Option<ClientKind>,
23 /// Configure every client this machine has that can be configured.
24 ///
25 /// Clients whose vendor gates prevent it are skipped and named in the
26 /// summary rather than failing the run — a workstation being pointed at a
27 /// deployment wants the ones that work.
28 #[arg(long, conflicts_with = "client")]
29 pub all: bool,
30 /// Restore the exact configuration saved by a previous `configure`.
31 ///
32 /// The restore is hash-verified: an edit made after `configure` is
33 /// preserved rather than overwritten.
34 #[arg(long)]
35 pub undo: bool,
36 #[command(flatten)]
37 pub target: AuthTarget,
38 /// Existing router token to configure instead of minting one.
39 ///
40 /// Prefer `--token-stdin` or `LINK_ASSISTANT_ROUTER_TOKEN` over argv,
41 /// which is visible in shell history and process listings.
42 #[arg(long, hide_env_values = true, conflicts_with = "token_stdin")]
43 pub token: Option<String>,
44 /// Read an existing router token as one line from standard input.
45 #[arg(long, conflicts_with = "token")]
46 pub token_stdin: bool,
47 /// Lifetime of an automatically minted token, in hours.
48 ///
49 /// A year by default, because this is the permanent path: a credential
50 /// that lapses next week makes "configured" mean "configured until
51 /// Tuesday". Re-run `configure` to renew it.
52 #[arg(long, default_value_t = 8760)]
53 pub ttl_hours: i64,
54}
55
56impl ConfigureArgs {
57 /// The clients this invocation acts on.
58 #[must_use]
59 pub fn clients(&self) -> Vec<ClientKind> {
60 self.client
61 .map_or_else(|| ClientKind::ALL.to_vec(), |client| vec![client])
62 }
63}