use clap::{
Args,
Subcommand,
};
use context::Context;
use key::KEY_LOCATION_HELP;
mod context;
mod key;
mod utils;
mod vault;
#[derive(Debug, Args)]
pub struct Secrets {
#[command(subcommand)]
command: Option<SecretsCommand>,
#[arg(long, help = "The path to the secret vault")]
vault_location: Option<String>,
#[arg(long, help = KEY_LOCATION_HELP)]
keys_location: Option<String>,
#[arg(long, help = "The key name")]
key_name: Option<String>,
#[arg(
long,
help = "GPG key ID or fingerprint for hardware/passphrase-protected keys (delegates crypto to the system gpg binary). Cannot be combined with --key-name."
)]
gpg_key_id: Option<String>,
}
#[derive(Debug, Subcommand)]
enum SecretsCommand {
#[command(visible_aliases = ["k"], arg_required_else_help = true, about = "Access private keys")]
Key(key::Key),
#[command(visible_aliases = ["v"], arg_required_else_help = true, about = "Access secret vault")]
Vault(vault::Vault),
#[command(visible_aliases = ["K"], about = "List private keys")]
ListKeys(key::ListKeys),
#[command(visible_aliases = ["init"], about = "Initialize a new secret vault")]
InitVault(vault::InitVault),
#[command(visible_aliases = ["export", "e"], about = "Export a secret to file")]
ExportSecret(vault::ExportSecret),
}
impl Secrets {
pub fn execute(&self) -> anyhow::Result<()> {
let mut context = Context::new();
if let Some(keys_location) = &self.keys_location {
context.set_keys_location(keys_location);
}
if let Some(vault_location) = &self.vault_location {
context.set_vault_location(vault_location);
}
if self.key_name.is_some() && self.gpg_key_id.is_some() {
anyhow::bail!("--key-name and --gpg-key-id are mutually exclusive");
}
if let Some(key_name) = &self.key_name {
context.set_key_name(key_name);
}
if let Some(gpg_key_id) = &self.gpg_key_id {
context.set_gpg_key_id(gpg_key_id);
}
match &self.command {
Some(SecretsCommand::Key(key)) => key.execute(&mut context),
Some(SecretsCommand::Vault(vault)) => vault.execute(&mut context),
Some(SecretsCommand::ListKeys(list_keys)) => list_keys.execute(&context),
Some(SecretsCommand::InitVault(init_store)) => init_store.execute(&context),
Some(SecretsCommand::ExportSecret(export_secret)) => export_secret.execute(&context),
None => Err(anyhow::anyhow!(
"No secrets subcommand given. Run 'mk secrets --help' to see available subcommands."
)),
}
}
}