diff --git a/e2e/util/context.go b/e2e/util/context.go index 924fa3b72..ec880fc41 100644 --- a/e2e/util/context.go +++ b/e2e/util/context.go @@ -9,7 +9,6 @@ import ( "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "k8s.io/kubectl/pkg/scheme" "sigs.k8s.io/controller-runtime/pkg/client" @@ -28,7 +27,6 @@ import ( var ConfigFile string type Cluster struct { - K8sClientSet *kubernetes.Clientset CtrlClient client.Client } @@ -65,38 +63,33 @@ func addToScheme(scheme *runtime.Scheme) error { return ramen.AddToScheme(scheme) } -func setupClient(kubeconfigPath string) (*kubernetes.Clientset, client.Client, error) { +func setupClient(kubeconfigPath string) (client.Client, error) { var err error if kubeconfigPath == "" { - return nil, nil, fmt.Errorf("kubeconfigPath is empty") + return nil, fmt.Errorf("kubeconfigPath is empty") } kubeconfigPath, err = filepath.Abs(kubeconfigPath) if err != nil { - return nil, nil, fmt.Errorf("unable to determine absolute path to file (%s): %w", kubeconfigPath, err) + return nil, fmt.Errorf("unable to determine absolute path to file (%s): %w", kubeconfigPath, err) } cfg, err := clientcmd.BuildConfigFromFlags("", kubeconfigPath) if err != nil { - return nil, nil, fmt.Errorf("failed to build config from kubeconfig (%s): %w", kubeconfigPath, err) - } - - k8sClientSet, err := kubernetes.NewForConfig(cfg) - if err != nil { - return nil, nil, fmt.Errorf("failed to build k8s client set from kubeconfig (%s): %w", kubeconfigPath, err) + return nil, fmt.Errorf("failed to build config from kubeconfig (%s): %w", kubeconfigPath, err) } if err := addToScheme(scheme.Scheme); err != nil { - return nil, nil, err + return nil, err } ctrlClient, err := client.New(cfg, client.Options{Scheme: scheme.Scheme}) if err != nil { - return nil, nil, fmt.Errorf("failed to build controller client from kubeconfig (%s): %w", kubeconfigPath, err) + return nil, fmt.Errorf("failed to build controller client from kubeconfig (%s): %w", kubeconfigPath, err) } - return k8sClientSet, ctrlClient, nil + return ctrlClient, nil } func NewContext(log logr.Logger, configFile string) (*Context, error) { @@ -109,17 +102,17 @@ func NewContext(log logr.Logger, configFile string) (*Context, error) { panic(err) } - ctx.Hub.K8sClientSet, ctx.Hub.CtrlClient, err = setupClient(config.Clusters["hub"].KubeconfigPath) + ctx.Hub.CtrlClient, err = setupClient(config.Clusters["hub"].KubeconfigPath) if err != nil { return nil, fmt.Errorf("failed to create clients for hub cluster: %w", err) } - ctx.C1.K8sClientSet, ctx.C1.CtrlClient, err = setupClient(config.Clusters["c1"].KubeconfigPath) + ctx.C1.CtrlClient, err = setupClient(config.Clusters["c1"].KubeconfigPath) if err != nil { return nil, fmt.Errorf("failed to create clients for c1 cluster: %w", err) } - ctx.C2.K8sClientSet, ctx.C2.CtrlClient, err = setupClient(config.Clusters["c2"].KubeconfigPath) + ctx.C2.CtrlClient, err = setupClient(config.Clusters["c2"].KubeconfigPath) if err != nil { return nil, fmt.Errorf("failed to create clients for c2 cluster: %w", err) } diff --git a/e2e/util/validation.go b/e2e/util/validation.go index 5cec6e902..fba1feb88 100644 --- a/e2e/util/validation.go +++ b/e2e/util/validation.go @@ -9,11 +9,14 @@ import ( "strings" v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/client" ) -func ValidateRamenHubOperator(k8sClient *kubernetes.Clientset) error { +func ValidateRamenHubOperator(k8sClient client.Client) error { labelSelector := "app=ramen-hub" podIdentifier := "ramen-hub-operator" @@ -37,7 +40,7 @@ func ValidateRamenHubOperator(k8sClient *kubernetes.Clientset) error { return nil } -func ValidateRamenDRClusterOperator(k8sClient *kubernetes.Clientset, clusterName string) error { +func ValidateRamenDRClusterOperator(k8sClient client.Client, clusterName string) error { labelSelector := "app=ramen-dr-cluster" podIdentifier := "ramen-dr-cluster-operator" @@ -61,7 +64,7 @@ func ValidateRamenDRClusterOperator(k8sClient *kubernetes.Clientset, clusterName return nil } -func GetRamenNameSpace(k8sClient *kubernetes.Clientset) (string, error) { +func GetRamenNameSpace(k8sClient client.Client) (string, error) { isOpenShift, err := IsOpenShiftCluster(k8sClient) if err != nil { return "", err @@ -76,30 +79,48 @@ func GetRamenNameSpace(k8sClient *kubernetes.Clientset) (string, error) { // IsOpenShiftCluster checks if the given Kubernetes cluster is an OpenShift cluster. // It returns true if the cluster is OpenShift, false otherwise, along with any error encountered. -func IsOpenShiftCluster(k8sClient *kubernetes.Clientset) (bool, error) { - discoveryClient := k8sClient.Discovery() +func IsOpenShiftCluster(k8sClient client.Client) (bool, error) { + configList := &unstructured.Unstructured{} + configList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: "config.openshift.io", + Version: "v1", + Kind: "ClusterVersion", + }) - apiGroups, err := discoveryClient.ServerGroups() - if err != nil { - return false, err + err := k8sClient.List(context.TODO(), configList) + if err == nil { + // found OpenShift only resource type, it is OpenShift + return true, nil } - for _, group := range apiGroups.Groups { - if group.Name == "route.openshift.io" { - return true, nil - } + if meta.IsNoMatchError(err) { + // api server says no match for OpenShift only resource type, + // it is not OpenShift + return false, nil } - return false, nil + // unexpected error + return false, err } // FindPod returns the first pod matching the label selector including the pod identifier in the namespace. -func FindPod(client *kubernetes.Clientset, namespace, labelSelector, podIdentifier string) ( +func FindPod(k8sClient client.Client, namespace, labelSelector, podIdentifier string) ( *v1.Pod, error, ) { - pods, err := client.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{ - LabelSelector: labelSelector, - }) + ls, err := labels.Parse(labelSelector) + if err != nil { + return nil, fmt.Errorf("failed to parse label selector %q: %v", labelSelector, err) + } + + pods := &v1.PodList{} + listOptions := []client.ListOption{ + client.InNamespace(namespace), + client.MatchingLabelsSelector{ + Selector: ls, + }, + } + + err = k8sClient.List(context.Background(), pods, listOptions...) if err != nil { return nil, fmt.Errorf("failed to list pods in namespace %s: %v", namespace, err) } diff --git a/e2e/validation_suite_test.go b/e2e/validation_suite_test.go index a024aa021..b833c7e72 100644 --- a/e2e/validation_suite_test.go +++ b/e2e/validation_suite_test.go @@ -12,19 +12,19 @@ import ( func Validate(t *testing.T) { t.Helper() t.Run("hub", func(t *testing.T) { - err := util.ValidateRamenHubOperator(util.Ctx.Hub.K8sClientSet) + err := util.ValidateRamenHubOperator(util.Ctx.Hub.CtrlClient) if err != nil { t.Fatal(err) } }) t.Run("c1", func(t *testing.T) { - err := util.ValidateRamenDRClusterOperator(util.Ctx.C1.K8sClientSet, "c1") + err := util.ValidateRamenDRClusterOperator(util.Ctx.C1.CtrlClient, "c1") if err != nil { t.Fatal(err) } }) t.Run("c2", func(t *testing.T) { - err := util.ValidateRamenDRClusterOperator(util.Ctx.C2.K8sClientSet, "c2") + err := util.ValidateRamenDRClusterOperator(util.Ctx.C2.CtrlClient, "c2") if err != nil { t.Fatal(err) }