From 75a8937215d1814a93730a58f1f02d4a74905911 Mon Sep 17 00:00:00 2001 From: Allen Li <46284272+qpdpQ@users.noreply.github.com> Date: Mon, 17 Nov 2025 13:42:13 -0500 Subject: [PATCH] support co-existence with other cert-manger (#2676) * support co-existence with other cert-manger Signed-off-by: Allen Li * support cert-manager co-exist Signed-off-by: Allen Li * remove test log Signed-off-by: Allen Li * update cert-manager-deployment-check function Signed-off-by: Allen Li * cleanup code Signed-off-by: Allen Li --------- Signed-off-by: Allen Li --- cp3pt0-deployment/common/utils.sh | 60 +++++++++++-- cp3pt0-deployment/setup_singleton.sh | 127 ++++++++++++++++++++------- 2 files changed, 147 insertions(+), 40 deletions(-) diff --git a/cp3pt0-deployment/common/utils.sh b/cp3pt0-deployment/common/utils.sh index 05d94aea9..4e33bd6e2 100644 --- a/cp3pt0-deployment/common/utils.sh +++ b/cp3pt0-deployment/common/utils.sh @@ -110,6 +110,43 @@ function translate_step() { echo "${step}" | tr '[1-9]' '[a-i]' } +function check_for_condition() { + local condition=$1 + local retries=$2 + local sleep_time=$3 + local wait_message=$4 + local success_message=$5 + local error_message=$6 + local debug_condition=${7:-} + + info "${wait_message}" + while true; do + result=$(eval "${condition}") + + if [[ ( ${retries} -eq 0 ) && ( -z "${result}" ) ]]; then + return 1 + fi + + sleep ${sleep_time} + result=$(eval "${condition}") + + if [[ -z "${result}" ]]; then + if [[ ! -z "${debug_condition}" ]]; then + debug "${debug_condition} -> \n$(eval "${debug_condition}")\n" + fi + + info "RETRYING: ${wait_message} (${retries} left)" + retries=$(( retries - 1 )) + else + break + fi + done + + if [[ ! -z "${success_message}" ]]; then + return 0 + fi +} + function wait_for_condition() { local condition=$1 local retries=$2 @@ -248,7 +285,7 @@ function wait_for_operator() { wait_for_condition "${condition}" ${retries} ${sleep_time} "${wait_message}" "${success_message}" "${error_message}" } -function wait_for_issuer() { +function check_for_issuer() { local issuer=$1 local namespace=$2 local condition="${OC} -n ${namespace} get issuer.v1.cert-manager.io ${issuer} --ignore-not-found -o jsonpath='{.status.conditions[?(@.type==\"Ready\")].status}' | grep 'True'" @@ -259,10 +296,11 @@ function wait_for_issuer() { local success_message="Issuer ${issuer} in namespace ${namespace} is Ready" local error_message="Timeout after ${total_time_mins} minutes waiting for Issuer ${issuer} in namespace ${namespace} to be Ready" - wait_for_condition "${condition}" ${retries} ${sleep_time} "${wait_message}" "${success_message}" "${error_message}" + check_for_condition "${condition}" ${retries} ${sleep_time} "${wait_message}" "${success_message}" "${error_message}" + return $? } -function wait_for_certificate() { +function check_for_certificate() { local certificate=$1 local namespace=$2 local condition="${OC} -n ${namespace} get certificate.v1.cert-manager.io ${certificate} --ignore-not-found -o jsonpath='{.status.conditions[?(@.type==\"Ready\")].status}' | grep 'True'" @@ -273,7 +311,8 @@ function wait_for_certificate() { local success_message="Certificate ${certificate} in namespace ${namespace} is Ready" local error_message="Timeout after ${total_time_mins} minutes waiting for Certificate ${certificate} in namespace ${namespace} to be Ready" - wait_for_condition "${condition}" ${retries} ${sleep_time} "${wait_message}" "${success_message}" "${error_message}" + check_for_condition "${condition}" ${retries} ${sleep_time} "${wait_message}" "${success_message}" "${error_message}" + return $? } function wait_for_csv() { @@ -774,10 +813,15 @@ function cm_smoke_test(){ cleanup_cm_resources $issuer_name $cert_name $sercret_name $namespace create_issuer $issuer_name $namespace create_certificate $issuer_name $cert_name $sercret_name $namespace - wait_for_issuer $issuer_name $namespace - wait_for_certificate $cert_name $namespace - if [[ $? -eq 0 ]]; then - cleanup_cm_resources $issuer_name $cert_name $sercret_name $namespace + check_for_issuer $issuer_name $namespace + ret1=$? + check_for_certificate $cert_name $namespace + ret2=$? + cleanup_cm_resources $issuer_name $cert_name $sercret_name $namespace + if [[ $ret1 -eq 0 && $ret2 -eq 0 ]]; then + return 0 + else + return 1 fi } diff --git a/cp3pt0-deployment/setup_singleton.sh b/cp3pt0-deployment/setup_singleton.sh index ab9d904a8..ab3ac6777 100755 --- a/cp3pt0-deployment/setup_singleton.sh +++ b/cp3pt0-deployment/setup_singleton.sh @@ -297,22 +297,43 @@ function cert_manager_deployment_check(){ fi title "Chekcing cert-manager type" - local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1) - if [ ! -z "$webhook_ns" ]; then - # Check if the cert-manager-webhook is owned by ibm-cert-manager-operator - local api_version=$("$OC" get deployments -n "$webhook_ns" cert-manager-webhook -o jsonpath='{.metadata.ownerReferences[*].apiVersion}' --ignore-not-found) + local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1 ) + + local api_version="" + local cm_namespace="" + + # loop through all namespaces if multiple cert-manager-webhook found + # Detect owner and namespace (only need to find one owned by IBM) + for ns in $webhook_ns; do + api_version=$("$OC" get deployments -n "$ns" cert-manager-webhook -o jsonpath='{.metadata.ownerReferences[*].apiVersion}' --ignore-not-found) + cm_namespace="$ns" if [ ! -z "$api_version" ]; then if [ "$api_version" == "$CERT_MANAGER_V1_OWNER" ] || [ "$api_version" == "$CERT_MANAGER_V1ALPHA1_OWNER" ]; then - info "Cluster has a ibm-cert-manager-operator already installed." + echo "Found ibm-cert-manager-operator owned cert-manager-webhook in namespace: $ns" + break + fi + fi + done + + # If we found a cert-manager-webhook namespace + if [[ ! -z "$cm_namespace" ]]; then + + # Run smoke test + if cm_smoke_test "test-issuer" "test-certificate" "test-certificate-secret" "$cm_namespace"; then + + if [[ -n "$api_version" ]]; then + info "Cluster has an ibm-cert-manager-operator already installed." exit 1 fi + + info "Cluster has a third-party cert-manager already installed." + exit 2 fi - info "Cluster has a third party cert-manager already installed." - exit 2 - else - info "There is no cert-manager-webhook pod running\n" - exit 0 fi + + info "There is no functional cert-manager-webhook pod running\n" + exit 0 + } function install_cert_manager() { @@ -323,39 +344,77 @@ function install_cert_manager() { warning "There is a cert-manager Subscription already\n" fi - local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1) - if [ ! -z "$webhook_ns" ]; then - warning "There is a cert-manager-webhook pod Running, so most likely another cert-manager is already installed\n" - info "Continue to upgrade check\n" - - # Check if the cert-manager-webhook is owned by ibm-cert-manager-operator - local api_version=$("$OC" get deployments -n "$webhook_ns" cert-manager-webhook -o jsonpath='{.metadata.ownerReferences[*].apiVersion}' --ignore-not-found) - if [ ! -z "$api_version" ]; then + local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1 | tr '\n' ' ') + local webhook_count=$("$OC" get deployments -A | grep cert-manager-webhook | wc -l) + + if [ -z "$webhook_ns" ]; then + + info "There is no cert-manager-webhook pod running; proceeding with installation" + + else + + warning "There is a cert-manager-webhook pod running; another cert-manager is likely installed" + info "Continue to upgrade check" + + local api_version="" + local cm_namespace="" + + # Try to detect owner apiVersion + # Loop through all namespaces if multiple cert-manager-webhook found, and look for ibm-cert-manager-operator + for ns in $webhook_ns; do + api_version=$("$OC" get deployment -n "$ns" cert-manager-webhook -o jsonpath='{.metadata.ownerReferences[*].apiVersion}' --ignore-not-found) + cm_namespace="$ns" + if [ ! -z "$api_version" ]; then + if [ "$api_version" == "$CERT_MANAGER_V1_OWNER" ] || [ "$api_version" == "$CERT_MANAGER_V1ALPHA1_OWNER" ]; then + echo "Found ibm-cert-manager-operator owned cert-manager-webhook in namespace: $ns" + break + fi + fi + done + + # Run smoke test + if cm_smoke_test "test-issuer" "test-certificate" "test-certificate-secret" $cm_namespace; then + + # Check owner type + if [ -z "$api_version" ]; then + warning "Cluster has a RedHat or Helm cert-manager, skipping" + return 0 + fi + + # LTSR operator case if [ "$api_version" == "$CERT_MANAGER_V1ALPHA1_OWNER" ]; then error "Cluster has not deactivated LTSR ibm-cert-manager-operator yet, please re-run this script" fi + # Non-IBM cert-manager if [ "$api_version" != "$CERT_MANAGER_V1_OWNER" ]; then warning "Cluster has a non ibm-cert-manager-operator already installed, skipping" return 0 fi - info "Upgrading ibm-cert-manager-operator to channel: $CHANNEL\n" - if [[ "$webhook_ns" != "$CERT_MANAGER_NAMESPACE" ]] && [[ "$CUSTOMIZED_CM_NAMESPACE" -eq 1 ]]; then - error "An ibm-cert-manager-operator already installed in namespace: $webhook_ns, please do not set parameter '-cmNs $CERT_MANAGER_NAMESPACE" + # IBM cert-manager upgrade logic + info "Upgrading ibm-cert-manager-operator to channel: $CHANNEL" + + if [[ "$cm_namespace" != "$CERT_MANAGER_NAMESPACE" ]] && [[ "$CUSTOMIZED_CM_NAMESPACE" -eq 1 ]];; then + error "An ibm-cert-manager-operator is already installed in namespace: $cm_namespace; do not set -cmNs $CERT_MANAGER_NAMESPACE" fi - CERT_MANAGER_NAMESPACE="$webhook_ns" + + CERT_MANAGER_NAMESPACE="$cm_namespace" + if [[ $ENABLE_PRIVATE_CATALOG -eq 1 ]]; then - CM_SOURCE_NS="$webhook_ns" + CM_SOURCE_NS="$cm_namespace" fi + else - warning "Cluster has a RedHat cert-manager or Helm cert-manager, skipping" - return 0 + # Smoke test failed + if [ "$webhook_count" -eq 1 ]; then + info "The existing cert-manager-webhook pod is not functional, proceeding with installation" + else + error "Multiple cert-manager-webhook pods found and all are functional; cannot proceed" + fi fi - else - info "There is no cert-manager-webhook pod running\n" fi - + # Validate the CatalogSource of IBM Cert Manager before proceeding with the installation or upgrade validate_operator_catalogsource ibm-cert-manager-operator $CERT_MANAGER_NAMESPACE $CERT_MANAGER_SOURCE $CM_SOURCE_NS $CHANNEL CERT_MANAGER_SOURCE CM_SOURCE_NS @@ -648,12 +707,16 @@ function verify_cert_manager(){ #check no duplicate webhook pod webhook_deployments=$(${OC} get deploy -A --no-headers --ignore-not-found | grep ${name} -c) - if [[ $webhook_deployments != "1" ]]; then - error "More than one cert-manager-webhook deployment exists on the cluster." + if [[ $webhook_deployments -gt 1 ]]; then + warning "More than one cert-manager-webhook deployment exists on the cluster. Checking cert-manager functionality." + local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1) + if cm_smoke_test "test-issuer" "test-certificate" "test-certificate-secret" $webhook_ns; then + info "Smoke test passed. Only one Cert Manager is managing the certificate in the cluster." + else + error "Smoke test failed. More than one Cert Manager is managing the certificate in the cluster." + fi fi - local webhook_ns=$("$OC" get deployments -A | grep cert-manager-webhook | cut -d ' ' -f1) - cm_smoke_test "test-issuer" "test-certificate" "test-certificate-secret" $webhook_ns success "Cert manager is ready." }