From f77305fbaf450c7a62a178569b29a3559ea2d63b Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Tue, 12 Aug 2025 01:07:57 +0530 Subject: [PATCH 1/6] Delete a labeled CertificateRequest and ensures it is recreated --- test/e2e/certman_operator_tests.go | 105 ++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 3 deletions(-) diff --git a/test/e2e/certman_operator_tests.go b/test/e2e/certman_operator_tests.go index 84fd048b..3a661361 100644 --- a/test/e2e/certman_operator_tests.go +++ b/test/e2e/certman_operator_tests.go @@ -13,15 +13,20 @@ import ( configv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1" "github.com/openshift/osde2e-common/pkg/clients/openshift" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/log" ) var _ = Describe("Certman Operator", Ordered, func() { var ( - k8s *openshift.Client - clientset *kubernetes.Clientset - secretName string + k8s *openshift.Client + clientset *kubernetes.Clientset + secretName string + dynamicClient dynamic.Interface + logger = log.Log ) const ( pollingDuration = 15 * time.Minute @@ -62,4 +67,98 @@ var _ = Describe("Certman Operator", Ordered, func() { return apiserver.Spec.ServingCerts.NamedCertificates[0].ServingCertificate.Name == secretName }, pollingDuration, 30*time.Second).Should(BeTrue(), "Certificate secret should be applied to apiserver object") }) + + It("Deletes a labeled CertificateRequest and ensures it is recreated with the same secret", func(ctx context.Context) { + crGVR := schema.GroupVersionResource{ + Group: "certman.managed.openshift.io", + Version: "v1alpha1", + Resource: "certificaterequests", + } + + log.Log.Info("STEP 1: Fetching existing CertificateRequest with owned=true label") + crList, err := dynamicClient.Resource(crGVR).Namespace(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: "certificaterequests.certman.managed.openshift.io", + }) + + if len(crList.Items) == 0 { + log.Log.Info("No labeled CertificateRequest found, skipping test") + Skip("SKIPPED: No labeled CertificateRequest found. This test only runs if a CR with 'owned=true' label is present.") + } + + originalCR := crList.Items[0] + originalCRName := originalCR.GetName() + originalCRUID := originalCR.GetUID() + initialIssuedCertCount := len(crList.Items) + + // Step 2: Delete the CertificateRequest + log.Log.Info("STEP 2: Deleting the original CertificateRequest") + err = dynamicClient.Resource(crGVR).Namespace(namespace).Delete(ctx, originalCRName, metav1.DeleteOptions{}) + Expect(err).ToNot(HaveOccurred(), "Failed to delete CertificateRequest") + + // Step 3: Handle deletion blocked by finalizer + Eventually(func(g Gomega) bool { + cr, err := dynamicClient.Resource(crGVR).Namespace(namespace).Get(ctx, originalCRName, metav1.GetOptions{}) + if err != nil { + log.Log.Info("CR appears to be deleted already", "name", originalCRName) + return true + } + if cr.GetDeletionTimestamp() == nil { + log.Log.Info("CR not marked for deletion yet", "name", cr.GetName()) + return false + } + + finalizers, found, err := unstructured.NestedStringSlice(cr.Object, "metadata", "finalizers") + if err != nil { + log.Log.Error(err, "Error retrieving finalizers") + return false + } + if !found || len(finalizers) == 0 { + log.Log.Info("No finalizers present", "name", cr.GetName()) + return false + } + + crCopy := cr.DeepCopy() + _ = unstructured.SetNestedStringSlice(crCopy.Object, []string{}, "metadata", "finalizers") + + _, err = dynamicClient.Resource(crGVR).Namespace(namespace).Update(ctx, crCopy, metav1.UpdateOptions{}) + if err != nil { + log.Log.Error(err, "Failed to remove finalizer") + return false + } + return true + }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "Finalizer should be removed") + + // Step 4: Wait for new CertificateRequest with new UID + var newCRName string + Eventually(func(g Gomega) bool { + newList, err := dynamicClient.Resource(crGVR).Namespace(namespace).List(ctx, metav1.ListOptions{}) + if err != nil { + log.Log.Error(err, "Failed to list new CertificateRequests") + return false + } + if len(newList.Items) == 0 { + log.Log.Info("Still waiting for new CertificateRequest (none found)") + return false + } + + newCount := len(newList.Items) + logger.Info("CertificateRequest count after reconciliation", "count", newCount) + if newCount != initialIssuedCertCount { + logger.Info("CertificateRequest count mismatch", "expected", initialIssuedCertCount, "got", newCount) + return false + } + + for _, cr := range newList.Items { + log.Log.Info("Found CR candidate", "name", cr.GetName(), "uid", cr.GetUID()) + if cr.GetUID() != originalCRUID { + newCRName = cr.GetName() + log.Log.Info("New CertificateRequest detected", "name", newCRName, "uid", cr.GetUID()) + return true + } + } + return false + }, 4*time.Minute, 10*time.Second).Should(BeTrue(), "New CertificateRequest should appear") + + log.Log.Info("✅ Test completed: Secret successfully recreated with new CertificateRequest", "secret", secretName) + }) }) From 9f1aadef4af9d394dfebd99da72416142dd6d318 Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Tue, 12 Aug 2025 10:38:23 +0530 Subject: [PATCH 2/6] Test lable changed --- test/e2e/certman_operator_tests.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/certman_operator_tests.go b/test/e2e/certman_operator_tests.go index 3a661361..9d517f21 100644 --- a/test/e2e/certman_operator_tests.go +++ b/test/e2e/certman_operator_tests.go @@ -68,7 +68,7 @@ var _ = Describe("Certman Operator", Ordered, func() { }, pollingDuration, 30*time.Second).Should(BeTrue(), "Certificate secret should be applied to apiserver object") }) - It("Deletes a labeled CertificateRequest and ensures it is recreated with the same secret", func(ctx context.Context) { + It("Delete a labeled CertificateRequest and ensures it is recreated", func(ctx context.Context) { crGVR := schema.GroupVersionResource{ Group: "certman.managed.openshift.io", Version: "v1alpha1", From 7cabfdd3ad0862ca27cd4c0d9dede62732741c74 Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Tue, 18 Nov 2025 11:18:45 +0530 Subject: [PATCH 3/6] ran make boilerplate-update for ci validate check --- boilerplate/_data/last-boilerplate-commit | 2 +- build/Dockerfile | 2 +- build/Dockerfile.olm-registry | 2 +- test/e2e/certman_operator_tests.go | 22 ++++++++++++---------- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/boilerplate/_data/last-boilerplate-commit b/boilerplate/_data/last-boilerplate-commit index 7ec73064..43916fa4 100644 --- a/boilerplate/_data/last-boilerplate-commit +++ b/boilerplate/_data/last-boilerplate-commit @@ -1 +1 @@ -98ddf9fb577ca36d7cfea7484fcdccf2cc52532a +6c37c92165ab2c46308a1c6a5b11d3cffd8a373d diff --git a/build/Dockerfile b/build/Dockerfile index df6fda19..99e9ebe5 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,7 +8,7 @@ COPY . . RUN make go-build #### -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1762956380 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1763362218 ENV USER_UID=1001 \ USER_NAME=certman-operator diff --git a/build/Dockerfile.olm-registry b/build/Dockerfile.olm-registry index bf933d8d..9979b51f 100644 --- a/build/Dockerfile.olm-registry +++ b/build/Dockerfile.olm-registry @@ -4,7 +4,7 @@ COPY ${SAAS_OPERATOR_DIR} manifests RUN initializer --permissive # ubi-micro does not work for clusters with fips enabled unless we make OpenSSL available -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1762956380 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1763362218 COPY --from=builder /bin/registry-server /bin/registry-server COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe diff --git a/test/e2e/certman_operator_tests.go b/test/e2e/certman_operator_tests.go index 4bf87ab9..1c1296ed 100644 --- a/test/e2e/certman_operator_tests.go +++ b/test/e2e/certman_operator_tests.go @@ -19,7 +19,9 @@ import ( "github.com/openshift/osde2e-common/pkg/clients/openshift" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" @@ -30,9 +32,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log" ) - var scheme = runtime.NewScheme() - var awsSecretBackup *corev1.Secret - var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { +var scheme = runtime.NewScheme() +var awsSecretBackup *corev1.Secret +var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() { var ( logger = log.Log k8s *openshift.Client @@ -284,7 +286,7 @@ import ( logger.Info("Cleanup: AfterAll cleanup completed") }) - It("Delete a labeled CertificateRequest and ensures it is recreated", func(ctx context.Context) { + ginkgo.It("Delete a labeled CertificateRequest and ensures it is recreated", func(ctx context.Context) { crGVR := schema.GroupVersionResource{ Group: "certman.managed.openshift.io", Version: "v1alpha1", @@ -298,7 +300,7 @@ import ( if len(crList.Items) == 0 { log.Log.Info("No labeled CertificateRequest found, skipping test") - Skip("SKIPPED: No labeled CertificateRequest found. This test only runs if a CR with 'owned=true' label is present.") + ginkgo.Skip("SKIPPED: No labeled CertificateRequest found. This test only runs if a CR with 'owned=true' label is present.") } originalCR := crList.Items[0] @@ -309,10 +311,10 @@ import ( // Step 2: Delete the CertificateRequest log.Log.Info("STEP 2: Deleting the original CertificateRequest") err = dynamicClient.Resource(crGVR).Namespace(namespace).Delete(ctx, originalCRName, metav1.DeleteOptions{}) - Expect(err).ToNot(HaveOccurred(), "Failed to delete CertificateRequest") + gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Failed to delete CertificateRequest") // Step 3: Handle deletion blocked by finalizer - Eventually(func(g Gomega) bool { + gomega.Eventually(func() bool { cr, err := dynamicClient.Resource(crGVR).Namespace(namespace).Get(ctx, originalCRName, metav1.GetOptions{}) if err != nil { log.Log.Info("CR appears to be deleted already", "name", originalCRName) @@ -342,11 +344,11 @@ import ( return false } return true - }, 1*time.Minute, 5*time.Second).Should(BeTrue(), "Finalizer should be removed") + }, 1*time.Minute, 5*time.Second).Should(gomega.BeTrue(), "Finalizer should be removed") // Step 4: Wait for new CertificateRequest with new UID var newCRName string - Eventually(func(g Gomega) bool { + gomega.Eventually(func() bool { newList, err := dynamicClient.Resource(crGVR).Namespace(namespace).List(ctx, metav1.ListOptions{}) if err != nil { log.Log.Error(err, "Failed to list new CertificateRequests") @@ -373,7 +375,7 @@ import ( } } return false - }, 4*time.Minute, 10*time.Second).Should(BeTrue(), "New CertificateRequest should appear") + }, 4*time.Minute, 10*time.Second).Should(gomega.BeTrue(), "New CertificateRequest should appear") log.Log.Info("✅ Test completed: Secret successfully recreated with new CertificateRequest", "secret", secretName) }) From 4fd5fa22c8f417e6c690e91d54fa47191ceac2d6 Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Tue, 2 Dec 2025 12:41:04 +0530 Subject: [PATCH 4/6] ran make boilerplate-update for ci validate check --- boilerplate/_data/last-boilerplate-commit | 2 +- boilerplate/openshift/golang-osd-e2e/e2e-template.yml | 9 ++++++++- build/Dockerfile | 2 +- build/Dockerfile.olm-registry | 2 +- test/e2e/e2e-template.yml | 9 ++++++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/boilerplate/_data/last-boilerplate-commit b/boilerplate/_data/last-boilerplate-commit index 43916fa4..6e82eb3a 100644 --- a/boilerplate/_data/last-boilerplate-commit +++ b/boilerplate/_data/last-boilerplate-commit @@ -1 +1 @@ -6c37c92165ab2c46308a1c6a5b11d3cffd8a373d +033d1698ffc3ba694d2ed53290d4af63d34e2521 diff --git a/boilerplate/openshift/golang-osd-e2e/e2e-template.yml b/boilerplate/openshift/golang-osd-e2e/e2e-template.yml index e41b3d51..e55944d1 100644 --- a/boilerplate/openshift/golang-osd-e2e/e2e-template.yml +++ b/boilerplate/openshift/golang-osd-e2e/e2e-template.yml @@ -56,6 +56,13 @@ objects: - --skip-must-gather - --configs - ${OSDE2E_CONFIGS} + resources: + requests: + cpu: "300m" + memory: "600Mi" + limits: + cpu: "1" + memory: "1200Mi" securityContext: runAsNonRoot: true allowPrivilegeEscalation: false @@ -85,4 +92,4 @@ objects: - name: USE_EXISTING_CLUSTER value: ${USE_EXISTING_CLUSTER} - name: CAD_PAGERDUTY_ROUTING_KEY - value: ${CAD_PAGERDUTY_ROUTING_KEY} + value: ${CAD_PAGERDUTY_ROUTING_KEY} diff --git a/build/Dockerfile b/build/Dockerfile index 99e9ebe5..0698ee66 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -8,7 +8,7 @@ COPY . . RUN make go-build #### -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1763362218 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1764578379 ENV USER_UID=1001 \ USER_NAME=certman-operator diff --git a/build/Dockerfile.olm-registry b/build/Dockerfile.olm-registry index 9979b51f..9742565e 100644 --- a/build/Dockerfile.olm-registry +++ b/build/Dockerfile.olm-registry @@ -4,7 +4,7 @@ COPY ${SAAS_OPERATOR_DIR} manifests RUN initializer --permissive # ubi-micro does not work for clusters with fips enabled unless we make OpenSSL available -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1763362218 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7-1764578379 COPY --from=builder /bin/registry-server /bin/registry-server COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe diff --git a/test/e2e/e2e-template.yml b/test/e2e/e2e-template.yml index 7cd9323e..d653f5f4 100644 --- a/test/e2e/e2e-template.yml +++ b/test/e2e/e2e-template.yml @@ -56,6 +56,13 @@ objects: - --skip-must-gather - --configs - ${OSDE2E_CONFIGS} + resources: + requests: + cpu: "300m" + memory: "600Mi" + limits: + cpu: "1" + memory: "1200Mi" securityContext: runAsNonRoot: true allowPrivilegeEscalation: false @@ -85,4 +92,4 @@ objects: - name: USE_EXISTING_CLUSTER value: ${USE_EXISTING_CLUSTER} - name: CAD_PAGERDUTY_ROUTING_KEY - value: ${CAD_PAGERDUTY_ROUTING_KEY} + value: ${CAD_PAGERDUTY_ROUTING_KEY} From e7d7eb573335ec4892771e9fc6ed1bb7d4aca7a1 Mon Sep 17 00:00:00 2001 From: Karanjit Singh Date: Mon, 2 Feb 2026 17:24:25 +0530 Subject: [PATCH 5/6] updated review comments --- test/e2e/certman_operator_tests.go | 184 ++++++++++++++--------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/test/e2e/certman_operator_tests.go b/test/e2e/certman_operator_tests.go index 7f1b3b74..28840d2b 100644 --- a/test/e2e/certman_operator_tests.go +++ b/test/e2e/certman_operator_tests.go @@ -529,7 +529,7 @@ var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFai gomega.Expect(certRequestsCount).To(gomega.Equal(1), "Should have exactly 1 certificate request") - ginkgo.GinkgoLogr.Info("✅ Metrics verification successful", + ginkgo.GinkgoLogr.Info(" Metrics verification successful", "certificateRequestsCount", certRequestsCount) }) @@ -812,109 +812,35 @@ var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFai }, pollingDuration, 30*time.Second).Should(gomega.BeTrue(), "ClusterDeployment should be automatically added as owner of CertificateRequest by operator") }) - ginkgo.AfterAll(func(ctx context.Context) { - - logger.Info("Cleanup: Running AfterAll cleanup") - - cfg := k8s.GetConfig() - - // Create fresh clients for cleanup - apiExtClient, err := apiextensionsclient.NewForConfig(cfg) - if err != nil { - logger.Info("Failed to create API Extensions client, skipping cleanup", "error", err) - return - } - - kubeClient, err := kubernetes.NewForConfig(cfg) - if err != nil { - logger.Info("Failed to create Kubernetes client, skipping cleanup", "error", err) - return - } - - cleanupDynamicClient, err := dynamic.NewForConfig(cfg) - if err != nil { - logger.Info("Failed to create dynamic client, skipping cleanup", "error", err) - return - } - - // Create RESTMapper for resource cleanup - dc, err := discovery.NewDiscoveryClientForConfig(cfg) - if err != nil { - logger.Info("Failed to create discovery client, skipping Certman cleanup", "error", err) - } else { - gr, err := restmapper.GetAPIGroupResources(dc) - if err != nil { - logger.Info("Failed to get API group resources, skipping Certman cleanup", "error", err) - } else { - mapper := restmapper.NewDiscoveryRESTMapper(gr) - - // Cleanup Certman with RESTMapper - if err := utils.CleanupCertman(ctx, kubeClient, apiExtClient, cleanupDynamicClient, mapper); err != nil { - logger.Info("Error during Certman cleanup", "error", err) - } - } - } + ginkgo.It("Delete a CertificateRequest and ensures it is recreated", func(ctx context.Context) { - if err := utils.CleanupHive(ctx, apiExtClient); err != nil { - logger.Info("Error during Hive cleanup", "error", err) - } - - if err := utils.CleanupAWSCreds(ctx, kubeClient); err != nil { - logger.Info("Error during AWS secret cleanup", "error", err) - } else { - logger.Info("AWS secret cleanup succeeded") - } - - if err := utils.CleanupLetsEncryptAccountSecret(ctx, kubeClient); err != nil { - logger.Info("Error during Let's Encrypt account secret cleanup", "error", err) - } else { - logger.Info("Let's Encrypt account secret cleanup succeeded") - } - - logger.Info("Cleaning up all test resources") - - // Cleanup all test resources (ClusterDeployment, CertificateRequests, secrets) - utils.CleanupAllTestResources(ctx, kubeClient, cleanupDynamicClient, certConfig, clusterDeploymentName, adminKubeconfigSecretName, ocmClusterID) - - logger.Info("Cleaning up certman-operator resources") - - if err := utils.CleanupCertmanResources(ctx, cleanupDynamicClient, operatorNS); err != nil { - logger.Error(err, "Error during certman-operator resources cleanup") - } - - logger.Info("Cleanup: AfterAll cleanup completed") - }) - - ginkgo.It("Delete a labeled CertificateRequest and ensures it is recreated", func(ctx context.Context) { crGVR := schema.GroupVersionResource{ Group: "certman.managed.openshift.io", Version: "v1alpha1", Resource: "certificaterequests", } - log.Log.Info("STEP 1: Fetching existing CertificateRequest with owned=true label") - crList, err := dynamicClient.Resource(crGVR).Namespace(namespace).List(ctx, metav1.ListOptions{ - LabelSelector: "certificaterequests.certman.managed.openshift.io", - }) - - if len(crList.Items) == 0 { - log.Log.Info("No labeled CertificateRequest found, skipping test") - ginkgo.Skip("SKIPPED: No labeled CertificateRequest found. This test only runs if a CR with 'owned=true' label is present.") + log.Log.Info("STEP 1: Fetching CertificateRequest owned by our ClusterDeployment", "clusterDeployment", clusterDeploymentName, "namespace", certConfig.TestNamespace) + originalCR, err := utils.FindCertificateRequestForClusterDeployment(ctx, dynamicClient, crGVR, certConfig.TestNamespace, clusterDeploymentName) + if err != nil { + log.Log.Info("No CertificateRequest found for our ClusterDeployment, skipping test", "error", err) + ginkgo.Skip("SKIPPED: No CertificateRequest found for ClusterDeployment. This test runs after \"should create ClusterDeployment and CertificateRequest\" and requires that CR to exist.") } - originalCR := crList.Items[0] originalCRName := originalCR.GetName() originalCRUID := originalCR.GetUID() + crList, err := dynamicClient.Resource(crGVR).Namespace(certConfig.TestNamespace).List(ctx, metav1.ListOptions{}) + gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Failed to list CertificateRequests for count") initialIssuedCertCount := len(crList.Items) - // Step 2: Delete the CertificateRequest - log.Log.Info("STEP 2: Deleting the original CertificateRequest") - err = dynamicClient.Resource(crGVR).Namespace(namespace).Delete(ctx, originalCRName, metav1.DeleteOptions{}) + // Step 2: Delete the CertificateRequest owned by our ClusterDeployment + log.Log.Info("STEP 2: Deleting the CertificateRequest owned by our ClusterDeployment", "name", originalCRName) + err = dynamicClient.Resource(crGVR).Namespace(certConfig.TestNamespace).Delete(ctx, originalCRName, metav1.DeleteOptions{}) gomega.Expect(err).ToNot(gomega.HaveOccurred(), "Failed to delete CertificateRequest") // Step 3: Handle deletion blocked by finalizer gomega.Eventually(func() bool { - cr, err := dynamicClient.Resource(crGVR).Namespace(namespace).Get(ctx, originalCRName, metav1.GetOptions{}) + cr, err := dynamicClient.Resource(crGVR).Namespace(certConfig.TestNamespace).Get(ctx, originalCRName, metav1.GetOptions{}) if err != nil { log.Log.Info("CR appears to be deleted already", "name", originalCRName) return true @@ -937,7 +863,7 @@ var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFai crCopy := cr.DeepCopy() _ = unstructured.SetNestedStringSlice(crCopy.Object, []string{}, "metadata", "finalizers") - _, err = dynamicClient.Resource(crGVR).Namespace(namespace).Update(ctx, crCopy, metav1.UpdateOptions{}) + _, err = dynamicClient.Resource(crGVR).Namespace(certConfig.TestNamespace).Update(ctx, crCopy, metav1.UpdateOptions{}) if err != nil { log.Log.Error(err, "Failed to remove finalizer") return false @@ -945,10 +871,10 @@ var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFai return true }, 1*time.Minute, 5*time.Second).Should(gomega.BeTrue(), "Finalizer should be removed") - // Step 4: Wait for new CertificateRequest with new UID + // Step 4: Wait for new CertificateRequest with new UID (operator recreates it for our ClusterDeployment) var newCRName string gomega.Eventually(func() bool { - newList, err := dynamicClient.Resource(crGVR).Namespace(namespace).List(ctx, metav1.ListOptions{}) + newList, err := dynamicClient.Resource(crGVR).Namespace(certConfig.TestNamespace).List(ctx, metav1.ListOptions{}) if err != nil { log.Log.Error(err, "Failed to list new CertificateRequests") return false @@ -974,9 +900,83 @@ var _ = ginkgo.Describe("Certman Operator", ginkgo.Ordered, ginkgo.ContinueOnFai } } return false - }, 4*time.Minute, 10*time.Second).Should(gomega.BeTrue(), "New CertificateRequest should appear") + }, 2*time.Minute, 10*time.Second).Should(gomega.BeTrue(), "New CertificateRequest should appear") - log.Log.Info("✅ Test completed: Secret successfully recreated with new CertificateRequest", "secret", secretName) + secretNameFromCR, _ := utils.GetCertificateSecretNameFromCR(originalCR) + log.Log.Info("Test completed: CertificateRequest recreated by operator", "newCR", newCRName, "certificateSecret", secretNameFromCR) + }) + + ginkgo.AfterAll(func(ctx context.Context) { + + logger.Info("Cleanup: Running AfterAll cleanup") + + cfg := k8s.GetConfig() + + // Create fresh clients for cleanup + apiExtClient, err := apiextensionsclient.NewForConfig(cfg) + if err != nil { + logger.Info("Failed to create API Extensions client, skipping cleanup", "error", err) + return + } + + kubeClient, err := kubernetes.NewForConfig(cfg) + if err != nil { + logger.Info("Failed to create Kubernetes client, skipping cleanup", "error", err) + return + } + + cleanupDynamicClient, err := dynamic.NewForConfig(cfg) + if err != nil { + logger.Info("Failed to create dynamic client, skipping cleanup", "error", err) + return + } + + // Create RESTMapper for resource cleanup + dc, err := discovery.NewDiscoveryClientForConfig(cfg) + if err != nil { + logger.Info("Failed to create discovery client, skipping Certman cleanup", "error", err) + } else { + gr, err := restmapper.GetAPIGroupResources(dc) + if err != nil { + logger.Info("Failed to get API group resources, skipping Certman cleanup", "error", err) + } else { + mapper := restmapper.NewDiscoveryRESTMapper(gr) + + // Cleanup Certman with RESTMapper + if err := utils.CleanupCertman(ctx, kubeClient, apiExtClient, cleanupDynamicClient, mapper); err != nil { + logger.Info("Error during Certman cleanup", "error", err) + } + } + } + + if err := utils.CleanupHive(ctx, apiExtClient); err != nil { + logger.Info("Error during Hive cleanup", "error", err) + } + + if err := utils.CleanupAWSCreds(ctx, kubeClient); err != nil { + logger.Info("Error during AWS secret cleanup", "error", err) + } else { + logger.Info("AWS secret cleanup succeeded") + } + + if err := utils.CleanupLetsEncryptAccountSecret(ctx, kubeClient); err != nil { + logger.Info("Error during Let's Encrypt account secret cleanup", "error", err) + } else { + logger.Info("Let's Encrypt account secret cleanup succeeded") + } + + logger.Info("Cleaning up all test resources") + + // Cleanup all test resources (ClusterDeployment, CertificateRequests, secrets) + utils.CleanupAllTestResources(ctx, kubeClient, cleanupDynamicClient, certConfig, clusterDeploymentName, adminKubeconfigSecretName, ocmClusterID) + + logger.Info("Cleaning up certman-operator resources") + + if err := utils.CleanupCertmanResources(ctx, cleanupDynamicClient, operatorNS); err != nil { + logger.Error(err, "Error during certman-operator resources cleanup") + } + + logger.Info("Cleanup: AfterAll cleanup completed") }) }) From 3bdf0673f71c8709ec6ec292e24954004bd35131 Mon Sep 17 00:00:00 2001 From: Karanjit Singh Date: Wed, 4 Feb 2026 11:49:09 +0530 Subject: [PATCH 6/6] boilerplate-update --- boilerplate/_data/last-boilerplate-commit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boilerplate/_data/last-boilerplate-commit b/boilerplate/_data/last-boilerplate-commit index 01f9820c..65923da3 100644 --- a/boilerplate/_data/last-boilerplate-commit +++ b/boilerplate/_data/last-boilerplate-commit @@ -1 +1 @@ -03d10f359a4a9d3b38c4f5e1494f771ef603fc3f +8ca4e1dfcab3443c52acf52b3912b6cf1c5f79a4