use zygo_core::supervisor::client::Client;
use zygo_core::supervisor::{Request, Response};
use crate::cli::{Cli, SecretsCommand};
use crate::output::{self, Style};
pub fn run(cli: &Cli, command: &SecretsCommand) -> anyhow::Result<u8> {
if let SecretsCommand::Keygen = command {
let key = zygo_core::secrets::SecretKey::generate()?;
println!("{key}");
let style = Style::stderr();
eprintln!(
"{}",
style.dim(&format!(
"put this in {} before starting the supervisor; Zygo does not store it, \
and a secret sealed with it cannot be read without it",
zygo_core::secrets::KEY_ENV
))
);
return Ok(0);
}
let paths = super::paths(cli);
let exe = std::env::current_exe()?;
let mut client = Client::connect_or_start(&paths, &exe)?;
match command {
SecretsCommand::Keygen => unreachable!("handled above"),
SecretsCommand::Set {
tenant,
name,
stdin,
} => {
let value = if *stdin {
super::login::read_all_stdin()?
} else {
super::login::prompt_password(tenant, &format!("Value for {name}: "))?
};
anyhow::ensure!(!value.is_empty(), "the value is empty");
let response = client.send(&Request::PutSecret {
tenant: tenant.clone(),
name: name.clone(),
value,
})?;
match response {
Response::Secrets { names } => {
if cli.json {
output::json(&serde_json::json!({ "secrets": names }))?;
} else {
eprintln!("{} {name} for {tenant}", Style::stderr().dim("stored"));
}
Ok(0)
}
other => super::supervisor::report_failure(cli, &other),
}
}
SecretsCommand::Ls { tenant } => {
let names = match client.send(&Request::Secrets {
tenant: tenant.clone(),
})? {
Response::Secrets { names } => names,
other => return super::supervisor::report_failure(cli, &other),
};
if cli.json {
output::json(&names)?;
return Ok(0);
}
if names.is_empty() {
eprintln!(
"{}",
Style::stderr().dim(&format!("{tenant} has no secrets"))
);
return Ok(0);
}
for name in &names {
println!("{name}");
}
Ok(0)
}
SecretsCommand::Rm { tenant, name } => {
let response = client.send(&Request::DeleteSecret {
tenant: tenant.clone(),
name: name.clone(),
})?;
match response {
Response::Secrets { .. } => {
if cli.json {
output::json(&serde_json::json!({ "removed": name }))?;
} else {
eprintln!("{} {name} from {tenant}", Style::stderr().dim("removed"));
}
Ok(0)
}
other => super::supervisor::report_failure(cli, &other),
}
}
}
}