diff --git a/harmony/src/domain/topology/k8s.rs b/harmony/src/domain/topology/k8s.rs index fccf0d1..3cab0b8 100644 --- a/harmony/src/domain/topology/k8s.rs +++ b/harmony/src/domain/topology/k8s.rs @@ -451,7 +451,20 @@ impl K8sClient { { let mut result = Vec::new(); for r in resource.iter() { - result.push(self.apply(r, ns).await?); + let apply_result = self.apply(r, ns).await; + if apply_result.is_err() { + // NOTE : We should be careful about this one, it may leak sensitive information in + // logs + // Maybe just reducing it to debug would be enough as we already know debug logs + // are unsafe. + // But keeping it at warn makes it much easier to understand what is going on. So be it for now. + warn!( + "Failed to apply k8s resource : {}", + serde_json::to_string_pretty(r).map_err(|e| Error::SerdeError(e))? + ); + } + + result.push(apply_result?); } Ok(result) diff --git a/harmony/src/domain/topology/k8s_anywhere.rs b/harmony/src/domain/topology/k8s_anywhere.rs index 95b2cdb..5739d57 100644 --- a/harmony/src/domain/topology/k8s_anywhere.rs +++ b/harmony/src/domain/topology/k8s_anywhere.rs @@ -108,25 +108,24 @@ impl K8sclient for K8sAnywhereTopology { #[async_trait] impl TlsRouter for K8sAnywhereTopology { async fn install_route(&self, route: TlsRoute) -> Result<(), String> { - if let Some(distro) = self.k8s_distribution.get() { - match distro { - KubernetesDistribution::OpenshiftFamily => { - OKDTlsPassthroughScore { - name: Rfc1123Name::try_from(route.to_string_short().as_str())?, - route, - } - .interpret(&Inventory::empty(), self) - .await?; - Ok(()) + let distro = self + .get_k8s_distribution() + .await + .map_err(|e| format!("Could not get k8s distribution {e}"))?; + + match distro { + KubernetesDistribution::OpenshiftFamily => { + OKDTlsPassthroughScore { + name: Rfc1123Name::try_from(route.backend_info_string().as_str())?, + route, } - KubernetesDistribution::K3sFamily | KubernetesDistribution::Default => Err( - format!("Distribution not supported yet for Tlsrouter {distro:?}"), - ), + .interpret(&Inventory::empty(), self) + .await?; + Ok(()) } - } else { - Err(format!( - "Could not find a k8s distribution, TlsRouter in K8sAnywhereTopology requires it" - )) + KubernetesDistribution::K3sFamily | KubernetesDistribution::Default => Err(format!( + "Distribution not supported yet for Tlsrouter {distro:?}" + )), } } } @@ -372,6 +371,7 @@ impl K8sAnywhereTopology { pub async fn get_k8s_distribution(&self) -> Result<&KubernetesDistribution, PreparationError> { self.k8s_distribution .get_or_try_init(async || { + debug!("Trying to detect k8s distribution"); let client = self.k8s_client().await.unwrap(); let discovery = client.discovery().await.map_err(|e| { @@ -387,14 +387,17 @@ impl K8sAnywhereTopology { .groups() .any(|g| g.name() == "project.openshift.io") { + info!("Found KubernetesDistribution OpenshiftFamily"); return Ok(KubernetesDistribution::OpenshiftFamily); } // K3d / K3s if version.git_version.contains("k3s") { + info!("Found KubernetesDistribution K3sFamily"); return Ok(KubernetesDistribution::K3sFamily); } + info!("Could not identify KubernetesDistribution, using Default"); return Ok(KubernetesDistribution::Default); }) .await diff --git a/harmony/src/domain/topology/router.rs b/harmony/src/domain/topology/router.rs index ded17d2..a904e1d 100644 --- a/harmony/src/domain/topology/router.rs +++ b/harmony/src/domain/topology/router.rs @@ -84,6 +84,10 @@ pub struct TlsRoute { pub fn to_string_short(&self) -> String { format!("{}-{}:{}", self.hostname, self.backend, self.target_port) } + + pub fn backend_info_string(&self) -> String { + format!("{}:{}", self.backend, self.target_port) + } } /// Installs and queries TLS passthrough routes (L4 TCP/SNI forwarding, no TLS termination). diff --git a/harmony/src/modules/k8s/resource.rs b/harmony/src/modules/k8s/resource.rs index 57f9731..dde7339 100644 --- a/harmony/src/modules/k8s/resource.rs +++ b/harmony/src/modules/k8s/resource.rs @@ -79,7 +79,33 @@ where _inventory: &Inventory, topology: &T, ) -> Result { - info!("Applying {} resources", self.score.resource.len()); + // TODO improve this log + let resource_names: Vec = self + .score + .resource + .iter() + .map(|r| { + format!( + "{}{}", + r.meta() + .name + .as_ref() + .map(|n| format!("{n}")) + .unwrap_or_default(), + r.meta() + .namespace + .as_ref() + .map(|ns| format!("@{}", ns)) + .unwrap_or_default() + ) + }) + .collect(); + + info!( + "Applying {} resources : {}", + resource_names.len(), + resource_names.join(", ") + ); topology .k8s_client() .await diff --git a/harmony/src/modules/okd/crd/route.rs b/harmony/src/modules/okd/crd/route.rs index 0532fd4..4c396d0 100644 --- a/harmony/src/modules/okd/crd/route.rs +++ b/harmony/src/modules/okd/crd/route.rs @@ -13,11 +13,11 @@ pub struct LocalObjectReference { #[derive(Deserialize, Serialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct Route { - // #[serde(skip_serializing_if = "Option::is_none")] - // pub api_version: Option, - // - // #[serde(skip_serializing_if = "Option::is_none")] - // pub kind: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub api_version: Option, + + #[serde(skip_serializing_if = "Option::is_none")] + pub kind: Option, pub metadata: ObjectMeta, pub spec: RouteSpec, @@ -50,6 +50,8 @@ impl k8s_openapi::Metadata for Route { impl Default for Route { fn default() -> Self { Route { + api_version: Some("route.openshift.io/v1".to_string()), + kind: Some("Route".to_string()), metadata: ObjectMeta::default(), spec: RouteSpec::default(), status: None, diff --git a/harmony/src/modules/okd/route.rs b/harmony/src/modules/okd/route.rs index 29a00cf..9ca2f82 100644 --- a/harmony/src/modules/okd/route.rs +++ b/harmony/src/modules/okd/route.rs @@ -52,7 +52,7 @@ impl Score for OKDRouteScore { ..ObjectMeta::default() }, spec: self.spec.clone(), - status: None, + ..Default::default() }; K8sResourceScore::single(route, Some(self.namespace.clone())).create_interpret() }