feat: K8sFlavour #161

Merged
wjro merged 7 commits from feat/detect_k8s_flavour into master 2025-10-21 15:56:48 +00:00
2 changed files with 75 additions and 1 deletions
Showing only changes of commit f073b7e5fb - Show all commits

View File

@ -2,9 +2,10 @@ use derive_new::new;
use k8s_openapi::{
ClusterResourceScope, NamespaceResourceScope,
api::{apps::v1::Deployment, core::v1::Pod},
apimachinery::pkg::version::Info,
};
use kube::{
Client, Config, Error, Resource,
Client, Config, Discovery, Error, Resource,
api::{Api, AttachParams, DeleteParams, ListParams, Patch, PatchParams, ResourceExt},
config::{KubeConfigOptions, Kubeconfig},
core::ErrorResponse,
@ -53,6 +54,17 @@ impl K8sClient {
})
}
pub async fn get_apiserver_version(&self) -> Result<Info, Error> {
let client: Client = self.client.clone();
let version_info: Info = client.apiserver_version().await?;
Ok(version_info)
}
pub async fn discovery(&self) -> Result<Discovery, Error> {
let discovery: Discovery = Discovery::new(self.client.clone()).run().await?;
Ok(discovery)
}
pub async fn get_resource_json_value(
&self,
name: &str,

View File

@ -47,6 +47,13 @@ struct K8sState {
message: String,
}
#[derive(Debug, Clone)]
pub enum K8sFlavour {
Okd,
wjro marked this conversation as resolved Outdated

Should be OpenshiftFamily(Version) as we want the same behavior between okd and openshift.

Should be OpenshiftFamily(Version) as we want the same behavior between okd and openshift.
K3d,
K8s,
}
#[derive(Debug, Clone)]
enum K8sSource {
LocalK3d,
@ -57,6 +64,7 @@ enum K8sSource {
pub struct K8sAnywhereTopology {
k8s_state: Arc<OnceCell<Option<K8sState>>>,
tenant_manager: Arc<OnceCell<K8sTenantManager>>,
flavour: Arc<OnceCell<K8sFlavour>>,
config: Arc<K8sAnywhereConfig>,
}
@ -162,6 +170,7 @@ impl K8sAnywhereTopology {
Self {
k8s_state: Arc::new(OnceCell::new()),
tenant_manager: Arc::new(OnceCell::new()),
flavour: Arc::new(OnceCell::new()),
config: Arc::new(K8sAnywhereConfig::from_env()),
}
}
@ -170,10 +179,63 @@ impl K8sAnywhereTopology {
Self {
k8s_state: Arc::new(OnceCell::new()),
tenant_manager: Arc::new(OnceCell::new()),
flavour: Arc::new(OnceCell::new()),
config: Arc::new(config),
}
}
pub async fn get_k8s_flavour(&self) -> K8sFlavour {
self.flavour
.get_or_try_init(async || {
let client = self.k8s_client().await.unwrap();
let discovery = client.discovery().await.map_err(|e| {
PreparationError::new(format!("Could not discover API groups: {}", e))
})?;
let version = client.get_apiserver_version().await.map_err(|e| {
PreparationError::new(format!("Could not get server version: {}", e))
})?;
let rules: &[&dyn Fn() -> Option<K8sFlavour>] = &[
// OpenShift / OKD
&|| {
discovery
.groups()
.any(|g| g.name().ends_with("openshift.io"))
.then_some(K8sFlavour::Okd)
},
// K3d / K3s
&|| {
version
.git_version
.contains("k3s")
.then_some(K8sFlavour::K3d)
wjro marked this conversation as resolved Outdated

That is a clear naming problem. Should be either k3d for real by detecting it another way or k3sFamily just like OpenshiftFamily

That is a clear naming problem. Should be either k3d for real by detecting it another way or k3sFamily just like OpenshiftFamily
},
// Vanilla Kubernetes
&|| {
if !discovery
.groups()
.any(|g| g.name().ends_with("openshift.io"))
&& !version.git_version.contains("k3s")
&& !version.git_version.contains("k3d")
{
Some(K8sFlavour::K8s)
wjro marked this conversation as resolved Outdated

This is more of a fallback to a default than a true way to detect that we're running vanilla k8s (made by kubeadm for example).

Should be called Default or Fallback or Unknown but not k8s.

This is more of a fallback to a default than a true way to detect that we're running vanilla k8s (made by kubeadm for example). Should be called Default or Fallback or Unknown but not k8s.
} else {
None
}
},
];
rules.iter().find_map(|rule| rule()).ok_or_else(|| {
PreparationError::new("Unknown Kubernetes cluster flavour".to_string())
})
})
.await
.unwrap()
.clone()
}
async fn get_cluster_observability_operator_prometheus_application_score(
&self,
sender: RHOBObservability,