86 lines
2.1 KiB
Rust
86 lines
2.1 KiB
Rust
|
|
use clap::{Parser, Subcommand};
|
||
|
|
use tracing::info;
|
||
|
|
|
||
|
|
mod parser;
|
||
|
|
mod classifier;
|
||
|
|
mod executor;
|
||
|
|
mod audit;
|
||
|
|
|
||
|
|
#[derive(Parser)]
|
||
|
|
#[command(name = "dd0c-run", version, about = "Runbook automation agent")]
|
||
|
|
struct Cli {
|
||
|
|
#[command(subcommand)]
|
||
|
|
command: Commands,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Subcommand)]
|
||
|
|
enum Commands {
|
||
|
|
/// Execute a runbook
|
||
|
|
Run {
|
||
|
|
/// Path to runbook file (YAML/Markdown)
|
||
|
|
#[arg(short, long)]
|
||
|
|
runbook: String,
|
||
|
|
|
||
|
|
/// dd0c SaaS endpoint
|
||
|
|
#[arg(long, default_value = "https://api.dd0c.dev")]
|
||
|
|
endpoint: String,
|
||
|
|
|
||
|
|
/// API key
|
||
|
|
#[arg(long, env = "DD0C_API_KEY")]
|
||
|
|
api_key: String,
|
||
|
|
|
||
|
|
/// Dry run (classify only, don't execute)
|
||
|
|
#[arg(long)]
|
||
|
|
dry_run: bool,
|
||
|
|
},
|
||
|
|
/// Classify a single command
|
||
|
|
Classify {
|
||
|
|
/// Command to classify
|
||
|
|
command: String,
|
||
|
|
},
|
||
|
|
/// Verify agent binary signature
|
||
|
|
Verify {
|
||
|
|
/// Path to signature file
|
||
|
|
#[arg(short, long)]
|
||
|
|
sig: String,
|
||
|
|
/// Path to public key
|
||
|
|
#[arg(short, long)]
|
||
|
|
pubkey: String,
|
||
|
|
},
|
||
|
|
/// Print version
|
||
|
|
Version,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[tokio::main]
|
||
|
|
async fn main() -> anyhow::Result<()> {
|
||
|
|
tracing_subscriber::fmt()
|
||
|
|
.with_env_filter(
|
||
|
|
tracing_subscriber::EnvFilter::try_from_default_env()
|
||
|
|
.unwrap_or_else(|_| "dd0c_run=info".into()),
|
||
|
|
)
|
||
|
|
.json()
|
||
|
|
.init();
|
||
|
|
|
||
|
|
let cli = Cli::parse();
|
||
|
|
|
||
|
|
match cli.command {
|
||
|
|
Commands::Run { runbook, endpoint, api_key, dry_run } => {
|
||
|
|
info!(runbook = %runbook, dry_run, "Starting runbook execution");
|
||
|
|
// TODO: Parse runbook → classify steps → execute with approval gates
|
||
|
|
}
|
||
|
|
Commands::Classify { command } => {
|
||
|
|
let result = classifier::classify(&command);
|
||
|
|
println!("{}", serde_json::to_string_pretty(&result)?);
|
||
|
|
}
|
||
|
|
Commands::Verify { sig, pubkey } => {
|
||
|
|
// TODO: Ed25519 signature verification
|
||
|
|
println!("Signature verification not yet implemented");
|
||
|
|
}
|
||
|
|
Commands::Version => {
|
||
|
|
println!("dd0c/run agent v{}", env!("CARGO_PKG_VERSION"));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Ok(())
|
||
|
|
}
|