mod analysis;
mod eks;
mod finding;
mod k8s;
mod output;
mod playbook;
mod version;
use std::{process, str};
use anyhow::Result;
use clap::{Args, Parser, Subcommand};
use serde::{Deserialize, Serialize};
#[derive(Parser, Debug)]
#[command(author, about, version)]
#[command(propagate_version = true)]
pub struct Cli {
#[command(subcommand)]
pub commands: Commands,
}
#[derive(Debug, Subcommand)]
pub enum Commands {
#[command(arg_required_else_help = true)]
Analyze(Analysis),
#[command(arg_required_else_help = true)]
Create(Create),
}
#[derive(Args, Debug, Serialize, Deserialize)]
pub struct Analysis {
#[arg(short, long, alias = "cluster-name", value_enum)]
pub cluster: String,
#[arg(short, long)]
pub region: Option<String>,
#[arg(short, long, value_enum, default_value_t)]
pub format: output::Format,
#[arg(short, long)]
pub output: Option<String>,
#[arg(long)]
pub ignore_recommended: bool,
}
#[derive(Args, Debug, Serialize, Deserialize)]
pub struct Create {
#[command(subcommand)]
pub command: CreateCommands,
}
#[derive(Debug, Subcommand, Serialize, Deserialize)]
pub enum CreateCommands {
#[command(arg_required_else_help = true)]
Playbook(Playbook),
}
#[derive(Args, Debug, Serialize, Deserialize)]
pub struct Playbook {
#[arg(short, long, alias = "cluster-name", value_enum)]
pub cluster: String,
#[arg(short, long)]
pub region: Option<String>,
#[arg(short, long)]
pub filename: Option<String>,
#[arg(long)]
pub ignore_recommended: bool,
}
pub async fn analyze(args: &Analysis) -> Result<()> {
let aws_config = eks::get_config(&args.region.to_owned()).await?;
let eks_client = aws_sdk_eks::Client::new(&aws_config);
let cluster = eks::get_cluster(&eks_client, &args.cluster).await?;
let results = analysis::analyze(&aws_config, &cluster).await?;
output::output(&results, &args.format, &args.output).await?;
Ok(())
}
pub async fn create(args: &Create) -> Result<()> {
match &args.command {
CreateCommands::Playbook(playbook) => {
let aws_config = eks::get_config(&playbook.region.to_owned()).await?;
let eks_client = aws_sdk_eks::Client::new(&aws_config);
let cluster = eks::get_cluster(&eks_client, &playbook.cluster).await?;
let cluster_version = cluster.version().unwrap();
if version::LATEST.eq(cluster_version) {
println!("Cluster is already at the latest supported version: {cluster_version}");
println!("Nothing to upgrade at this time");
return Ok(());
}
let results = analysis::analyze(&aws_config, &cluster).await?;
if let Err(err) = playbook::create(playbook, &cluster, results) {
eprintln!("{err}");
process::exit(2);
}
}
}
Ok(())
}