use clap::{Args, ValueEnum};
use serde::Serialize;
use crate::{
config::ProjectConfig,
kubernetes::{KubeClient, KubeRsClient},
profiles::Profile,
NylError, Result,
};
#[derive(Args, Debug)]
pub struct ClusterInfoArgs {
#[arg(short, long)]
pub profile: Option<String>,
#[arg(long, default_value = "text", value_enum)]
pub output: OutputFormat,
}
#[derive(Debug, Clone, Copy, ValueEnum)]
pub enum OutputFormat {
Text,
Json,
Yaml,
Csv,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct ClusterInfo {
kube_version: String,
api_versions: Vec<String>,
}
pub async fn execute(args: ClusterInfoArgs) -> Result<()> {
let project_config = ProjectConfig::load_with_warning(None)?;
let env_name = args.profile.as_deref().unwrap_or("default");
let profile: Profile = if let Some(values) = project_config.get_profile_values(env_name) {
Profile {
values: values.iter().map(|(k, v)| (k.clone(), v.clone())).collect(),
..Default::default()
}
} else if args.profile.is_some() {
return Err(NylError::Config(format!("Profile '{}' not found", env_name)));
} else if !project_config.has_profiles() {
Profile::default()
} else {
return Err(NylError::Config(format!(
"Profile '{}' not found. Available profiles: {}",
env_name,
project_config.profile_names().join(", ")
)));
};
let client = KubeRsClient::from_profile(&profile, None).await?;
let kube_version = client.get_server_version().await?;
let api_versions = client.get_api_versions().await?;
let info = ClusterInfo {
kube_version,
api_versions,
};
match args.output {
OutputFormat::Text => output_text(&info),
OutputFormat::Json => output_json(&info)?,
OutputFormat::Yaml => output_yaml(&info)?,
OutputFormat::Csv => output_csv(&info),
}
Ok(())
}
fn output_text(info: &ClusterInfo) {
println!("Kubernetes Version: {}", info.kube_version);
println!("API Versions:");
for version in &info.api_versions {
println!(" - {}", version);
}
}
fn output_json(info: &ClusterInfo) -> Result<()> {
let json =
serde_json::to_string_pretty(info).map_err(|e| NylError::Config(format!("Failed to serialize JSON: {}", e)))?;
println!("{}", json);
Ok(())
}
fn output_yaml(info: &ClusterInfo) -> Result<()> {
let yaml = serde_norway::to_string(info)?;
print!("{}", yaml);
Ok(())
}
fn output_csv(info: &ClusterInfo) {
println!("{}", info.kube_version);
println!("{}", info.api_versions.join(","));
}