use anyhow::{bail, Result};
use aws_sdk_eks::types::Cluster;
use serde::{Deserialize, Serialize};
use crate::{eks, finding::Findings, k8s, version};
#[derive(Debug, Serialize, Deserialize)]
pub(crate) struct Results {
pub(crate) cluster: eks::ClusterFindings,
pub(crate) subnets: eks::SubnetFindings,
pub(crate) data_plane: eks::DataPlaneFindings,
pub(crate) addons: eks::AddonFindings,
pub(crate) kubernetes: k8s::KubernetesFindings,
}
impl Results {
pub(crate) fn to_stdout_table(&self) -> Result<String> {
let mut output = String::new();
output.push_str(&self.subnets.pod_ips.to_stdout_table()?);
output.push_str(&self.subnets.control_plane_ips.to_stdout_table()?);
output.push_str(&self.cluster.cluster_health.to_stdout_table()?);
output.push_str(&self.data_plane.eks_managed_nodegroup_health.to_stdout_table()?);
output.push_str(&self.addons.health.to_stdout_table()?);
output.push_str(&self.addons.version_compatibility.to_stdout_table()?);
output.push_str(&self.data_plane.eks_managed_nodegroup_update.to_stdout_table()?);
output.push_str(&self.data_plane.self_managed_nodegroup_update.to_stdout_table()?);
output.push_str(&self.kubernetes.version_skew.to_stdout_table()?);
output.push_str(&self.kubernetes.min_replicas.to_stdout_table()?);
output.push_str(&self.kubernetes.min_ready_seconds.to_stdout_table()?);
output.push_str(&self.kubernetes.pod_topology_distribution.to_stdout_table()?);
output.push_str(&self.kubernetes.readiness_probe.to_stdout_table()?);
output.push_str(&self.kubernetes.termination_grace_period.to_stdout_table()?);
output.push_str(&self.kubernetes.docker_socket.to_stdout_table()?);
output.push_str(&self.kubernetes.pod_security_policy.to_stdout_table()?);
output.push_str(&self.kubernetes.kube_proxy_version_skew.to_stdout_table()?);
Ok(output)
}
}
pub(crate) async fn analyze(aws_shared_config: &aws_config::SdkConfig, cluster: &Cluster) -> Result<Results> {
let asg_client = aws_sdk_autoscaling::Client::new(aws_shared_config);
let ec2_client = aws_sdk_ec2::Client::new(aws_shared_config);
let eks_client = aws_sdk_eks::Client::new(aws_shared_config);
let cluster_name = cluster.name().unwrap();
let k8s_client = match kube::Client::try_default().await {
Ok(client) => client,
Err(_) => {
bail!(
"Unable to connect to cluster. Ensure kubeconfig file is present and updated to connect to the cluster.
Try: aws eks update-kubeconfig --name {cluster_name}"
);
}
};
let cluster_version = cluster.version().unwrap();
let target_version = version::get_target_version(cluster_version)?;
let cluster_findings = eks::get_cluster_findings(cluster).await?;
let subnet_findings = eks::get_subnet_findings(&ec2_client, &k8s_client, cluster).await?;
let addon_findings = eks::get_addon_findings(&eks_client, cluster_name, cluster_version).await?;
let dataplane_findings = eks::get_data_plane_findings(&asg_client, &ec2_client, &eks_client, cluster).await?;
let kubernetes_findings = k8s::get_kubernetes_findings(&k8s_client, cluster_version, &target_version).await?;
Ok(Results {
cluster: cluster_findings,
subnets: subnet_findings,
addons: addon_findings,
data_plane: dataplane_findings,
kubernetes: kubernetes_findings,
})
}