From a5ff0f94cfb3306f3dc5c0cabe07e9650294077c Mon Sep 17 00:00:00 2001 From: Danil Grigorev Date: Wed, 20 Sep 2023 09:11:40 +0200 Subject: [PATCH] Use separate cluster setup for rancher - Add tests for 2 cluster CAPI import setup Signed-off-by: Danil Grigorev --- Makefile | 4 +- .../controllers/cross_cluster_import_test.go | 163 ++++++++++++++++++ internal/controllers/import_controller.go | 16 +- .../controllers/import_controller_test.go | 17 +- internal/controllers/suite_test.go | 1 + internal/rancher/doc.go | 5 +- internal/rancher/setup/cluster.go | 80 +++++++++ internal/rancher/setup/doc.go | 18 ++ internal/test/envtest.go | 22 ++- main.go | 55 +----- util/predicates/suite_test.go | 4 +- 11 files changed, 316 insertions(+), 69 deletions(-) create mode 100644 internal/controllers/cross_cluster_import_test.go create mode 100644 internal/rancher/setup/cluster.go create mode 100644 internal/rancher/setup/doc.go diff --git a/Makefile b/Makefile index 48b8cd4c5..c8b7b9b64 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,6 @@ help: ## Display this help. .PHONY: manifests manifests: vendor controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. $(CONTROLLER_GEN) rbac:roleName=manager-role crd paths="./..." output:crd:artifacts:config=hack/crd/bases - $(CONTROLLER_GEN) rbac:roleName=manager-role crd paths="./vendor/sigs.k8s.io/cluster-api/..." output:crd:artifacts:config=hack/crd/bases # Vendor is only required for pulling latest CRDs from the dependencies $(MAKE) vendor-clean @@ -182,7 +181,6 @@ manifests: vendor controller-gen ## Generate WebhookConfiguration, ClusterRole a vendor: go mod tidy go mod vendor - go mod verify .PHONY: vendor-clean vendor-clean: @@ -235,7 +233,7 @@ ARTIFACTS ?= ${ROOT_DIR}/_artifacts KUBEBUILDER_ASSETS ?= $(shell $(SETUP_ENVTEST) use --use-env -p path $(KUBEBUILDER_ENVTEST_KUBERNETES_VERSION)) .PHONY: test -test: $(SETUP_ENVTEST) manifests ## Run tests. +test: $(SETUP_ENVTEST) manifests kubectl ## Run tests. KUBEBUILDER_ASSETS="$(KUBEBUILDER_ASSETS)" go test ./... $(TEST_ARGS) ##@ Build diff --git a/internal/controllers/cross_cluster_import_test.go b/internal/controllers/cross_cluster_import_test.go new file mode 100644 index 000000000..422991c6b --- /dev/null +++ b/internal/controllers/cross_cluster_import_test.go @@ -0,0 +1,163 @@ +/* +Copyright 2023 SUSE. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + provisioningv1 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/provisioning/v1" + "github.com/rancher-sandbox/rancher-turtles/internal/rancher/setup" + "github.com/rancher-sandbox/rancher-turtles/internal/test" + turtlesnaming "github.com/rancher-sandbox/rancher-turtles/util/naming" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/rest" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/util/kubeconfig" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/envtest" + + ctrl "sigs.k8s.io/controller-runtime" +) + +var ( + rancherEnv *envtest.Environment + otherEnv *envtest.Environment + rancherCfg *rest.Config + otherCfg *rest.Config + rancherCl client.Client + otherCl client.Client + clusterCtx context.Context + cancel context.CancelFunc + capiCluster *clusterv1.Cluster + rancherCluster *provisioningv1.Cluster + r *CAPIImportReconciler +) + +var _ = Describe("In separate clusters", func() { + + BeforeEach(func() { + By("bootstrapping rancher environment") + var err error + rancherEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{ + filepath.Join("..", "..", "hack", "crd", "bases"), + }, + ErrorIfCRDPathMissing: true, + Scheme: test.FullScheme, + } + rancherCfg, rancherCl, err = test.StartEnvTest(rancherEnv) + Expect(err).NotTo(HaveOccurred()) + Expect(rancherCfg).NotTo(BeNil()) + Expect(rancherCl).NotTo(BeNil()) + + By("Bootstrapping other cluster environment") + otherEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{ + filepath.Join("..", "..", "hack", "crd", "bases"), + }, + ErrorIfCRDPathMissing: true, + Scheme: test.FullScheme, + } + otherCfg, otherCl, err = test.StartEnvTest(otherEnv) + Expect(err).NotTo(HaveOccurred()) + Expect(otherCfg).NotTo(BeNil()) + Expect(otherCl).NotTo(BeNil()) + + Expect(otherCl.Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: testNamespace, + Labels: map[string]string{ + importLabelName: "true", + }, + }, + })).To(Succeed()) + + Expect(rancherCl.Create(ctx, &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: testNamespace, + }, + })).To(Succeed()) + + clusterCtx, cancel = context.WithCancel(ctx) + capiCluster = &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + Namespace: testNamespace, + }, + } + + rancherCluster = &provisioningv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), + Namespace: testNamespace, + }, + } + }) + + AfterEach(func() { + cancel() + By("tearing down the 2 clsuter environment") + Expect(test.StopEnvTest(rancherEnv)).To(Succeed()) + Expect(test.StopEnvTest(otherEnv)).To(Succeed()) + }) + + It("minimal controller setup should create a Rancher cluster object from a CAPI cluster object located in a different cluster", func() { + mgr, err := ctrl.NewManager(otherCfg, ctrl.Options{ + Scheme: otherEnv.Scheme, + MetricsBindAddress: "0", + HealthProbeBindAddress: "0", + }) + Expect(err).ToNot(HaveOccurred()) + + config := kubeconfig.FromEnvTestConfig(rancherCfg, &clusterv1.Cluster{ + ObjectMeta: metav1.ObjectMeta{Name: "test"}, + }) + kubeconfigFile, err := os.CreateTemp("", "kubeconfig") + Expect(err).ToNot(HaveOccurred()) + defer os.Remove(kubeconfigFile.Name()) + Expect(os.WriteFile(kubeconfigFile.Name(), config, 0600)).To(Succeed()) + + rancher, err := setup.SetupRancherCluster(mgr, kubeconfigFile.Name()) + Expect(err).ToNot(HaveOccurred()) + + reconciler := &CAPIImportReconciler{ + Client: mgr.GetClient(), + RancherCluster: rancher, + } + Expect(reconciler.SetupWithManager(ctx, mgr, controller.Options{})).To(Succeed()) + + go func() { + Expect(mgr.Start(clusterCtx)).To(Succeed()) + }() + + Expect(otherCl.Create(ctx, capiCluster)).To(Succeed()) + capiCluster.Status.ControlPlaneReady = true + Expect(otherCl.Status().Update(ctx, capiCluster)).To(Succeed()) + + args := []string{"get", fmt.Sprintf("clusters.%s", provisioningv1.GroupVersion.Group), rancherCluster.Name, "-n", rancherCluster.Namespace, "--kubeconfig", kubeconfigFile.Name()} + Eventually(exec.Command("kubectl", args...).Run()).Should(Succeed()) + }) + +}) diff --git a/internal/controllers/import_controller.go b/internal/controllers/import_controller.go index ec441481a..131163b14 100644 --- a/internal/controllers/import_controller.go +++ b/internal/controllers/import_controller.go @@ -35,6 +35,7 @@ import ( "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" @@ -64,8 +65,8 @@ const ( // CAPIImportReconciler represents a reconciler for importing CAPI clusters in Rancher. type CAPIImportReconciler struct { - Client client.Client - RancherClient client.Client + client.Client + RancherCluster cluster.Cluster recorder record.EventRecorder WatchFilterValue string Scheme *runtime.Scheme @@ -102,7 +103,7 @@ func (r *CAPIImportReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Ma // Watch Rancher provisioningv2 clusters // NOTE: we will import the types from rancher in the future err = c.Watch( - source.Kind(mgr.GetCache(), &provisioningv1.Cluster{}), + source.Kind(r.RancherCluster.GetCache(), &provisioningv1.Cluster{}), handler.EnqueueRequestsFromMapFunc(r.rancherClusterToCapiCluster(ctx, capiPredicates)), //&handler.EnqueueRequestForOwner{OwnerType: &clusterv1.Cluster{}}, ) @@ -196,7 +197,7 @@ func (r *CAPIImportReconciler) reconcile(ctx context.Context, capiCluster *clust Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), }} - err := r.RancherClient.Get(ctx, client.ObjectKeyFromObject(rancherCluster), rancherCluster) + err := r.RancherCluster.GetClient().Get(ctx, client.ObjectKeyFromObject(rancherCluster), rancherCluster) if client.IgnoreNotFound(err) != nil { log.Error(err, fmt.Sprintf("Unable to fetch rancher cluster %s", client.ObjectKeyFromObject(rancherCluster))) return ctrl.Result{Requeue: true}, err @@ -214,7 +215,7 @@ func (r *CAPIImportReconciler) reconcileNormal(ctx context.Context, capiCluster ) (ctrl.Result, error) { log := log.FromContext(ctx) - err := r.RancherClient.Get(ctx, client.ObjectKeyFromObject(rancherCluster), rancherCluster) + err := r.RancherCluster.GetClient().Get(ctx, client.ObjectKeyFromObject(rancherCluster), rancherCluster) if apierrors.IsNotFound(err) { shouldImport, err := util.ShouldAutoImport(ctx, log, r.Client, capiCluster, importLabelName) if err != nil { @@ -226,7 +227,7 @@ func (r *CAPIImportReconciler) reconcileNormal(ctx context.Context, capiCluster return ctrl.Result{}, nil } - if err := r.RancherClient.Create(ctx, &provisioningv1.Cluster{ + if err := r.RancherCluster.GetClient().Create(ctx, &provisioningv1.Cluster{ ObjectMeta: metav1.ObjectMeta{ Name: turtlesnaming.Name(capiCluster.Name).ToRancherName(), Namespace: capiCluster.Namespace, @@ -252,6 +253,7 @@ func (r *CAPIImportReconciler) reconcileNormal(ctx context.Context, capiCluster if rancherCluster.Status.ClusterName == "" { log.Info("cluster name not set yet, requeue") + log.Info(rancherCluster.Name) return ctrl.Result{Requeue: true}, nil } @@ -316,7 +318,7 @@ func (r *CAPIImportReconciler) getClusterRegistrationManifest(ctx context.Contex Name: clusterRegistrationTokenName, Namespace: clusterName, }} - err := r.RancherClient.Get(ctx, client.ObjectKeyFromObject(token), token) + err := r.RancherCluster.GetClient().Get(ctx, client.ObjectKeyFromObject(token), token) if client.IgnoreNotFound(err) != nil { return "", fmt.Errorf("error getting registration token for cluster %s: %w", clusterName, err) diff --git a/internal/controllers/import_controller_test.go b/internal/controllers/import_controller_test.go index 3e7bb4735..d4df7a649 100644 --- a/internal/controllers/import_controller_test.go +++ b/internal/controllers/import_controller_test.go @@ -18,6 +18,7 @@ package controllers import ( "bufio" + "context" "encoding/json" "errors" "fmt" @@ -43,6 +44,7 @@ import ( "sigs.k8s.io/cluster-api/controllers/remote" "sigs.k8s.io/cluster-api/util/secret" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/cluster" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) @@ -53,12 +55,24 @@ var _ = Describe("reconcile CAPI Cluster", func() { rancherCluster *provisioningv1.Cluster clusterRegistrationToken *managementv3.ClusterRegistrationToken capiKubeconfigSecret *corev1.Secret + cancel context.CancelFunc + clusterCtx context.Context ) BeforeEach(func() { + // rancher and rancher-turtles deployed in the same cluster + clusterCtx, cancel = context.WithCancel(ctx) + cluster, err := cluster.New(testEnv.Config, func(clusterOptions *cluster.Options) { + clusterOptions.Scheme = testEnv.Scheme + }) + Expect(err).ToNot(HaveOccurred()) + go func() { + Expect(cluster.Start(clusterCtx)).To(Succeed()) + }() + r = &CAPIImportReconciler{ Client: cl, - RancherClient: cl, // rancher and rancher-turtles deployed in the same cluster + RancherCluster: cluster, remoteClientGetter: remote.NewClusterClient, } @@ -95,6 +109,7 @@ var _ = Describe("reconcile CAPI Cluster", func() { }) AfterEach(func() { + defer cancel() objs, err := manifestToObjects(strings.NewReader(testdata.ImportManifest)) clientObjs := []client.Object{ capiCluster, diff --git a/internal/controllers/suite_test.go b/internal/controllers/suite_test.go index fa9d3d14f..e75fe8b7b 100644 --- a/internal/controllers/suite_test.go +++ b/internal/controllers/suite_test.go @@ -59,6 +59,7 @@ var _ = BeforeSuite(func() { filepath.Join("..", "..", "hack", "crd", "bases"), }, ErrorIfCRDPathMissing: true, + Scheme: test.FullScheme, } cfg, cl, err = test.StartEnvTest(testEnv) Expect(err).NotTo(HaveOccurred()) diff --git a/internal/rancher/doc.go b/internal/rancher/doc.go index 2139ab733..85225d49d 100644 --- a/internal/rancher/doc.go +++ b/internal/rancher/doc.go @@ -14,7 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -// Package rancher contains the rancher provisioning.cattle.io/v1 and -// management.cattle.io/v3 API proxy implementations. +// Package rancher contains rancher provisioning.cattle.io/v1 and +// management.cattle.io/v3 API proxy implementations and cluster connectivity +// setup procedures. // +kubebuilder:object:generate=true package rancher diff --git a/internal/rancher/setup/cluster.go b/internal/rancher/setup/cluster.go new file mode 100644 index 000000000..187e6f949 --- /dev/null +++ b/internal/rancher/setup/cluster.go @@ -0,0 +1,80 @@ +package setup + +import ( + "fmt" + "os" + + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "sigs.k8s.io/controller-runtime/pkg/cluster" + + ctrl "sigs.k8s.io/controller-runtime" +) + +var ( + setupLog = ctrl.Log.WithName("setup") +) + +// SetupRancherCluster creates a controller runtime cluster instance +// always connected to the rancher manager cluster +func SetupRancherCluster(mgr ctrl.Manager, rancherKubeconfig string) (cluster.Cluster, error) { + if rancherKubeconfig == "" { + return mgr, nil + } + + config, err := GetConfig(rancherKubeconfig) + if err != nil { + return nil, fmt.Errorf("unable to get rest config: %w", err) + } + + rancherCluster, err := cluster.New( + config, + func(clusterOptions *cluster.Options) { + clusterOptions.Scheme = mgr.GetScheme() + }) + if err != nil { + return nil, fmt.Errorf("unable to setup rancher cluster: %w", err) + } + + // Add rancher cluster as a runnable to the manager instance + // to allow it to be started/stopped with the manager under it's leader election + if err := mgr.Add(rancherCluster); err != nil { + return nil, fmt.Errorf("unable to add rancher cluster as runnable: %w", err) + } + + return rancherCluster, nil +} + +// SetupRancherClusterOrDie creates a controller runtime cluster instance +// always connected to the rancher manager cluster +func SetupRancherClusterOrDie(mgr ctrl.Manager, rancherKubeconfig string) cluster.Cluster { + cluster, err := SetupRancherCluster(mgr, rancherKubeconfig) + if err != nil { + setupLog.Error(err, "unable to add rancher cluster to manager") + os.Exit(1) + } + + return cluster +} + +// GetConfig loads a REST Config from a path using default kubeconfig context. +func GetConfig(kubeconfigPath string) (*rest.Config, error) { + kubeconfig, err := os.ReadFile(kubeconfigPath) + if err != nil { + return nil, fmt.Errorf("unable to read rancher kubeconfig from file: %w", err) + } + cfg, err := clientcmd.RESTConfigFromKubeConfig(kubeconfig) + if err != nil { + return nil, fmt.Errorf("unable to initiate rancher client: %w", err) + } + + if cfg.QPS == 0.0 { + cfg.QPS = 20.0 + } + + if cfg.Burst == 0 { + cfg.Burst = 30 + } + + return cfg, nil +} diff --git a/internal/rancher/setup/doc.go b/internal/rancher/setup/doc.go new file mode 100644 index 000000000..8c8924250 --- /dev/null +++ b/internal/rancher/setup/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2023 SUSE. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package setup contains the rancher cluster setup procedurces +package setup diff --git a/internal/test/envtest.go b/internal/test/envtest.go index d1f3d1561..b28b32ff3 100644 --- a/internal/test/envtest.go +++ b/internal/test/envtest.go @@ -32,13 +32,23 @@ import ( provisioningv1 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/provisioning/v1" ) -var scheme = runtime.NewScheme() +var ( + FullScheme = runtime.NewScheme() + PartialScheme = runtime.NewScheme() + RancherScheme = runtime.NewScheme() +) func init() { - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(clusterv1.AddToScheme(scheme)) - utilruntime.Must(provisioningv1.AddToScheme(scheme)) - utilruntime.Must(managementv3.AddToScheme(scheme)) + utilruntime.Must(clientgoscheme.AddToScheme(FullScheme)) + utilruntime.Must(clusterv1.AddToScheme(FullScheme)) + utilruntime.Must(provisioningv1.AddToScheme(FullScheme)) + utilruntime.Must(managementv3.AddToScheme(FullScheme)) + + utilruntime.Must(clientgoscheme.AddToScheme(PartialScheme)) + utilruntime.Must(clusterv1.AddToScheme(PartialScheme)) + + utilruntime.Must(provisioningv1.AddToScheme(RancherScheme)) + utilruntime.Must(managementv3.AddToScheme(RancherScheme)) } // StartEnvTest starts a new test environment. @@ -52,7 +62,7 @@ func StartEnvTest(testEnv *envtest.Environment) (*rest.Config, client.Client, er return nil, nil, errors.New("envtest.Environment.Start() returned nil config") } - cl, err := client.New(cfg, client.Options{Scheme: scheme}) + cl, err := client.New(cfg, client.Options{Scheme: testEnv.Scheme}) if err != nil { return nil, nil, err } diff --git a/main.go b/main.go index 41ea4d406..cd973f453 100644 --- a/main.go +++ b/main.go @@ -28,9 +28,6 @@ import ( "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" "k8s.io/client-go/tools/leaderelection/resourcelock" "k8s.io/component-base/version" "k8s.io/klog/v2" @@ -45,6 +42,7 @@ import ( "github.com/rancher-sandbox/rancher-turtles/internal/controllers" managementv3 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/management/v3" provisioningv1 "github.com/rancher-sandbox/rancher-turtles/internal/rancher/provisioning/v1" + "github.com/rancher-sandbox/rancher-turtles/internal/rancher/setup" ) var ( @@ -117,7 +115,7 @@ func main() { ctrl.SetLogger(klogr.New()) - mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ + options := ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsBindAddr, LeaderElection: enableLeaderElection, @@ -132,7 +130,9 @@ func main() { &corev1.Secret{}, }, HealthProbeBindAddress: healthAddr, - }) + } + + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), options) if err != nil { setupLog.Error(err, "unable to start manager") os.Exit(1) @@ -166,55 +166,12 @@ func setupChecks(mgr ctrl.Manager) { } func setupReconcilers(ctx context.Context, mgr ctrl.Manager) { - rancherClient, err := setupRancherClient(mgr) - if err != nil { - setupLog.Error(err, "failed to create client") - os.Exit(1) - } - if err := (&controllers.CAPIImportReconciler{ Client: mgr.GetClient(), - RancherClient: rancherClient, + RancherCluster: setup.SetupRancherClusterOrDie(mgr, rancherKubeconfig), WatchFilterValue: watchFilterValue, }).SetupWithManager(ctx, mgr, controller.Options{MaxConcurrentReconciles: concurrencyNumber}); err != nil { setupLog.Error(err, "unable to create capi controller") os.Exit(1) } } - -// setupRancherClient can either create a client for an in-cluster installation (rancher and rancher-turtles in the same cluster) -// or create a client for an out-of-cluster installation (rancher and rancher-turtles in different clusters) based on the -// existence of Rancher kubeconfig file. -func setupRancherClient(mgr ctrl.Manager) (client.Client, error) { - if len(rancherKubeconfig) > 0 { - setupLog.Info("out-of-cluster installation of rancher-turtles", "using kubeconfig from path", rancherKubeconfig) - - restConfig, err := loadConfigWithContext("", &clientcmd.ClientConfigLoadingRules{ExplicitPath: rancherKubeconfig}, "") - if err != nil { - return nil, fmt.Errorf("unable to load kubeconfig from file: %w", err) - } - - rancherClient, err := client.New(restConfig, client.Options{Scheme: mgr.GetClient().Scheme()}) - if err != nil { - return nil, err - } - - return rancherClient, nil - } - - setupLog.Info("in-cluster installation of rancher-turtles") - - return mgr.GetClient(), nil -} - -// loadConfigWithContext loads a REST Config from a path using a logic similar to the one used in controller-runtime. -func loadConfigWithContext(apiServerURL string, loader clientcmd.ClientConfigLoader, context string) (*rest.Config, error) { - return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( - loader, - &clientcmd.ConfigOverrides{ - ClusterInfo: clientcmdapi.Cluster{ - Server: apiServerURL, - }, - CurrentContext: context, - }).ClientConfig() -} diff --git a/util/predicates/suite_test.go b/util/predicates/suite_test.go index 4a0118f0f..da312f728 100644 --- a/util/predicates/suite_test.go +++ b/util/predicates/suite_test.go @@ -32,7 +32,9 @@ var _ = BeforeSuite(func() { By("bootstrapping test environment") var err error - testEnv = &envtest.Environment{} + testEnv = &envtest.Environment{ + Scheme: test.FullScheme, + } cfg, cl, err = test.StartEnvTest(testEnv) Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil())