diff --git a/.openshift-tests-extension/openshift_payload_cluster-version-operator.json b/.openshift-tests-extension/openshift_payload_cluster-version-operator.json index 64960e141..e645a7a50 100644 --- a/.openshift-tests-extension/openshift_payload_cluster-version-operator.json +++ b/.openshift-tests-extension/openshift_payload_cluster-version-operator.json @@ -8,5 +8,15 @@ "source": "openshift:payload:cluster-version-operator", "lifecycle": "blocking", "environmentSelector": {} + }, + { + "name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator-tests with cluster access should have correct runlevel and scc", + "labels": {}, + "resources": { + "isolation": {} + }, + "source": "openshift:payload:cluster-version-operator", + "lifecycle": "blocking", + "environmentSelector": {} } ] \ No newline at end of file diff --git a/test/cvo/cvo.go b/test/cvo/cvo.go index 124f13e81..5bf3f3e1c 100644 --- a/test/cvo/cvo.go +++ b/test/cvo/cvo.go @@ -1,6 +1,14 @@ package cvo import ( + "context" + + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) @@ -9,4 +17,57 @@ var _ = Describe(`[Jira:"Cluster Version Operator"] cluster-version-operator-tes It("should support passing tests", func() { Expect(true).To(BeTrue()) }) + + Context("with cluster access", func() { + const cvoNamespace = "openshift-cluster-version" + var ( + restCfg *rest.Config + kubeClient kubernetes.Interface + ) + + BeforeEach(func() { + var err error + + // Respects KUBECONFIG env var + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + cfg := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{}) + restCfg, err = cfg.ClientConfig() + Expect(err).NotTo(HaveOccurred(), "Failed to load Kubernetes configuration. Please ensure KUBECONFIG environment variable is set.") + + kubeClient, err = kubernetes.NewForConfig(restCfg) + Expect(err).NotTo(HaveOccurred(), "Failed to create Kubernetes client") + }) + + // Migrated from case NonHyperShiftHOST-Author:jiajliu-Low-46922-check runlevel and scc in cvo ns + // Refer to https://github.com/openshift/openshift-tests-private/blob/master/test/extended/ota/cvo/cvo.go#L1081 + It("should have correct runlevel and scc", func() { + ctx := context.Background() + + // Skip the test on HyperShift since CVO runs in management cluster instead of hosted cluster + _, err := kubeClient.AppsV1().Deployments(cvoNamespace).Get(ctx, "cluster-version-operator", metav1.GetOptions{}) + if errors.IsNotFound(err) { + Skip("Skipping test: CVO deployment not found in hypershift hosted cluster!") + } + Expect(err).NotTo(HaveOccurred(), "Failed to get CVO deployment") + + By("Check runlevel in cvo namespace.") + ns, err := kubeClient.CoreV1().Namespaces().Get(ctx, cvoNamespace, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred(), "Failed to get namespace %s", cvoNamespace) + + runLevel := ns.ObjectMeta.Labels["openshift.io/run-level"] + Expect(runLevel).To(Equal(""), "Expected 'openshift.io/run-level' label to be empty, but got %s", runLevel) + + By("Check scc of cvo pod.") + podList, err := kubeClient.CoreV1().Pods(cvoNamespace).List(ctx, metav1.ListOptions{ + LabelSelector: "k8s-app=cluster-version-operator", + FieldSelector: "status.phase=Running", + }) + Expect(err).NotTo(HaveOccurred(), "Failed to list running CVO pods") + Expect(podList.Items).To(HaveLen(1), "Expected exactly one running CVO pod, but found: %d", len(podList.Items)) + + cvoPod := podList.Items[0] + sccAnnotation := cvoPod.ObjectMeta.Annotations["openshift.io/scc"] + Expect(sccAnnotation).To(Equal("hostaccess"), "Expected SCC for pod %s to be 'hostaccess', but got %s", cvoPod.Name, sccAnnotation) + }) + }) })