From 52a1a679d46f039fa6b35e995d703bc0baecabfe Mon Sep 17 00:00:00 2001 From: Kieron Browne Date: Tue, 11 Jul 2023 15:22:50 +0000 Subject: [PATCH] Use controller roles for k8sManager in integration tests This also introduces helpers to create and start the manager, and to create other client with different permissions in testEnvs. Issue: https://github.com/cloudfoundry/korifi/issues/2660 Co-authored-by: Danail Branekov --- api/repositories/image_repository_test.go | 26 +-- api/repositories/package_repository_test.go | 23 +-- api/repositories/repositories_suite_test.go | 15 +- .../api/v1alpha1/cfapp_webhook_test.go | 2 +- .../api/v1alpha1/cfbuild_webhook_test.go | 2 +- controllers/api/v1alpha1/cforg_types_test.go | 4 +- .../api/v1alpha1/cfpackage_webhook_test.go | 2 +- .../api/v1alpha1/cfprocess_webhook_test.go | 2 +- .../api/v1alpha1/cfroute_webhook_test.go | 8 +- .../api/v1alpha1/cfspace_types_test.go | 8 +- .../api/v1alpha1/webhook_suite_test.go | 130 +++++-------- controllers/cleanup/build_cleaner_test.go | 2 +- controllers/cleanup/cleanup_suite_test.go | 11 +- controllers/cleanup/package_cleaner_test.go | 2 +- .../networking/cfdomain_controller_test.go | 18 +- .../networking/cfroute_controller_test.go | 62 +++--- .../controllers/networking/suite_test.go | 47 ++--- .../cfservicebinding_controller_test.go | 34 ++-- .../cfserviceinstance_controller_test.go | 18 +- .../controllers/services/suite_test.go | 53 ++---- .../workloads/cfapp_controller_test.go | 86 ++++----- .../workloads/cfbuild_controller_test.go | 71 +++---- .../workloads/cforg_controller_test.go | 74 +++---- .../workloads/cfpackage_controller_test.go | 24 +-- .../workloads/cfprocess_controller_test.go | 68 +++---- .../workloads/cfspace_controller_test.go | 158 +++++++-------- .../workloads/cftask_controller_test.go | 40 ++-- .../controllers/workloads/env/builder_test.go | 2 +- .../workloads/env/env_suite_test.go | 64 +++---- .../workloads/env/vcap_app_builder_test.go | 4 +- .../env/vcap_services_builder_test.go | 8 +- .../controllers/workloads/suite_test.go | 69 +++---- .../integration/integration_suite_test.go | 7 +- .../integration/name_registry_test.go | 6 +- .../finalizer/finalizer_webhook_test.go | 6 +- .../finalizer/suite_integration_test.go | 114 ++++------- .../version/suite_integration_test.go | 125 +++++------- .../webhooks/version/version_webhook_test.go | 16 +- .../webhooks/workloads/apprev_webhook_test.go | 10 +- .../workloads/cfapp_validator_test.go | 30 +-- .../workloads/cforg_validator_test.go | 24 +-- .../workloads/cfspace_validator_test.go | 24 +-- .../workloads/cftask_defaulter_test.go | 6 +- .../workloads/cftask_validator_test.go | 18 +- .../workloads/suite_integration_test.go | 93 +++------ .../controllers/integration/suite_test.go | 51 ++--- .../taskworkload_controller_test.go | 6 +- .../builderinfo_controller_test.go | 68 +++---- .../buildworkload_controller_test.go | 180 +++++++++--------- .../kpack_build_controller_test.go | 14 +- kpack-image-builder/controllers/suite_test.go | 55 ++---- .../finalizer/finalizer_webhook_test.go | 2 +- .../finalizer/suite_integration_test.go | 83 +++----- statefulset-runner/api/v1/pod_webhook_test.go | 6 +- .../api/v1/webhook_suite_test.go | 84 ++------ .../controllers/integration/suite_test.go | 50 ++--- tests/helpers/controllers_user.go | 73 ------- ...cache_syncing_client.go => sync_client.go} | 25 ++- tests/helpers/test_env.go | 126 ++++++++++++ 59 files changed, 1064 insertions(+), 1375 deletions(-) delete mode 100644 tests/helpers/controllers_user.go rename tests/helpers/{cache_syncing_client.go => sync_client.go} (73%) create mode 100644 tests/helpers/test_env.go diff --git a/api/repositories/image_repository_test.go b/api/repositories/image_repository_test.go index 775671dbc..49cc3f9c6 100644 --- a/api/repositories/image_repository_test.go +++ b/api/repositories/image_repository_test.go @@ -5,11 +5,13 @@ import ( "context" "errors" "io" + "path/filepath" apierrors "code.cloudfoundry.org/korifi/api/errors" "code.cloudfoundry.org/korifi/api/repositories" "code.cloudfoundry.org/korifi/api/repositories/fake" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/tests/helpers" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -18,16 +20,16 @@ import ( var _ = Describe("ImageRepository", func() { var ( - imagePusher *fake.ImagePusher - privilegedK8sClient k8sclient.Interface - imageSource io.Reader - imageRepo *repositories.ImageRepository - imageName string - imageRef string - tags []string - uploadErr error - org *korifiv1alpha1.CFOrg - space *korifiv1alpha1.CFSpace + imagePusher *fake.ImagePusher + k8sClient k8sclient.Interface + imageSource io.Reader + imageRepo *repositories.ImageRepository + imageName string + imageRef string + tags []string + uploadErr error + org *korifiv1alpha1.CFOrg + space *korifiv1alpha1.CFSpace ) BeforeEach(func() { @@ -38,7 +40,7 @@ var _ = Describe("ImageRepository", func() { imageSource = bytes.NewBufferString("") var err error - privilegedK8sClient, err = k8sclient.NewForConfig(k8sConfig) + k8sClient, err = k8sclient.NewForConfig(helpers.SetupTestEnvUser(testEnv, filepath.Join("helm", "korifi", "api", "role.yaml"))) Expect(err).NotTo(HaveOccurred()) org = createOrgWithCleanup(ctx, prefixedGUID("org")) @@ -47,7 +49,7 @@ var _ = Describe("ImageRepository", func() { tags = []string{"foo", "bar"} imageRepo = repositories.NewImageRepository( - privilegedK8sClient, + k8sClient, userClientFactory, imagePusher, []string{"push-secret-name"}, diff --git a/api/repositories/package_repository_test.go b/api/repositories/package_repository_test.go index 9b3c5dd4e..92828f4fa 100644 --- a/api/repositories/package_repository_test.go +++ b/api/repositories/package_repository_test.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "path/filepath" "time" apierrors "code.cloudfoundry.org/korifi/api/errors" @@ -12,6 +13,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" "code.cloudfoundry.org/korifi/controllers/cleanup" "code.cloudfoundry.org/korifi/controllers/controllers/workloads" + "code.cloudfoundry.org/korifi/tests/helpers" "code.cloudfoundry.org/korifi/tests/matchers" "code.cloudfoundry.org/korifi/tools" "code.cloudfoundry.org/korifi/tools/image" @@ -26,7 +28,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" ) var _ = Describe("PackageRepository", func() { @@ -36,7 +37,7 @@ var _ = Describe("PackageRepository", func() { org *korifiv1alpha1.CFOrg space *korifiv1alpha1.CFSpace app *korifiv1alpha1.CFApp - mgrCancel context.CancelFunc + stopManager context.CancelFunc ) BeforeEach(func() { @@ -53,13 +54,9 @@ var _ = Describe("PackageRepository", func() { space = createSpaceWithCleanup(ctx, org.Name, prefixedGUID("space")) app = createApp(space.Name) - k8sManager, err := ctrl.NewManager(k8sConfig, ctrl.Options{ - Scheme: scheme.Scheme, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) - k8sInterface, err := kubernetes.NewForConfig(k8sConfig) + k8sInterface, err := kubernetes.NewForConfig(k8sManager.GetConfig()) Expect(err).NotTo(HaveOccurred()) err = (workloads.NewCFPackageReconciler( @@ -72,17 +69,11 @@ var _ = Describe("PackageRepository", func() { )).SetupWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - var mgrCtx context.Context - mgrCtx, mgrCancel = context.WithCancel(ctx) - go func() { - defer GinkgoRecover() - err = k8sManager.Start(mgrCtx) - Expect(err).NotTo(HaveOccurred()) - }() + stopManager = helpers.StartK8sManager(k8sManager) }) AfterEach(func() { - mgrCancel() + stopManager() }) Describe("CreatePackage", func() { diff --git a/api/repositories/repositories_suite_test.go b/api/repositories/repositories_suite_test.go index 8ee6a76f9..5076ef4b6 100644 --- a/api/repositories/repositories_suite_test.go +++ b/api/repositories/repositories_suite_test.go @@ -49,7 +49,6 @@ var ( k8sClient client.WithWatch namespaceRetriever repositories.NamespaceRetriever userClientFactory authorization.UserK8sClientFactory - k8sConfig *rest.Config userName string authInfo authorization.Info rootNamespace string @@ -78,7 +77,7 @@ var _ = BeforeSuite(func() { } var err error - k8sConfig, err = testEnv.Start() + _, err = testEnv.Start() Expect(err).NotTo(HaveOccurred()) err = korifiv1alpha1.AddToScheme(scheme.Scheme) @@ -86,11 +85,11 @@ var _ = BeforeSuite(func() { err = buildv1alpha2.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - k8sClient, err = client.NewWithWatch(k8sConfig, client.Options{Scheme: scheme.Scheme}) + k8sClient, err = client.NewWithWatch(testEnv.Config, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) Expect(k8sClient).NotTo(BeNil()) - dynamicClient, err := dynamic.NewForConfig(k8sConfig) + dynamicClient, err := dynamic.NewForConfig(testEnv.Config) Expect(err).NotTo(HaveOccurred()) Expect(dynamicClient).NotTo(BeNil()) namespaceRetriever = repositories.NewNamespaceRetriever(dynamicClient) @@ -118,16 +117,16 @@ var _ = BeforeEach(func() { builderName = "kpack-image-builder" runnerName = "statefulset-runner" tokenInspector := authorization.NewTokenReviewer(k8sClient) - certInspector := authorization.NewCertInspector(k8sConfig) + certInspector := authorization.NewCertInspector(testEnv.Config) baseIDProvider := authorization.NewCertTokenIdentityProvider(tokenInspector, certInspector) idProvider = authorization.NewCachingIdentityProvider(baseIDProvider, cache.NewExpiring()) nsPerms = authorization.NewNamespacePermissions(k8sClient, idProvider) - httpClient, err := rest.HTTPClientFor(k8sConfig) + httpClient, err := rest.HTTPClientFor(testEnv.Config) Expect(err).NotTo(HaveOccurred()) - mapper, err := apiutil.NewDynamicRESTMapper(k8sConfig, httpClient) + mapper, err := apiutil.NewDynamicRESTMapper(testEnv.Config, httpClient) Expect(err).NotTo(HaveOccurred()) - userClientFactory = authorization.NewUnprivilegedClientFactory(k8sConfig, mapper, k8s.NewDefaultBackoff()) + userClientFactory = authorization.NewUnprivilegedClientFactory(testEnv.Config, mapper, k8s.NewDefaultBackoff()) Expect(k8sClient.Create(context.Background(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: rootNamespace}})).To(Succeed()) createRoleBinding(context.Background(), userName, rootNamespaceUserRole.Name, rootNamespace) diff --git a/controllers/api/v1alpha1/cfapp_webhook_test.go b/controllers/api/v1alpha1/cfapp_webhook_test.go index 2289a1310..33164c915 100644 --- a/controllers/api/v1alpha1/cfapp_webhook_test.go +++ b/controllers/api/v1alpha1/cfapp_webhook_test.go @@ -40,7 +40,7 @@ var _ = Describe("CFAppMutatingWebhook", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) }) It("adds a label matching metadata.name", func() { diff --git a/controllers/api/v1alpha1/cfbuild_webhook_test.go b/controllers/api/v1alpha1/cfbuild_webhook_test.go index c6a8e3b82..aa932d1fb 100644 --- a/controllers/api/v1alpha1/cfbuild_webhook_test.go +++ b/controllers/api/v1alpha1/cfbuild_webhook_test.go @@ -53,7 +53,7 @@ var _ = Describe("CFBuildMutatingWebhook", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfBuild)).To(Succeed()) + Expect(adminClient.Create(ctx, cfBuild)).To(Succeed()) }) It("sets labels with the guids of the related app and package", func() { diff --git a/controllers/api/v1alpha1/cforg_types_test.go b/controllers/api/v1alpha1/cforg_types_test.go index 79d1c9e3e..1e49a36f4 100644 --- a/controllers/api/v1alpha1/cforg_types_test.go +++ b/controllers/api/v1alpha1/cforg_types_test.go @@ -28,7 +28,7 @@ var _ = Describe("CF Org", func() { }) JustBeforeEach(func() { - createErr = k8sClient.Create(ctx, cfOrg) + createErr = adminClient.Create(ctx, cfOrg) }) It("accepts a valid name", func() { @@ -37,7 +37,7 @@ var _ = Describe("CF Org", func() { When("an org with the same display name already exists", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &korifiv1alpha1.CFOrg{ + Expect(adminClient.Create(ctx, &korifiv1alpha1.CFOrg{ ObjectMeta: metav1.ObjectMeta{ Namespace: namespace, Name: uuid.NewString(), diff --git a/controllers/api/v1alpha1/cfpackage_webhook_test.go b/controllers/api/v1alpha1/cfpackage_webhook_test.go index 87607b67d..a1a7edf84 100644 --- a/controllers/api/v1alpha1/cfpackage_webhook_test.go +++ b/controllers/api/v1alpha1/cfpackage_webhook_test.go @@ -35,7 +35,7 @@ var _ = Describe("CFPackageMutatingWebhook", func() { }) BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfPackage)).To(Succeed()) + Expect(adminClient.Create(ctx, cfPackage)).To(Succeed()) }) It("sets a label with the app guid", func() { diff --git a/controllers/api/v1alpha1/cfprocess_webhook_test.go b/controllers/api/v1alpha1/cfprocess_webhook_test.go index af5e51b15..779caffae 100644 --- a/controllers/api/v1alpha1/cfprocess_webhook_test.go +++ b/controllers/api/v1alpha1/cfprocess_webhook_test.go @@ -46,7 +46,7 @@ var _ = Describe("CFProcessMutatingWebhook", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(context.Background(), cfProcess)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfProcess)).To(Succeed()) }) Describe("labels", func() { diff --git a/controllers/api/v1alpha1/cfroute_webhook_test.go b/controllers/api/v1alpha1/cfroute_webhook_test.go index 273d5848f..83b0fbd37 100644 --- a/controllers/api/v1alpha1/cfroute_webhook_test.go +++ b/controllers/api/v1alpha1/cfroute_webhook_test.go @@ -33,7 +33,7 @@ var _ = Describe("CFRouteMutatingWebhook Integration Tests", func() { Name: "a" + uuid.NewString() + ".com", }, } - Expect(k8sClient.Create(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDomain)).To(Succeed()) cfRoute = &korifiv1alpha1.CFRoute{ ObjectMeta: metav1.ObjectMeta{ @@ -52,12 +52,12 @@ var _ = Describe("CFRouteMutatingWebhook Integration Tests", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfRoute)).To(Succeed()) + Expect(adminClient.Create(ctx, cfRoute)).To(Succeed()) }) AfterEach(func() { - Expect(k8sClient.Delete(ctx, cfRoute)).To(Succeed()) - Expect(k8sClient.Delete(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Delete(ctx, cfRoute)).To(Succeed()) + Expect(adminClient.Delete(ctx, cfDomain)).To(Succeed()) }) It("adds labels with guids of the domain and route", func() { diff --git a/controllers/api/v1alpha1/cfspace_types_test.go b/controllers/api/v1alpha1/cfspace_types_test.go index 1372c7f69..fccb9cec9 100644 --- a/controllers/api/v1alpha1/cfspace_types_test.go +++ b/controllers/api/v1alpha1/cfspace_types_test.go @@ -28,9 +28,9 @@ var _ = Describe("CF Space", func() { DisplayName: uuid.NewString(), }, } - Expect(k8sClient.Create(ctx, cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, cfOrg)).To(Succeed()) - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{Name: cfOrg.Name}, })).To(Succeed()) @@ -46,7 +46,7 @@ var _ = Describe("CF Space", func() { }) JustBeforeEach(func() { - createErr = k8sClient.Create(ctx, cfSpace) + createErr = adminClient.Create(ctx, cfSpace) }) It("accepts a valid name", func() { @@ -55,7 +55,7 @@ var _ = Describe("CF Space", func() { When("a space with the same display name already exists", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &korifiv1alpha1.CFSpace{ + Expect(adminClient.Create(ctx, &korifiv1alpha1.CFSpace{ ObjectMeta: metav1.ObjectMeta{ Namespace: cfOrg.Name, Name: uuid.NewString(), diff --git a/controllers/api/v1alpha1/webhook_suite_test.go b/controllers/api/v1alpha1/webhook_suite_test.go index e18c49ac7..ee4f2c798 100644 --- a/controllers/api/v1alpha1/webhook_suite_test.go +++ b/controllers/api/v1alpha1/webhook_suite_test.go @@ -19,14 +19,12 @@ package v1alpha1_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" "time" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" "code.cloudfoundry.org/korifi/controllers/controllers/workloads/testutils" "code.cloudfoundry.org/korifi/controllers/coordination" "code.cloudfoundry.org/korifi/controllers/webhooks" @@ -42,13 +40,11 @@ import ( coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - //+kubebuilder:scaffold:imports ) const ( @@ -58,11 +54,12 @@ const ( ) var ( - ctx context.Context - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client - namespace string + ctx context.Context + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client + namespace string ) func TestKorifiMutatingWebhooks(t *testing.T) { @@ -76,7 +73,7 @@ func TestKorifiMutatingWebhooks(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancel = context.WithCancel(context.TODO()) + ctx, stopManager = context.WithCancel(context.TODO()) testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds")}, @@ -88,92 +85,61 @@ var _ = BeforeSuite(func() { namespace = testutils.PrefixedGUID("webhooks-test-ns") - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - Expect(corev1.AddToScheme(scheme)).To(Succeed()) - Expect(korifiv1alpha1.AddToScheme(scheme)).To(Succeed()) - Expect(admissionv1beta1.AddToScheme(scheme)).To(Succeed()) - Expect(coordinationv1.AddToScheme(scheme)).To(Succeed()) - - // start webhook server using Manager - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - k8sClient = helpers.NewCacheSyncingClient(mgr.GetClient()) + Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(admissionv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(coordinationv1.AddToScheme(scheme.Scheme)).To(Succeed()) + + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) + + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) - Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(workloads.NewCFAppValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.AppEntityType)), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.AppEntityType)), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(networking.NewCFRouteValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), networking.RouteEntityType)), + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), networking.RouteEntityType)), namespace, - mgr.GetClient(), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + k8sManager.GetClient(), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect(networking.NewCFDomainValidator(mgr.GetClient()).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect(networking.NewCFDomainValidator(k8sManager.GetClient()).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(korifiv1alpha1.NewCFProcessDefaulter(defaultMemoryMB, defaultDiskQuotaMB, defaultTimeout). - SetupWebhookWithManager(mgr)).To(Succeed()) - - Expect((&korifiv1alpha1.CFBuild{}).SetupWebhookWithManager(mgr)).To(Succeed()) - - orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFOrgEntityType)) - orgPlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), namespace) - Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) - - spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFSpaceEntityType)) - spacePlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), namespace) - Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) - version.NewVersionWebhook("some-version").SetupWebhookWithManager(mgr) - finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(mgr) - - //+kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + SetupWebhookWithManager(k8sManager)).To(Succeed()) + + Expect((&korifiv1alpha1.CFBuild{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) + + orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFOrgEntityType)) + orgPlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), namespace) + Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) + + spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFSpaceEntityType)) + spacePlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), namespace) + Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) + version.NewVersionWebhook("some-version").SetupWebhookWithManager(k8sManager) + finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(k8sManager) + + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, }, })).To(Succeed()) + + stopManager = helpers.StartK8sManager(k8sManager) }) var _ = AfterSuite(func() { - cancel() - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) + stopManager() + stopClientCache() + Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/controllers/cleanup/build_cleaner_test.go b/controllers/cleanup/build_cleaner_test.go index 8bb498791..36f282a3d 100644 --- a/controllers/cleanup/build_cleaner_test.go +++ b/controllers/cleanup/build_cleaner_test.go @@ -26,7 +26,7 @@ var _ = Describe("BuildCleaner", func() { ) BeforeEach(func() { - cleaner = cleanup.NewBuildCleaner(k8sClient, 1) + cleaner = cleanup.NewBuildCleaner(controllersClient, 1) namespace = GenerateGUID() Expect(k8sClient.Create(ctx, &corev1.Namespace{ diff --git a/controllers/cleanup/cleanup_suite_test.go b/controllers/cleanup/cleanup_suite_test.go index 1b675efa0..8ae189b8b 100644 --- a/controllers/cleanup/cleanup_suite_test.go +++ b/controllers/cleanup/cleanup_suite_test.go @@ -6,6 +6,7 @@ import ( "testing" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/tests/helpers" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gcustom" @@ -25,9 +26,10 @@ func TestCleanup(t *testing.T) { } var ( - ctx context.Context - testEnv *envtest.Environment - k8sClient client.Client + ctx context.Context + testEnv *envtest.Environment + k8sClient client.Client + controllersClient client.Client ) var _ = BeforeSuite(func() { @@ -48,6 +50,9 @@ var _ = BeforeSuite(func() { k8sClient, err = client.New(cfg, client.Options{}) Expect(err).NotTo(HaveOccurred()) + controllersClient, err = client.New(helpers.SetupTestEnvUser(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")), client.Options{}) + Expect(err).NotTo(HaveOccurred()) + ctx = context.Background() }) diff --git a/controllers/cleanup/package_cleaner_test.go b/controllers/cleanup/package_cleaner_test.go index c9a36abc7..f57333462 100644 --- a/controllers/cleanup/package_cleaner_test.go +++ b/controllers/cleanup/package_cleaner_test.go @@ -28,7 +28,7 @@ var _ = Describe("PackageCleaner", func() { ) BeforeEach(func() { - cleaner = cleanup.NewPackageCleaner(k8sClient, 1) + cleaner = cleanup.NewPackageCleaner(controllersClient, 1) namespace = GenerateGUID() Expect(k8sClient.Create(ctx, &corev1.Namespace{ diff --git a/controllers/controllers/networking/cfdomain_controller_test.go b/controllers/controllers/networking/cfdomain_controller_test.go index 10a64baa9..69303d8eb 100644 --- a/controllers/controllers/networking/cfdomain_controller_test.go +++ b/controllers/controllers/networking/cfdomain_controller_test.go @@ -31,21 +31,21 @@ var _ = Describe("CFDomainReconciler Integration Tests", func() { ctx = context.Background() domainNamespace = GenerateGUID() - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: domainNamespace, }, })).To(Succeed()) route1Namespace = GenerateGUID() - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: route1Namespace, }, })).To(Succeed()) route2Namespace = GenerateGUID() - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: route2Namespace, }, @@ -62,7 +62,7 @@ var _ = Describe("CFDomainReconciler Integration Tests", func() { Name: testDomainName, }, } - Expect(k8sClient.Create(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDomain)).To(Succeed()) createValidRoute(ctx, &korifiv1alpha1.CFRoute{ ObjectMeta: metav1.ObjectMeta{ @@ -99,17 +99,17 @@ var _ = Describe("CFDomainReconciler Integration Tests", func() { When("a domain is deleted", func() { JustBeforeEach(func() { - Expect(k8sClient.Delete(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Delete(ctx, cfDomain)).To(Succeed()) }) It("deletes the domain routes", func() { Eventually(func(g Gomega) { routes := &korifiv1alpha1.CFRouteList{} - g.Expect(k8sClient.List(ctx, routes, client.InNamespace(route1Namespace))).To(Succeed()) + g.Expect(adminClient.List(ctx, routes, client.InNamespace(route1Namespace))).To(Succeed()) g.Expect(routes.Items).To(BeEmpty()) - g.Expect(k8sClient.List(ctx, routes, client.InNamespace(route2Namespace))).To(Succeed()) + g.Expect(adminClient.List(ctx, routes, client.InNamespace(route2Namespace))).To(Succeed()) g.Expect(routes.Items).To(BeEmpty()) }).Should(Succeed()) }) @@ -121,10 +121,10 @@ var _ = Describe("CFDomainReconciler Integration Tests", func() { }) func createValidRoute(ctx context.Context, route *korifiv1alpha1.CFRoute) { - Expect(k8sClient.Create(ctx, route)).To(Succeed()) + Expect(adminClient.Create(ctx, route)).To(Succeed()) Eventually(func(g Gomega) { createdRoute := &korifiv1alpha1.CFRoute{} - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(route), createdRoute)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(route), createdRoute)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdRoute.Status.Conditions, "Valid")).To(BeTrue()) }).Should(Succeed()) } diff --git a/controllers/controllers/networking/cfroute_controller_test.go b/controllers/controllers/networking/cfroute_controller_test.go index d2af93965..679bd4b2c 100644 --- a/controllers/controllers/networking/cfroute_controller_test.go +++ b/controllers/controllers/networking/cfroute_controller_test.go @@ -46,7 +46,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { Name: testNamespace, }, } - Expect(k8sClient.Create(ctx, ns)).To(Succeed()) + Expect(adminClient.Create(ctx, ns)).To(Succeed()) testDomainGUID = GenerateGUID() testRouteGUID = GenerateGUID() @@ -61,7 +61,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { Name: "a" + GenerateGUID() + ".com", }, } - Expect(k8sClient.Create(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDomain)).To(Succeed()) cfApp := &korifiv1alpha1.CFApp{ ObjectMeta: metav1.ObjectMeta{ @@ -76,7 +76,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { DisplayName: testAppGUID, }, } - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) cfRoute = &korifiv1alpha1.CFRoute{ ObjectMeta: metav1.ObjectMeta{ @@ -100,17 +100,17 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { } AfterEach(func() { - Expect(client.IgnoreNotFound(k8sClient.Delete(ctx, ns))).To(Succeed()) + Expect(client.IgnoreNotFound(adminClient.Delete(ctx, ns))).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfRoute)).To(Succeed()) + Expect(adminClient.Create(ctx, cfRoute)).To(Succeed()) }) It("reconciles the CFRoute to a root Contour HTTPProxy which includes a proxy for a route destination", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.VirtualHost.Fqdn).To(Equal(fqdnProxyName())) g.Expect(proxy.Spec.VirtualHost.TLS.SecretName).To(Equal("korifi-controllers-system/korifi-workloads-ingress-cert")) @@ -131,7 +131,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("reconciles the CFRoute to a child proxy with no routes", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.VirtualHost).To(BeNil()) g.Expect(proxy.Spec.Routes).To(BeEmpty()) g.Expect(proxy.ObjectMeta.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ @@ -147,7 +147,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("sets the ObservedGeneration status field", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) g.Expect(cfRoute.Status.ObservedGeneration).To(Equal(cfRoute.Generation)) }).Should(Succeed()) }) @@ -170,7 +170,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("reconciles the CFRoute to a root Contour HTTPProxy which includes a proxy for a route destination", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Includes).To(ConsistOf(contourv1.Include{ Name: testRouteGUID, Namespace: testNamespace, @@ -181,7 +181,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("reconciles the CFRoute to a child proxy with a route", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Routes).To(ConsistOf(contourv1.Route{ Conditions: []contourv1.MatchCondition{ { @@ -204,7 +204,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { Eventually(func(g Gomega) { var svc corev1.Service - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) g.Expect(svc.Labels).To(SatisfyAll( HaveKeyWithValue("korifi.cloudfoundry.org/app-guid", cfRoute.Spec.Destinations[0].AppRef.Name), HaveKeyWithValue("korifi.cloudfoundry.org/route-guid", cfRoute.Name), @@ -227,7 +227,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("adds the FQDN and URI status fields to the CFRoute", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) g.Expect(cfRoute.Status.FQDN).To(Equal(fqdnProxyName())) g.Expect(cfRoute.Status.URI).To(Equal(fqdnProxyName() + "/test/path")) }).Should(Succeed()) @@ -235,7 +235,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("adds the Destinations status field to the CFRoute", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, cfRoute)).To(Succeed()) g.Expect(cfRoute.Status.Destinations).To(Equal(cfRoute.Spec.Destinations)) }).Should(Succeed()) }) @@ -275,18 +275,18 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { }, }, } - Expect(k8sClient.Create(ctx, anotherRoute)).To(Succeed()) + Expect(adminClient.Create(ctx, anotherRoute)).To(Succeed()) Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) }).Should(Succeed()) }) It("adds another include to the contour FQDN proxy", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Includes).To(ConsistOf([]contourv1.Include{ { Name: testRouteGUID, @@ -303,7 +303,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("reconciles them to a child contour proxy with a route", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: anotherRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: anotherRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.VirtualHost).To(BeNil()) g.Expect(proxy.Spec.Routes).To(ConsistOf(contourv1.Route{ Conditions: []contourv1.MatchCondition{ @@ -326,16 +326,16 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Includes).To(HaveLen(2)) }).Should(Succeed()) - Expect(k8sClient.Delete(ctx, anotherRoute)).To(Succeed()) + Expect(adminClient.Delete(ctx, anotherRoute)).To(Succeed()) }) It("removes it from the FQDN proxy includes list", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Includes).To(ConsistOf(contourv1.Include{ Name: testRouteGUID, Namespace: testNamespace, @@ -367,10 +367,10 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, cfRoute, func() { + Expect(k8s.Patch(ctx, adminClient, cfRoute, func() { cfRoute.Spec.Destinations = append(cfRoute.Spec.Destinations, korifiv1alpha1.Destination{ GUID: GenerateGUID(), AppRef: corev1.LocalObjectReference{ @@ -386,7 +386,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("reconciles the CFRoute to a child proxy with a route", func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &proxy)).To(Succeed()) g.Expect(proxy.Spec.Routes).To(ConsistOf([]contourv1.Route{ { Conditions: []contourv1.MatchCondition{{Prefix: "/test/path"}}, @@ -411,7 +411,7 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { Eventually(func(g Gomega) { var svc corev1.Service - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) g.Expect(svc.Labels).To(SatisfyAll( HaveKeyWithValue("korifi.cloudfoundry.org/app-guid", cfRoute.Spec.Destinations[1].AppRef.Name), HaveKeyWithValue("korifi.cloudfoundry.org/route-guid", cfRoute.Name), @@ -455,19 +455,19 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { var proxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, &proxy)).To(Succeed()) var routeProxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &routeProxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &routeProxy)).To(Succeed()) g.Expect(routeProxy.Spec.Routes).To(HaveLen(1)) g.Expect(routeProxy.Spec.Routes[0].Services).To(HaveLen(1)) serviceName = routeProxy.Spec.Routes[0].Services[0].Name var svc corev1.Service - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, &svc)).To(Succeed()) }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, cfRoute, func() { + Expect(k8s.Patch(ctx, adminClient, cfRoute, func() { cfRoute.Spec.Destinations = []korifiv1alpha1.Destination{} })).To(Succeed()) }) @@ -475,21 +475,21 @@ var _ = Describe("CFRouteReconciler Integration Tests", func() { It("deletes the Route on the HTTP proxy", func() { Eventually(func(g Gomega) { var routeProxy contourv1.HTTPProxy - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &routeProxy)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testRouteGUID, Namespace: testNamespace}, &routeProxy)).To(Succeed()) g.Expect(routeProxy.Spec.Routes).To(BeEmpty()) }).Should(Succeed()) }) It("deletes the corresponding service", func() { Eventually(func(g Gomega) { - err := k8sClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, new(corev1.Service)) + err := adminClient.Get(ctx, types.NamespacedName{Name: serviceName, Namespace: testNamespace}, new(corev1.Service)) g.Expect(errors.IsNotFound(err)).To(BeTrue()) }).Should(Succeed()) }) It("does not delete the FQDN proxy", func() { Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, new(contourv1.HTTPProxy))).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: fqdnProxyName(), Namespace: testNamespace}, new(contourv1.HTTPProxy))).To(Succeed()) }).Should(Succeed()) }) }) diff --git a/controllers/controllers/networking/suite_test.go b/controllers/controllers/networking/suite_test.go index edd5b1974..d688957a4 100644 --- a/controllers/controllers/networking/suite_test.go +++ b/controllers/controllers/networking/suite_test.go @@ -36,10 +36,11 @@ import ( const rootNamespace = "cf" var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client - logOutput *gbytes.Buffer + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client + logOutput *gbytes.Buffer ) func TestNetworkingControllers(t *testing.T) { @@ -55,12 +56,7 @@ var _ = BeforeSuite(func() { GinkgoWriter.TeeTo(logOutput) logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - var ctx context.Context - ctx, cancel = context.WithCancel(context.TODO()) - - // TODO: Add directory path for Contour CRDs testEnv = &envtest.Environment{ - // TODO: Reconcile with CRDInstallOptions CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds"), filepath.Join("..", "..", "..", "tests", "vendor", "contour"), @@ -71,25 +67,16 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(contourv1.AddToScheme(scheme.Scheme)).To(Succeed()) - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).ToNot(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - k8sClient = helpers.NewCacheSyncingClient(k8sManager.GetClient()) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) err = (NewCFRouteReconciler( k8sManager.GetClient(), @@ -127,23 +114,17 @@ var _ = BeforeSuite(func() { k8sManager.GetClient(), ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - err = shared.SetupIndexWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).ToNot(HaveOccurred()) - }() - - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: rootNamespace, }, })).To(Succeed()) + + stopManager = helpers.StartK8sManager(k8sManager) }) var _ = AfterSuite(func() { - cancel() + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/controllers/controllers/services/cfservicebinding_controller_test.go b/controllers/controllers/services/cfservicebinding_controller_test.go index db69e6121..62313e712 100644 --- a/controllers/controllers/services/cfservicebinding_controller_test.go +++ b/controllers/controllers/services/cfservicebinding_controller_test.go @@ -37,16 +37,16 @@ var _ = Describe("CFServiceBinding", func() { BeforeEach(func() { namespace = BuildNamespaceObject(GenerateGUID()) Expect( - k8sClient.Create(context.Background(), namespace), + adminClient.Create(context.Background(), namespace), ).To(Succeed()) cfAppGUID = GenerateGUID() desiredCFApp = BuildCFAppCRObject(cfAppGUID, namespace.Name) Expect( - k8sClient.Create(context.Background(), desiredCFApp), + adminClient.Create(context.Background(), desiredCFApp), ).To(Succeed()) - Expect(k8s.Patch(context.Background(), k8sClient, desiredCFApp, func() { + Expect(k8s.Patch(context.Background(), adminClient, desiredCFApp, func() { desiredCFApp.Status = korifiv1alpha1.CFAppStatus{ Conditions: nil, VCAPServicesSecretName: "foo", @@ -72,7 +72,7 @@ var _ = Describe("CFServiceBinding", func() { }, } Expect( - k8sClient.Create(context.Background(), secret), + adminClient.Create(context.Background(), secret), ).To(Succeed()) cfServiceInstance = &korifiv1alpha1.CFServiceInstance{ @@ -88,7 +88,7 @@ var _ = Describe("CFServiceBinding", func() { }, } Expect( - k8sClient.Create(context.Background(), cfServiceInstance), + adminClient.Create(context.Background(), cfServiceInstance), ).To(Succeed()) cfServiceBindingGUID = GenerateGUID() @@ -111,18 +111,18 @@ var _ = Describe("CFServiceBinding", func() { }) AfterEach(func() { - Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), namespace)).To(Succeed()) }) JustBeforeEach(func() { Expect( - k8sClient.Create(context.Background(), cfServiceBinding), + adminClient.Create(context.Background(), cfServiceBinding), ).To(Succeed()) }) It("makes the service instance owner of the service binding", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), cfServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), cfServiceBinding)).To(Succeed()) g.Expect(cfServiceBinding.GetOwnerReferences()).To(ConsistOf(HaveField("Name", cfServiceInstance.Name))) }).Should(Succeed()) }) @@ -130,7 +130,7 @@ var _ = Describe("CFServiceBinding", func() { It("resolves the secretName and updates the CFServiceBinding status", func() { Eventually(func(g Gomega) { updatedCFServiceBinding := new(korifiv1alpha1.CFServiceBinding) - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) g.Expect(updatedCFServiceBinding.Status).To(MatchFields(IgnoreExtras, Fields{ "Binding": MatchFields(IgnoreExtras, Fields{"Name": Equal(secret.Name)}), "Conditions": ContainElement(MatchFields(IgnoreExtras, Fields{ @@ -146,7 +146,7 @@ var _ = Describe("CFServiceBinding", func() { It("creates a servicebinding.io ServiceBinding", func() { Eventually(func(g Gomega) { sbServiceBinding := servicebindingv1beta1.ServiceBinding{} - g.Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: fmt.Sprintf("cf-binding-%s", cfServiceBindingGUID), Namespace: namespace.Name}, &sbServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), types.NamespacedName{Name: fmt.Sprintf("cf-binding-%s", cfServiceBindingGUID), Namespace: namespace.Name}, &sbServiceBinding)).To(Succeed()) g.Expect(sbServiceBinding).To(MatchFields(IgnoreExtras, Fields{ "ObjectMeta": MatchFields(IgnoreExtras, Fields{ "Name": Equal(fmt.Sprintf("cf-binding-%s", cfServiceBindingGUID)), @@ -187,7 +187,7 @@ var _ = Describe("CFServiceBinding", func() { It("sets the ObservedGeneration status field", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), cfServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), cfServiceBinding)).To(Succeed()) g.Expect(cfServiceBinding.Status.ObservedGeneration).To(Equal(cfServiceBinding.Generation)) }).Should(Succeed()) }) @@ -224,7 +224,7 @@ var _ = Describe("CFServiceBinding", func() { It("sets the displayName as the name on the servicebinding.io ServiceBinding", func() { Eventually(func(g Gomega) { sbServiceBinding := servicebindingv1beta1.ServiceBinding{} - g.Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: fmt.Sprintf("cf-binding-%s", cfServiceBindingGUID), Namespace: namespace.Name}, &sbServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), types.NamespacedName{Name: fmt.Sprintf("cf-binding-%s", cfServiceBindingGUID), Namespace: namespace.Name}, &sbServiceBinding)).To(Succeed()) g.Expect(sbServiceBinding).To(MatchFields(IgnoreExtras, Fields{ "Spec": MatchFields(IgnoreExtras, Fields{ "Name": Equal(bindingName), @@ -258,7 +258,7 @@ var _ = Describe("CFServiceBinding", func() { }, } Expect( - k8sClient.Create(ctx, instance), + adminClient.Create(ctx, instance), ).To(Succeed()) cfServiceBinding.Spec.Service.Name = instance.Name @@ -267,7 +267,7 @@ var _ = Describe("CFServiceBinding", func() { It("updates the CFServiceBinding status", func() { Eventually(func(g Gomega) { updatedCFServiceBinding := new(korifiv1alpha1.CFServiceBinding) - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) g.Expect(updatedCFServiceBinding.Status).To(MatchFields(IgnoreExtras, Fields{ "Binding": MatchFields(IgnoreExtras, Fields{"Name": Equal("")}), "Conditions": ContainElement(MatchFields(IgnoreExtras, Fields{ @@ -284,7 +284,7 @@ var _ = Describe("CFServiceBinding", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { updatedCFServiceBinding := new(korifiv1alpha1.CFServiceBinding) - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) g.Expect(updatedCFServiceBinding.Status).To(MatchFields(IgnoreExtras, Fields{ "Conditions": ContainElement(MatchFields(IgnoreExtras, Fields{ "Type": Equal("BindingSecretAvailable"), @@ -293,13 +293,13 @@ var _ = Describe("CFServiceBinding", func() { })) }).Should(Succeed()) - Expect(k8sClient.Create(context.Background(), otherSecret)).To(Succeed()) + Expect(adminClient.Create(context.Background(), otherSecret)).To(Succeed()) }) It("resolves the secretName and updates the CFServiceBinding status", func() { Eventually(func(g Gomega) { updatedCFServiceBinding := new(korifiv1alpha1.CFServiceBinding) - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfServiceBinding), updatedCFServiceBinding)).To(Succeed()) g.Expect(updatedCFServiceBinding.Status).To(MatchFields(IgnoreExtras, Fields{ "Binding": MatchFields(IgnoreExtras, Fields{"Name": Equal(otherSecret.Name)}), "Conditions": ContainElement(MatchFields(IgnoreExtras, Fields{ diff --git a/controllers/controllers/services/cfserviceinstance_controller_test.go b/controllers/controllers/services/cfserviceinstance_controller_test.go index 6ea652b78..71cffcb54 100644 --- a/controllers/controllers/services/cfserviceinstance_controller_test.go +++ b/controllers/controllers/services/cfserviceinstance_controller_test.go @@ -25,7 +25,7 @@ var _ = Describe("CFServiceInstance", func() { BeforeEach(func() { namespace = BuildNamespaceObject(GenerateGUID()) Expect( - k8sClient.Create(context.Background(), namespace), + adminClient.Create(context.Background(), namespace), ).To(Succeed()) secret = &corev1.Secret{ @@ -36,7 +36,7 @@ var _ = Describe("CFServiceInstance", func() { StringData: map[string]string{"foo": "bar"}, } - Expect(k8sClient.Create(ctx, secret)).To(Succeed()) + Expect(adminClient.Create(ctx, secret)).To(Succeed()) cfServiceInstance = &korifiv1alpha1.CFServiceInstance{ ObjectMeta: metav1.ObjectMeta{ @@ -53,18 +53,18 @@ var _ = Describe("CFServiceInstance", func() { }) AfterEach(func() { - Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), namespace)).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Create(context.Background(), cfServiceInstance)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfServiceInstance)).To(Succeed()) }) It("sets the BindingSecretAvailable condition to true in the CFServiceInstance status", func() { Eventually(func(g Gomega) { updatedCFServiceInstance := new(korifiv1alpha1.CFServiceInstance) serviceInstanceNamespacedName := client.ObjectKeyFromObject(cfServiceInstance) - g.Expect(k8sClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) g.Expect(updatedCFServiceInstance.Status.Binding.Name).To(Equal("secret-name")) g.Expect(updatedCFServiceInstance.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{ @@ -80,7 +80,7 @@ var _ = Describe("CFServiceInstance", func() { Eventually(func(g Gomega) { updatedCFServiceInstance := new(korifiv1alpha1.CFServiceInstance) serviceInstanceNamespacedName := client.ObjectKeyFromObject(cfServiceInstance) - g.Expect(k8sClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) g.Expect(updatedCFServiceInstance.Status.ObservedGeneration).To(Equal(cfServiceInstance.Generation)) }).Should(Succeed()) }) @@ -98,7 +98,7 @@ var _ = Describe("CFServiceInstance", func() { Eventually(func(g Gomega) { updatedCFServiceInstance := new(korifiv1alpha1.CFServiceInstance) serviceInstanceNamespacedName := client.ObjectKeyFromObject(cfServiceInstance) - g.Expect(k8sClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) g.Expect(updatedCFServiceInstance.Status.Binding).To(BeZero()) g.Expect(updatedCFServiceInstance.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{ @@ -112,7 +112,7 @@ var _ = Describe("CFServiceInstance", func() { When("the referenced secret is created afterwards", func() { BeforeEach(func() { - Expect(k8sClient.Create(context.Background(), &corev1.Secret{ + Expect(adminClient.Create(context.Background(), &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "other-secret-name", Namespace: namespace.Name, @@ -124,7 +124,7 @@ var _ = Describe("CFServiceInstance", func() { Eventually(func(g Gomega) { updatedCFServiceInstance := new(korifiv1alpha1.CFServiceInstance) serviceInstanceNamespacedName := client.ObjectKeyFromObject(cfServiceInstance) - g.Expect(k8sClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), serviceInstanceNamespacedName, updatedCFServiceInstance)).To(Succeed()) g.Expect(updatedCFServiceInstance.Status.Binding.Name).To(Equal("other-secret-name")) g.Expect(updatedCFServiceInstance.Status.Conditions).To(ContainElement(MatchFields(IgnoreExtras, Fields{ diff --git a/controllers/controllers/services/suite_test.go b/controllers/controllers/services/suite_test.go index 2832675b2..da4e65467 100644 --- a/controllers/controllers/services/suite_test.go +++ b/controllers/controllers/services/suite_test.go @@ -24,7 +24,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" . "code.cloudfoundry.org/korifi/controllers/controllers/services" - . "code.cloudfoundry.org/korifi/controllers/controllers/shared" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" "code.cloudfoundry.org/korifi/tests/helpers" . "github.com/onsi/ginkgo/v2" @@ -37,18 +37,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - //+kubebuilder:scaffold:imports ) -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - var ( - ctx context.Context - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client - logOutput *gbytes.Buffer + ctx context.Context + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client + logOutput *gbytes.Buffer ) func TestAPIs(t *testing.T) { @@ -64,7 +61,7 @@ var _ = BeforeSuite(func() { GinkgoWriter.TeeTo(logOutput) logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancel = context.WithCancel(context.TODO()) + ctx, stopManager = context.WithCancel(context.TODO()) testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -74,27 +71,16 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(servicebindingv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) - //+kubebuilder:scaffold:scheme - - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).ToNot(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - k8sClient = helpers.NewCacheSyncingClient(k8sManager.GetClient()) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) err = (NewCFServiceBindingReconciler( k8sManager.GetClient(), @@ -110,20 +96,11 @@ var _ = BeforeSuite(func() { )).SetupWithManager(k8sManager) Expect(err).ToNot(HaveOccurred()) - // Add new reconcilers here - - // Setup index for manager - err = SetupIndexWithManager(k8sManager) - Expect(err).ToNot(HaveOccurred()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).ToNot(HaveOccurred()) - }() + stopManager = helpers.StartK8sManager(k8sManager) }) var _ = AfterSuite(func() { - cancel() + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/controllers/controllers/workloads/cfapp_controller_test.go b/controllers/controllers/workloads/cfapp_controller_test.go index 1fc37759e..1aac4166d 100644 --- a/controllers/controllers/workloads/cfapp_controller_test.go +++ b/controllers/controllers/workloads/cfapp_controller_test.go @@ -41,7 +41,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { Name: "a" + uuid.NewString() + ".com", }, } - Expect(k8sClient.Create(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDomain)).To(Succeed()) }) When("a new CFApp resource is created", func() { @@ -81,7 +81,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { "foo": "bar", }, } - Expect(k8sClient.Create(context.Background(), serviceInstanceSecret)).To(Succeed()) + Expect(adminClient.Create(context.Background(), serviceInstanceSecret)).To(Succeed()) serviceInstance := &korifiv1alpha1.CFServiceInstance{ ObjectMeta: metav1.ObjectMeta{ @@ -93,7 +93,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { SecretName: serviceInstanceSecret.Name, }, } - Expect(k8sClient.Create(ctx, serviceInstance)).To(Succeed()) + Expect(adminClient.Create(ctx, serviceInstance)).To(Succeed()) serviceBinding = &korifiv1alpha1.CFServiceBinding{ ObjectMeta: metav1.ObjectMeta{ @@ -110,8 +110,8 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { }, }, } - Expect(k8sClient.Create(ctx, serviceBinding)).To(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, serviceBinding, func() { + Expect(adminClient.Create(ctx, serviceBinding)).To(Succeed()) + Expect(k8s.Patch(ctx, adminClient, serviceBinding, func() { serviceBinding.Status.Conditions = []metav1.Condition{} serviceBinding.Status.Binding = corev1.LocalObjectReference{ Name: serviceInstanceSecret.Name, @@ -120,7 +120,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) }) It("sets the last-stop-app-rev annotation to the value of the app-rev annotation", func() { @@ -156,7 +156,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { g.Expect(vcapApplicationSecretName).NotTo(BeEmpty()) vcapApplicationSecretLookupKey := types.NamespacedName{Name: vcapApplicationSecretName, Namespace: cfSpace.Status.GUID} - g.Expect(k8sClient.Get(ctx, vcapApplicationSecretLookupKey, &createdSecret)).To(Succeed()) + g.Expect(adminClient.Get(ctx, vcapApplicationSecretLookupKey, &createdSecret)).To(Succeed()) }).Should(Succeed()) Expect(createdSecret.Data).To(HaveKeyWithValue("VCAP_APPLICATION", ContainSubstring("application_id"))) @@ -174,7 +174,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { g.Expect(vcapServicesSecretName).NotTo(BeEmpty()) vcapServicesSecretLookupKey := types.NamespacedName{Name: vcapServicesSecretName, Namespace: cfSpace.Status.GUID} - g.Expect(k8sClient.Get(ctx, vcapServicesSecretLookupKey, secret)).To(Succeed()) + g.Expect(adminClient.Get(ctx, vcapServicesSecretLookupKey, secret)).To(Succeed()) g.Expect(secret.Data).To(HaveKeyWithValue("VCAP_SERVICES", ContainSubstring("user-provided"))) }).Should(Succeed()) @@ -213,12 +213,12 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { JustBeforeEach(func() { vcapServicesSecret = getVCAPServicesSecret() - Expect(k8sClient.Delete(ctx, serviceBinding)).To(Succeed()) + Expect(adminClient.Delete(ctx, serviceBinding)).To(Succeed()) }) It("updates the VCAP_SERVICES secret", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(vcapServicesSecret), vcapServicesSecret)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(vcapServicesSecret), vcapServicesSecret)).To(Succeed()) g.Expect(vcapServicesSecret.Data).To(HaveKeyWithValue("VCAP_SERVICES", Equal([]byte("{}")))) }).Should(Succeed()) }) @@ -237,7 +237,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { cfApp = BuildCFAppCRObject(cfAppGUID, cfSpace.Status.GUID) cfApp.Spec.CurrentDropletRef.Name = "droplet-that-does-not-exist" Expect( - k8sClient.Create(context.Background(), cfApp), + adminClient.Create(context.Background(), cfApp), ).To(Succeed()) }) @@ -281,12 +281,12 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { cfApp = BuildCFAppCRObject(cfAppGUID, cfSpace.Status.GUID) Expect( - k8sClient.Create(context.Background(), cfApp), + adminClient.Create(context.Background(), cfApp), ).To(Succeed()) cfPackage = BuildCFPackageCRObject(cfPackageGUID, cfSpace.Status.GUID, cfAppGUID, "ref") Expect( - k8sClient.Create(context.Background(), cfPackage), + adminClient.Create(context.Background(), cfPackage), ).To(Succeed()) cfBuild = BuildCFBuildObject(cfBuildGUID, cfSpace.Status.GUID, cfPackageGUID, cfAppGUID) @@ -298,9 +298,9 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { JustBeforeEach(func() { buildDropletStatus := BuildCFBuildDropletStatusObject(dropletProcessTypes, []int32{port8080, port9000}) - cfBuild = createBuildWithDroplet(context.Background(), k8sClient, cfBuild, buildDropletStatus) + cfBuild = createBuildWithDroplet(context.Background(), adminClient, cfBuild, buildDropletStatus) - patchAppWithDroplet(context.Background(), k8sClient, cfAppGUID, cfSpace.Status.GUID, cfBuildGUID) + patchAppWithDroplet(context.Background(), adminClient, cfAppGUID, cfSpace.Status.GUID, cfBuildGUID) }) When("CFProcesses do not exist for the app", func() { @@ -312,7 +312,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { cfProcessList := korifiv1alpha1.CFProcessList{} Eventually(func() []korifiv1alpha1.CFProcess { Expect( - k8sClient.List(testCtx, &cfProcessList, &client.ListOptions{ + adminClient.List(testCtx, &cfProcessList, &client.ListOptions{ LabelSelector: labelSelectorForAppAndProcess(cfAppGUID, process.Type), Namespace: cfApp.Namespace, }), @@ -349,7 +349,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { cfProcessForTypeWebGUID = GenerateGUID() cfProcessForTypeWeb = BuildCFProcessCRObject(cfProcessForTypeWebGUID, cfSpace.Status.GUID, cfAppGUID, processTypeWeb, processTypeWebCommand, "") cfProcessForTypeWeb.Spec.Command = "" - Expect(k8sClient.Create(beforeCtx, cfProcessForTypeWeb)).To(Succeed()) + Expect(adminClient.Create(beforeCtx, cfProcessForTypeWeb)).To(Succeed()) }) When("a process from processTypes does not exist", func() { @@ -367,7 +367,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { When("the command on the web process is not empty", func() { BeforeEach(func() { - Expect(k8s.Patch(context.Background(), k8sClient, cfProcessForTypeWeb, func() { + Expect(k8s.Patch(context.Background(), adminClient, cfProcessForTypeWeb, func() { cfProcessForTypeWeb.Spec.Command = "something else" })).To(Succeed()) }) @@ -397,7 +397,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { var webProcessesList korifiv1alpha1.CFProcessList Eventually(func() []korifiv1alpha1.CFProcess { Expect( - k8sClient.List(context.Background(), &webProcessesList, &client.ListOptions{ + adminClient.List(context.Background(), &webProcessesList, &client.ListOptions{ LabelSelector: labelSelectorForAppAndProcess(cfAppGUID, processTypeWeb), Namespace: cfApp.Namespace, }), @@ -418,24 +418,22 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { BeforeEach(func() { existingWebProcess = BuildCFProcessCRObject(GenerateGUID(), cfSpace.Status.GUID, cfAppGUID, processTypeWeb, processTypeWebCommand, "") Expect( - k8sClient.Create(context.Background(), existingWebProcess), + adminClient.Create(context.Background(), existingWebProcess), ).To(Succeed()) }) It("doesn't alter the existing `web` process", func() { var webProcessesList korifiv1alpha1.CFProcessList - Consistently(func() []korifiv1alpha1.CFProcess { - Expect( - k8sClient.List(context.Background(), &webProcessesList, &client.ListOptions{ - LabelSelector: labelSelectorForAppAndProcess(cfAppGUID, processTypeWeb), - Namespace: cfApp.Namespace, - }), - ).To(Succeed()) - return webProcessesList.Items - }, 5*time.Second).Should(HaveLen(1)) - webProcess := webProcessesList.Items[0] - Expect(webProcess.Name).To(Equal(existingWebProcess.Name)) - Expect(webProcess.Spec).To(Equal(existingWebProcess.Spec)) + Consistently(func(g Gomega) { + g.Expect(adminClient.List(context.Background(), &webProcessesList, &client.ListOptions{ + LabelSelector: labelSelectorForAppAndProcess(cfAppGUID, processTypeWeb), + Namespace: cfApp.Namespace, + })).To(Succeed()) + g.Expect(webProcessesList.Items).To(HaveLen(1)) + }).WithTimeout(5 * time.Second).Should(Succeed()) + + Expect(webProcessesList.Items[0].Name).To(Equal(existingWebProcess.Name)) + Expect(webProcessesList.Items[0].Spec).To(Equal(existingWebProcess.Spec)) }) }) }) @@ -456,7 +454,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { } dropletPorts := []int32{} buildDropletStatus := BuildCFBuildDropletStatusObject(dropletProcessTypeMap, dropletPorts) - otherCFBuild = createBuildWithDroplet(beforeCtx, k8sClient, otherCFBuild, buildDropletStatus) + otherCFBuild = createBuildWithDroplet(beforeCtx, adminClient, otherCFBuild, buildDropletStatus) }) It("eventually creates CFProcess with empty ports and a healthCheck type of \"process\"", func() { @@ -467,7 +465,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { cfProcessList := korifiv1alpha1.CFProcessList{} Eventually(func() []korifiv1alpha1.CFProcess { Expect( - k8sClient.List(testCtx, &cfProcessList, &client.ListOptions{ + adminClient.List(testCtx, &cfProcessList, &client.ListOptions{ LabelSelector: labelSelectorForAppAndProcess(cfAppGUID, process.Type), Namespace: cfApp.Namespace, }), @@ -502,7 +500,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { g.Expect(readyStatusCondition.Status).To(Equal(metav1.ConditionTrue)) g.Expect(readyStatusCondition.ObservedGeneration).To(Equal(createdCFApp.Generation)) }).Should(Succeed()) - Expect(k8sClient.Delete(context.Background(), cfBuild)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), cfBuild)).To(Succeed()) }) It("sets the ready condition to false", func() { @@ -530,7 +528,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { BeforeEach(func() { cfAppGUID = GenerateGUID() cfApp = BuildCFAppCRObject(cfAppGUID, cfSpace.Status.GUID) - Expect(k8sClient.Create(context.Background(), cfApp)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfApp)).To(Succeed()) cfRouteGUID = GenerateGUID() cfRoute = &korifiv1alpha1.CFRoute{ @@ -559,17 +557,17 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { }, }, } - Expect(k8sClient.Create(context.Background(), cfRoute)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfRoute)).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Delete(context.Background(), cfApp)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), cfApp)).To(Succeed()) }) It("eventually deletes the CFApp", func() { Eventually(func() bool { var createdCFApp korifiv1alpha1.CFApp - err := k8sClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, &createdCFApp) + err := adminClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, &createdCFApp) return apierrors.IsNotFound(err) }).Should(BeTrue(), "timed out waiting for app to be deleted") }) @@ -581,7 +579,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { It("eventually deletes the destination on the CFRoute", func() { Eventually(func(g Gomega) { var createdCFRoute korifiv1alpha1.CFRoute - err := k8sClient.Get(context.Background(), types.NamespacedName{Name: cfRouteGUID, Namespace: cfSpace.Status.GUID}, &createdCFRoute) + err := adminClient.Get(context.Background(), types.NamespacedName{Name: cfRouteGUID, Namespace: cfSpace.Status.GUID}, &createdCFRoute) g.Expect(err).NotTo(HaveOccurred()) g.Expect(createdCFRoute.Spec.Destinations).To(BeEmpty()) }).Should(Succeed()) @@ -600,13 +598,13 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { }, }, } - Expect(k8sClient.Create(context.Background(), &cfServiceBinding)).To(Succeed()) + Expect(adminClient.Create(context.Background(), &cfServiceBinding)).To(Succeed()) }) It("deletes the referencing service bindings", func() { Eventually(func(g Gomega) { sbList := korifiv1alpha1.CFServiceBindingList{} - g.Expect(k8sClient.List(context.Background(), &sbList, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) + g.Expect(adminClient.List(context.Background(), &sbList, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) g.Expect(sbList.Items).To(BeEmpty()) }).Should(Succeed()) }) @@ -617,7 +615,7 @@ var _ = Describe("CFAppReconciler Integration Tests", func() { func getApp(nsGUID, appGUID string) (*korifiv1alpha1.CFApp, error) { cfAppLookupKey := types.NamespacedName{Name: appGUID, Namespace: nsGUID} createdCFApp := &korifiv1alpha1.CFApp{} - err := k8sClient.Get(context.Background(), cfAppLookupKey, createdCFApp) + err := adminClient.Get(context.Background(), cfAppLookupKey, createdCFApp) return createdCFApp, err } @@ -625,7 +623,7 @@ func findProcessWithType(cfApp *korifiv1alpha1.CFApp, processType string) *korif cfProcessList := &korifiv1alpha1.CFProcessList{} Eventually(func(g Gomega) { - g.Expect(k8sClient.List(ctx, cfProcessList, &client.ListOptions{ + g.Expect(adminClient.List(ctx, cfProcessList, &client.ListOptions{ LabelSelector: labelSelectorForAppAndProcess(cfApp.Name, processType), Namespace: cfApp.Namespace, })).To(Succeed()) diff --git a/controllers/controllers/workloads/cfbuild_controller_test.go b/controllers/controllers/workloads/cfbuild_controller_test.go index c0da57101..8f0b574a0 100644 --- a/controllers/controllers/workloads/cfbuild_controller_test.go +++ b/controllers/controllers/workloads/cfbuild_controller_test.go @@ -2,6 +2,7 @@ package workloads_test import ( "context" + "errors" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" . "code.cloudfoundry.org/korifi/controllers/controllers/workloads/testutils" @@ -43,7 +44,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { Eventually(func(g Gomega) { workload := new(korifiv1alpha1.BuildWorkload) lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} - g.Expect(k8sClient.Get(context.Background(), lookupKey, workload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, workload)).To(Succeed()) assertion(workload, g) }).Should(Succeed()) } @@ -56,11 +57,11 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { beforeCtx := context.Background() desiredCFApp = BuildCFAppCRObject(cfAppGUID, cfSpace.Status.GUID) - Expect(k8sClient.Create(beforeCtx, desiredCFApp)).To(Succeed()) + Expect(adminClient.Create(beforeCtx, desiredCFApp)).To(Succeed()) Eventually(func(g Gomega) { actualCFApp := &korifiv1alpha1.CFApp{} - g.Expect(k8sClient.Get(beforeCtx, types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, actualCFApp)).To(Succeed()) + g.Expect(adminClient.Get(beforeCtx, types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, actualCFApp)).To(Succeed()) g.Expect(actualCFApp.Status.VCAPServicesSecretName).NotTo(BeEmpty()) }).Should(Succeed()) @@ -68,14 +69,14 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { "a_key": "a-val", "b_key": "b-val", }) - Expect(k8sClient.Create(context.Background(), envVarSecret)).To(Succeed()) + Expect(adminClient.Create(context.Background(), envVarSecret)).To(Succeed()) dockerRegistrySecret := BuildDockerRegistrySecret(wellFormedRegistryCredentialsSecret, cfSpace.Status.GUID) - Expect(k8sClient.Create(beforeCtx, dockerRegistrySecret)).To(Succeed()) + Expect(adminClient.Create(beforeCtx, dockerRegistrySecret)).To(Succeed()) registryServiceAccountName := "kpack-service-account" registryServiceAccount := BuildServiceAccount(registryServiceAccountName, cfSpace.Status.GUID, wellFormedRegistryCredentialsSecret) - Expect(k8sClient.Create(beforeCtx, registryServiceAccount)).To(Succeed()) + Expect(adminClient.Create(beforeCtx, registryServiceAccount)).To(Succeed()) desiredBuildpacks = []string{"first-buildpack", "second-buildpack"} }) @@ -86,17 +87,17 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { BeforeEach(func() { cleanCallCount = buildCleaner.CleanCallCount() desiredCFPackage = BuildCFPackageCRObject(cfPackageGUID, cfSpace.Status.GUID, cfAppGUID, "ref") - Expect(k8sClient.Create(ctx, desiredCFPackage)).To(Succeed()) + Expect(adminClient.Create(ctx, desiredCFPackage)).To(Succeed()) kpackSecret := BuildDockerRegistrySecret("source-registry-image-pull-secret", cfSpace.Status.GUID) - Expect(k8sClient.Create(ctx, kpackSecret)).To(Succeed()) + Expect(adminClient.Create(ctx, kpackSecret)).To(Succeed()) }) JustBeforeEach(func() { cfBuildGUID = PrefixedGUID("cf-build") desiredCFBuild = BuildCFBuildObject(cfBuildGUID, cfSpace.Status.GUID, cfPackageGUID, cfAppGUID) desiredCFBuild.Spec.Lifecycle.Data.Buildpacks = desiredBuildpacks - Expect(k8sClient.Create(context.Background(), desiredCFBuild)).To(Succeed()) + Expect(adminClient.Create(context.Background(), desiredCFBuild)).To(Succeed()) }) It("cleans up older builds and droplets", func() { @@ -112,7 +113,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { Eventually(func(g Gomega) { var createdCFBuild korifiv1alpha1.CFBuild lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} - g.Expect(k8sClient.Get(context.Background(), lookupKey, &createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, &createdCFBuild)).To(Succeed()) g.Expect(createdCFBuild.GetOwnerReferences()).To(ConsistOf( metav1.OwnerReference{ APIVersion: korifiv1alpha1.GroupVersion.Identifier(), @@ -130,14 +131,14 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { Eventually(func(g Gomega) { var createdCFBuild korifiv1alpha1.CFBuild lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} - g.Expect(k8sClient.Get(context.Background(), lookupKey, &createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, &createdCFBuild)).To(Succeed()) g.Expect(createdCFBuild.Status.ObservedGeneration).To(Equal(createdCFBuild.Generation)) }).Should(Succeed()) }) It("creates a BuildWorkload with the buildRef, source, env, and buildpacks set", func() { createdCFApp := &korifiv1alpha1.CFApp{} - Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, createdCFApp)).To(Succeed()) + Expect(adminClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, createdCFApp)).To(Succeed()) eventuallyBuildWorkloadShould(func(workload *korifiv1alpha1.BuildWorkload, g Gomega) { g.Expect(workload.Spec.BuildRef.Name).To(Equal(cfBuildGUID)) @@ -197,7 +198,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { createdWorkload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdWorkload)).To(Succeed()) g.Expect(createdWorkload.GetOwnerReferences()).To(ConsistOf(metav1.OwnerReference{ UID: desiredCFBuild.UID, Kind: "CFBuild", @@ -213,7 +214,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { createdCFBuild := new(korifiv1alpha1.CFBuild) - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) stagingCondition := meta.FindStatusCondition(createdCFBuild.Status.Conditions, stagingConditionType) g.Expect(stagingCondition).NotTo(BeNil()) @@ -251,7 +252,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { StringData: secret1Data, } Expect( - k8sClient.Create(ctx, secret1), + adminClient.Create(ctx, secret1), ).To(Succeed()) serviceInstance1 = &korifiv1alpha1.CFServiceInstance{ @@ -270,7 +271,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { }, } Expect( - k8sClient.Create(ctx, serviceInstance1), + adminClient.Create(ctx, serviceInstance1), ).To(Succeed()) serviceBinding1Name := "service-binding-1-name" @@ -295,7 +296,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { }, } Expect( - k8sClient.Create(ctx, serviceBinding1), + adminClient.Create(ctx, serviceBinding1), ).To(Succeed()) secret2Data := map[string]string{ @@ -310,7 +311,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { StringData: secret2Data, } Expect( - k8sClient.Create(ctx, secret2), + adminClient.Create(ctx, secret2), ).To(Succeed()) serviceInstance2 = &korifiv1alpha1.CFServiceInstance{ @@ -326,7 +327,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { }, } Expect( - k8sClient.Create(ctx, serviceInstance2), + adminClient.Create(ctx, serviceInstance2), ).To(Succeed()) serviceBinding2Name := "service-binding-2-name" @@ -351,7 +352,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { }, } Expect( - k8sClient.Create(ctx, serviceBinding2), + adminClient.Create(ctx, serviceBinding2), ).To(Succeed()) createdServiceBinding1 := serviceBinding1.DeepCopy() @@ -362,7 +363,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { Reason: "SecretFound", Message: "", }) - Expect(k8sClient.Status().Patch(ctx, createdServiceBinding1, client.MergeFrom(serviceBinding1))).To(Succeed()) + Expect(adminClient.Status().Patch(ctx, createdServiceBinding1, client.MergeFrom(serviceBinding1))).To(Succeed()) createdServiceBinding2 := serviceBinding2.DeepCopy() createdServiceBinding2.Status.Binding.Name = secret2.Name @@ -372,7 +373,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { Reason: "SecretFound", Message: "", }) - Expect(k8sClient.Status().Patch(ctx, createdServiceBinding2, client.MergeFrom(serviceBinding2))).To(Succeed()) + Expect(adminClient.Status().Patch(ctx, createdServiceBinding2, client.MergeFrom(serviceBinding2))).To(Succeed()) }) It("creates a BuildWorkload with the underlying secret mapped onto it", func() { @@ -394,7 +395,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { It("sets the VCAP_SERVICES env var in the image", func() { createdCFApp := &korifiv1alpha1.CFApp{} - Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, createdCFApp)).To(Succeed()) + Expect(adminClient.Get(context.Background(), types.NamespacedName{Name: cfAppGUID, Namespace: cfSpace.Status.GUID}, createdCFApp)).To(Succeed()) eventuallyBuildWorkloadShould(func(workload *korifiv1alpha1.BuildWorkload, g Gomega) { g.Expect(workload.Spec.Env).To(ContainElements( @@ -439,15 +440,15 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { } newCFBuild = BuildCFBuildObject(newCFBuildGUID, cfSpace.Status.GUID, cfPackageGUID, cfAppGUID) - Expect(k8sClient.Create(ctx, existingBuildWorkload)).To(Succeed()) - Expect(k8sClient.Create(ctx, newCFBuild)).To(Succeed()) + Expect(adminClient.Create(ctx, existingBuildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, newCFBuild)).To(Succeed()) }) It("sets the status conditions on CFBuild", func() { lookupKey := types.NamespacedName{Name: newCFBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { createdCFBuild := new(korifiv1alpha1.CFBuild) - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) stagingCondition := meta.FindStatusCondition(createdCFBuild.Status.Conditions, stagingConditionType) g.Expect(stagingCondition).NotTo(BeNil()) @@ -472,11 +473,11 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { BeforeEach(func() { desiredCFPackage = BuildCFPackageCRObject(cfPackageGUID, cfSpace.Status.GUID, cfAppGUID, "ref") desiredCFPackage.Spec.Source.Registry.ImagePullSecrets = []corev1.LocalObjectReference{{Name: wellFormedRegistryCredentialsSecret}} - Expect(k8sClient.Create(context.Background(), desiredCFPackage)).To(Succeed()) + Expect(adminClient.Create(context.Background(), desiredCFPackage)).To(Succeed()) cfBuildGUID = PrefixedGUID("cf-build") desiredCFBuild = BuildCFBuildObject(cfBuildGUID, cfSpace.Status.GUID, cfPackageGUID, cfAppGUID) - Expect(k8sClient.Create(context.Background(), desiredCFBuild)).To(Succeed()) + Expect(adminClient.Create(context.Background(), desiredCFBuild)).To(Succeed()) }) When("the BuildWorkload failed", func() { @@ -485,8 +486,8 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { workload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(testCtx, lookupKey, workload)).To(Succeed()) - g.Expect(k8s.Patch(testCtx, k8sClient, workload, func() { + g.Expect(adminClient.Get(testCtx, lookupKey, workload)).To(Succeed()) + g.Expect(k8s.Patch(testCtx, adminClient, workload, func() { setBuildWorkloadStatus(workload, succeededConditionType, metav1.ConditionFalse) })).To(Succeed()) }).Should(Succeed()) @@ -496,7 +497,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} createdCFBuild := new(korifiv1alpha1.CFBuild) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) stagingStatusCondition := meta.FindStatusCondition(createdCFBuild.Status.Conditions, stagingConditionType) g.Expect(stagingStatusCondition).NotTo(BeNil()) @@ -537,8 +538,8 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { workload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(ctx, lookupKey, workload)).To(Succeed()) - g.Expect(k8s.Patch(ctx, k8sClient, workload, func() { + g.Expect(adminClient.Get(ctx, lookupKey, workload)).To(Succeed()) + g.Expect(k8s.Patch(ctx, adminClient, workload, func() { setBuildWorkloadStatus(workload, succeededConditionType, "True") workload.Status.Droplet = &korifiv1alpha1.BuildDropletStatus{ Registry: korifiv1alpha1.Registry{ @@ -558,7 +559,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { createdCFBuild := new(korifiv1alpha1.CFBuild) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) stagingStatusCondition := meta.FindStatusCondition(createdCFBuild.Status.Conditions, stagingConditionType) g.Expect(stagingStatusCondition).NotTo(BeNil()) g.Expect(stagingStatusCondition.Status).To(Equal(metav1.ConditionFalse)) @@ -577,7 +578,7 @@ var _ = Describe("CFBuildReconciler Integration Tests", func() { lookupKey := types.NamespacedName{Name: cfBuildGUID, Namespace: cfSpace.Status.GUID} Eventually(func(g Gomega) { createdCFBuild := new(korifiv1alpha1.CFBuild) - g.Expect(k8sClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), lookupKey, createdCFBuild)).To(Succeed()) g.Expect(createdCFBuild.Status.Droplet).NotTo(BeNil()) g.Expect(createdCFBuild.Status.Droplet.Registry.Image).To(Equal(buildImageRef)) g.Expect(createdCFBuild.Status.Droplet.Registry.ImagePullSecrets).To(ConsistOf(corev1.LocalObjectReference{Name: imagePullSecretName})) diff --git a/controllers/controllers/workloads/cforg_controller_test.go b/controllers/controllers/workloads/cforg_controller_test.go index bdbc3892d..f9d8c9f6f 100644 --- a/controllers/controllers/workloads/cforg_controller_test.go +++ b/controllers/controllers/workloads/cforg_controller_test.go @@ -41,15 +41,15 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { Resources: []string{"cfapps"}, }, } - role = createClusterRole(ctx, k8sClient, PrefixedGUID("clusterrole"), rules) + role = createClusterRole(ctx, adminClient, PrefixedGUID("clusterrole"), rules) username = PrefixedGUID("user") - roleBinding = createRoleBinding(ctx, k8sClient, PrefixedGUID("role-binding"), username, role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) + roleBinding = createRoleBinding(ctx, adminClient, PrefixedGUID("role-binding"), username, role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) username2 := PrefixedGUID("user2") - roleBindingWithPropagateAnnotationSetToFalse = createRoleBinding(ctx, k8sClient, PrefixedGUID("rb-propagate-annotation-false"), username2, role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "false"}) + roleBindingWithPropagateAnnotationSetToFalse = createRoleBinding(ctx, adminClient, PrefixedGUID("rb-propagate-annotation-false"), username2, role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "false"}) - roleBindingWithMissingPropagateAnnotation = createRoleBinding(ctx, k8sClient, PrefixedGUID("rb-missing-propagate-annotation"), username2, role.Name, cfRootNamespace, nil) + roleBindingWithMissingPropagateAnnotation = createRoleBinding(ctx, adminClient, PrefixedGUID("rb-missing-propagate-annotation"), username2, role.Name, cfRootNamespace, nil) orgGUID = PrefixedGUID("cf-org") cfOrg = korifiv1alpha1.CFOrg{ @@ -65,13 +65,13 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { When("the CFOrg is created", func() { JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, &cfOrg)).To(Succeed()) }) It("creates an org namespace and sets labels", func() { Eventually(func(g Gomega) { var orgNamespace v1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) g.Expect(orgNamespace.Labels).To(SatisfyAll( HaveKeyWithValue(korifiv1alpha1.OrgNameKey, korifiv1alpha1.OrgSpaceDeprecatedName), @@ -84,7 +84,7 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { It("sets the finalizer on cfOrg", func() { Eventually(func(g Gomega) []string { var createdCFOrg korifiv1alpha1.CFOrg - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdCFOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdCFOrg)).To(Succeed()) return createdCFOrg.ObjectMeta.Finalizers }).Should(ConsistOf([]string{ "cfOrg.korifi.cloudfoundry.org", @@ -95,8 +95,8 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { var createdSecret1, createdSecret2 v1.Secret Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret2.Name}, &createdSecret2)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret2.Name}, &createdSecret2)).To(Succeed()) }).Should(Succeed()) Expect(createdSecret1.Data).To(Equal(imageRegistrySecret1.Data)) @@ -112,17 +112,17 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { When("the image-registry-credentials secret does not exist in the root-ns", Serial, func() { BeforeEach(func() { - Expect(k8sClient.Delete(ctx, imageRegistrySecret1)).To(Succeed()) + Expect(adminClient.Delete(ctx, imageRegistrySecret1)).To(Succeed()) }) AfterEach(func() { - imageRegistrySecret1 = createImageRegistrySecret(ctx, k8sClient, packageRegistrySecretName, cfRootNamespace) + imageRegistrySecret1 = createImageRegistrySecret(ctx, adminClient, packageRegistrySecretName, cfRootNamespace) }) It("sets the CFOrg's Ready condition to 'False'", func() { Eventually(func(g Gomega) { var createdOrg korifiv1alpha1.CFOrg - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdOrg.Status.Conditions, "Ready")).To(BeFalse()) @@ -142,28 +142,28 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { It("propagates the role-bindings with annotation \"cloudfoundry.org/propagate-cf-role\" set to \"true\" from root-ns to org namespace", func() { Eventually(func(_ Gomega) error { var createdRoleBinding rbacv1.RoleBinding - return k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBinding.Name}, &createdRoleBinding) + return adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBinding.Name}, &createdRoleBinding) }).Should(Succeed()) }) It("does not propagate role-bindings with annotation \"cloudfoundry.org/propagate-cf-role\" set to \"false\"", func() { Consistently(func(_ Gomega) bool { var newRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBindingWithPropagateAnnotationSetToFalse.Name}, &newRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBindingWithPropagateAnnotationSetToFalse.Name}, &newRoleBinding)) }, time.Second).Should(BeTrue()) }) It("does not propagate role-bindings with missing annotation \"cloudfoundry.org/propagate-cf-role\"", func() { Consistently(func(_ Gomega) bool { var newRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBindingWithMissingPropagateAnnotation.Name}, &newRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: roleBindingWithMissingPropagateAnnotation.Name}, &newRoleBinding)) }, time.Second).Should(BeTrue()) }) It("sets the status on the CFOrg", func() { Eventually(func(g Gomega) { var createdOrg korifiv1alpha1.CFOrg - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) g.Expect(createdOrg.Status.GUID).To(Equal(orgGUID)) g.Expect(createdOrg.Status.ObservedGeneration).To(Equal(createdOrg.Generation)) @@ -174,7 +174,7 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { It("sets restricted pod security labels on the namespace", func() { Eventually(func(g Gomega) { var ns v1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &ns)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &ns)).To(Succeed()) g.Expect(ns.Labels).To(HaveKeyWithValue(api.EnforceLevelLabel, string(api.LevelRestricted))) }).Should(Succeed()) @@ -185,30 +185,30 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { var originalOrg *korifiv1alpha1.CFOrg BeforeEach(func() { - Expect(k8sClient.Create(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, &cfOrg)).To(Succeed()) originalOrg = cfOrg.DeepCopy() var createdNamespace v1.Namespace Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &createdNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &createdNamespace)).To(Succeed()) }).Should(Succeed()) updatedNamespace := createdNamespace.DeepCopy() updatedNamespace.Labels["foo.com/bar"] = "42" updatedNamespace.Annotations["foo.com/bar"] = "43" - Expect(k8sClient.Patch(ctx, updatedNamespace, client.MergeFrom(&createdNamespace))).To(Succeed()) + Expect(adminClient.Patch(ctx, updatedNamespace, client.MergeFrom(&createdNamespace))).To(Succeed()) cfOrg.Spec.DisplayName += "x" }) JustBeforeEach(func() { - Expect(k8sClient.Patch(ctx, &cfOrg, client.MergeFrom(originalOrg))).To(Succeed()) + Expect(adminClient.Patch(ctx, &cfOrg, client.MergeFrom(originalOrg))).To(Succeed()) }) It("sets the new display name annotation and preserves the added label and annoations", func() { Eventually(func(g Gomega) { var createdOrg v1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &createdOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &createdOrg)).To(Succeed()) g.Expect(createdOrg.Annotations).To(HaveKeyWithValue("foo.com/bar", "43")) g.Expect(createdOrg.Annotations).To(HaveKeyWithValue(korifiv1alpha1.OrgNameKey, cfOrg.Spec.DisplayName)) @@ -220,22 +220,22 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { When("role-bindings are added/updated in root-ns after CFOrg creation", func() { var newlyCreatedRoleBinding *rbacv1.RoleBinding BeforeEach(func() { - Expect(k8sClient.Create(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, &cfOrg)).To(Succeed()) Eventually(func(g Gomega) { var createdOrg korifiv1alpha1.CFOrg - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdOrg.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) - newlyCreatedRoleBinding = createRoleBinding(ctx, k8sClient, PrefixedGUID("newly-created-role-binding"), PrefixedGUID("new-user"), role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) + newlyCreatedRoleBinding = createRoleBinding(ctx, adminClient, PrefixedGUID("newly-created-role-binding"), PrefixedGUID("new-user"), role.Name, cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) }) It("propagates the new role-binding to org namespace", func() { Eventually(func(g Gomega) { var createdRoleBindings rbacv1.RoleBindingList - g.Expect(k8sClient.List(ctx, &createdRoleBindings, client.InNamespace(cfOrg.Name))).To(Succeed()) + g.Expect(adminClient.List(ctx, &createdRoleBindings, client.InNamespace(cfOrg.Name))).To(Succeed()) g.Expect(createdRoleBindings.Items).To(ContainElements( MatchFields(IgnoreExtras, Fields{ @@ -255,24 +255,24 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { When("role bindings are deleted in the root-ns after CFOrg creation", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, &cfOrg)).To(Succeed()) Eventually(func(g Gomega) { var createdOrg korifiv1alpha1.CFOrg - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfRootNamespace, Name: orgGUID}, &createdOrg)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdOrg.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Delete(ctx, roleBinding)).To(Succeed()) + Expect(adminClient.Delete(ctx, roleBinding)).To(Succeed()) }) It("deletes the corresponding role binding in CFOrg", func() { Eventually(func() bool { var deletedRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, &deletedRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, &deletedRoleBinding)) }).Should(BeTrue(), "timed out waiting for role binding to be deleted") }) @@ -281,12 +281,12 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { origRoleBinding := roleBinding.DeepCopy() roleBinding.Annotations["cloudfoundry.org/propagate-deletion"] = "false" - Expect(k8sClient.Patch(ctx, roleBinding, client.MergeFrom(origRoleBinding))).To(Succeed()) + Expect(adminClient.Patch(ctx, roleBinding, client.MergeFrom(origRoleBinding))).To(Succeed()) Eventually(func(g Gomega) map[string]string { var copiedRoleBinding rbacv1.RoleBinding g.Expect( - k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, &copiedRoleBinding), + adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, &copiedRoleBinding), ).To(Succeed()) return copiedRoleBinding.Annotations }).Should(HaveKeyWithValue("cloudfoundry.org/propagate-deletion", "false")) @@ -294,7 +294,7 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { It("doesn't delete the corresponding role binding in the CFOrg", func() { Consistently(func() bool { - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, new(rbacv1.RoleBinding))) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfOrg.Name}, new(rbacv1.RoleBinding))) }).Should(BeFalse(), "org's copy of role binding was deleted and shouldn't have been") }) }) @@ -302,21 +302,21 @@ var _ = Describe("CFOrgReconciler Integration Tests", func() { When("the CFOrg is deleted", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, &cfOrg)).To(Succeed()) Eventually(func(g Gomega) { var orgNamespace v1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) }).Should(Succeed()) - Expect(k8sClient.Delete(ctx, &cfOrg)).To(Succeed()) + Expect(adminClient.Delete(ctx, &cfOrg)).To(Succeed()) }) It("eventually deletes the namespace", func() { // Envtests do not cleanup namespaces. For testing, we check for deletion timestamps on namespace. Eventually(func(g Gomega) bool { var orgNamespace v1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: orgGUID}, &orgNamespace)).To(Succeed()) return orgNamespace.GetDeletionTimestamp().IsZero() }).Should(BeFalse(), "timed out waiting for deletion timestamps to be set on namespace") diff --git a/controllers/controllers/workloads/cfpackage_controller_test.go b/controllers/controllers/workloads/cfpackage_controller_test.go index da9839b15..c364425ff 100644 --- a/controllers/controllers/workloads/cfpackage_controller_test.go +++ b/controllers/controllers/workloads/cfpackage_controller_test.go @@ -36,7 +36,7 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { cfApp = BuildCFAppCRObject(cfAppGUID, cfSpace.Status.GUID) - Expect(k8sClient.Create(context.Background(), cfApp)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfApp)).To(Succeed()) }) When("a new CFPackage resource is created", func() { @@ -47,13 +47,13 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { cfPackage = BuildCFPackageCRObject(cfPackageGUID, cfSpace.Status.GUID, cfAppGUID, "ref") cfPackage.Spec.Source = korifiv1alpha1.PackageSource{} - Expect(k8sClient.Create(context.Background(), cfPackage)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfPackage)).To(Succeed()) }) It("initializes it", func() { var createdCFPackage korifiv1alpha1.CFPackage Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdCFPackage.Status.Conditions, workloads.InitializedConditionType)).To(BeTrue()) }).Should(Succeed()) @@ -85,7 +85,7 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { It("sets the ObservedGeneration status field", func() { var createdCFPackage korifiv1alpha1.CFPackage Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) g.Expect(createdCFPackage.Status.ObservedGeneration).To(Equal(createdCFPackage.Generation)) }).Should(Succeed()) @@ -96,20 +96,20 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { BeforeEach(func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdCFPackage.Status.Conditions, workloads.InitializedConditionType)).To(BeTrue()) }).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, &createdCFPackage, func() { + Expect(k8s.PatchResource(ctx, adminClient, &createdCFPackage, func() { createdCFPackage.Spec.Source.Registry.Image = "hello" })).To(Succeed()) }) It("sets the ready condition to true", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), &createdCFPackage)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdCFPackage.Status.Conditions, shared.StatusConditionReady)).To(BeTrue()) }).Should(Succeed()) }) @@ -129,14 +129,14 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(context.Background(), cfPackage)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfPackage)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(cfPackage.Status.Conditions, workloads.InitializedConditionType)).To(BeTrue()) }).Should(Succeed()) - Expect(k8sClient.Delete(context.Background(), cfPackage)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), cfPackage)).To(Succeed()) }) It("deletes itself and the corresponding source image", func() { @@ -151,7 +151,7 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { Expect(tagsToDelete).To(ConsistOf(cfPackage.Name)) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(MatchError(ContainSubstring("not found"))) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(MatchError(ContainSubstring("not found"))) }).Should(Succeed()) }) @@ -178,7 +178,7 @@ var _ = Describe("CFPackageReconciler Integration Tests", func() { It("ignores the errors and finishes finalization", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(MatchError(ContainSubstring("not found"))) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(cfPackage), cfPackage)).To(MatchError(ContainSubstring("not found"))) }).Should(Succeed()) }) }) diff --git a/controllers/controllers/workloads/cfprocess_controller_test.go b/controllers/controllers/workloads/cfprocess_controller_test.go index cc5840c2e..e705b38c7 100644 --- a/controllers/controllers/workloads/cfprocess_controller_test.go +++ b/controllers/controllers/workloads/cfprocess_controller_test.go @@ -71,20 +71,20 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { "c-test-env-key-third": "c-test-env-val-third", "a-test-env-key-first": "a-test-env-val-first", }) - Expect(k8sClient.Create(ctx, appEnvSecret)).To(Succeed()) + Expect(adminClient.Create(ctx, appEnvSecret)).To(Succeed()) - Expect(k8sClient.Create(ctx, cfPackage)).To(Succeed()) + Expect(adminClient.Create(ctx, cfPackage)).To(Succeed()) buildDropletStatus := BuildCFBuildDropletStatusObject(map[string]string{"web": "command-from-droplet"}, []int32{}) - cfBuild = createBuildWithDroplet(ctx, k8sClient, cfBuild, buildDropletStatus) + cfBuild = createBuildWithDroplet(ctx, adminClient, cfBuild, buildDropletStatus) - Expect(k8sClient.Create(ctx, cfProcess)).To(Succeed()) - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfProcess)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) }) It("eventually reconciles to set owner references on CFProcess", func() { Eventually(func() []metav1.OwnerReference { var createdCFProcess korifiv1alpha1.CFProcess - err := k8sClient.Get(ctx, types.NamespacedName{Name: testProcessGUID, Namespace: cfSpace.Status.GUID}, &createdCFProcess) + err := adminClient.Get(ctx, types.NamespacedName{Name: testProcessGUID, Namespace: cfSpace.Status.GUID}, &createdCFProcess) if err != nil { return nil } @@ -102,7 +102,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("sets the ObservedGeneration status field", func() { Eventually(func(g Gomega) { var createdCFProcess korifiv1alpha1.CFProcess - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: testProcessGUID, Namespace: cfSpace.Status.GUID}, &createdCFProcess)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: testProcessGUID, Namespace: cfSpace.Status.GUID}, &createdCFProcess)).To(Succeed()) g.Expect(createdCFProcess.Status.ObservedGeneration).To(Equal(createdCFProcess.Generation)) }).Should(Succeed()) @@ -114,7 +114,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("the CFApp desired state is STARTED", func() { BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StartedState })).To(Succeed()) }) @@ -122,7 +122,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("eventually reconciles the CFProcess into an AppWorkload", func() { eventuallyCreatedAppWorkloadShould(testProcessGUID, cfSpace.Status.GUID, func(g Gomega, appWorkload korifiv1alpha1.AppWorkload) { var updatedCFApp korifiv1alpha1.CFApp - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfApp), &updatedCFApp)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfApp), &updatedCFApp)).To(Succeed()) g.Expect(appWorkload.OwnerReferences).To(ConsistOf(metav1.OwnerReference{ APIVersion: korifiv1alpha1.GroupVersion.Identifier(), @@ -223,7 +223,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("The process command field isn't set", func() { BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfProcess, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfProcess, func() { cfProcess.Spec.Command = "" })).To(Succeed()) }) @@ -238,7 +238,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("a CFApp desired state is updated to STOPPED", func() { JustBeforeEach(func() { eventuallyCreatedAppWorkloadShould(testProcessGUID, cfSpace.Status.GUID, func(g Gomega, appWorkload korifiv1alpha1.AppWorkload) {}) - Expect(k8s.Patch(ctx, k8sClient, cfApp, func() { + Expect(k8s.Patch(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StoppedState })).To(Succeed()) }) @@ -246,7 +246,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("eventually deletes the AppWorkloads", func() { Eventually(func() ([]korifiv1alpha1.AppWorkload, error) { var appWorkloads korifiv1alpha1.AppWorkloadList - err := k8sClient.List(ctx, &appWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{ + err := adminClient.List(ctx, &appWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, }) return appWorkloads.Items, err @@ -257,7 +257,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("the app process instances are scaled down to 0", func() { JustBeforeEach(func() { eventuallyCreatedAppWorkloadShould(testProcessGUID, cfSpace.Status.GUID, func(g Gomega, appWorkload korifiv1alpha1.AppWorkload) {}) - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.DesiredInstances = tools.PtrTo(0) })).To(Succeed()) }) @@ -265,7 +265,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("deletes the app workload", func() { Eventually(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - err := k8sClient.List(context.Background(), &appWorkloads, client.InNamespace(cfProcess.Namespace), client.MatchingLabels{ + err := adminClient.List(context.Background(), &appWorkloads, client.InNamespace(cfProcess.Namespace), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, }) g.Expect(err).NotTo(HaveOccurred()) @@ -277,7 +277,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("the app process instances are unset", func() { JustBeforeEach(func() { eventuallyCreatedAppWorkloadShould(testProcessGUID, cfSpace.Status.GUID, func(g Gomega, appWorkload korifiv1alpha1.AppWorkload) {}) - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.DesiredInstances = nil })).To(Succeed()) }) @@ -285,7 +285,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("does not delete the app workload", func() { Consistently(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - err := k8sClient.List(context.Background(), &appWorkloads, client.InNamespace(cfProcess.Namespace), client.MatchingLabels{ + err := adminClient.List(context.Background(), &appWorkloads, client.InNamespace(cfProcess.Namespace), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, }) g.Expect(err).NotTo(HaveOccurred()) @@ -300,7 +300,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - g.Expect(k8sClient.List(context.Background(), &appWorkloads, + g.Expect(adminClient.List(context.Background(), &appWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, @@ -310,7 +310,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { prevAppWorkloadName = appWorkloads.Items[0].Name }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, cfApp, func() { + Expect(k8s.Patch(ctx, adminClient, cfApp, func() { cfApp.Annotations[korifiv1alpha1.CFAppRevisionKey] = "6" cfApp.Annotations[korifiv1alpha1.CFAppLastStopRevisionKey] = "6" })).To(Succeed()) @@ -319,7 +319,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { It("deletes the app workload and createas a new one", func() { Eventually(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - g.Expect(k8sClient.List(context.Background(), &appWorkloads, + g.Expect(adminClient.List(context.Background(), &appWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, @@ -337,7 +337,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { JustBeforeEach(func() { Eventually(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - g.Expect(k8sClient.List(context.Background(), &appWorkloads, + g.Expect(adminClient.List(context.Background(), &appWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: testProcessGUID, @@ -347,7 +347,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { appWorkloadName = appWorkloads.Items[0].Name }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, cfApp, func() { + Expect(k8s.Patch(ctx, adminClient, cfApp, func() { cfApp.Annotations[korifiv1alpha1.CFAppRevisionKey] = "6" })).To(Succeed()) }) @@ -361,7 +361,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { } Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(&appWorkload), &appWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(&appWorkload), &appWorkload)).To(Succeed()) }, "1s").Should(Succeed()) }) }) @@ -378,7 +378,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { Name: "a" + uuid.NewString() + ".com", }, } - Expect(k8sClient.Create(ctx, cfDomain)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDomain)).To(Succeed()) destination := korifiv1alpha1.Destination{ GUID: "destination2-guid", @@ -403,8 +403,8 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { Destinations: []korifiv1alpha1.Destination{destination}, }, } - Expect(k8sClient.Create(ctx, cfRoute)).To(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, cfRoute, func() { + Expect(adminClient.Create(ctx, cfRoute)).To(Succeed()) + Expect(k8s.Patch(ctx, adminClient, cfRoute, func() { cfRoute.Status = korifiv1alpha1.CFRouteStatus{ CurrentStatus: "valid", Description: "ok", @@ -412,7 +412,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { } })).To(Succeed()) - Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StartedState })).To(Succeed()) }) @@ -428,7 +428,7 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("the process has a health check", func() { JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.HealthCheck.Type = "http" cfProcess.Spec.HealthCheck.Data.InvocationTimeoutSeconds = 3 cfProcess.Spec.HealthCheck.Data.TimeoutSeconds = 31 @@ -464,13 +464,13 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { ) BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StartedState })).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.HealthCheck = korifiv1alpha1.HealthCheck{ Type: "http", Data: korifiv1alpha1.HealthCheckData{ @@ -513,13 +513,13 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { ) BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StartedState })).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.HealthCheck = korifiv1alpha1.HealthCheck{ Type: "port", Data: korifiv1alpha1.HealthCheckData{ @@ -553,13 +553,13 @@ var _ = Describe("CFProcessReconciler Integration Tests", func() { When("the CFProcess has a process health check", func() { BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfApp, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfApp, func() { cfApp.Spec.DesiredState = korifiv1alpha1.StartedState })).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, cfProcess, func() { + Expect(k8s.Patch(ctx, adminClient, cfProcess, func() { cfProcess.Spec.HealthCheck = korifiv1alpha1.HealthCheck{Type: "process"} })).To(Succeed()) }) @@ -578,7 +578,7 @@ func eventuallyCreatedAppWorkloadShould(processGUID, namespace string, shouldFn Eventually(func(g Gomega) { var appWorkloads korifiv1alpha1.AppWorkloadList - err := k8sClient.List(context.Background(), &appWorkloads, client.InNamespace(namespace), client.MatchingLabels{ + err := adminClient.List(context.Background(), &appWorkloads, client.InNamespace(namespace), client.MatchingLabels{ korifiv1alpha1.CFProcessGUIDLabelKey: processGUID, }) g.Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/controllers/workloads/cfspace_controller_test.go b/controllers/controllers/workloads/cfspace_controller_test.go index 38e1ada0a..cae181ba1 100644 --- a/controllers/controllers/workloads/cfspace_controller_test.go +++ b/controllers/controllers/workloads/cfspace_controller_test.go @@ -46,24 +46,24 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { Resources: []string{"cfapps"}, }, } - role = createClusterRole(ctx, k8sClient, PrefixedGUID("clusterrole"), rules) + role = createClusterRole(ctx, adminClient, PrefixedGUID("clusterrole"), rules) username = PrefixedGUID("user") - roleBinding = createRoleBinding(ctx, k8sClient, PrefixedGUID("role-binding"), username, role.Name, cfOrg.Status.GUID, map[string]string{ + roleBinding = createRoleBinding(ctx, adminClient, PrefixedGUID("role-binding"), username, role.Name, cfOrg.Status.GUID, map[string]string{ "cloudfoundry.org/propagate-cf-role": "true", "kapp.k14s.io/foo": "bar", "meta.helm.sh/bar": "baz", }) - roleBindingWithPropagateAnnotationSetToFalse = createRoleBinding(ctx, k8sClient, PrefixedGUID("rb-propagate-annotation-false"), username, role.Name, cfOrg.Status.GUID, map[string]string{"cloudfoundry.org/propagate-cf-role": "false"}) - roleBindingWithMissingPropagateAnnotation = createRoleBinding(ctx, k8sClient, PrefixedGUID("rb-missing-propagate-annotation"), username, role.Name, cfOrg.Status.GUID, nil) + roleBindingWithPropagateAnnotationSetToFalse = createRoleBinding(ctx, adminClient, PrefixedGUID("rb-propagate-annotation-false"), username, role.Name, cfOrg.Status.GUID, map[string]string{"cloudfoundry.org/propagate-cf-role": "false"}) + roleBindingWithMissingPropagateAnnotation = createRoleBinding(ctx, adminClient, PrefixedGUID("rb-missing-propagate-annotation"), username, role.Name, cfOrg.Status.GUID, nil) - serviceAccount = createServiceAccount(ctx, k8sClient, PrefixedGUID("service-account"), cfRootNamespace, map[string]string{ + serviceAccount = createServiceAccount(ctx, adminClient, PrefixedGUID("service-account"), cfRootNamespace, map[string]string{ "cloudfoundry.org/propagate-service-account": "true", "kapp.k14s.io/baz": "foo", "meta.helm.sh/foo": "bar", }) - serviceAccountWithPropagateAnnotationSetToFalse = createServiceAccount(ctx, k8sClient, PrefixedGUID("service-account-false-propagate"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "false"}) - serviceAccountWithMissingPropagateAnnotation = createServiceAccount(ctx, k8sClient, PrefixedGUID("service-account-no-propagate"), cfRootNamespace, nil) + serviceAccountWithPropagateAnnotationSetToFalse = createServiceAccount(ctx, adminClient, PrefixedGUID("service-account-false-propagate"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "false"}) + serviceAccountWithMissingPropagateAnnotation = createServiceAccount(ctx, adminClient, PrefixedGUID("service-account-no-propagate"), cfRootNamespace, nil) spaceGUID = PrefixedGUID("cf-space") cfSpace = &korifiv1alpha1.CFSpace{ @@ -79,13 +79,13 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("the CFSpace is created", func() { JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) }) It("creates a namespace and sets labels", func() { Eventually(func(g Gomega) { var createdSpace corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(createdSpace.Labels).To(SatisfyAll( HaveKeyWithValue(korifiv1alpha1.SpaceNameKey, korifiv1alpha1.OrgSpaceDeprecatedName), @@ -98,7 +98,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("sets the finalizer on cfSpace", func() { Eventually(func(g Gomega) []string { var createdCFSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdCFSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdCFSpace)).To(Succeed()) return createdCFSpace.ObjectMeta.Finalizers }).Should(ConsistOf([]string{ "cfSpace.korifi.cloudfoundry.org", @@ -109,8 +109,8 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { var createdSecret1, createdSecret2 corev1.Secret Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: imageRegistrySecret2.Name}, &createdSecret2)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: imageRegistrySecret2.Name}, &createdSecret2)).To(Succeed()) }).Should(Succeed()) Expect(createdSecret1.Data).To(Equal(imageRegistrySecret1.Data)) @@ -136,26 +136,26 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("the image-registry-credentials secret does not exist in the org namespace", Serial, func() { BeforeEach(func() { - Expect(k8sClient.Delete(ctx, imageRegistrySecret1)).To(Succeed()) + Expect(adminClient.Delete(ctx, imageRegistrySecret1)).To(Succeed()) var orgSecret corev1.Secret - Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &orgSecret)).To(Succeed()) - Expect(k8sClient.Delete(ctx, &orgSecret)).To(Succeed()) + Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &orgSecret)).To(Succeed()) + Expect(adminClient.Delete(ctx, &orgSecret)).To(Succeed()) }) AfterEach(func() { - imageRegistrySecret1 = createImageRegistrySecret(ctx, k8sClient, packageRegistrySecretName, cfRootNamespace) + imageRegistrySecret1 = createImageRegistrySecret(ctx, adminClient, packageRegistrySecretName, cfRootNamespace) Eventually(func(g Gomega) { var createdSecret1 corev1.Secret - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Name, Name: imageRegistrySecret1.Name}, &createdSecret1)).To(Succeed()) }).Should(Succeed()) }) It("sets the CFSpace's Ready condition to 'False'", func() { Eventually(func(g Gomega) { var createdCFSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdCFSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdCFSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdCFSpace.Status.Conditions, "Ready")).To(BeFalse()) @@ -176,7 +176,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { var createdRoleBinding rbacv1.RoleBinding Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBinding.Name}, &createdRoleBinding)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBinding.Name}, &createdRoleBinding)).To(Succeed()) }).Should(Succeed()) By("omitting annotations from deployment tools", func() { @@ -189,14 +189,14 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("does not propagate role-bindings with annotation \"cloudfoundry.org/propagate-cf-role\" set to \"false\" ", func() { Consistently(func(g Gomega) bool { var newRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBindingWithPropagateAnnotationSetToFalse.Name}, &newRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBindingWithPropagateAnnotationSetToFalse.Name}, &newRoleBinding)) }, time.Second).Should(BeTrue()) }) It("does not propagate role-bindings with missing annotation \"cloudfoundry.org/propagate-cf-role\" ", func() { Consistently(func(g Gomega) bool { var newRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBindingWithMissingPropagateAnnotation.Name}, &newRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: roleBindingWithMissingPropagateAnnotation.Name}, &newRoleBinding)) }, time.Second).Should(BeTrue()) }) @@ -204,7 +204,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { var createdServiceAccount corev1.ServiceAccount Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccount.Name}, &createdServiceAccount)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccount.Name}, &createdServiceAccount)).To(Succeed()) }).Should(Succeed()) By("omitting annotations from deployment tools", func() { @@ -217,7 +217,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("removes all secret references other than the package registry secret from the propagated service account", func() { Eventually(func(g Gomega) { var createdServiceAccounts corev1.ServiceAccountList - g.Expect(k8sClient.List(ctx, &createdServiceAccounts, client.InNamespace(cfSpace.Name))).To(Succeed()) + g.Expect(adminClient.List(ctx, &createdServiceAccounts, client.InNamespace(cfSpace.Name))).To(Succeed()) g.Expect(createdServiceAccounts.Items).To(ContainElements( MatchFields(IgnoreExtras, Fields{ @@ -236,21 +236,21 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("does not propagate service accounts with annotation \"cloudfoundry.org/propagate-service-account\" set to \"false\" ", func() { Consistently(func(g Gomega) bool { var newServiceAccount corev1.ServiceAccount - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccountWithPropagateAnnotationSetToFalse.Name}, &newServiceAccount)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccountWithPropagateAnnotationSetToFalse.Name}, &newServiceAccount)) }, time.Second).Should(BeTrue()) }) It("does not propagate service accounts with missing annotation \"cloudfoundry.org/propagate-service-account\" ", func() { Consistently(func(g Gomega) bool { var newServiceAccount corev1.ServiceAccount - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccountWithMissingPropagateAnnotation.Name}, &newServiceAccount)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Name, Name: serviceAccountWithMissingPropagateAnnotation.Name}, &newServiceAccount)) }, time.Second).Should(BeTrue()) }) It("sets status on CFSpace", func() { Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfSpace), &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfSpace), &createdSpace)).To(Succeed()) g.Expect(createdSpace.Status.GUID).To(Equal(cfSpace.Name)) g.Expect(createdSpace.Status.ObservedGeneration).To(Equal(createdSpace.Generation)) @@ -261,7 +261,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("sets restricted pod security labels on the namespace", func() { Eventually(func(g Gomega) { var ns corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: cfSpace.Name}, &ns)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: cfSpace.Name}, &ns)).To(Succeed()) g.Expect(ns.Labels).To(HaveKeyWithValue(api.EnforceLevelLabel, string(api.LevelRestricted))) }).Should(Succeed()) @@ -272,29 +272,29 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { var originalSpace *korifiv1alpha1.CFSpace BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) originalSpace = cfSpace.DeepCopy() var createdNamespace corev1.Namespace Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdNamespace)).To(Succeed()) }).Should(Succeed()) updatedNamespace := createdNamespace.DeepCopy() updatedNamespace.Labels["foo.com/bar"] = "42" updatedNamespace.Annotations["foo.com/bar"] = "43" - Expect(k8sClient.Patch(ctx, updatedNamespace, client.MergeFrom(&createdNamespace))).To(Succeed()) + Expect(adminClient.Patch(ctx, updatedNamespace, client.MergeFrom(&createdNamespace))).To(Succeed()) cfSpace.Spec.DisplayName += "x" }) JustBeforeEach(func() { - Expect(k8sClient.Patch(ctx, cfSpace, client.MergeFrom(originalSpace))).To(Succeed()) + Expect(adminClient.Patch(ctx, cfSpace, client.MergeFrom(originalSpace))).To(Succeed()) }) It("sets the new display name annotation and preserves the added label and annoations", func() { Eventually(func(g Gomega) { var createdNamespace corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &createdNamespace)).To(Succeed()) g.Expect(createdNamespace.Annotations).To(HaveKeyWithValue(korifiv1alpha1.SpaceNameKey, cfSpace.Spec.DisplayName)) g.Expect(createdNamespace.Labels).To(HaveKeyWithValue("foo.com/bar", "42")) @@ -306,17 +306,17 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("role-bindings are added/updated in CFOrg namespace after CFSpace creation", func() { var newlyCreatedRoleBinding *rbacv1.RoleBinding BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) - newlyCreatedRoleBinding = createRoleBinding(ctx, k8sClient, PrefixedGUID("newly-created-role-binding"), username, role.Name, cfOrg.Status.GUID, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) + newlyCreatedRoleBinding = createRoleBinding(ctx, adminClient, PrefixedGUID("newly-created-role-binding"), username, role.Name, cfOrg.Status.GUID, map[string]string{"cloudfoundry.org/propagate-cf-role": "true"}) - Expect(k8s.Patch(ctx, k8sClient, roleBinding, func() { + Expect(k8s.Patch(ctx, adminClient, roleBinding, func() { roleBinding.SetLabels(map[string]string{"foo": "bar"}) })).To(Succeed()) }) @@ -324,7 +324,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("propagates the new role-binding to CFSpace namespace", func() { Eventually(func(g Gomega) { var createdRoleBindings rbacv1.RoleBindingList - g.Expect(k8sClient.List(ctx, &createdRoleBindings, client.InNamespace(cfSpace.Name))).To(Succeed()) + g.Expect(adminClient.List(ctx, &createdRoleBindings, client.InNamespace(cfSpace.Name))).To(Succeed()) g.Expect(createdRoleBindings.Items).To(ContainElements( MatchFields(IgnoreExtras, Fields{ @@ -346,16 +346,16 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("service accounts are added in the root namespace after CFSpace creation", func() { var newlyCreatedServiceAccount *corev1.ServiceAccount BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) - newlyCreatedServiceAccount = createServiceAccount(ctx, k8sClient, PrefixedGUID("newly-created-service-account"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "true"}) - Expect(k8s.Patch(ctx, k8sClient, serviceAccount, func() { + newlyCreatedServiceAccount = createServiceAccount(ctx, adminClient, PrefixedGUID("newly-created-service-account"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "true"}) + Expect(k8s.Patch(ctx, adminClient, serviceAccount, func() { serviceAccount.SetLabels(map[string]string{"foo": "bar"}) })).To(Succeed()) }) @@ -363,7 +363,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("propagates the new service account to CFSpace namespace", func() { Eventually(func(g Gomega) { var createdServiceAccounts corev1.ServiceAccountList - g.Expect(k8sClient.List(ctx, &createdServiceAccounts, client.InNamespace(cfSpace.Name))).To(Succeed()) + g.Expect(adminClient.List(ctx, &createdServiceAccounts, client.InNamespace(cfSpace.Name))).To(Succeed()) g.Expect(createdServiceAccounts.Items).To(ContainElements( MatchFields(IgnoreExtras, Fields{ @@ -391,22 +391,22 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { ) BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) - rootServiceAccount = createServiceAccount(ctx, k8sClient, PrefixedGUID("existing-service-account"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "true"}) + rootServiceAccount = createServiceAccount(ctx, adminClient, PrefixedGUID("existing-service-account"), cfRootNamespace, map[string]string{"cloudfoundry.org/propagate-service-account": "true"}) // Ensure that the service account is propagated into the CFSpace namespace Eventually(func() error { - return k8sClient.Get(ctx, types.NamespacedName{Name: rootServiceAccount.Name, Namespace: cfSpace.Name}, &propagatedServiceAccount) + return adminClient.Get(ctx, types.NamespacedName{Name: rootServiceAccount.Name, Namespace: cfSpace.Name}, &propagatedServiceAccount) }).Should(Succeed()) // Simulate k8s adding a token secret to the propagated service account AND the propagated service account having a stale image registry credential secret - Expect(k8s.PatchResource(ctx, k8sClient, &propagatedServiceAccount, func() { + Expect(k8s.PatchResource(ctx, adminClient, &propagatedServiceAccount, func() { tokenSecretName = rootServiceAccount.Name + "-token-XYZABC" dockercfgSecretName = rootServiceAccount.Name + "-dockercfg-ABCXYZ" propagatedServiceAccount.Secrets = []corev1.ObjectReference{{Name: tokenSecretName}, {Name: dockercfgSecretName}, {Name: "out-of-date-registry-credentials"}} @@ -414,7 +414,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { })).To(Succeed()) // Modify the root service account to trigger reconciliation - Expect(k8s.PatchResource(ctx, k8sClient, rootServiceAccount, func() { + Expect(k8s.PatchResource(ctx, adminClient, rootServiceAccount, func() { rootServiceAccount.Labels = map[string]string{"new-label": "sample-value"} })).To(Succeed()) }) @@ -423,7 +423,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { Eventually(func(g Gomega) { var updatedPropagatedServiceAccount corev1.ServiceAccount g.Expect( - k8sClient.Get(ctx, client.ObjectKeyFromObject(&propagatedServiceAccount), &updatedPropagatedServiceAccount), + adminClient.Get(ctx, client.ObjectKeyFromObject(&propagatedServiceAccount), &updatedPropagatedServiceAccount), ).To(Succeed()) g.Expect(updatedPropagatedServiceAccount.Secrets).To(ConsistOf( corev1.ObjectReference{Name: tokenSecretName}, @@ -450,11 +450,11 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { ) BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) @@ -466,15 +466,15 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { }, } - Expect(k8sClient.Create(ctx, rootServiceAccount)).To(Succeed()) + Expect(adminClient.Create(ctx, rootServiceAccount)).To(Succeed()) // Ensure that the service account is propagated into the CFSpace namespace Eventually(func() error { - return k8sClient.Get(ctx, types.NamespacedName{Name: rootServiceAccount.Name, Namespace: cfSpace.Name}, &propagatedServiceAccount) + return adminClient.Get(ctx, types.NamespacedName{Name: rootServiceAccount.Name, Namespace: cfSpace.Name}, &propagatedServiceAccount) }).Should(Succeed()) // Simulate k8s adding a token secret to the propagated service account - Expect(k8s.PatchResource(ctx, k8sClient, &propagatedServiceAccount, func() { + Expect(k8s.PatchResource(ctx, adminClient, &propagatedServiceAccount, func() { tokenSecretName = rootServiceAccount.Name + "-token-XYZABC" dockercfgSecretName = rootServiceAccount.Name + "-dockercfg-ABCXYZ" propagatedServiceAccount.Secrets = []corev1.ObjectReference{{Name: tokenSecretName}, {Name: dockercfgSecretName}} @@ -482,7 +482,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { })).To(Succeed()) // Add the package registry secret to the root service account - Expect(k8s.PatchResource(ctx, k8sClient, rootServiceAccount, func() { + Expect(k8s.PatchResource(ctx, adminClient, rootServiceAccount, func() { rootServiceAccount.Secrets = []corev1.ObjectReference{{Name: packageRegistrySecretName}} rootServiceAccount.ImagePullSecrets = []corev1.LocalObjectReference{{Name: packageRegistrySecretName}} })).To(Succeed()) @@ -492,7 +492,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { Eventually(func(g Gomega) { var updatedPropagatedServiceAccount corev1.ServiceAccount g.Expect( - k8sClient.Get(ctx, client.ObjectKeyFromObject(&propagatedServiceAccount), &updatedPropagatedServiceAccount), + adminClient.Get(ctx, client.ObjectKeyFromObject(&propagatedServiceAccount), &updatedPropagatedServiceAccount), ).To(Succeed()) g.Expect(updatedPropagatedServiceAccount.Secrets).To(ConsistOf( corev1.ObjectReference{Name: tokenSecretName}, @@ -509,23 +509,23 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("role bindings are deleted in the CFOrg namespace after CFSpace creation", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Delete(ctx, roleBinding)).To(Succeed()) + Expect(adminClient.Delete(ctx, roleBinding)).To(Succeed()) }) It("deletes the corresponding role binding in CFSpace", func() { Eventually(func() bool { var deletedRoleBinding rbacv1.RoleBinding - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, &deletedRoleBinding)) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, &deletedRoleBinding)) }).Should(BeTrue(), "timed out waiting for role binding to be deleted") }) @@ -534,12 +534,12 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { origRoleBinding := roleBinding.DeepCopy() roleBinding.Annotations["cloudfoundry.org/propagate-deletion"] = "false" - Expect(k8sClient.Patch(ctx, roleBinding, client.MergeFrom(origRoleBinding))).To(Succeed()) + Expect(adminClient.Patch(ctx, roleBinding, client.MergeFrom(origRoleBinding))).To(Succeed()) Eventually(func(g Gomega) map[string]string { var copiedRoleBinding rbacv1.RoleBinding g.Expect( - k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, &copiedRoleBinding), + adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, &copiedRoleBinding), ).To(Succeed()) return copiedRoleBinding.Annotations }).Should(HaveKeyWithValue("cloudfoundry.org/propagate-deletion", "false")) @@ -547,7 +547,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("doesn't delete the corresponding role binding in the CFSpace", func() { Consistently(func() bool { - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, new(rbacv1.RoleBinding))) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: roleBinding.Name, Namespace: cfSpace.Name}, new(rbacv1.RoleBinding))) }).Should(BeFalse(), "space's copy of role binding was deleted and shouldn't have been") }) }) @@ -555,22 +555,22 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("service accounts are deleted in the root namespace after CFSpace creation", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var createdSpace korifiv1alpha1.CFSpace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfOrg.Status.GUID, Name: spaceGUID}, &createdSpace)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(createdSpace.Status.Conditions, "Ready")).To(BeTrue()) }, 20*time.Second).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Delete(ctx, serviceAccount)).To(Succeed()) + Expect(adminClient.Delete(ctx, serviceAccount)).To(Succeed()) }) It("deletes the corresponding service account in CFSpace", func() { Eventually(func() bool { - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, new(corev1.ServiceAccount))) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, new(corev1.ServiceAccount))) }).Should(BeTrue(), "timed out waiting for service account to be deleted") }) @@ -579,12 +579,12 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { origServiceAccount := serviceAccount.DeepCopy() serviceAccount.Annotations["cloudfoundry.org/propagate-deletion"] = "false" - Expect(k8sClient.Patch(ctx, serviceAccount, client.MergeFrom(origServiceAccount))).To(Succeed()) + Expect(adminClient.Patch(ctx, serviceAccount, client.MergeFrom(origServiceAccount))).To(Succeed()) Eventually(func(g Gomega) map[string]string { var copiedServiceAccount corev1.ServiceAccount g.Expect( - k8sClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, &copiedServiceAccount), + adminClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, &copiedServiceAccount), ).To(Succeed()) return copiedServiceAccount.Annotations }).Should(HaveKeyWithValue("cloudfoundry.org/propagate-deletion", "false")) @@ -592,7 +592,7 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { It("doesn't delete the corresponding service account in the CFSpace", func() { Consistently(func() bool { - return apierrors.IsNotFound(k8sClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, new(corev1.ServiceAccount))) + return apierrors.IsNotFound(adminClient.Get(ctx, types.NamespacedName{Name: serviceAccount.Name, Namespace: cfSpace.Name}, new(corev1.ServiceAccount))) }).Should(BeFalse(), "space's copy of service account was deleted and shouldn't have been") }) }) @@ -600,23 +600,23 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { When("the CFSpace is deleted", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { var spaceNamespace corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) }).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Delete(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Delete(ctx, cfSpace)).To(Succeed()) }) It("eventually deletes the namespace", func() { // Envtests do not cleanup namespaces. For testing, we check for deletion timestamps on namespace. Eventually(func(g Gomega) bool { var spaceNamespace corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) return spaceNamespace.GetDeletionTimestamp().IsZero() }).Should(BeFalse(), "timed out waiting for deletion timestamps to be set on namespace") @@ -631,13 +631,13 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { BeforeEach(func() { cfApp = BuildCFAppCRObject(PrefixedGUID("cf-app"), spaceGUID) - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) }) It("cleans up the CFApp", func() { Eventually(func(g Gomega) bool { var cfa korifiv1alpha1.CFApp - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfApp), &cfa)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfApp), &cfa)).To(Succeed()) return cfa.GetDeletionTimestamp().IsZero() }).Should(BeFalse(), "timed out waiting for deletion timestamps to be set on CFApp") @@ -647,19 +647,19 @@ var _ = Describe("CFSpaceReconciler Integration Tests", func() { BeforeEach(func() { updatedCFApp := cfApp.DeepCopy() updatedCFApp.Finalizers = append(updatedCFApp.Finalizers, "new-finalizer") - Expect(k8sClient.Patch(ctx, updatedCFApp, client.MergeFrom(cfApp))).To(Succeed()) + Expect(adminClient.Patch(ctx, updatedCFApp, client.MergeFrom(cfApp))).To(Succeed()) }) It("times out and deletes the namespace", func() { Eventually(func(g Gomega) bool { var spaceNamespace corev1.Namespace - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: spaceGUID}, &spaceNamespace)).To(Succeed()) return spaceNamespace.GetDeletionTimestamp().IsZero() }).Should(BeFalse(), "timed out waiting for deletion timestamps to be set on namespace") var cfAppList korifiv1alpha1.CFAppList - Expect(k8sClient.List(ctx, &cfAppList, client.InNamespace(spaceGUID))).To(Succeed()) + Expect(adminClient.List(ctx, &cfAppList, client.InNamespace(spaceGUID))).To(Succeed()) Expect(cfAppList.Items).NotTo(BeEmpty()) }) }) diff --git a/controllers/controllers/workloads/cftask_controller_test.go b/controllers/controllers/workloads/cftask_controller_test.go index 62b7848f1..7f1406ff9 100644 --- a/controllers/controllers/workloads/cftask_controller_test.go +++ b/controllers/controllers/workloads/cftask_controller_test.go @@ -45,7 +45,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { }, }, } - Expect(k8sClient.Create(ctx, cfPackage)).To(Succeed()) + Expect(adminClient.Create(ctx, cfPackage)).To(Succeed()) cfDroplet = &korifiv1alpha1.CFBuild{ ObjectMeta: metav1.ObjectMeta{ @@ -62,7 +62,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Lifecycle: korifiv1alpha1.Lifecycle{Type: "buildpack"}, }, } - Expect(k8sClient.Create(ctx, cfDroplet)).To(Succeed()) + Expect(adminClient.Create(ctx, cfDroplet)).To(Succeed()) cfDropletCopy := cfDroplet.DeepCopy() cfDropletCopy.Status.Droplet = &korifiv1alpha1.BuildDropletStatus{ @@ -83,7 +83,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Status: "Unknown", Reason: "reason", }) - Expect(k8sClient.Status().Patch(ctx, cfDropletCopy, client.MergeFrom(cfDroplet))).To(Succeed()) + Expect(adminClient.Status().Patch(ctx, cfDropletCopy, client.MergeFrom(cfDroplet))).To(Succeed()) envSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -96,7 +96,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { }, Type: corev1.SecretTypeOpaque, } - Expect(k8sClient.Create(ctx, envSecret)).To(Succeed()) + Expect(adminClient.Create(ctx, envSecret)).To(Succeed()) cfProcess := &korifiv1alpha1.CFProcess{ ObjectMeta: metav1.ObjectMeta{ @@ -120,7 +120,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Ports: []int32{8080}, }, } - Expect(k8sClient.Create(ctx, cfProcess)).To(Succeed()) + Expect(adminClient.Create(ctx, cfProcess)).To(Succeed()) cfApp = &korifiv1alpha1.CFApp{ ObjectMeta: metav1.ObjectMeta{ @@ -137,7 +137,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { EnvSecretName: envSecret.Name, }, } - Expect(k8sClient.Create(ctx, cfApp)).To(Succeed()) + Expect(adminClient.Create(ctx, cfApp)).To(Succeed()) cfTask = &korifiv1alpha1.CFTask{ ObjectMeta: metav1.ObjectMeta{ @@ -163,7 +163,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { task = &korifiv1alpha1.CFTask{} Eventually(func(g Gomega) { app := new(korifiv1alpha1.CFApp) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfApp.Name}, app)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfApp.Name}, app)).To(Succeed()) readyCondition := meta.FindStatusCondition(app.Status.Conditions, "Ready") g.Expect(readyCondition).NotTo(BeNil()) @@ -174,10 +174,10 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, cfTask)).To(Succeed()) + Expect(adminClient.Create(ctx, cfTask)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfTask.Name}, task)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfTask.Name}, task)).To(Succeed()) initializedStatusCondition := meta.FindStatusCondition(task.Status.Conditions, korifiv1alpha1.TaskInitializedConditionType) g.Expect(initializedStatusCondition).NotTo(BeNil()) g.Expect(initializedStatusCondition.Status).To(Equal(metav1.ConditionTrue), "task did not become initialized") @@ -208,7 +208,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Eventually(func(g Gomega) { var taskWorkloads korifiv1alpha1.TaskWorkloadList - g.Expect(k8sClient.List(ctx, &taskWorkloads, + g.Expect(adminClient.List(ctx, &taskWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{korifiv1alpha1.CFTaskGUIDLabelKey: cfTask.Name}, )).To(Succeed()) @@ -231,7 +231,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { }).Should(Succeed()) // Refresh the VCAPServicesSecretName - Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfApp), cfApp)).To(Succeed()) + Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfApp), cfApp)).To(Succeed()) Expect(taskWorkload.Spec.Env).To(ConsistOf( corev1.EnvVar{ @@ -297,14 +297,14 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Eventually(func(g Gomega) { var taskWorkloads korifiv1alpha1.TaskWorkloadList - g.Expect(k8sClient.List(ctx, &taskWorkloads, + g.Expect(adminClient.List(ctx, &taskWorkloads, client.InNamespace(cfSpace.Status.GUID), client.MatchingLabels{korifiv1alpha1.CFTaskGUIDLabelKey: cfTask.Name}, )).To(Succeed()) g.Expect(taskWorkloads.Items).To(HaveLen(1)) modifiedTaskWorkload := taskWorkloads.Items[0].DeepCopy() - g.Expect(k8s.Patch(ctx, k8sClient, modifiedTaskWorkload, func() { + g.Expect(k8s.Patch(ctx, adminClient, modifiedTaskWorkload, func() { meta.SetStatusCondition(&modifiedTaskWorkload.Status.Conditions, metav1.Condition{ Type: korifiv1alpha1.TaskStartedConditionType, Status: metav1.ConditionTrue, @@ -317,7 +317,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { It("reflects the status in the korifi task", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfTask.Name}, task)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Namespace: cfSpace.Status.GUID, Name: cfTask.Name}, task)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(task.Status.Conditions, korifiv1alpha1.TaskStartedConditionType)).To(BeTrue()) }).Should(Succeed()) }) @@ -326,19 +326,19 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Describe("CFTask Cancellation", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfTask)).To(Succeed()) + Expect(adminClient.Create(ctx, cfTask)).To(Succeed()) }) When("spec.canceled is set to true", func() { BeforeEach(func() { - Expect(k8s.PatchResource(ctx, k8sClient, cfTask, func() { + Expect(k8s.PatchResource(ctx, adminClient, cfTask, func() { cfTask.Spec.Canceled = true })).To(Succeed()) }) It("sets the canceled status condition", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) canceledStatusCondition := meta.FindStatusCondition(cfTask.Status.Conditions, korifiv1alpha1.TaskCanceledConditionType) g.Expect(canceledStatusCondition).NotTo(BeNil()) g.Expect(canceledStatusCondition.Status).To(Equal(metav1.ConditionTrue)) @@ -351,11 +351,11 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { Describe("CFTask TTL", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, cfTask)).To(Succeed()) + Expect(adminClient.Create(ctx, cfTask)).To(Succeed()) // wait for reconciler to set initialized condition to avoid it overwriting the succeeded condition Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) + g.Expect(controllersClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(cfTask.Status.Conditions, korifiv1alpha1.TaskInitializedConditionType)).To(BeTrue()) }).Should(Succeed()) @@ -371,7 +371,7 @@ var _ = Describe("CFTaskReconciler Integration Tests", func() { }) It("it can get the task shortly after completion", func() { - Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) + Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfTask), cfTask)).To(Succeed()) }) It("deletes the task after it expires", func() { diff --git a/controllers/controllers/workloads/env/builder_test.go b/controllers/controllers/workloads/env/builder_test.go index 08c7d2360..9aaa9f82b 100644 --- a/controllers/controllers/workloads/env/builder_test.go +++ b/controllers/controllers/workloads/env/builder_test.go @@ -26,7 +26,7 @@ var _ = Describe("Builder", func() { ) BeforeEach(func() { - builder = env.NewWorkloadEnvBuilder(k8sClient) + builder = env.NewWorkloadEnvBuilder(controllersClient) appSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ diff --git a/controllers/controllers/workloads/env/env_suite_test.go b/controllers/controllers/workloads/env/env_suite_test.go index a65e40e36..bd330b692 100644 --- a/controllers/controllers/workloads/env/env_suite_test.go +++ b/controllers/controllers/workloads/env/env_suite_test.go @@ -7,6 +7,7 @@ import ( "time" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/tests/helpers" k8serrors "k8s.io/apimachinery/pkg/api/errors" "code.cloudfoundry.org/korifi/controllers/controllers/shared" @@ -22,7 +23,6 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -30,14 +30,16 @@ import ( ) var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client - rootNamespace string - cfOrg *korifiv1alpha1.CFOrg - cfSpace *korifiv1alpha1.CFSpace - ctx context.Context - cfApp *korifiv1alpha1.CFApp + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client + controllersClient client.Client + rootNamespace string + cfOrg *korifiv1alpha1.CFOrg + cfSpace *korifiv1alpha1.CFSpace + ctx context.Context + cfApp *korifiv1alpha1.CFApp ) func TestEnvBuilders(t *testing.T) { @@ -51,9 +53,6 @@ func TestEnvBuilders(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true), zap.Level(zapcore.DebugLevel))) - mgrCtx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "..", "helm", "korifi", "controllers", "crds"), @@ -61,36 +60,25 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(servicebindingv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) - //+kubebuilder:scaffold:scheme + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) - k8sClient = k8sManager.GetClient() - - err = shared.SetupIndexWithManager(k8sManager) - Expect(err).NotTo(HaveOccurred()) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) + controllersClient = helpers.NewSyncClient(k8sManager.GetClient()) - go func() { - defer GinkgoRecover() - err = k8sManager.Start(mgrCtx) - Expect(err).NotTo(HaveOccurred()) - }() + stopManager = helpers.StartK8sManager(k8sManager) }) var _ = AfterSuite(func() { - cancel() + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) @@ -169,23 +157,23 @@ func createNamespace(name string) *corev1.Namespace { Name: name, }, } - Expect(k8sClient.Create(ctx, ns)).To(Succeed()) + Expect(adminClient.Create(ctx, ns)).To(Succeed()) return ns } func ensureCreate(obj client.Object) { - Expect(k8sClient.Create(ctx, obj)).To(Succeed()) + Expect(controllersClient.Create(ctx, obj)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) + g.Expect(controllersClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) }).Should(Succeed()) } func ensurePatch[T any, PT k8s.ObjectWithDeepCopy[T]](obj PT, modifyFunc func(PT)) { - Expect(k8s.Patch(ctx, k8sClient, obj, func() { + Expect(k8s.Patch(ctx, controllersClient, obj, func() { modifyFunc(obj) })).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) + g.Expect(controllersClient.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) objCopy := obj.DeepCopy() modifyFunc(objCopy) g.Expect(equality.Semantic.DeepEqual(objCopy, obj)).To(BeTrue()) @@ -193,9 +181,9 @@ func ensurePatch[T any, PT k8s.ObjectWithDeepCopy[T]](obj PT, modifyFunc func(PT } func ensureDelete(obj client.Object) { - Expect(k8sClient.Delete(ctx, obj)).To(Succeed()) + Expect(controllersClient.Delete(ctx, obj)).To(Succeed()) Eventually(func(g Gomega) { - err := k8sClient.Get(ctx, client.ObjectKeyFromObject(obj), obj) + err := controllersClient.Get(ctx, client.ObjectKeyFromObject(obj), obj) g.Expect(k8serrors.IsNotFound(err)).To(BeTrue()) }).Should(Succeed()) } diff --git a/controllers/controllers/workloads/env/vcap_app_builder_test.go b/controllers/controllers/workloads/env/vcap_app_builder_test.go index 2b4a41727..a4f25aa61 100644 --- a/controllers/controllers/workloads/env/vcap_app_builder_test.go +++ b/controllers/controllers/workloads/env/vcap_app_builder_test.go @@ -13,7 +13,7 @@ var _ = Describe("VCAP_APPLICATION env value builder", func() { var builder *env.VCAPApplicationEnvValueBuilder BeforeEach(func() { - builder = env.NewVCAPApplicationEnvValueBuilder(k8sClient, nil) + builder = env.NewVCAPApplicationEnvValueBuilder(controllersClient, nil) }) Describe("BuildEnvValue", func() { @@ -42,7 +42,7 @@ var _ = Describe("VCAP_APPLICATION env value builder", func() { When("extra values are provided", func() { BeforeEach(func() { - builder = env.NewVCAPApplicationEnvValueBuilder(k8sClient, map[string]any{ + builder = env.NewVCAPApplicationEnvValueBuilder(controllersClient, map[string]any{ "application_id": "not-the-application-id", "foo": "bar", "answer": 42, diff --git a/controllers/controllers/workloads/env/vcap_services_builder_test.go b/controllers/controllers/workloads/env/vcap_services_builder_test.go index 66270d163..c1f2bf567 100644 --- a/controllers/controllers/workloads/env/vcap_services_builder_test.go +++ b/controllers/controllers/workloads/env/vcap_services_builder_test.go @@ -24,7 +24,7 @@ var _ = Describe("Builder", func() { ) BeforeEach(func() { - builder = env.NewVCAPServicesEnvValueBuilder(k8sClient) + builder = env.NewVCAPServicesEnvValueBuilder(controllersClient) serviceInstance = &korifiv1alpha1.CFServiceInstance{ ObjectMeta: metav1.ObjectMeta{ @@ -146,6 +146,8 @@ var _ = Describe("Builder", func() { }) It("returns the service info", func() { + Expect(buildVCAPServicesEnvValueErr).NotTo(HaveOccurred()) + Expect(extractServiceInfo(vcapServices, "user-provided", 1)).To(ContainElements( SatisfyAll( HaveLen(10), @@ -232,10 +234,10 @@ var _ = Describe("Builder", func() { When("there are no service bindings for the app", func() { BeforeEach(func() { - Expect(k8sClient.DeleteAllOf(ctx, &korifiv1alpha1.CFServiceBinding{}, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) + Expect(adminClient.DeleteAllOf(ctx, &korifiv1alpha1.CFServiceBinding{}, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) Eventually(func(g Gomega) { sbList := &korifiv1alpha1.CFServiceBindingList{} - g.Expect(k8sClient.List(ctx, sbList, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) + g.Expect(controllersClient.List(ctx, sbList, client.InNamespace(cfSpace.Status.GUID))).To(Succeed()) g.Expect(sbList.Items).To(BeEmpty()) }).Should(Succeed()) }) diff --git a/controllers/controllers/workloads/suite_test.go b/controllers/controllers/workloads/suite_test.go index c87c919eb..faa9162b8 100644 --- a/controllers/controllers/workloads/suite_test.go +++ b/controllers/controllers/workloads/suite_test.go @@ -8,7 +8,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" "code.cloudfoundry.org/korifi/controllers/config" - . "code.cloudfoundry.org/korifi/controllers/controllers/shared" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" . "code.cloudfoundry.org/korifi/controllers/controllers/workloads" "code.cloudfoundry.org/korifi/controllers/controllers/workloads/env" "code.cloudfoundry.org/korifi/controllers/controllers/workloads/fake" @@ -35,7 +35,6 @@ import ( rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - k8sclient "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" admission "k8s.io/pod-security-admission/api" ctrl "sigs.k8s.io/controller-runtime" @@ -47,9 +46,11 @@ import ( var ( ctx context.Context - cancel context.CancelFunc + stopManager context.CancelFunc + stopClientCache context.CancelFunc testEnv *envtest.Environment - k8sClient client.Client + adminClient client.Client + controllersClient client.Client cfRootNamespace string cfOrg *korifiv1alpha1.CFOrg imageRegistrySecret1 *corev1.Secret @@ -83,7 +84,7 @@ var _ = BeforeSuite(func() { GinkgoWriter.TeeTo(logOutput) logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true), zap.Level(zapcore.DebugLevel))) - ctx, cancel = context.WithCancel(context.TODO()) + ctx = context.Background() testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -95,28 +96,18 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(servicebindingv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) - //+kubebuilder:scaffold:scheme + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) - - k8sClient = helpers.NewCacheSyncingClient(k8sManager.GetClient()) + controllersClient = k8sManager.GetClient() + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) cfRootNamespace = testutils.PrefixedGUID("root-namespace") @@ -143,10 +134,6 @@ var _ = BeforeSuite(func() { )).SetupWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - registryAuthFetcherClient, err := k8sclient.NewForConfig(cfg) - Expect(err).NotTo(HaveOccurred()) - Expect(registryAuthFetcherClient).NotTo(BeNil()) - buildCleaner = new(fake.BuildCleaner) cfBuildReconciler := NewCFBuildReconciler( k8sManager.GetClient(), @@ -257,24 +244,18 @@ var _ = BeforeSuite(func() { webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), services.ServiceBindingEntityType)), ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - // Setup index for manager - err = SetupIndexWithManager(k8sManager) - Expect(err).NotTo(HaveOccurred()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() + stopManager = helpers.StartK8sManager(k8sManager) createNamespace(cfRootNamespace) - imageRegistrySecret1 = createImageRegistrySecret(ctx, k8sClient, packageRegistrySecretName, cfRootNamespace) - imageRegistrySecret2 = createImageRegistrySecret(ctx, k8sClient, otherRegistrySecretName, cfRootNamespace) + imageRegistrySecret1 = createImageRegistrySecret(ctx, adminClient, packageRegistrySecretName, cfRootNamespace) + imageRegistrySecret2 = createImageRegistrySecret(ctx, adminClient, otherRegistrySecretName, cfRootNamespace) + cfOrg = createOrg(cfRootNamespace) }) var _ = AfterSuite(func() { - cancel() + stopManager() + stopClientCache() Expect(testEnv.Stop()).To(Succeed()) }) @@ -298,7 +279,7 @@ func createNamespace(name string) *corev1.Namespace { }, } Expect( - k8sClient.Create(ctx, ns)).To(Succeed()) + adminClient.Create(ctx, ns)).To(Succeed()) return ns } @@ -372,7 +353,7 @@ func createServiceAccount(ctx context.Context, k8sclient client.Client, serviceA {Name: otherRegistrySecretName}, }, } - Expect(k8sClient.Create(ctx, serviceAccount)).To(Succeed()) + Expect(adminClient.Create(ctx, serviceAccount)).To(Succeed()) return serviceAccount } @@ -399,10 +380,10 @@ func createOrg(rootNamespace string) *korifiv1alpha1.CFOrg { DisplayName: testutils.PrefixedGUID("org"), }, } - Expect(k8sClient.Create(ctx, org)).To(Succeed()) + Expect(adminClient.Create(ctx, org)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(org), org)).To(Succeed()) - g.Expect(meta.IsStatusConditionTrue(org.Status.Conditions, StatusConditionReady)).To(BeTrue()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(org), org)).To(Succeed()) + g.Expect(meta.IsStatusConditionTrue(org.Status.Conditions, shared.StatusConditionReady)).To(BeTrue()) }).Should(Succeed()) return org } @@ -417,10 +398,10 @@ func createSpace(org *korifiv1alpha1.CFOrg) *korifiv1alpha1.CFSpace { DisplayName: testutils.PrefixedGUID("space"), }, } - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cfSpace), cfSpace)).To(Succeed()) - g.Expect(meta.IsStatusConditionTrue(cfSpace.Status.Conditions, StatusConditionReady)).To(BeTrue()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(cfSpace), cfSpace)).To(Succeed()) + g.Expect(meta.IsStatusConditionTrue(cfSpace.Status.Conditions, shared.StatusConditionReady)).To(BeTrue()) }).Should(Succeed()) return cfSpace } diff --git a/controllers/coordination/integration/integration_suite_test.go b/controllers/coordination/integration/integration_suite_test.go index 10835375a..c3937f4c6 100644 --- a/controllers/coordination/integration/integration_suite_test.go +++ b/controllers/coordination/integration/integration_suite_test.go @@ -2,6 +2,7 @@ package integration_test import ( "context" + "path/filepath" "testing" "time" @@ -26,7 +27,7 @@ func TestIntegration(t *testing.T) { var ( testEnv *envtest.Environment - k8sClient client.Client + adminClient client.Client controllersClient client.Client cacheStop context.CancelFunc ) @@ -39,10 +40,10 @@ var _ = BeforeSuite(func() { adminConfig, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - k8sClient, err = client.New(adminConfig, client.Options{Scheme: scheme.Scheme}) + adminClient, err = client.New(adminConfig, client.Options{Scheme: scheme.Scheme}) Expect(err).NotTo(HaveOccurred()) - controllersConf := helpers.SetupControllersUser(testEnv) + controllersConf := helpers.SetupTestEnvUser(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) userCache, err := cache.New(controllersConf, cache.Options{}) Expect(err).NotTo(HaveOccurred()) diff --git a/controllers/coordination/integration/name_registry_test.go b/controllers/coordination/integration/name_registry_test.go index 93c2758a9..2cf1f48a6 100644 --- a/controllers/coordination/integration/name_registry_test.go +++ b/controllers/coordination/integration/name_registry_test.go @@ -50,7 +50,7 @@ var _ = Describe("Name Registry", func() { }) It("can register the same name for different entity types in the same namespace", func() { - anotherNameRegistry := coordination.NewNameRegistry(k8sClient, "something-else") + anotherNameRegistry := coordination.NewNameRegistry(controllersClient, "something-else") Expect(nameRegistry.RegisterName(ctx, ns1.Name, name, "owner-namespace", "owner-name")).To(Succeed()) Expect(anotherNameRegistry.RegisterName(ctx, ns1.Name, name, "owner-namespace", "owner-name")).To(Succeed()) }) @@ -72,7 +72,7 @@ var _ = Describe("Name Registry", func() { }) It("returns an already exists error when trying to register that name again", func() { - anotherNameRegistry := coordination.NewNameRegistry(k8sClient, "my-entity") + anotherNameRegistry := coordination.NewNameRegistry(controllersClient, "my-entity") err := anotherNameRegistry.RegisterName(ctx, ns1.Name, name, "owner-namespace", "owner-name") Expect(k8serrors.IsAlreadyExists(err)).To(BeTrue()) }) @@ -221,7 +221,7 @@ func createNamespace(ctx context.Context, name string) *corev1.Namespace { Name: name, }, } - Expect(k8sClient.Create(ctx, ns)).To(Succeed()) + Expect(adminClient.Create(ctx, ns)).To(Succeed()) return ns } diff --git a/controllers/webhooks/finalizer/finalizer_webhook_test.go b/controllers/webhooks/finalizer/finalizer_webhook_test.go index 42c6ec086..cf65f8160 100644 --- a/controllers/webhooks/finalizer/finalizer_webhook_test.go +++ b/controllers/webhooks/finalizer/finalizer_webhook_test.go @@ -16,7 +16,7 @@ var _ = Describe("Controllers Finalizers Webhook", func() { DescribeTable("Adding finalizers", func(obj client.Object, expectedFinalizers ...string) { if obj.GetNamespace() != rootNamespace { - Expect(k8sClient.Create(context.Background(), &korifiv1alpha1.CFOrg{ + Expect(adminClient.Create(context.Background(), &korifiv1alpha1.CFOrg{ ObjectMeta: metav1.ObjectMeta{ Name: obj.GetNamespace(), Namespace: rootNamespace, @@ -26,7 +26,7 @@ var _ = Describe("Controllers Finalizers Webhook", func() { }, })).To(Succeed()) - Expect(k8sClient.Create(context.Background(), &corev1.Namespace{ + Expect(adminClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: obj.GetNamespace(), Labels: map[string]string{korifiv1alpha1.OrgNameKey: obj.GetNamespace()}, @@ -34,7 +34,7 @@ var _ = Describe("Controllers Finalizers Webhook", func() { })).To(Succeed()) } - Expect(k8sClient.Create(context.Background(), obj)).To(Succeed()) + Expect(adminClient.Create(context.Background(), obj)).To(Succeed()) Expect(obj.GetFinalizers()).To(ConsistOf(expectedFinalizers)) }, Entry("cfapp", diff --git a/controllers/webhooks/finalizer/suite_integration_test.go b/controllers/webhooks/finalizer/suite_integration_test.go index eb81c5038..e7fe50457 100644 --- a/controllers/webhooks/finalizer/suite_integration_test.go +++ b/controllers/webhooks/finalizer/suite_integration_test.go @@ -2,14 +2,12 @@ package finalizer_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" "time" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" "code.cloudfoundry.org/korifi/controllers/coordination" "code.cloudfoundry.org/korifi/controllers/webhooks" "code.cloudfoundry.org/korifi/controllers/webhooks/finalizer" @@ -24,8 +22,7 @@ import ( coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -34,9 +31,10 @@ import ( ) var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client ) const ( @@ -55,9 +53,6 @@ func TestWorkloadsWebhooks(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds"), @@ -68,84 +63,56 @@ var _ = BeforeSuite(func() { }, } - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - Expect(korifiv1alpha1.AddToScheme(scheme)).To(Succeed()) - Expect(admissionv1beta1.AddToScheme(scheme)).To(Succeed()) - Expect(corev1.AddToScheme(scheme)).To(Succeed()) - Expect(coordinationv1.AddToScheme(scheme)).To(Succeed()) - - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - k8sClient = helpers.NewCacheSyncingClient(mgr.GetClient()) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(admissionv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(coordinationv1.AddToScheme(scheme.Scheme)).To(Succeed()) + + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(mgr) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) - version.NewVersionWebhook("some-version").SetupWebhookWithManager(mgr) - Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(mgr)).To(Succeed()) + finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(k8sManager) + + version.NewVersionWebhook("some-version").SetupWebhookWithManager(k8sManager) + Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(workloads.NewCFAppValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.AppEntityType)), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.AppEntityType)), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFOrgEntityType)) - orgPlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFOrgEntityType)) + orgPlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFSpaceEntityType)) - spacePlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFSpaceEntityType)) + spacePlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect(networking.NewCFDomainValidator(mgr.GetClient()).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect(networking.NewCFDomainValidator(k8sManager.GetClient()).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(networking.NewCFRouteValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), networking.RouteEntityType)), + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), networking.RouteEntityType)), rootNamespace, - mgr.GetClient(), - ).SetupWebhookWithManager(mgr)).To(Succeed()) - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - - // Create root namespace - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + k8sManager.GetClient(), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) + + stopManager = helpers.StartK8sManager(k8sManager) + + ctx := context.Background() + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: rootNamespace, }, })).To(Succeed()) - Expect(k8sClient.Create(ctx, &korifiv1alpha1.CFDomain{ + Expect(adminClient.Create(ctx, &korifiv1alpha1.CFDomain{ ObjectMeta: metav1.ObjectMeta{ Namespace: rootNamespace, Name: defaultDomainName, @@ -157,6 +124,7 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() // call the cancel function to stop the controller context + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/controllers/webhooks/version/suite_integration_test.go b/controllers/webhooks/version/suite_integration_test.go index 712c18308..665027f31 100644 --- a/controllers/webhooks/version/suite_integration_test.go +++ b/controllers/webhooks/version/suite_integration_test.go @@ -2,14 +2,12 @@ package version_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" "time" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" "code.cloudfoundry.org/korifi/controllers/coordination" "code.cloudfoundry.org/korifi/controllers/webhooks" "code.cloudfoundry.org/korifi/tests/helpers" @@ -25,8 +23,7 @@ import ( coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -35,9 +32,10 @@ import ( ) var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client ) const rootNamespace = "cf" @@ -53,9 +51,6 @@ func TestWorkloadsWebhooks(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds"), @@ -66,89 +61,60 @@ var _ = BeforeSuite(func() { }, } - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - Expect(korifiv1alpha1.AddToScheme(scheme)).To(Succeed()) - Expect(admissionv1beta1.AddToScheme(scheme)).To(Succeed()) - Expect(corev1.AddToScheme(scheme)).To(Succeed()) - Expect(coordinationv1.AddToScheme(scheme)).To(Succeed()) - - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - k8sClient = helpers.NewCacheSyncingClient(mgr.GetClient()) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(admissionv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(coordinationv1.AddToScheme(scheme.Scheme)).To(Succeed()) + + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - version.NewVersionWebhook("some-version").SetupWebhookWithManager(mgr) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) + + version.NewVersionWebhook("some-version").SetupWebhookWithManager(k8sManager) // other required hooks - Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(mgr)).To(Succeed()) - orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFOrgEntityType)) - orgPlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) + orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFOrgEntityType)) + orgPlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFSpaceEntityType)) - spacePlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFSpaceEntityType)) + spacePlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect(networking.NewCFDomainValidator(mgr.GetClient()).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect(networking.NewCFDomainValidator(k8sManager.GetClient()).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(services.NewCFServiceInstanceValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), services.ServiceInstanceEntityType)), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), services.ServiceInstanceEntityType)), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(workloads.NewCFAppValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.AppEntityType)), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.AppEntityType)), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFPackage{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) - Expect(workloads.NewCFTaskValidator().SetupWebhookWithManager(mgr)).To(Succeed()) + Expect(workloads.NewCFTaskValidator().SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(korifiv1alpha1.NewCFProcessDefaulter(defaultMemoryMB, defaultDiskQuotaMB, defaultTimeout). - SetupWebhookWithManager(mgr)).To(Succeed()) - Expect((&korifiv1alpha1.CFBuild{}).SetupWebhookWithManager(mgr)).To(Succeed()) - Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(mgr)).To(Succeed()) + SetupWebhookWithManager(k8sManager)).To(Succeed()) + Expect((&korifiv1alpha1.CFBuild{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) + Expect((&korifiv1alpha1.CFRoute{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(networking.NewCFRouteValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), networking.RouteEntityType)), + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), networking.RouteEntityType)), rootNamespace, - mgr.GetClient(), - ).SetupWebhookWithManager(mgr)).To(Succeed()) + k8sManager.GetClient(), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(services.NewCFServiceBindingValidator( - webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), services.ServiceBindingEntityType)), - ).SetupWebhookWithManager(mgr)).To(Succeed()) - finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(mgr) - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - - // Create root namespace - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), services.ServiceBindingEntityType)), + ).SetupWebhookWithManager(k8sManager)).To(Succeed()) + finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(k8sManager) + + stopManager = helpers.StartK8sManager(k8sManager) + + Expect(adminClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: rootNamespace, }, @@ -156,6 +122,7 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() // call the cancel function to stop the controller context + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/controllers/webhooks/version/version_webhook_test.go b/controllers/webhooks/version/version_webhook_test.go index f8f14dd27..9d75d34f2 100644 --- a/controllers/webhooks/version/version_webhook_test.go +++ b/controllers/webhooks/version/version_webhook_test.go @@ -25,13 +25,13 @@ var _ = Describe("Setting the version annotation", func() { Describe("create", func() { var testObjects []client.Object createObject := func(obj client.Object) client.Object { - Expect(k8sClient.Create(context.Background(), obj)).To(Succeed()) + Expect(adminClient.Create(context.Background(), obj)).To(Succeed()) return obj } BeforeEach(func() { orgNamespace := "test-org-" + uuid.NewString() - Expect(k8sClient.Create(context.Background(), &corev1.Namespace{ + Expect(adminClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: orgNamespace, Labels: map[string]string{korifiv1alpha1.OrgNameKey: orgNamespace}, @@ -199,16 +199,16 @@ var _ = Describe("Setting the version annotation", func() { }, Spec: korifiv1alpha1.TaskWorkloadSpec{Command: []string{"foo"}}, } - Expect(k8sClient.Create(context.Background(), taskWorkload)).To(Succeed()) + Expect(adminClient.Create(context.Background(), taskWorkload)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) g.Expect(taskWorkload.Annotations).To(HaveKeyWithValue(version.KorifiCreationVersionKey, "some-version")) }).Should(Succeed()) }) When("unsetting the version", func() { JustBeforeEach(func() { - Expect(k8s.Patch(context.Background(), k8sClient, taskWorkload, func() { + Expect(k8s.Patch(context.Background(), adminClient, taskWorkload, func() { delete(taskWorkload.Annotations, version.KorifiCreationVersionKey) taskWorkload.Spec.Command = []string{"bar"} })).To(Succeed()) @@ -216,7 +216,7 @@ var _ = Describe("Setting the version annotation", func() { It("restores it", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) g.Expect(taskWorkload.Annotations).To(HaveKeyWithValue(version.KorifiCreationVersionKey, "some-version")) g.Expect(taskWorkload.Spec.Command).To(ConsistOf("bar")) }).Should(Succeed()) @@ -225,14 +225,14 @@ var _ = Describe("Setting the version annotation", func() { When("updating the version", func() { JustBeforeEach(func() { - Expect(k8s.Patch(context.Background(), k8sClient, taskWorkload, func() { + Expect(k8s.Patch(context.Background(), adminClient, taskWorkload, func() { taskWorkload.Annotations[version.KorifiCreationVersionKey] = "foo" })).To(Succeed()) }) It("leaves the new version", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) g.Expect(taskWorkload.Annotations).To(HaveKeyWithValue(version.KorifiCreationVersionKey, "foo")) }).Should(Succeed()) }) diff --git a/controllers/webhooks/workloads/apprev_webhook_test.go b/controllers/webhooks/workloads/apprev_webhook_test.go index 0439d9c79..bea2a95b8 100644 --- a/controllers/webhooks/workloads/apprev_webhook_test.go +++ b/controllers/webhooks/workloads/apprev_webhook_test.go @@ -25,7 +25,7 @@ var _ = Describe("ApprevWebhook", func() { namespace = "ns-" + uuid.NewString() - Expect(k8sClient.Create(ctx, &v1.Namespace{ + Expect(adminClient.Create(ctx, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, }, @@ -36,13 +36,13 @@ var _ = Describe("ApprevWebhook", func() { korifiv1alpha1.CFAppRevisionKey: "5", } app.Spec.DesiredState = korifiv1alpha1.StartedState - Expect(k8sClient.Create(ctx, app)).To(Succeed()) + Expect(adminClient.Create(ctx, app)).To(Succeed()) originalApp = app.DeepCopy() }) JustBeforeEach(func() { app.Spec.DisplayName = "changed-display-name" - Expect(k8sClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) + Expect(adminClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) }) It("does not change the app rev", func() { @@ -65,7 +65,7 @@ var _ = Describe("ApprevWebhook", func() { When("the app rev is not a number", func() { BeforeEach(func() { app.Annotations[korifiv1alpha1.CFAppRevisionKey] = "a" - Expect(k8sClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) + Expect(adminClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) originalApp = app.DeepCopy() }) @@ -77,7 +77,7 @@ var _ = Describe("ApprevWebhook", func() { When("the app rev is negative", func() { BeforeEach(func() { app.Annotations[korifiv1alpha1.CFAppRevisionKey] = "-10" - Expect(k8sClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) + Expect(adminClient.Patch(ctx, app, client.MergeFrom(originalApp))).To(Succeed()) originalApp = app.DeepCopy() }) diff --git a/controllers/webhooks/workloads/cfapp_validator_test.go b/controllers/webhooks/workloads/cfapp_validator_test.go index 89eb3472c..6f03704d3 100644 --- a/controllers/webhooks/workloads/cfapp_validator_test.go +++ b/controllers/webhooks/workloads/cfapp_validator_test.go @@ -33,12 +33,12 @@ var _ = Describe("CFAppValidatingWebhook", func() { namespace1 = "ns-1-" + uuid.NewString() namespace2 = "ns-2-" + uuid.NewString() - Expect(k8sClient.Create(ctx, &v1.Namespace{ + Expect(adminClient.Create(ctx, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace1, }, })).To(Succeed()) - Expect(k8sClient.Create(ctx, &v1.Namespace{ + Expect(adminClient.Create(ctx, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace2, }, @@ -58,7 +58,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { }) JustBeforeEach(func() { - createErr = k8sClient.Create(ctx, app1) + createErr = adminClient.Create(ctx, app1) }) It("should succeed", func() { @@ -68,7 +68,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { When("another CFApp exists with a different name in the same namespace", func() { BeforeEach(func() { app2 := makeCFApp(app2Guid, namespace1, app2Name) - Expect(k8sClient.Create(ctx, app2)).To(Succeed()) + Expect(adminClient.Create(ctx, app2)).To(Succeed()) }) It("should succeed", func() { @@ -79,7 +79,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { When("another CFApp exists with the same name in a different namespace", func() { BeforeEach(func() { app2 := makeCFApp(app2Guid, namespace2, app1Name) - Expect(k8sClient.Create(ctx, app2)).To(Succeed()) + Expect(adminClient.Create(ctx, app2)).To(Succeed()) }) It("should succeed", func() { @@ -90,7 +90,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { When("another CFApp exists with the same name in the same namespace", func() { BeforeEach(func() { app2 := makeCFApp(app2Guid, namespace1, app1Name) - Expect(k8sClient.Create(ctx, app2)).To(Succeed()) + Expect(adminClient.Create(ctx, app2)).To(Succeed()) }) It("should fail", func() { @@ -102,7 +102,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { BeforeEach(func() { app2 := makeCFApp(app2Guid, namespace1, strings.ToUpper(app1Name)) Expect( - k8sClient.Create(ctx, app2), + adminClient.Create(ctx, app2), ).To(Succeed()) }) @@ -120,12 +120,12 @@ var _ = Describe("CFAppValidatingWebhook", func() { BeforeEach(func() { app1 = makeCFApp(app1Guid, namespace1, app1Name) - Expect(k8sClient.Create(ctx, app1)).To(Succeed()) + Expect(adminClient.Create(ctx, app1)).To(Succeed()) originalApp1 = app1.DeepCopy() }) JustBeforeEach(func() { - updateErr = k8sClient.Patch(context.Background(), app1, client.MergeFrom(originalApp1)) + updateErr = adminClient.Patch(context.Background(), app1, client.MergeFrom(originalApp1)) }) When("changing the name", func() { @@ -140,7 +140,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { Expect(updateErr).NotTo(HaveOccurred()) app1Actual := korifiv1alpha1.CFApp{} - Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(app1), &app1Actual)).To(Succeed()) + Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(app1), &app1Actual)).To(Succeed()) Expect(app1Actual.Spec.DisplayName).To(Equal(newName)) }) @@ -149,7 +149,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { Expect(updateErr).NotTo(HaveOccurred()) reuseOldNameApp := makeCFApp(uuid.NewString(), namespace1, app1Name) - Expect(k8sClient.Create(ctx, reuseOldNameApp)).To(Succeed()) + Expect(adminClient.Create(ctx, reuseOldNameApp)).To(Succeed()) }) }) }) @@ -163,7 +163,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { Expect(updateErr).NotTo(HaveOccurred()) app1Actual := korifiv1alpha1.CFApp{} - Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(app1), &app1Actual)).To(Succeed()) + Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(app1), &app1Actual)).To(Succeed()) Expect(app1Actual.Spec.DesiredState).To(Equal(korifiv1alpha1.StartedState)) }) }) @@ -172,7 +172,7 @@ var _ = Describe("CFAppValidatingWebhook", func() { BeforeEach(func() { app2 := makeCFApp(app2Guid, namespace1, app2Name) app1.Spec.DisplayName = app2Name - Expect(k8sClient.Create(ctx, app2)).To(Succeed()) + Expect(adminClient.Create(ctx, app2)).To(Succeed()) }) It("should fail", func() { @@ -186,11 +186,11 @@ var _ = Describe("CFAppValidatingWebhook", func() { BeforeEach(func() { app1 = makeCFApp(app1Guid, namespace1, app1Name) - Expect(k8sClient.Create(ctx, app1)).To(Succeed()) + Expect(adminClient.Create(ctx, app1)).To(Succeed()) }) JustBeforeEach(func() { - deleteErr = k8sClient.Delete(ctx, app1) + deleteErr = adminClient.Delete(ctx, app1) }) It("succeeds", func() { diff --git a/controllers/webhooks/workloads/cforg_validator_test.go b/controllers/webhooks/workloads/cforg_validator_test.go index 892d2d46c..71bfe068a 100644 --- a/controllers/webhooks/workloads/cforg_validator_test.go +++ b/controllers/webhooks/workloads/cforg_validator_test.go @@ -42,7 +42,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { }) JustBeforeEach(func() { - createErr = k8sClient.Create(ctx, org1) + createErr = adminClient.Create(ctx, org1) }) It("should succeed", func() { @@ -72,7 +72,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { When("another CFOrg exists with a different name in the same namespace", func() { BeforeEach(func() { org2 := makeCFOrg(org2Guid, rootNamespace, org2Name) - Expect(k8sClient.Create(ctx, org2)).To(Succeed()) + Expect(adminClient.Create(ctx, org2)).To(Succeed()) }) It("should succeed", func() { @@ -83,7 +83,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { When("another CFOrg exists with the same name in the same namespace", func() { BeforeEach(func() { org2 := makeCFOrg(org2Guid, rootNamespace, org1Name) - Expect(k8sClient.Create(ctx, org2)).To(Succeed()) + Expect(adminClient.Create(ctx, org2)).To(Succeed()) }) It("should fail", func() { @@ -95,7 +95,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { BeforeEach(func() { org2 := makeCFOrg(org2Guid, rootNamespace, strings.ToUpper(org1Name)) Expect( - k8sClient.Create(ctx, org2), + adminClient.Create(ctx, org2), ).To(Succeed()) }) @@ -113,12 +113,12 @@ var _ = Describe("CFOrgValidatingWebhook", func() { BeforeEach(func() { org1 = makeCFOrg(org1Guid, rootNamespace, org1Name) - Expect(k8sClient.Create(ctx, org1)).To(Succeed()) + Expect(adminClient.Create(ctx, org1)).To(Succeed()) originalOrg1 = org1.DeepCopy() }) JustBeforeEach(func() { - updateErr = k8sClient.Patch(context.Background(), org1, client.MergeFrom(originalOrg1)) + updateErr = adminClient.Patch(context.Background(), org1, client.MergeFrom(originalOrg1)) }) When("changing the name", func() { @@ -132,7 +132,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { It("should succeed", func() { Expect(updateErr).NotTo(HaveOccurred()) org1Actual := korifiv1alpha1.CFOrg{} - Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(org1), &org1Actual)).To(Succeed()) + Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(org1), &org1Actual)).To(Succeed()) Expect(org1Actual.Spec.DisplayName).To(Equal(newName)) }) @@ -141,7 +141,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { Expect(updateErr).NotTo(HaveOccurred()) reuseOldNameOrg := makeCFOrg(uuid.NewString(), rootNamespace, org1Name) - Expect(k8sClient.Create(ctx, reuseOldNameOrg)).To(Succeed()) + Expect(adminClient.Create(ctx, reuseOldNameOrg)).To(Succeed()) }) }) }) @@ -150,7 +150,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { It("should succeed", func() { Expect(updateErr).NotTo(HaveOccurred()) org1Actual := korifiv1alpha1.CFOrg{} - Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(org1), &org1Actual)).To(Succeed()) + Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(org1), &org1Actual)).To(Succeed()) }) }) @@ -158,7 +158,7 @@ var _ = Describe("CFOrgValidatingWebhook", func() { BeforeEach(func() { org2 := makeCFOrg(org2Guid, rootNamespace, org2Name) org1.Spec.DisplayName = org2Name - Expect(k8sClient.Create(ctx, org2)).To(Succeed()) + Expect(adminClient.Create(ctx, org2)).To(Succeed()) }) It("should fail", func() { @@ -172,11 +172,11 @@ var _ = Describe("CFOrgValidatingWebhook", func() { BeforeEach(func() { org1 = makeCFOrg(org1Guid, rootNamespace, org1Name) - Expect(k8sClient.Create(ctx, org1)).To(Succeed()) + Expect(adminClient.Create(ctx, org1)).To(Succeed()) }) JustBeforeEach(func() { - deleteErr = k8sClient.Delete(ctx, org1) + deleteErr = adminClient.Delete(ctx, org1) }) It("succeeds", func() { diff --git a/controllers/webhooks/workloads/cfspace_validator_test.go b/controllers/webhooks/workloads/cfspace_validator_test.go index 69dc59fcf..0fd8e541f 100644 --- a/controllers/webhooks/workloads/cfspace_validator_test.go +++ b/controllers/webhooks/workloads/cfspace_validator_test.go @@ -26,7 +26,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { ctx = context.Background() orgNamespace = "test-org-" + uuid.NewString() - Expect(k8sClient.Create(ctx, &korifiv1alpha1.CFOrg{ + Expect(adminClient.Create(ctx, &korifiv1alpha1.CFOrg{ ObjectMeta: metav1.ObjectMeta{ Name: orgNamespace, Namespace: rootNamespace, @@ -36,7 +36,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { }, })).To(Succeed()) - Expect(k8sClient.Create(ctx, &v1.Namespace{ + Expect(adminClient.Create(ctx, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: orgNamespace, Labels: map[string]string{korifiv1alpha1.OrgNameKey: orgNamespace}, @@ -52,7 +52,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { }) JustBeforeEach(func() { - err = k8sClient.Create(ctx, cfSpace) + err = adminClient.Create(ctx, cfSpace) }) It("succeeds", func() { @@ -62,7 +62,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { When("a corresponding CFOrg does not exist", func() { BeforeEach(func() { cfSpace.Namespace = "not-an-org" - Expect(k8sClient.Create(ctx, &v1.Namespace{ + Expect(adminClient.Create(ctx, &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: "not-an-org", }, @@ -87,7 +87,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { When("the name already exists in the org namespace", func() { BeforeEach(func() { cfSpace2 = makeCFSpace(orgNamespace, "my-space") - Expect(k8sClient.Create(ctx, cfSpace2)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace2)).To(Succeed()) }) It("fails", func() { @@ -98,7 +98,7 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { When("another CFSpace exists with the same name(case insensitive) in the same namespace", func() { BeforeEach(func() { cfSpace2 = makeCFSpace(orgNamespace, "My-Space") - Expect(k8sClient.Create(ctx, cfSpace2)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace2)).To(Succeed()) }) It("should fail", func() { @@ -110,12 +110,12 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { Describe("updating a space", func() { BeforeEach(func() { cfSpace = makeCFSpace(orgNamespace, "my-space") - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) }) When("the space name is changed to another which is unique in the root CF namespace", func() { It("succeeds", func() { - Expect(k8s.Patch(ctx, k8sClient, cfSpace, func() { + Expect(k8s.Patch(ctx, adminClient, cfSpace, func() { cfSpace.Spec.DisplayName = "another-space" })).To(Succeed()) }) @@ -124,11 +124,11 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { When("the new space name already exists in the org namespace", func() { BeforeEach(func() { cfSpace2 = makeCFSpace(orgNamespace, "another-space") - Expect(k8sClient.Create(ctx, cfSpace2)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace2)).To(Succeed()) }) It("fails", func() { - Expect(k8s.Patch(ctx, k8sClient, cfSpace, func() { + Expect(k8s.Patch(ctx, adminClient, cfSpace, func() { cfSpace.Spec.DisplayName = "another-space" })).To(MatchError(ContainSubstring("Name must be unique per organization"))) }) @@ -138,11 +138,11 @@ var _ = Describe("CFSpaceValidatingWebhook", func() { Describe("deleting a space", func() { BeforeEach(func() { cfSpace = makeCFSpace(orgNamespace, "my-space") - Expect(k8sClient.Create(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Create(ctx, cfSpace)).To(Succeed()) }) It("can delete the space", func() { - Expect(k8sClient.Delete(ctx, cfSpace)).To(Succeed()) + Expect(adminClient.Delete(ctx, cfSpace)).To(Succeed()) }) }) }) diff --git a/controllers/webhooks/workloads/cftask_defaulter_test.go b/controllers/webhooks/workloads/cftask_defaulter_test.go index 7040ec44b..1c7971136 100644 --- a/controllers/webhooks/workloads/cftask_defaulter_test.go +++ b/controllers/webhooks/workloads/cftask_defaulter_test.go @@ -35,8 +35,8 @@ var _ = Describe("CFTaskMutatingWebhook", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(context.Background(), cfTask)).To(Succeed()) - Expect(k8s.Patch(context.Background(), k8sClient, cfTask, func() { + Expect(adminClient.Create(context.Background(), cfTask)).To(Succeed()) + Expect(k8s.Patch(context.Background(), adminClient, cfTask, func() { cfTask.Status = korifiv1alpha1.CFTaskStatus{ Conditions: []metav1.Condition{}, } @@ -66,7 +66,7 @@ var _ = Describe("CFTaskMutatingWebhook", func() { JustBeforeEach(func() { currentSeqId = cfTask.Status.SequenceID - Expect(k8s.Patch(context.Background(), k8sClient, cfTask, updateTaskFunc)).To(Succeed()) + Expect(k8s.Patch(context.Background(), adminClient, cfTask, updateTaskFunc)).To(Succeed()) }) When("the spec is updated", func() { diff --git a/controllers/webhooks/workloads/cftask_validator_test.go b/controllers/webhooks/workloads/cftask_validator_test.go index 48d562da0..eb5068363 100644 --- a/controllers/webhooks/workloads/cftask_validator_test.go +++ b/controllers/webhooks/workloads/cftask_validator_test.go @@ -24,7 +24,7 @@ var _ = Describe("CFTask Creation", func() { BeforeEach(func() { cfApp := makeCFApp(testutils.PrefixedGUID("cfapp"), rootNamespace, testutils.PrefixedGUID("appName")) - Expect(k8sClient.Create(context.Background(), cfApp)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfApp)).To(Succeed()) cfTask = &korifiv1alpha1.CFTask{ ObjectMeta: metav1.ObjectMeta{ @@ -41,7 +41,7 @@ var _ = Describe("CFTask Creation", func() { }) JustBeforeEach(func() { - creationErr = k8sClient.Create(context.Background(), cfTask) + creationErr = adminClient.Create(context.Background(), cfTask) }) It("suceeds", func() { @@ -92,7 +92,7 @@ var _ = Describe("CFTask Creation", func() { SequenceID: seqId, } - creationErr = k8sClient.Status().Patch(context.Background(), cfTask, client.MergeFrom(originalCfTask)) + creationErr = adminClient.Status().Patch(context.Background(), cfTask, client.MergeFrom(originalCfTask)) }) It("suceeds", func() { @@ -124,7 +124,7 @@ var _ = Describe("CFTask Update", func() { BeforeEach(func() { cfApp := makeCFApp(testutils.PrefixedGUID("cfapp"), rootNamespace, testutils.PrefixedGUID("appName")) - Expect(k8sClient.Create(context.Background(), cfApp)).To(Succeed()) + Expect(adminClient.Create(context.Background(), cfApp)).To(Succeed()) updateFunc = func() {} cfTask = &korifiv1alpha1.CFTask{ @@ -139,8 +139,8 @@ var _ = Describe("CFTask Update", func() { }, }, } - Expect(k8sClient.Create(context.Background(), cfTask)).To(Succeed()) - Expect(k8s.Patch(context.Background(), k8sClient, cfTask, func() { + Expect(adminClient.Create(context.Background(), cfTask)).To(Succeed()) + Expect(k8s.Patch(context.Background(), adminClient, cfTask, func() { cfTask.Status = korifiv1alpha1.CFTaskStatus{ Conditions: []metav1.Condition{}, } @@ -148,7 +148,7 @@ var _ = Describe("CFTask Update", func() { }) JustBeforeEach(func() { - updateErr = k8s.Patch(context.Background(), k8sClient, cfTask, updateFunc) + updateErr = k8s.Patch(context.Background(), adminClient, cfTask, updateFunc) }) When("canceled is not changed", func() { @@ -206,7 +206,7 @@ var _ = Describe("CFTask Update", func() { When("the task is already canceled before an update", func() { BeforeEach(func() { - Expect(k8s.Patch(context.Background(), k8sClient, cfTask, func() { + Expect(k8s.Patch(context.Background(), adminClient, cfTask, func() { cfTask.Spec.Canceled = true })).To(Succeed()) @@ -247,7 +247,7 @@ func setStatusCondition(cftask *korifiv1alpha1.CFTask, conditionType string) { Reason: "foo", Message: "bar", }) - Expect(k8sClient.Status().Patch(context.Background(), cftask, client.MergeFrom(clone))).To(Succeed()) + Expect(adminClient.Status().Patch(context.Background(), cftask, client.MergeFrom(clone))).To(Succeed()) // the status update clears any unapplied changes to the rest of the object, so reset spec changes: cftask.Spec = clone.Spec diff --git a/controllers/webhooks/workloads/suite_integration_test.go b/controllers/webhooks/workloads/suite_integration_test.go index 02726610e..9e10af83e 100644 --- a/controllers/webhooks/workloads/suite_integration_test.go +++ b/controllers/webhooks/workloads/suite_integration_test.go @@ -2,15 +2,13 @@ package workloads_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" "time" korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" "code.cloudfoundry.org/korifi/controllers/config" + "code.cloudfoundry.org/korifi/controllers/controllers/shared" "code.cloudfoundry.org/korifi/controllers/coordination" "code.cloudfoundry.org/korifi/controllers/webhooks" "code.cloudfoundry.org/korifi/tests/helpers" @@ -26,7 +24,6 @@ import ( rbacv1 "k8s.io/api/rbac/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" - ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -35,9 +32,10 @@ import ( ) var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client ) const rootNamespace = "cf" @@ -53,9 +51,6 @@ func TestWorkloadsWebhooks(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds"), @@ -76,70 +71,37 @@ var _ = BeforeSuite(func() { Expect(coordinationv1.AddToScheme(scheme.Scheme)).To(Succeed()) Expect(rbacv1.AddToScheme(scheme.Scheme)).To(Succeed()) - //+kubebuilder:scaffold:scheme - - // start webhook server using Manager - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(helpers.SetupControllersUser(testEnv), ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "controllers", "role.yaml")) + Expect(shared.SetupIndexWithManager(k8sManager)).To(Succeed()) - k8sClient, err = client.New(adminConfig, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) - Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(mgr)).To(Succeed()) + Expect((&korifiv1alpha1.CFApp{}).SetupWebhookWithManager(k8sManager)).To(Succeed()) - (&workloads.AppRevWebhook{}).SetupWebhookWithManager(mgr) + (&workloads.AppRevWebhook{}).SetupWebhookWithManager(k8sManager) - appNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.AppEntityType)) - Expect(workloads.NewCFAppValidator(appNameDuplicateValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + appNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.AppEntityType)) + Expect(workloads.NewCFAppValidator(appNameDuplicateValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFOrgEntityType)) - orgPlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + orgNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFOrgEntityType)) + orgPlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFOrgValidator(orgNameDuplicateValidator, orgPlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) - spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(mgr.GetClient(), workloads.CFSpaceEntityType)) - spacePlacementValidator := webhooks.NewPlacementValidator(mgr.GetClient(), rootNamespace) - Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(mgr)).To(Succeed()) + spaceNameDuplicateValidator := webhooks.NewDuplicateValidator(coordination.NewNameRegistry(k8sManager.GetClient(), workloads.CFSpaceEntityType)) + spacePlacementValidator := webhooks.NewPlacementValidator(k8sManager.GetClient(), rootNamespace) + Expect(workloads.NewCFSpaceValidator(spaceNameDuplicateValidator, spacePlacementValidator).SetupWebhookWithManager(k8sManager)).To(Succeed()) Expect(workloads.NewCFTaskDefaulter(config.CFProcessDefaults{ MemoryMB: 500, DiskQuotaMB: 512, - }).SetupWebhookWithManager(mgr)).To(Succeed()) - Expect(workloads.NewCFTaskValidator().SetupWebhookWithManager(mgr)).To(Succeed()) - version.NewVersionWebhook("some-version").SetupWebhookWithManager(mgr) - finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(mgr) - - //+kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - - // Create root namespace - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + }).SetupWebhookWithManager(k8sManager)).To(Succeed()) + Expect(workloads.NewCFTaskValidator().SetupWebhookWithManager(k8sManager)).To(Succeed()) + version.NewVersionWebhook("some-version").SetupWebhookWithManager(k8sManager) + finalizer.NewControllersFinalizerWebhook().SetupWebhookWithManager(k8sManager) + + stopManager = helpers.StartK8sManager(k8sManager) + + Expect(adminClient.Create(context.Background(), &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: rootNamespace, }, @@ -147,6 +109,7 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() // call the cancel function to stop the controller context + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/job-task-runner/controllers/integration/suite_test.go b/job-task-runner/controllers/integration/suite_test.go index 84c3503b1..dc8dce803 100644 --- a/job-task-runner/controllers/integration/suite_test.go +++ b/job-task-runner/controllers/integration/suite_test.go @@ -24,6 +24,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" "code.cloudfoundry.org/korifi/job-task-runner/controllers" + "code.cloudfoundry.org/korifi/tests/helpers" "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" @@ -36,15 +37,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - //+kubebuilder:scaffold:imports ) -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - var ( - cancel context.CancelFunc - k8sClient client.Client + stopManager context.CancelFunc + stopClient context.CancelFunc + adminClient client.Client testEnv *envtest.Environment testNamespace *corev1.Namespace ) @@ -61,9 +59,6 @@ func TestJobTaskWorkloadController(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -72,58 +67,38 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) err = korifiv1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme - - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "job-task-runner", "role.yaml")) logger := ctrl.Log.WithName("job-task-runner").WithName("TaskWorkload") - managerClient := k8sManager.GetClient() - taskWorkloadReconciler := controllers.NewTaskWorkloadReconciler( logger, - managerClient, + k8sManager.GetClient(), k8sManager.GetScheme(), - controllers.NewStatusGetter(logger, managerClient), + controllers.NewStatusGetter(logger, k8sManager.GetClient()), time.Minute, ) err = taskWorkloadReconciler.SetupWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) + stopManager = helpers.StartK8sManager(k8sManager) - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() + adminClient, stopClient = helpers.NewCachedClient(testEnv.Config) }) var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") + stopClient() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) var _ = BeforeEach(func() { - testNamespace = createNamespace(context.Background(), k8sClient, prefixedGUID("testns")) + testNamespace = createNamespace(context.Background(), adminClient, prefixedGUID("testns")) }) func prefixedGUID(prefix string) string { diff --git a/job-task-runner/controllers/integration/taskworkload_controller_test.go b/job-task-runner/controllers/integration/taskworkload_controller_test.go index dea3291dd..4a6161545 100644 --- a/job-task-runner/controllers/integration/taskworkload_controller_test.go +++ b/job-task-runner/controllers/integration/taskworkload_controller_test.go @@ -51,7 +51,7 @@ var _ = Describe("Job TaskWorkload Controller Integration Test", func() { }) JustBeforeEach(func() { - createErr = k8sClient.Create(context.Background(), taskWorkload) + createErr = adminClient.Create(context.Background(), taskWorkload) }) It("creates a job owned by the task workload", func() { @@ -59,7 +59,7 @@ var _ = Describe("Job TaskWorkload Controller Integration Test", func() { jobList := &batchv1.JobList{} Eventually(func(g Gomega) { - g.Expect(k8sClient.List(context.Background(), jobList, client.InNamespace(testNamespace.Name))).To(Succeed()) + g.Expect(adminClient.List(context.Background(), jobList, client.InNamespace(testNamespace.Name))).To(Succeed()) g.Expect(jobList.Items).To(HaveLen(1)) }).Should(Succeed()) @@ -100,7 +100,7 @@ var _ = Describe("Job TaskWorkload Controller Integration Test", func() { It("sets the initialized condition on the task workload status", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(taskWorkload), taskWorkload)).To(Succeed()) g.Expect(meta.IsStatusConditionTrue(taskWorkload.Status.Conditions, korifiv1alpha1.TaskInitializedConditionType)).To(BeTrue()) }).Should(Succeed()) }) diff --git a/kpack-image-builder/controllers/builderinfo_controller_test.go b/kpack-image-builder/controllers/builderinfo_controller_test.go index 2f2b5d124..e5b649483 100644 --- a/kpack-image-builder/controllers/builderinfo_controller_test.go +++ b/kpack-image-builder/controllers/builderinfo_controller_test.go @@ -41,10 +41,10 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { AfterEach(func() { if info != nil { - Expect(k8sClient.Delete(context.Background(), info)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), info)).To(Succeed()) } if clusterBuilder != nil { - Expect(k8sClient.Delete(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), clusterBuilder)).To(Succeed()) } }) @@ -56,7 +56,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { }, } - Expect(k8sClient.Create(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Create(context.Background(), clusterBuilder)).To(Succeed()) clusterBuilder.Status = buildv1alpha2.BuilderStatus{ Order: []corev1alpha1.OrderEntry{ @@ -78,7 +78,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Type: "Ready", Status: "True", }) - Expect(k8sClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) }) When("the BuilderInfo is first created", func() { @@ -89,12 +89,12 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Namespace: rootNamespace.Name, }, } - Expect(k8sClient.Create(context.Background(), info)).To(Succeed()) + Expect(adminClient.Create(context.Background(), info)).To(Succeed()) }) It("sets the buildpacks on the BuilderInfo", func() { Eventually(func(g Gomega) []v1alpha1.BuilderInfoStatusBuildpack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Buildpacks }).ShouldNot(BeEmpty()) @@ -117,7 +117,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { It("sets the stacks on the BuilderInfo", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.Stacks).To(HaveLen(1)) }).Should(Succeed()) @@ -126,7 +126,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { It("marks the BuilderInfo as ready", func() { Eventually(func(g Gomega) []v1alpha1.BuilderInfoStatusBuildpack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Buildpacks }).ShouldNot(BeEmpty()) @@ -140,7 +140,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { It("sets the ObservedGeneration status field", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.ObservedGeneration).To(Equal(info.Generation)) }).Should(Succeed()) }) @@ -157,12 +157,12 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { } } Expect(ok).To(BeTrue()) - Expect(k8sClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) }) It("marks the BuilderInfo as not ready", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) readyCondition := meta.FindStatusCondition(info.Status.Conditions, "Ready") g.Expect(readyCondition).NotTo(BeNil()) g.Expect(readyCondition.Status).To(Equal(metav1.ConditionFalse)) @@ -185,12 +185,12 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { } } Expect(ok).To(BeTrue()) - Expect(k8sClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) }) It("marks the BuilderInfo as not ready", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) readyCondition := meta.FindStatusCondition(info.Status.Conditions, "Ready") g.Expect(readyCondition).NotTo(BeNil()) g.Expect(readyCondition.Status).To(Equal(metav1.ConditionFalse)) @@ -216,10 +216,10 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Namespace: rootNamespace.Name, }, } - Expect(k8sClient.Create(context.Background(), info)).To(Succeed()) + Expect(adminClient.Create(context.Background(), info)).To(Succeed()) Eventually(func(g Gomega) []v1alpha1.BuilderInfoStatusBuildpack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Buildpacks }).ShouldNot(BeEmpty()) }) @@ -250,12 +250,12 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { }}, }, } - Expect(k8sClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) }) It("updates the buildpacks on the BuilderInfo", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.Buildpacks).To(HaveLen(4)) }).Should(Succeed()) @@ -284,7 +284,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { It("updates the stacks on the BuilderInfo", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.Stacks).To(ConsistOf(HaveField("Name", newStack))) }).Should(Succeed()) }) @@ -298,16 +298,16 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Namespace: rootNamespace.Name, }, } - Expect(k8sClient.Create(context.Background(), info)).To(Succeed()) + Expect(adminClient.Create(context.Background(), info)).To(Succeed()) }) It("doesn't modify that resource", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) }).Should(Succeed()) Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.Buildpacks).To(BeEmpty()) }).Should(Succeed()) }) @@ -320,7 +320,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Name: PrefixedGUID("wrong-namespace"), }, } - Expect(k8sClient.Create(context.Background(), wrongNamespace)).To(Succeed()) + Expect(adminClient.Create(context.Background(), wrongNamespace)).To(Succeed()) info = &v1alpha1.BuilderInfo{ ObjectMeta: metav1.ObjectMeta{ @@ -328,16 +328,16 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Namespace: wrongNamespace.Name, }, } - Expect(k8sClient.Create(context.Background(), info)).To(Succeed()) + Expect(adminClient.Create(context.Background(), info)).To(Succeed()) }) It("doesn't modify that resource", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) }).Should(Succeed()) Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) g.Expect(info.Status.Buildpacks).To(BeEmpty()) }).Should(Succeed()) }) @@ -354,7 +354,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { Namespace: rootNamespace.Name, }, } - Expect(k8sClient.Create(context.Background(), info)).To(Succeed()) + Expect(adminClient.Create(context.Background(), info)).To(Succeed()) wrongClusterBuilder = &buildv1alpha2.ClusterBuilder{ ObjectMeta: metav1.ObjectMeta{ @@ -362,7 +362,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { }, } - Expect(k8sClient.Create(context.Background(), wrongClusterBuilder)).To(Succeed()) + Expect(adminClient.Create(context.Background(), wrongClusterBuilder)).To(Succeed()) wrongClusterBuilder.Status = buildv1alpha2.BuilderStatus{ Order: []corev1alpha1.OrderEntry{ @@ -374,16 +374,16 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { ID: stack, }, } - Expect(k8sClient.Status().Update(context.Background(), wrongClusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), wrongClusterBuilder)).To(Succeed()) }) AfterEach(func() { - Expect(k8sClient.Delete(context.Background(), wrongClusterBuilder)).To(Succeed()) + Expect(adminClient.Delete(context.Background(), wrongClusterBuilder)).To(Succeed()) }) It("doesn't set the buildpacks on the BuilderInfo", func() { Consistently(func(g Gomega) []v1alpha1.BuilderInfoStatusBuildpack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Buildpacks }).Should(BeEmpty()) @@ -404,7 +404,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { }, } - Expect(k8sClient.Create(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Create(context.Background(), clusterBuilder)).To(Succeed()) clusterBuilder.Status = buildv1alpha2.BuilderStatus{ Order: []corev1alpha1.OrderEntry{ @@ -422,12 +422,12 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { }}, }, } - Expect(k8sClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) + Expect(adminClient.Status().Update(context.Background(), clusterBuilder)).To(Succeed()) }) It("sets the buildpacks on the BuilderInfo", func() { Eventually(func(g Gomega) []v1alpha1.BuilderInfoStatusBuildpack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Buildpacks }).ShouldNot(BeEmpty()) @@ -441,7 +441,7 @@ var _ = Describe("BuilderInfoReconciler", Serial, func() { It("sets the stack", func() { Eventually(func(g Gomega) []v1alpha1.BuilderInfoStatusStack { - g.Expect(k8sClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) + g.Expect(adminClient.Get(context.Background(), client.ObjectKeyFromObject(info), info)).To(Succeed()) return info.Status.Stacks }).Should(HaveLen(1)) diff --git a/kpack-image-builder/controllers/buildworkload_controller_test.go b/kpack-image-builder/controllers/buildworkload_controller_test.go index 075e86980..46adaaf79 100644 --- a/kpack-image-builder/controllers/buildworkload_controller_test.go +++ b/kpack-image-builder/controllers/buildworkload_controller_test.go @@ -50,13 +50,13 @@ var _ = Describe("BuildWorkloadReconciler", func() { expectedCacheVolumeSize = "1024Mi" reconcilerName = "kpack-image-builder" namespaceGUID = PrefixedGUID("namespace") - Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespaceGUID}})).To(Succeed()) + Expect(adminClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespaceGUID}})).To(Succeed()) dockerRegistrySecret := buildDockerRegistrySecret(wellFormedRegistryCredentialsSecret, namespaceGUID) - Expect(k8sClient.Create(ctx, dockerRegistrySecret)).To(Succeed()) + Expect(adminClient.Create(ctx, dockerRegistrySecret)).To(Succeed()) registryServiceAccount := buildServiceAccount("builder-service-account", namespaceGUID, wellFormedRegistryCredentialsSecret) - Expect(k8sClient.Create(ctx, registryServiceAccount)).To(Succeed()) + Expect(adminClient.Create(ctx, registryServiceAccount)).To(Succeed()) clusterBuilder = &buildv1alpha2.ClusterBuilder{ ObjectMeta: metav1.ObjectMeta{ @@ -79,9 +79,9 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, }, } - Expect(k8sClient.Create(ctx, clusterBuilder)).To(Succeed()) + Expect(adminClient.Create(ctx, clusterBuilder)).To(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, clusterBuilder, func() { + Expect(k8s.Patch(ctx, adminClient, clusterBuilder, func() { clusterBuilder.Status.Conditions = corev1alpha1.Conditions{ { Type: corev1alpha1.ConditionType("Ready"), @@ -140,14 +140,14 @@ var _ = Describe("BuildWorkloadReconciler", func() { AfterEach(func() { if clusterBuilder != nil { - Expect(k8sClient.Delete(ctx, clusterBuilder)).To(Succeed()) + Expect(adminClient.Delete(ctx, clusterBuilder)).To(Succeed()) } }) Describe("BuildWorkload initialization phase", func() { JustBeforeEach(func() { buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) }) CheckInitialization := func() { @@ -156,7 +156,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("reconciles the kpack.Image", func() { Eventually(func(g Gomega) { kpackImage := new(buildv1alpha2.Image) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) g.Expect(kpackImage.Spec.Build).ToNot(BeNil()) g.Expect(kpackImage.Spec.Source.Registry.Image).To(BeEquivalentTo(source.Registry.Image)) g.Expect(kpackImage.Spec.Source.Registry.ImagePullSecrets).To(BeEquivalentTo(source.Registry.ImagePullSecrets)) @@ -175,7 +175,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { cfBuildLookupKey := types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID} updatedBuildWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, cfBuildLookupKey, updatedBuildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, cfBuildLookupKey, updatedBuildWorkload)).To(Succeed()) g.Expect(updatedBuildWorkload.Status.ObservedGeneration).To(Equal(updatedBuildWorkload.Generation)) g.Expect(mustHaveCondition(g, updatedBuildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) @@ -194,7 +194,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("kpack image already exists", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &buildv1alpha2.Image{ + Expect(adminClient.Create(ctx, &buildv1alpha2.Image{ ObjectMeta: metav1.ObjectMeta{ Name: "app-guid", Namespace: namespaceGUID, @@ -225,7 +225,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { var originalImageUID types.UID BeforeEach(func() { oldSize := resource.MustParse("512Mi") - Expect(k8sClient.Create(ctx, &buildv1alpha2.Image{ + Expect(adminClient.Create(ctx, &buildv1alpha2.Image{ ObjectMeta: metav1.ObjectMeta{ Name: "app-guid", Namespace: namespaceGUID, @@ -252,7 +252,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { })).To(Succeed()) Eventually(func(g Gomega) { kpackImage := new(buildv1alpha2.Image) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) originalImageUID = kpackImage.UID g.Expect(originalImageUID).NotTo(BeEmpty()) }).Should(Succeed()) @@ -261,7 +261,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("deletes the kpack image and recreates it", func() { Eventually(func(g Gomega) { kpackImage := new(buildv1alpha2.Image) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) g.Expect(kpackImage.UID).NotTo(Equal(originalImageUID)) }).Should(Succeed()) }) @@ -281,7 +281,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("doesn't create the kpack Image as long as the secret is missing", func() { Consistently(func() bool { lookupKey := types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID} - return k8serrors.IsNotFound(k8sClient.Get(ctx, lookupKey, new(buildv1alpha2.Image))) + return k8serrors.IsNotFound(adminClient.Get(ctx, lookupKey, new(buildv1alpha2.Image))) }).Should(BeTrue()) }) }) @@ -308,7 +308,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, } Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(builder), builder)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(builder), builder)).To(Succeed()) g.Expect(builder.OwnerReferences).To(HaveLen(1)) g.Expect(builder.OwnerReferences[0].Name).To(Equal(buildWorkload.Name)) g.Expect(builder.OwnerReferences[0].Controller).To(BeNil()) @@ -333,7 +333,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("sets the builder ref on the image", func() { Eventually(func(g Gomega) { kpackImage := new(buildv1alpha2.Image) - g.Expect(k8sClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) + g.Expect(adminClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage)).To(Succeed()) g.Expect(kpackImage.Spec.Builder.Name).To(Equal(controllers.ComputeBuilderName(buildWorkload.Spec.Buildpacks))) g.Expect(kpackImage.Spec.Builder.Namespace).To(Equal(buildWorkload.Namespace)) g.Expect(kpackImage.Spec.Builder.Kind).To(Equal("Builder")) @@ -349,7 +349,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { anotherBuildworkloadGUID = PrefixedGUID("another-buildworkload-") anotherBuildWorkload := buildWorkloadObject(anotherBuildworkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, anotherBuildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, anotherBuildWorkload)).To(Succeed()) sharedBuilder = &buildv1alpha2.Builder{ ObjectMeta: metav1.ObjectMeta{ @@ -358,13 +358,13 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, } Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(sharedBuilder), sharedBuilder)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(sharedBuilder), sharedBuilder)).To(Succeed()) }).Should(Succeed()) }) It("shares the kpack builder", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(sharedBuilder), sharedBuilder)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(sharedBuilder), sharedBuilder)).To(Succeed()) g.Expect(sharedBuilder.OwnerReferences).To(HaveLen(2)) g.Expect( []string{sharedBuilder.OwnerReferences[0].Name, sharedBuilder.OwnerReferences[1].Name}, @@ -383,7 +383,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("fails the build", func() { updatedWorkload := &korifiv1alpha1.BuildWorkload{ObjectMeta: metav1.ObjectMeta{Name: buildWorkloadGUID, Namespace: namespaceGUID}} Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(updatedWorkload), updatedWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(updatedWorkload), updatedWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) foundCondition := meta.FindStatusCondition(updatedWorkload.Status.Conditions, "Succeeded") @@ -402,7 +402,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("does not create a kpack image resource", func() { Consistently(func(g Gomega) { kpackImage := new(buildv1alpha2.Image) - err := k8sClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage) + err := adminClient.Get(ctx, types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID}, kpackImage) g.Expect(err).To(MatchError(fmt.Sprintf("Image.kpack.io %q not found", "app-guid"))) }).Should(Succeed()) }) @@ -410,15 +410,15 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("the other reconciler has partially reconciled the object and created an Image", func() { BeforeEach(func() { image := buildKpackImageObject("app-guid", namespaceGUID, source, env, services) - Expect(k8sClient.Create(ctx, image)).To(Succeed()) + Expect(adminClient.Create(ctx, image)).To(Succeed()) kpackImageLookupKey := types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID} createdKpackImage := new(buildv1alpha2.Image) Eventually(func() error { - return k8sClient.Get(ctx, kpackImageLookupKey, createdKpackImage) + return adminClient.Get(ctx, kpackImageLookupKey, createdKpackImage) }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, createdKpackImage, func() { + Expect(k8s.Patch(ctx, adminClient, createdKpackImage, func() { setKpackImageStatus(createdKpackImage, "Ready", metav1.ConditionTrue) createdKpackImage.Status.LatestImage = "some-org/my-image@sha256:some-sha" createdKpackImage.Status.LatestStack = "cflinuxfs3" @@ -428,10 +428,10 @@ var _ = Describe("BuildWorkloadReconciler", func() { JustBeforeEach(func() { updatedBuildWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func() error { - return k8sClient.Get(ctx, types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID}, updatedBuildWorkload) + return adminClient.Get(ctx, types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID}, updatedBuildWorkload) }).Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, updatedBuildWorkload, func() { + Expect(k8s.Patch(ctx, adminClient, updatedBuildWorkload, func() { meta.SetStatusCondition(&updatedBuildWorkload.Status.Conditions, metav1.Condition{ Type: korifiv1alpha1.SucceededConditionType, Status: metav1.ConditionUnknown, @@ -443,12 +443,12 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("doesn't continue to reconcile the object", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) }) @@ -468,12 +468,12 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) kpackImageLookupKey := types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID} createdKpackImage = new(buildv1alpha2.Image) Eventually(func() error { - return k8sClient.Get(ctx, kpackImageLookupKey, createdKpackImage) + return adminClient.Get(ctx, kpackImageLookupKey, createdKpackImage) }).Should(Succeed()) build = &buildv1alpha2.Build{ @@ -489,14 +489,14 @@ var _ = Describe("BuildWorkloadReconciler", func() { } build1 = build.DeepCopy() - Expect(k8sClient.Create(ctx, build1)).To(Succeed()) + Expect(adminClient.Create(ctx, build1)).To(Succeed()) buildSucceededStatus = "" buildSucceededReason = "" }) JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, build1, func() { + Expect(k8s.Patch(ctx, adminClient, build1, func() { build1.Status.Conditions = append(build1.Status.Conditions, corev1alpha1.Condition{ Type: corev1alpha1.ConditionType("Succeeded"), Status: corev1.ConditionStatus(buildSucceededStatus), @@ -519,11 +519,11 @@ var _ = Describe("BuildWorkloadReconciler", func() { source2 := source source2.Registry.Image += "2" buildWorkload2 := buildWorkloadObject(cfBuildGUID2, namespaceGUID, source2, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload2)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload2)).To(Succeed()) Eventually(func(g Gomega) { kpackImageLookupKey := types.NamespacedName{Name: "app-guid", Namespace: namespaceGUID} - g.Expect(k8sClient.Get(ctx, kpackImageLookupKey, createdKpackImage)).To(Succeed()) + g.Expect(adminClient.Get(ctx, kpackImageLookupKey, createdKpackImage)).To(Succeed()) g.Expect(createdKpackImage.Spec.Source.Registry.Image).To(Equal(source2.Registry.Image)) }).Should(Succeed()) @@ -532,11 +532,11 @@ var _ = Describe("BuildWorkloadReconciler", func() { build2 = build.DeepCopy() build2.Name = "build-2" build2.Labels[buildv1alpha2.ImageGenerationLabel] = "2" - Expect(k8sClient.Create(ctx, build2)).To(Succeed()) + Expect(adminClient.Create(ctx, build2)).To(Succeed()) }) JustBeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, build2, func() { + Expect(k8s.Patch(ctx, adminClient, build2, func() { build2.Status.Conditions = append(build2.Status.Conditions, corev1alpha1.Condition{ Type: corev1alpha1.ConditionType("Succeeded"), Status: corev1.ConditionStatus("True"), @@ -548,13 +548,13 @@ var _ = Describe("BuildWorkloadReconciler", func() { lookupKey := types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID} updatedWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, lookupKey, updatedWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, lookupKey, updatedWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) }).Should(Succeed()) lookupKey.Name = cfBuildGUID2 Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, lookupKey, updatedWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, lookupKey, updatedWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionTrue)) }).Should(Succeed()) }) @@ -570,7 +570,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { lookupKey := types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID} updatedWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func(g Gomega) { - err := k8sClient.Get(ctx, lookupKey, updatedWorkload) + err := adminClient.Get(ctx, lookupKey, updatedWorkload) g.Expect(err).NotTo(HaveOccurred()) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Reason).To(Equal("BuildFailed")) @@ -593,7 +593,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { lookupKey := types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID} updatedWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func(g Gomega) { - err := k8sClient.Get(ctx, lookupKey, updatedWorkload) + err := adminClient.Get(ctx, lookupKey, updatedWorkload) g.Expect(err).NotTo(HaveOccurred()) g.Expect(mustHaveCondition(g, updatedWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionTrue)) }).Should(Succeed()) @@ -603,7 +603,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { lookupKey := types.NamespacedName{Name: buildWorkloadGUID, Namespace: namespaceGUID} updatedBuildWorkload := new(korifiv1alpha1.BuildWorkload) Eventually(func(g Gomega) *korifiv1alpha1.BuildDropletStatus { - err := k8sClient.Get(ctx, lookupKey, updatedBuildWorkload) + err := adminClient.Get(ctx, lookupKey, updatedBuildWorkload) g.Expect(err).NotTo(HaveOccurred()) return updatedBuildWorkload.Status.Droplet }).ShouldNot(BeNil()) @@ -639,19 +639,19 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, }, } - Expect(k8sClient.Create(ctx, latestBuild)).To(Succeed()) + Expect(adminClient.Create(ctx, latestBuild)).To(Succeed()) }) It("does not set the droplet while the latest build is running", func() { helpers.EventuallyShouldHold(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(buildWorkload.Status.Droplet).To(BeNil()) }) }) When("the latest build succeeds", func() { BeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, latestBuild, func() { + Expect(k8s.Patch(ctx, adminClient, latestBuild, func() { latestBuild.Status.Conditions = append(latestBuild.Status.Conditions, corev1alpha1.Condition{ Type: corev1alpha1.ConditionType("Succeeded"), Status: corev1.ConditionStatus(corev1.ConditionTrue), @@ -664,7 +664,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("sets the latest build image to the build workload status", func() { helpers.EventuallyShouldHold(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionTrue)) g.Expect(buildWorkload.Status.Droplet).NotTo(BeNil()) g.Expect(buildWorkload.Status.Droplet.Registry.Image).To(Equal("latest-image")) @@ -673,7 +673,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { }) When("the latest build fails", func() { BeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, latestBuild, func() { + Expect(k8s.Patch(ctx, adminClient, latestBuild, func() { latestBuild.Status.Conditions = append(latestBuild.Status.Conditions, corev1alpha1.Condition{ Type: corev1alpha1.ConditionType("Succeeded"), Status: corev1.ConditionStatus(corev1.ConditionFalse), @@ -684,7 +684,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("fails the build workload", func() { helpers.EventuallyShouldHold(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) g.Expect(buildWorkload.Status.Droplet).To(BeNil()) }) @@ -696,10 +696,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { Describe("awaiting kpack builder readiness", func() { BeforeEach(func() { - buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) - - Expect(k8s.Patch(ctx, k8sClient, clusterBuilder, func() { + Expect(k8s.Patch(ctx, adminClient, clusterBuilder, func() { clusterBuilder.Status.Conditions = corev1alpha1.Conditions{ { Type: corev1alpha1.ConditionType("Ready"), @@ -708,11 +705,14 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, } })).To(Succeed()) + + buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) }) It("sets the Succeeded condition to False", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Reason).To(Equal("BuilderNotReady")) }).Should(Succeed()) @@ -721,7 +721,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("the kpack builder becomes ready", func() { BeforeEach(func() { Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(meta.FindStatusCondition(buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType)).To( SatisfyAny( BeNil(), @@ -733,7 +733,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { ) }, "2s").Should(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, clusterBuilder, func() { + Expect(k8s.Patch(ctx, adminClient, clusterBuilder, func() { clusterBuilder.Status.Conditions = corev1alpha1.Conditions{ { Type: corev1alpha1.ConditionType("Ready"), @@ -746,11 +746,11 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("never sets Succeeded condition to False (as it is tolerant towards builder being unavailable for a while)", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).ToNot(Equal(metav1.ConditionFalse)) }).Should(Succeed()) Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).ToNot(Equal(metav1.ConditionFalse)) }).Should(Succeed()) }) @@ -758,13 +758,13 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("the kpack builder is not found", func() { BeforeEach(func() { - Expect(k8sClient.Delete(ctx, clusterBuilder)).To(Succeed()) + Expect(adminClient.Delete(ctx, clusterBuilder)).To(Succeed()) clusterBuilder = nil }) It("sets the Succeeded condition to False", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Status).To(Equal(metav1.ConditionFalse)) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Reason).To(Equal("BuilderNotReady")) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, "Succeeded").Message).To(Equal("ClusterBuilder not found")) @@ -778,24 +778,24 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(buildWorkload.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) source2 := source source2.Registry.Image += "2" buildWorkload2 = buildWorkloadObject(testutils.GenerateGUID(), namespaceGUID, source2, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload2)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload2)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload2), buildWorkload2)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload2), buildWorkload2)).To(Succeed()) g.Expect(buildWorkload2.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, &buildv1alpha2.Build{ + Expect(adminClient.Create(ctx, &buildv1alpha2.Build{ ObjectMeta: metav1.ObjectMeta{ Name: "build", Namespace: namespaceGUID, @@ -810,7 +810,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("fails the first build workload", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionFalse)) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType).Reason).To(Equal("KpackMissedBuild")) }).Should(Succeed()) @@ -818,7 +818,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("previous build workload builds are still running", func() { BeforeEach(func() { - Expect(k8sClient.Create(ctx, &buildv1alpha2.Build{ + Expect(adminClient.Create(ctx, &buildv1alpha2.Build{ ObjectMeta: metav1.ObjectMeta{ Name: testutils.GenerateGUID(), Namespace: namespaceGUID, @@ -832,7 +832,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { It("does not fail it", func() { Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) }) @@ -840,7 +840,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { When("the first build workload has already completed", func() { BeforeEach(func() { - Expect(k8s.Patch(ctx, k8sClient, buildWorkload, func() { + Expect(k8s.Patch(ctx, adminClient, buildWorkload, func() { meta.SetStatusCondition(&buildWorkload.Status.Conditions, metav1.Condition{ Type: korifiv1alpha1.SucceededConditionType, Status: metav1.ConditionTrue, @@ -849,14 +849,14 @@ var _ = Describe("BuildWorkloadReconciler", func() { })).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionTrue)) }).Should(Succeed()) }) It("does not fail the first build workload", func() { Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionTrue)) }).Should(Succeed()) }) @@ -869,9 +869,9 @@ var _ = Describe("BuildWorkloadReconciler", func() { source3 := source source3.Registry.Image += "3" buildWorkload3 = buildWorkloadObject(testutils.GenerateGUID(), namespaceGUID, source3, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload3)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload3)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload3), buildWorkload3)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload3), buildWorkload3)).To(Succeed()) g.Expect(buildWorkload3.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) }) @@ -881,7 +881,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { g.Expect(mustHaveCondition(g, buildWorkload3.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) Consistently(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload3), buildWorkload3)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload3), buildWorkload3)).To(Succeed()) g.Expect(mustHaveCondition(g, buildWorkload3.Status.Conditions, korifiv1alpha1.SucceededConditionType).Status).To(Equal(metav1.ConditionUnknown)) }).Should(Succeed()) }) @@ -895,18 +895,18 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { readyStatus = "True" buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), buildWorkload)).To(Succeed()) g.Expect(buildWorkload.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) source2 := source source2.Registry.Image += "x" buildWorkload2 = buildWorkloadObject(buildWorkloadGUID+"x", namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload2)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload2)).To(Succeed()) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload2), buildWorkload2)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload2), buildWorkload2)).To(Succeed()) g.Expect(buildWorkload2.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) }) @@ -918,9 +918,9 @@ var _ = Describe("BuildWorkloadReconciler", func() { Name: "app-guid", }, } - Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(image), image)).To(Succeed()) + Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(image), image)).To(Succeed()) - Expect(k8sClient.Create(ctx, &buildv1alpha2.Build{ + Expect(adminClient.Create(ctx, &buildv1alpha2.Build{ ObjectMeta: metav1.ObjectMeta{ Name: "first-build", Namespace: namespaceGUID, @@ -932,7 +932,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, })).To(Succeed()) - Expect(k8s.Patch(ctx, k8sClient, image, func() { + Expect(k8s.Patch(ctx, adminClient, image, func() { gen, err := strconv.ParseInt(buildWorkload2.Labels[controllers.ImageGenerationKey], 10, 64) Expect(err).NotTo(HaveOccurred()) image.Status.ObservedGeneration = gen @@ -952,7 +952,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { Name: "first-build", }, } - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(latestBuild), latestBuild)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(latestBuild), latestBuild)).To(Succeed()) g.Expect(latestBuild.Annotations).To(HaveKey(buildv1alpha2.BuildNeededAnnotation)) }).Should(Succeed()) }) @@ -970,7 +970,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { Name: "first-build", }, } - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(latestBuild), latestBuild)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(latestBuild), latestBuild)).To(Succeed()) g.Expect(latestBuild.Annotations).NotTo(HaveKey(buildv1alpha2.BuildNeededAnnotation)) }).Should(Succeed()) }) @@ -982,7 +982,7 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { buildWorkload = buildWorkloadObject(buildWorkloadGUID, namespaceGUID, source, env, services, reconcilerName, buildpacks) - Expect(k8sClient.Create(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, buildWorkload)).To(Succeed()) kpackBuild = &buildv1alpha2.Build{ ObjectMeta: metav1.ObjectMeta{ @@ -998,24 +998,24 @@ var _ = Describe("BuildWorkloadReconciler", func() { }, } - Expect(k8sClient.Create(ctx, kpackBuild)).To(Succeed()) + Expect(adminClient.Create(ctx, kpackBuild)).To(Succeed()) }) JustBeforeEach(func() { Eventually(func(g Gomega) { foundBuildWorkload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(Succeed()) g.Expect(foundBuildWorkload.Labels).To(HaveKey(controllers.ImageGenerationKey)) }).Should(Succeed()) - Expect(k8sClient.Delete(ctx, buildWorkload)).To(Succeed()) + Expect(adminClient.Delete(ctx, buildWorkload)).To(Succeed()) }) It("deletes the corresponding kpack.Build", func() { Eventually(func(g Gomega) { foundBuildWorkload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(MatchError(ContainSubstring("not found"))) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(MatchError(ContainSubstring("not found"))) foundKpackBuild := new(buildv1alpha2.Build) - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(kpackBuild), foundKpackBuild)).To(MatchError(ContainSubstring("not found"))) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(kpackBuild), foundKpackBuild)).To(MatchError(ContainSubstring("not found"))) }).Should(Succeed()) }) @@ -1023,18 +1023,18 @@ var _ = Describe("BuildWorkloadReconciler", func() { BeforeEach(func() { otherBuildWorkload := buildWorkloadObject(testutils.GenerateGUID(), namespaceGUID, source, env, services, reconcilerName, buildpacks) otherBuildWorkload.Labels[controllers.ImageGenerationKey] = "1" - Expect(k8sClient.Create(ctx, otherBuildWorkload)).To(Succeed()) + Expect(adminClient.Create(ctx, otherBuildWorkload)).To(Succeed()) }) It("doesn't delete the kpack.Build", func() { Eventually(func(g Gomega) { foundBuildWorkload := new(korifiv1alpha1.BuildWorkload) - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(MatchError(ContainSubstring("not found"))) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(buildWorkload), foundBuildWorkload)).To(MatchError(ContainSubstring("not found"))) }).Should(Succeed()) Consistently(func(g Gomega) { foundKpackBuild := new(buildv1alpha2.Build) - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(kpackBuild), foundKpackBuild)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(kpackBuild), foundKpackBuild)).To(Succeed()) }).Should(Succeed()) }) }) diff --git a/kpack-image-builder/controllers/kpack_build_controller_test.go b/kpack-image-builder/controllers/kpack_build_controller_test.go index 371de41df..53a4e636e 100644 --- a/kpack-image-builder/controllers/kpack_build_controller_test.go +++ b/kpack-image-builder/controllers/kpack_build_controller_test.go @@ -22,7 +22,7 @@ var _ = Describe("KpackBuildReconciler", func() { BeforeEach(func() { namespaceGUID = PrefixedGUID("namespace") - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespaceGUID, }, @@ -49,23 +49,23 @@ var _ = Describe("KpackBuildReconciler", func() { }, }, } - Expect(k8sClient.Create(ctx, &build)).To(Succeed()) + Expect(adminClient.Create(ctx, &build)).To(Succeed()) }) JustBeforeEach(func() { if setImage { buildOrig := build.DeepCopy() build.Status.LatestImage = "foo.reg/latest-image@sha256:abcdef123" - Expect(k8sClient.Status().Patch(ctx, &build, client.MergeFrom(buildOrig))).To(Succeed()) + Expect(adminClient.Status().Patch(ctx, &build, client.MergeFrom(buildOrig))).To(Succeed()) } Eventually(func(g Gomega) { gotBuild := kpackv1alpha2.Build{} - g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(&build), &gotBuild)).To(Succeed()) + g.Expect(adminClient.Get(ctx, client.ObjectKeyFromObject(&build), &gotBuild)).To(Succeed()) g.Expect(gotBuild.Finalizers).NotTo(BeEmpty()) }).Should(Succeed()) - Expect(k8sClient.Delete(ctx, &build)).To(Succeed()) + Expect(adminClient.Delete(ctx, &build)).To(Succeed()) }) It("works", func() { @@ -77,7 +77,7 @@ var _ = Describe("KpackBuildReconciler", func() { g.Expect(imageRef).To(Equal(build.Status.LatestImage)) g.Expect(tagsToDelete).To(ConsistOf("bob")) - err := k8sClient.Get(ctx, client.ObjectKeyFromObject(&build), &build) + err := adminClient.Get(ctx, client.ObjectKeyFromObject(&build), &build) g.Expect(k8serrors.IsNotFound(err)).To(BeTrue()) }).Should(Succeed()) }) @@ -101,7 +101,7 @@ var _ = Describe("KpackBuildReconciler", func() { It("still deletes the build", func() { Eventually(func(g Gomega) { - err := k8sClient.Get(ctx, client.ObjectKeyFromObject(&build), &build) + err := adminClient.Get(ctx, client.ObjectKeyFromObject(&build), &build) g.Expect(k8serrors.IsNotFound(err)).To(BeTrue()) }).Should(Succeed()) }) diff --git a/kpack-image-builder/controllers/suite_test.go b/kpack-image-builder/controllers/suite_test.go index 612a9e2b1..0601dc5e1 100644 --- a/kpack-image-builder/controllers/suite_test.go +++ b/kpack-image-builder/controllers/suite_test.go @@ -27,17 +27,17 @@ import ( "code.cloudfoundry.org/korifi/kpack-image-builder/controllers" "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/fake" "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/webhooks/finalizer" + "code.cloudfoundry.org/korifi/tests/helpers" "code.cloudfoundry.org/korifi/tools" "code.cloudfoundry.org/korifi/tools/k8s" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" buildv1alpha2 "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" @@ -55,9 +55,9 @@ const ( var ( ctx context.Context - cancel context.CancelFunc - cfg *rest.Config - k8sClient client.Client + stopManager context.CancelFunc + stopClientCache context.CancelFunc + adminClient client.Client testEnv *envtest.Environment fakeImageConfigGetter *fake.ImageConfigGetter fakeImageDeleter *fake.ImageDeleter @@ -79,10 +79,8 @@ func TestAPIs(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + ctx = context.Background() - ctx, cancel = context.WithCancel(context.Background()) - - By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "helm", "korifi", "controllers", "crds"), @@ -96,29 +94,14 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - var err error - cfg, err = testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - err = korifiv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(buildv1alpha2.AddToScheme(scheme.Scheme)).To(Succeed()) - err = buildv1alpha2.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) - - k8sClient = k8sManager.GetClient() + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "kpack-image-builder", "role.yaml")) + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) finalizer.NewKpackImageBuilderFinalizerWebhook().SetupWebhookWithManager(k8sManager) @@ -169,23 +152,17 @@ var _ = BeforeSuite(func() { err = kpackBuildReconciler.SetupWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - //+kubebuilder:scaffold:scheme + stopManager = helpers.StartK8sManager(k8sManager) rootNamespace = &v1.Namespace{ ObjectMeta: ctrl.ObjectMeta{ Name: controllerConfig.CFRootNamespace, }, } - Expect(k8sClient.Create(ctx, rootNamespace)).To(Succeed()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() + Expect(adminClient.Create(ctx, rootNamespace)).To(Succeed()) // create a test storage class that can't be resized - Expect(k8sClient.Create(ctx, &storagev1.StorageClass{ + Expect(adminClient.Create(ctx, &storagev1.StorageClass{ ObjectMeta: metav1.ObjectMeta{ Name: "non-resizable-class", }, @@ -195,7 +172,7 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/kpack-image-builder/controllers/webhooks/finalizer/finalizer_webhook_test.go b/kpack-image-builder/controllers/webhooks/finalizer/finalizer_webhook_test.go index a10d8be63..39fc2dac7 100644 --- a/kpack-image-builder/controllers/webhooks/finalizer/finalizer_webhook_test.go +++ b/kpack-image-builder/controllers/webhooks/finalizer/finalizer_webhook_test.go @@ -16,7 +16,7 @@ import ( var _ = Describe("KpackImageBuilder Finalizers Webhook", func() { DescribeTable("Adding finalizers", func(obj client.Object, expectedFinalizers []string) { - Expect(k8sClient.Create(context.Background(), obj)).To(Succeed()) + Expect(adminClient.Create(context.Background(), obj)).To(Succeed()) Expect(obj.GetFinalizers()).To(Equal(expectedFinalizers)) }, Entry("kpack-image-builder-buildworkload", diff --git a/kpack-image-builder/controllers/webhooks/finalizer/suite_integration_test.go b/kpack-image-builder/controllers/webhooks/finalizer/suite_integration_test.go index a56b770ed..5008abce6 100644 --- a/kpack-image-builder/controllers/webhooks/finalizer/suite_integration_test.go +++ b/kpack-image-builder/controllers/webhooks/finalizer/suite_integration_test.go @@ -2,9 +2,6 @@ package finalizer_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" "time" @@ -12,6 +9,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" "code.cloudfoundry.org/korifi/controllers/webhooks/version" "code.cloudfoundry.org/korifi/kpack-image-builder/controllers/webhooks/finalizer" + "code.cloudfoundry.org/korifi/tests/helpers" buildv1alpha2 "github.com/pivotal/kpack/pkg/apis/build/v1alpha2" . "github.com/onsi/ginkgo/v2" @@ -20,8 +18,7 @@ import ( coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - ctrl "sigs.k8s.io/controller-runtime" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -30,9 +27,10 @@ import ( ) var ( - cancel context.CancelFunc - testEnv *envtest.Environment - k8sClient client.Client + stopManager context.CancelFunc + stopClientCache context.CancelFunc + testEnv *envtest.Environment + adminClient client.Client ) const ( @@ -51,7 +49,7 @@ var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc + stopManager = cancelFunc testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ @@ -67,55 +65,25 @@ var _ = BeforeSuite(func() { }, } - cfg, err := testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - scheme := runtime.NewScheme() - Expect(korifiv1alpha1.AddToScheme(scheme)).To(Succeed()) - Expect(admissionv1beta1.AddToScheme(scheme)).To(Succeed()) - Expect(corev1.AddToScheme(scheme)).To(Succeed()) - Expect(coordinationv1.AddToScheme(scheme)).To(Succeed()) - Expect(buildv1alpha2.AddToScheme(scheme)).To(Succeed()) - - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - k8sClient = mgr.GetClient() - - finalizer.NewKpackImageBuilderFinalizerWebhook().SetupWebhookWithManager(mgr) - version.NewVersionWebhook("some-version").SetupWebhookWithManager(mgr) - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - if err != nil { - Expect(err).NotTo(HaveOccurred()) - } - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) - - // Create root namespace - Expect(k8sClient.Create(ctx, &corev1.Namespace{ + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(admissionv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(coordinationv1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(buildv1alpha2.AddToScheme(scheme.Scheme)).To(Succeed()) + + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "kpack-image-builder", "role.yaml")) + + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) + + finalizer.NewKpackImageBuilderFinalizerWebhook().SetupWebhookWithManager(k8sManager) + version.NewVersionWebhook("some-version").SetupWebhookWithManager(k8sManager) + + stopManager = helpers.StartK8sManager(k8sManager) + + Expect(adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: rootNamespace, }, @@ -123,6 +91,7 @@ var _ = BeforeSuite(func() { }) var _ = AfterSuite(func() { - cancel() // call the cancel function to stop the controller context + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/statefulset-runner/api/v1/pod_webhook_test.go b/statefulset-runner/api/v1/pod_webhook_test.go index 05eecc0ba..9bc41ddc6 100644 --- a/statefulset-runner/api/v1/pod_webhook_test.go +++ b/statefulset-runner/api/v1/pod_webhook_test.go @@ -18,7 +18,7 @@ var _ = Describe("StatefulSet Runner Pod Mutating Webhook", func() { BeforeEach(func() { namespace = testutils.PrefixedGUID("ns") - err := k8sClient.Create(ctx, &corev1.Namespace{ + err := adminClient.Create(ctx, &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ Name: namespace, }, @@ -46,10 +46,10 @@ var _ = Describe("StatefulSet Runner Pod Mutating Webhook", func() { }) JustBeforeEach(func() { - Expect(k8sClient.Create(ctx, stsPod)).To(Succeed()) + Expect(adminClient.Create(ctx, stsPod)).To(Succeed()) lookupKey := client.ObjectKeyFromObject(stsPod) Eventually(func(g Gomega) { - g.Expect(k8sClient.Get(ctx, lookupKey, stsPod)).To(Succeed()) + g.Expect(adminClient.Get(ctx, lookupKey, stsPod)).To(Succeed()) }).Should(Succeed()) }) diff --git a/statefulset-runner/api/v1/webhook_suite_test.go b/statefulset-runner/api/v1/webhook_suite_test.go index 74495551d..3716efac9 100644 --- a/statefulset-runner/api/v1/webhook_suite_test.go +++ b/statefulset-runner/api/v1/webhook_suite_test.go @@ -18,23 +18,18 @@ package v1_test import ( "context" - "crypto/tls" - "fmt" - "net" "path/filepath" "testing" - "time" "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" v1 "code.cloudfoundry.org/korifi/statefulset-runner/api/v1" + "code.cloudfoundry.org/korifi/tests/helpers" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" admissionv1beta1 "k8s.io/api/admission/v1beta1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/rest" - ctrl "sigs.k8s.io/controller-runtime" + "k8s.io/client-go/kubernetes/scheme" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -42,11 +37,11 @@ import ( ) var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - ctx context.Context - cancel context.CancelFunc + adminClient client.Client + testEnv *envtest.Environment + ctx context.Context + stopManager context.CancelFunc + stopClientCache context.CancelFunc ) func TestAPIs(t *testing.T) { @@ -58,7 +53,7 @@ func TestAPIs(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancel = context.WithCancel(context.TODO()) + ctx = context.Background() By("bootstrapping test environment") testEnv = &envtest.Environment{ @@ -68,67 +63,24 @@ var _ = BeforeSuite(func() { }, } - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - scheme := runtime.NewScheme() + Expect(v1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(admissionv1beta1.AddToScheme(scheme.Scheme)).To(Succeed()) + Expect(corev1.AddToScheme(scheme.Scheme)).To(Succeed()) - err = v1alpha1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = admissionv1beta1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - - err = corev1.AddToScheme(scheme) - Expect(err).NotTo(HaveOccurred()) + mgr := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "statefulset-runner", "role.yaml")) - //+kubebuilder:scaffold:scheme + adminClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - // start webhook server using Manager - webhookInstallOptions := &testEnv.WebhookInstallOptions - mgr, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) - - err = (&v1.STSPodDefaulter{}).SetupWebhookWithManager(mgr) - Expect(err).NotTo(HaveOccurred()) + Expect((&v1.STSPodDefaulter{}).SetupWebhookWithManager(mgr)).To(Succeed()) - //+kubebuilder:scaffold:webhook - - go func() { - defer GinkgoRecover() - err = mgr.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() - - // wait for the webhook server to get ready - dialer := &net.Dialer{Timeout: time.Second} - addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort) - Eventually(func() error { - conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true}) - if err != nil { - return err - } - conn.Close() - return nil - }).Should(Succeed()) + stopManager = helpers.StartK8sManager(mgr) }) var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/statefulset-runner/controllers/integration/suite_test.go b/statefulset-runner/controllers/integration/suite_test.go index 1a1387627..3fbe390e9 100644 --- a/statefulset-runner/controllers/integration/suite_test.go +++ b/statefulset-runner/controllers/integration/suite_test.go @@ -24,6 +24,7 @@ import ( korifiv1alpha1 "code.cloudfoundry.org/korifi/controllers/api/v1alpha1" . "code.cloudfoundry.org/korifi/statefulset-runner/controllers" + "code.cloudfoundry.org/korifi/tests/helpers" "github.com/google/uuid" . "github.com/onsi/ginkgo/v2" @@ -36,16 +37,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - //+kubebuilder:scaffold:imports ) -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - var ( - cancel context.CancelFunc - k8sClient client.Client - testEnv *envtest.Environment + stopManager context.CancelFunc + stopClientCache context.CancelFunc + k8sClient client.Client + testEnv *envtest.Environment ) func TestAppWorkloadsController(t *testing.T) { @@ -60,10 +58,6 @@ func TestAppWorkloadsController(t *testing.T) { var _ = BeforeSuite(func() { logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - ctx, cancelFunc := context.WithCancel(context.TODO()) - cancel = cancelFunc - - By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{ filepath.Join("..", "..", "..", "helm", "korifi", "controllers", "crds"), @@ -71,25 +65,13 @@ var _ = BeforeSuite(func() { ErrorIfCRDPathMissing: true, } - cfg, err := testEnv.Start() + _, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - err = korifiv1alpha1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) + Expect(korifiv1alpha1.AddToScheme(scheme.Scheme)).To(Succeed()) - //+kubebuilder:scaffold:scheme - - webhookInstallOptions := &testEnv.WebhookInstallOptions - k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{ - Scheme: scheme.Scheme, - Host: webhookInstallOptions.LocalServingHost, - Port: webhookInstallOptions.LocalServingPort, - CertDir: webhookInstallOptions.LocalServingCertDir, - LeaderElection: false, - MetricsBindAddress: "0", - }) - Expect(err).NotTo(HaveOccurred()) + k8sManager := helpers.NewK8sManager(testEnv, filepath.Join("helm", "korifi", "statefulset-runner", "role.yaml")) + k8sClient, stopClientCache = helpers.NewCachedClient(testEnv.Config) logger := ctrl.Log.WithName("statefulset-runner").WithName("AppWorkload") appWorkloadReconciler := NewAppWorkloadReconciler( @@ -110,20 +92,12 @@ var _ = BeforeSuite(func() { err = (runnerInfoReconciler).SetupWithManager(k8sManager) Expect(err).NotTo(HaveOccurred()) - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - - go func() { - defer GinkgoRecover() - err = k8sManager.Start(ctx) - Expect(err).NotTo(HaveOccurred()) - }() + stopManager = helpers.StartK8sManager(k8sManager) }) var _ = AfterSuite(func() { - cancel() - By("tearing down the test environment") + stopClientCache() + stopManager() Expect(testEnv.Stop()).To(Succeed()) }) diff --git a/tests/helpers/controllers_user.go b/tests/helpers/controllers_user.go deleted file mode 100644 index 0644594c5..000000000 --- a/tests/helpers/controllers_user.go +++ /dev/null @@ -1,73 +0,0 @@ -package helpers - -import ( - "context" - "os" - "path/filepath" - "runtime" - - . "github.com/onsi/gomega" //lint:ignore ST1001 this is a test file - - . "github.com/onsi/ginkgo/v2" //lint:ignore ST1001 this is a test file - rbacv1 "k8s.io/api/rbac/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" -) - -func SetupControllersUser(testEnv *envtest.Environment) *rest.Config { - controllersUser, err := testEnv.ControlPlane.AddUser(envtest.User{Name: "envtest-controller"}, testEnv.Config) - Expect(err).NotTo(HaveOccurred()) - - adminClient, err := client.New(testEnv.Config, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - - bindUserToControllersRole(adminClient, "envtest-controller") - - return controllersUser.Config() -} - -func bindUserToControllersRole(k8sClient client.Client, userName string) { - GinkgoHelper() - - controllersRole := ensureControllersClusterRole(k8sClient) - - Expect(k8sClient.Create(context.Background(), &rbacv1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: "envtest-controller", - }, - Subjects: []rbacv1.Subject{{ - Kind: "User", - Name: userName, - }}, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: controllersRole.Name, - }, - })).To(Succeed()) -} - -func ensureControllersClusterRole(k8sClient client.Client) *rbacv1.ClusterRole { - clusterRoleDefinition, err := os.ReadFile(controllersRoleYamlPath()) - Expect(err).NotTo(HaveOccurred()) - - roleObject, _, err := scheme.Codecs.UniversalDeserializer().Decode(clusterRoleDefinition, nil, new(rbacv1.ClusterRole)) - Expect(err).NotTo(HaveOccurred()) - - clusterRole, ok := roleObject.(*rbacv1.ClusterRole) - Expect(ok).To(BeTrue()) - - Expect(client.IgnoreAlreadyExists(k8sClient.Create(context.Background(), clusterRole))).To(Succeed()) - - return clusterRole -} - -func controllersRoleYamlPath() string { - _, thisFilePath, _, ok := runtime.Caller(0) - Expect(ok).To(BeTrue()) - thisFileDir := filepath.Dir(thisFilePath) - - return filepath.Join(thisFileDir, "..", "..", "helm", "korifi", "controllers", "role.yaml") -} diff --git a/tests/helpers/cache_syncing_client.go b/tests/helpers/sync_client.go similarity index 73% rename from tests/helpers/cache_syncing_client.go rename to tests/helpers/sync_client.go index c496b65e5..cccd00611 100644 --- a/tests/helpers/cache_syncing_client.go +++ b/tests/helpers/sync_client.go @@ -9,17 +9,17 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -type CacheSyncingClient struct { +type SyncClient struct { client.Client } -func NewCacheSyncingClient(client client.Client) *CacheSyncingClient { - return &CacheSyncingClient{ - Client: client, +func NewSyncClient(k8sClient client.Client) *SyncClient { + return &SyncClient{ + Client: k8sClient, } } -func (c *CacheSyncingClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { +func (c *SyncClient) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error { GinkgoHelper() if err := c.Client.Create(ctx, obj, opts...); err != nil { @@ -32,7 +32,7 @@ func (c *CacheSyncingClient) Create(ctx context.Context, obj client.Object, opts return nil } -func (c *CacheSyncingClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, _ ...client.PatchOption) error { +func (c *SyncClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, _ ...client.PatchOption) error { GinkgoHelper() err := c.Client.Patch(ctx, obj, patch) @@ -50,7 +50,7 @@ func (c *CacheSyncingClient) Patch(ctx context.Context, obj client.Object, patch return nil } -func (c *CacheSyncingClient) Status() client.SubResourceWriter { +func (c *SyncClient) Status() client.SubResourceWriter { GinkgoHelper() return &syncStatusWriter{ @@ -75,14 +75,13 @@ func (w *syncStatusWriter) Patch(ctx context.Context, obj client.Object, patch c dryRunClient := client.NewDryRunClient(w.client) Eventually(func(g Gomega) { g.Expect(w.client.Get(ctx, client.ObjectKeyFromObject(obj), obj)).To(Succeed()) + currentStatus, err := getStatus(obj) g.Expect(err).NotTo(HaveOccurred()) - objCopy, ok := obj.DeepCopyObject().(client.Object) - g.Expect(ok).To(BeTrue()) - - g.Expect(dryRunClient.Status().Patch(ctx, objCopy, patch, opts...)).To(Succeed()) - patchedStatus, err := getStatus(objCopy) + err = dryRunClient.Status().Patch(ctx, obj, patch, opts...) + g.Expect(err).NotTo(HaveOccurred()) + patchedStatus, err := getStatus(obj) g.Expect(err).NotTo(HaveOccurred()) g.Expect(patchedStatus).To(Equal(currentStatus)) @@ -94,7 +93,7 @@ func (w *syncStatusWriter) Patch(ctx context.Context, obj client.Object, patch c func getStatus(obj runtime.Object) (any, error) { GinkgoHelper() - unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) + unstructuredObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj.DeepCopyObject()) if err != nil { return nil, err } diff --git a/tests/helpers/test_env.go b/tests/helpers/test_env.go new file mode 100644 index 000000000..7709f703c --- /dev/null +++ b/tests/helpers/test_env.go @@ -0,0 +1,126 @@ +package helpers + +import ( + "context" + "os" + "path/filepath" + "runtime" + + "github.com/google/uuid" + . "github.com/onsi/ginkgo/v2" //lint:ignore ST1001 this is a test file + . "github.com/onsi/gomega" //lint:ignore ST1001 this is a test file + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/cache" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + "sigs.k8s.io/controller-runtime/pkg/manager" +) + +func NewCachedClient(cfg *rest.Config) (client.Client, context.CancelFunc) { + ctx, cancel := context.WithCancel(context.Background()) + + clientCache, err := cache.New(cfg, cache.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + + go func() { + defer GinkgoRecover() + Expect(clientCache.Start(ctx)).To(Succeed()) + }() + clientCache.WaitForCacheSync(ctx) + + k8sClient, err := client.New(cfg, client.Options{ + Scheme: scheme.Scheme, + Cache: &client.CacheOptions{Reader: clientCache}, + }) + Expect(err).NotTo(HaveOccurred()) + + return NewSyncClient(k8sClient), cancel +} + +func NewK8sManager(testEnv *envtest.Environment, managerRolePath string) manager.Manager { + k8sManager, err := ctrl.NewManager(SetupTestEnvUser(testEnv, managerRolePath), ctrl.Options{ + Scheme: scheme.Scheme, + Host: testEnv.WebhookInstallOptions.LocalServingHost, + Port: testEnv.WebhookInstallOptions.LocalServingPort, + CertDir: testEnv.WebhookInstallOptions.LocalServingCertDir, + LeaderElection: false, + MetricsBindAddress: "0", + }) + Expect(err).NotTo(HaveOccurred()) + + return k8sManager +} + +func StartK8sManager(k8sManager manager.Manager) context.CancelFunc { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + defer GinkgoRecover() + Expect(k8sManager.Start(ctx)).To(Succeed()) + }() + + Eventually(func(g Gomega) { + g.Expect(k8sManager.GetWebhookServer().StartedChecker()(nil)).To(Succeed()) + }).Should(Succeed()) + + return cancel +} + +func SetupTestEnvUser(testEnv *envtest.Environment, roleDefinitionPath string) *rest.Config { + userName := uuid.NewString() + controllersUser, err := testEnv.ControlPlane.AddUser(envtest.User{Name: userName}, testEnv.Config) + Expect(err).NotTo(HaveOccurred()) + + adminClient, err := client.New(testEnv.Config, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + + controllersRole := ensureClusterRole(adminClient, roleDefinitionPath) + bindUserToClusterRole(adminClient, userName, controllersRole.Name) + + return controllersUser.Config() +} + +func bindUserToClusterRole(k8sClient client.Client, userName, roleName string) { + GinkgoHelper() + + Expect(k8sClient.Create(context.Background(), &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: userName, + }, + Subjects: []rbacv1.Subject{{ + Kind: "User", + Name: userName, + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: roleName, + }, + })).To(Succeed()) +} + +func ensureClusterRole(k8sClient client.Client, roleDefinitionPath string) *rbacv1.ClusterRole { + clusterRoleDefinition, err := os.ReadFile(toAbsPath(roleDefinitionPath)) + Expect(err).NotTo(HaveOccurred()) + + roleObject, _, err := scheme.Codecs.UniversalDeserializer().Decode(clusterRoleDefinition, nil, new(rbacv1.ClusterRole)) + Expect(err).NotTo(HaveOccurred()) + + clusterRole, ok := roleObject.(*rbacv1.ClusterRole) + Expect(ok).To(BeTrue()) + + Expect(client.IgnoreAlreadyExists(k8sClient.Create(context.Background(), clusterRole))).To(Succeed()) + + return clusterRole +} + +func toAbsPath(roleDefinitionPath string) string { + _, thisFilePath, _, ok := runtime.Caller(0) + Expect(ok).To(BeTrue()) + thisFileDir := filepath.Dir(thisFilePath) + + return filepath.Join(thisFileDir, "..", "..", roleDefinitionPath) +}