secret : trousseau OS (keyring) + injection @secret au start/run (issue #36) - valeurs jamais affichees ni journalisees, mock testable, fallback clair sans trousseau
This commit is contained in:
@@ -17,6 +17,7 @@ pub mod open_cmd;
|
||||
pub mod projects_cmd;
|
||||
pub mod run_cmd;
|
||||
pub mod search_cmd;
|
||||
pub mod secret_cmd;
|
||||
pub mod self_uninstall;
|
||||
pub mod sessions_cmd;
|
||||
pub mod stats_cmd;
|
||||
@@ -65,6 +66,7 @@ pub fn execute_command(app: &App, cmd: &Command) -> Result<i32> {
|
||||
interval,
|
||||
} => watch_cmd::run(app, agent, *restart, *notify, *interval),
|
||||
Command::Alias(sub) => alias_cmd::run(app, sub),
|
||||
Command::Secret(sub) => secret_cmd::run(app, sub),
|
||||
Command::Start(a) => run_cmd::start(app, a),
|
||||
Command::Stop {
|
||||
agent,
|
||||
@@ -202,6 +204,11 @@ pub fn resolve_exec(
|
||||
args.extend(extra_args.iter().cloned());
|
||||
let mut env = agent.env.clone();
|
||||
env.extend(extra_env.clone());
|
||||
let warnings =
|
||||
crate::secrets::resolve_env_secrets(&crate::secrets::store(), &agent.name, &mut env);
|
||||
for w in warnings {
|
||||
app.log.warn(&w);
|
||||
}
|
||||
let (program, args) = route_cmd_script(program, args);
|
||||
Ok(ResolvedExec { program, args, env })
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
//! secret: manage secrets in the OS keyring (values never shown or logged).
|
||||
|
||||
use super::*;
|
||||
use crate::cli::SecretCmd;
|
||||
use crate::output::print_json;
|
||||
use crate::secrets::{self, SecretStore};
|
||||
|
||||
pub fn run(app: &App, sub: &SecretCmd) -> Result<i32> {
|
||||
match sub {
|
||||
SecretCmd::Set { name, agent, value } => {
|
||||
if app.dry_run() {
|
||||
app.log.dry(format!("would store secret {name} for {agent} in the OS keyring"));
|
||||
return Ok(0);
|
||||
}
|
||||
let key = secrets::key_for(agent, name);
|
||||
secrets::store().set(&key, value)?;
|
||||
app.log.success(&format!("secret {name} stored for {agent}"));
|
||||
app.log.info("use it with --env NAME=@secret (injected at start/run)");
|
||||
Ok(0)
|
||||
}
|
||||
SecretCmd::Unset { name, agent } => {
|
||||
let key = secrets::key_for(agent, name);
|
||||
if app.dry_run() {
|
||||
app.log.dry(format!("would remove secret {key}"));
|
||||
return Ok(0);
|
||||
}
|
||||
let removed = secrets::store().remove(&key)?;
|
||||
if removed {
|
||||
app.log.success(&format!("secret {name} removed for {agent}"));
|
||||
} else {
|
||||
app.log.info(&format!("secret {name} does not exist for {agent}"));
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
SecretCmd::List => {
|
||||
let all = secrets::store().list().unwrap_or_default();
|
||||
if app.json() {
|
||||
print_json(&all);
|
||||
return Ok(0);
|
||||
}
|
||||
if all.is_empty() {
|
||||
app.log.info("no secrets stored — see: am secret set NAME --agent AGENT --value ...");
|
||||
return Ok(0);
|
||||
}
|
||||
let mut table = crate::output::Table::new(vec!["SECRET"]);
|
||||
for k in all {
|
||||
if k != "__index__" {
|
||||
table.row(vec![k]);
|
||||
}
|
||||
}
|
||||
print!("{}", table.render());
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user