fix: modified cert-manager ensure ready to check for existence of pods with labels matching cert-manager in kubernetes env. replaced deprecated olm subscription based install of cert-manager for supported helm-chart #218

Merged
wjro merged 2 commits from fix/cert-manager into master 2026-01-23 16:28:34 +00:00
3 changed files with 61 additions and 41 deletions

View File

@@ -925,6 +925,27 @@ impl K8sClient {
api.get_opt(name).await api.get_opt(name).await
} }
pub async fn list_all_resources_with_labels<K>(&self, labels: &str) -> Result<Vec<K>, Error>
where
K: Resource + Clone + std::fmt::Debug + DeserializeOwned,
<K as kube::Resource>::DynamicType: Default,
{
let api: Api<K> = Api::all(self.client.clone());
let lp = ListParams::default().labels(labels);
Ok(api.list(&lp).await?.items)
}
pub async fn get_all_resource_in_all_namespace<K>(&self) -> Result<Vec<K>, Error>
where
Review

Remove comment and make name more explicit

Remove comment and make name more explicit
K: Resource + Clone + std::fmt::Debug + DeserializeOwned,
<K as Resource>::Scope: ApplyStrategy<K>,
<K as kube::Resource>::DynamicType: Default,
{
let api: Api<K> = Api::all(self.client.clone());
Ok(api.list(&Default::default()).await?.items)
}
/// Lists all resources of a specific type `K`. /// Lists all resources of a specific type `K`.
/// ///
/// This function uses the `ApplyStrategy` trait to correctly determine /// This function uses the `ApplyStrategy` trait to correctly determine

View File

@@ -4,7 +4,7 @@ use async_trait::async_trait;
use base64::{Engine, engine::general_purpose}; use base64::{Engine, engine::general_purpose};
use harmony_types::rfc1123::Rfc1123Name; use harmony_types::rfc1123::Rfc1123Name;
use k8s_openapi::api::{ use k8s_openapi::api::{
core::v1::Secret, core::v1::{Pod, Secret},
rbac::v1::{ClusterRoleBinding, RoleRef, Subject}, rbac::v1::{ClusterRoleBinding, RoleRef, Subject},
}; };
use kube::api::{DynamicObject, GroupVersionKind, ObjectMeta}; use kube::api::{DynamicObject, GroupVersionKind, ObjectMeta};
@@ -28,10 +28,7 @@ use crate::{
score_cert_management::CertificateManagementScore, score_cert_management::CertificateManagementScore,
}, },
k3d::K3DInstallationScore, k3d::K3DInstallationScore,
k8s::{ k8s::ingress::{K8sIngressScore, PathType},
apps::crd::Subscription,
ingress::{K8sIngressScore, PathType},
},
monitoring::{ monitoring::{
grafana::{grafana::Grafana, helm::helm_grafana::grafana_helm_chart_score}, grafana::{grafana::Grafana, helm::helm_grafana::grafana_helm_chart_score},
kube_prometheus::crd::{ kube_prometheus::crd::{
@@ -376,7 +373,6 @@ impl Serialize for K8sAnywhereTopology {
impl CertificateManagement for K8sAnywhereTopology { impl CertificateManagement for K8sAnywhereTopology {
async fn install(&self) -> Result<Outcome, ExecutorError> { async fn install(&self) -> Result<Outcome, ExecutorError> {
let cert_management_operator = CertManagerOperatorScore::default(); let cert_management_operator = CertManagerOperatorScore::default();
cert_management_operator cert_management_operator
.interpret(&Inventory::empty(), self) .interpret(&Inventory::empty(), self)
.await .await
@@ -390,17 +386,21 @@ impl CertificateManagement for K8sAnywhereTopology {
async fn ensure_ready(&self) -> Result<Outcome, ExecutorError> { async fn ensure_ready(&self) -> Result<Outcome, ExecutorError> {
let k8s_client = self.k8s_client().await.unwrap(); let k8s_client = self.k8s_client().await.unwrap();
let pods = k8s_client
match k8s_client .list_all_resources_with_labels::<Pod>(
.get_resource::<Subscription>("cert-manager", Some("openshift-operators")) "app.kubernetes.io/component=controller,\
app.kubernetes.io/name=cert-manager",
)
.await .await
.map_err(|e| ExecutorError::UnexpectedError(format!("{}", e)))? .map_err(|e| ExecutorError::UnexpectedError(format!("{}", e)))?;
{
Some(subscription) => { if pods.is_empty() {
trace!("subscription {:#?}", subscription,); info!("cert-manager not installed (no controller pods found)");
Ok(Outcome::success(format!("Certificate Management Ready",))) self.install().await
} } else {
None => self.install().await, trace!("cert-manager controller pods found: {:#?}", pods);
Review

should be info since this has a major implication of installing a full thing

should be info since this has a major implication of installing a full thing
info!("cert-manager controller pods found");
Ok(Outcome::success("Certificate Management Ready".to_string()))
} }
} }

View File

@@ -1,18 +1,17 @@
use kube::api::ObjectMeta; use std::{collections::HashMap, str::FromStr};
use non_blank_string_rs::NonBlankString;
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
interpret::Interpret, interpret::Interpret,
modules::k8s::{ modules::helm::chart::HelmChartScore,
apps::crd::{Subscription, SubscriptionSpec},
resource::K8sResourceScore,
},
score::Score, score::Score,
topology::{K8sclient, Topology, k8s::K8sClient}, topology::{HelmCommand, K8sclient, Topology},
}; };
/// Install the Cert-Manager Operator via RedHat Community Operators registry.redhat.io/redhat/community-operator-index:v4.19 /// Install the Cert-Manager Operator via helm chart
/// This Score creates a Subscription CR in the specified namespace /// This Score installs the cert-manager CRs in the specified namespace
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct CertManagerOperatorScore { pub struct CertManagerOperatorScore {
@@ -35,30 +34,30 @@ impl Default for CertManagerOperatorScore {
} }
} }
impl<T: Topology + K8sclient> Score<T> for CertManagerOperatorScore { impl<T: Topology + K8sclient + HelmCommand + 'static> Score<T> for CertManagerOperatorScore {
fn name(&self) -> String { fn name(&self) -> String {
"CertManagerOperatorScore".to_string() "CertManagerOperatorScore".to_string()
} }
fn create_interpret(&self) -> Box<dyn Interpret<T>> { fn create_interpret(&self) -> Box<dyn Interpret<T>> {
let metadata = ObjectMeta { let cert_manager_score = HelmChartScore {
name: Some("cert-manager".to_string()), namespace: Some(NonBlankString::from_str(&self.namespace.as_str()).unwrap()),
namespace: Some(self.namespace.clone()), release_name: NonBlankString::from_str("cert-manager").unwrap(),
..ObjectMeta::default() chart_name: NonBlankString::from_str("oci://quay.io/jetstack/charts/cert-manager")
.unwrap(),
chart_version: None,
values_overrides: Some(HashMap::from([(
NonBlankString::from_str("installCRDs").unwrap(),
"true".to_string(),
)])),
values_yaml: None,
create_namespace: true,
install_only: true,
repository: None,
}; };
let spec = SubscriptionSpec { let cert_score = cert_manager_score.create_interpret();
channel: Some(self.channel.clone()),
config: None,
install_plan_approval: Some(self.install_plan_approval.clone()),
name: "cert-manager".to_string(),
source: self.source.clone(),
source_namespace: self.source_namespace.clone(),
starting_csv: None,
};
let subscription = Subscription { metadata, spec }; cert_score
K8sResourceScore::single(subscription, Some(self.namespace.clone())).create_interpret()
} }
} }