use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(
name = "hackamore-agent",
about = "Configure stock tools to reach hackamore"
)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Show(Common),
Env(Common),
Status(Common),
Setup(SetupArgs),
Teardown(TeardownArgs),
}
#[derive(clap::Args)]
struct Common {
#[arg(long)]
hackamore_url: String,
#[arg(long)]
token: String,
}
#[derive(clap::Args)]
struct SetupArgs {
#[command(flatten)]
common: Common,
#[arg(long)]
home: Option<std::path::PathBuf>,
}
#[derive(clap::Args)]
struct TeardownArgs {
#[arg(long)]
home: Option<std::path::PathBuf>,
}
fn resolve_home(
explicit: Option<std::path::PathBuf>,
) -> Result<std::path::PathBuf, Box<dyn std::error::Error>> {
explicit
.or_else(|| std::env::var_os("HOME").map(Into::into))
.ok_or_else(|| "no --home and $HOME is unset".into())
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
match Cli::parse().command {
Command::Show(c) => {
let doc = hackamore_agent::fetch_provision(&c.hackamore_url, &c.token).await?;
println!("{}", serde_json::to_string_pretty(&doc)?);
}
Command::Env(c) => {
let doc = hackamore_agent::fetch_provision(&c.hackamore_url, &c.token).await?;
print!("{}", hackamore_agent::render_env(&doc));
}
Command::Status(c) => {
let doc = hackamore_agent::fetch_provision(&c.hackamore_url, &c.token).await?;
print!("{}", hackamore_agent::render_status(&doc));
}
Command::Setup(args) => {
let doc =
hackamore_agent::fetch_provision(&args.common.hackamore_url, &args.common.token)
.await?;
let home = resolve_home(args.home)?;
let written = hackamore_agent::write_configs(&home, &doc)?;
for p in &written {
println!("wrote {}", p.display());
}
}
Command::Teardown(args) => {
let home = resolve_home(args.home)?;
let removed = hackamore_agent::teardown(&home)?;
for p in &removed {
println!("removed {}", p.display());
}
}
}
Ok(())
}