From 484e5b7ea278e7826926cbd59e53cccf8461c4e6 Mon Sep 17 00:00:00 2001 From: Sreyas Natarajan Date: Thu, 10 Aug 2023 15:56:57 -0700 Subject: [PATCH] Enable v1a2 controller and webhook integration tests - This change enables controller and webhook integration tests for v1alpha2. - The testsuite works with the v1A2 FSS to create the right CRD storage versions prior to the integration tests. This way, the right v1a1 and v1a2 CRDs are installed with the right storage versions when v1a1/v1a2 controller/webhook integration tests are run. --- ...ontentlibraryitem_controller_suite_test.go | 8 +- ...contentlibraryitem_controller_intg_test.go | 2 +- ...ontentlibraryitem_controller_suite_test.go | 8 +- .../virtualmachine_controller_suite_test.go | 8 +- ...rtualmachineclass_controller_suite_test.go | 8 +- ...inepublishrequest_controller_suite_test.go | 8 +- ...ualmachineservice_controller_suite_test.go | 9 +- ...setresourcepolicy_controller_suite_test.go | 9 +- .../v1alpha2/volume_controller_suite_test.go | 9 +- pkg/manager/manager.go | 6 + test/builder/test_suite.go | 86 +++++++++--- test/builder/util.go | 131 +++++++++++++++++- .../virtualmachine_mutator_suite_test.go | 9 +- .../virtualmachine_validator_suite_test.go | 9 +- .../virtualmachineclass_mutator_suite_test.go | 9 +- ...irtualmachineclass_validator_suite_test.go | 9 +- ...hinepublishrequest_validator_suite_test.go | 9 +- ...irtualmachineservice_mutator_suite_test.go | 7 +- ...tualmachineservice_validator_suite_test.go | 9 +- ...esetresourcepolicy_validator_suite_test.go | 9 +- 20 files changed, 278 insertions(+), 84 deletions(-) diff --git a/controllers/contentlibrary/v1alpha2/clustercontentlibraryitem/clustercontentlibraryitem_controller_suite_test.go b/controllers/contentlibrary/v1alpha2/clustercontentlibraryitem/clustercontentlibraryitem_controller_suite_test.go index e97853763..d51552050 100644 --- a/controllers/contentlibrary/v1alpha2/clustercontentlibraryitem/clustercontentlibraryitem_controller_suite_test.go +++ b/controllers/contentlibrary/v1alpha2/clustercontentlibraryitem/clustercontentlibraryitem_controller_suite_test.go @@ -12,23 +12,23 @@ import ( "github.com/vmware-tanzu/vm-operator/controllers/contentlibrary/v1alpha2/clustercontentlibraryitem" ctrlContext "github.com/vmware-tanzu/vm-operator/pkg/context" + "github.com/vmware-tanzu/vm-operator/pkg/lib" providerfake "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/fake" "github.com/vmware-tanzu/vm-operator/test/builder" ) var intgFakeVMProvider = providerfake.NewVMProviderA2() -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( clustercontentlibraryitem.AddToManager, func(ctx *ctrlContext.ControllerManagerContext, _ ctrlmgr.Manager) error { ctx.VMProviderA2 = intgFakeVMProvider return nil }, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestClusterContentLibraryItem(t *testing.T) { - _ = intgTests - suite.Register(t, "ClusterContentLibraryItem controller suite", nil /*intgTests*/, unitTests) + suite.Register(t, "ClusterContentLibraryItem controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_intg_test.go b/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_intg_test.go index 73039fa01..d82b5401a 100644 --- a/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_intg_test.go +++ b/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_intg_test.go @@ -90,7 +90,7 @@ func clItemReconcile() { imageName, err := utils.GetImageFieldNameFromItem(clItemKey.Name) Expect(err).ToNot(HaveOccurred()) - vmiKey := client.ObjectKey{Name: imageName} + vmiKey := client.ObjectKey{Name: imageName, Namespace: ctx.Namespace} By("Finalizer should be added to ContentLibraryItem", func() { waitForContentLibraryItemFinalizer(clItemKey) diff --git a/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_suite_test.go b/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_suite_test.go index 1655ae2da..7e2e51e8b 100644 --- a/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_suite_test.go +++ b/controllers/contentlibrary/v1alpha2/contentlibraryitem/contentlibraryitem_controller_suite_test.go @@ -24,12 +24,12 @@ var suite = builder.NewTestSuiteForControllerWithFSS( ctx.VMProviderA2 = intgFakeVMProvider return nil }, - map[string]bool{lib.VMImageRegistryFSS: true}, -) + map[string]bool{ + lib.VMImageRegistryFSS: true, + lib.VMServiceV1Alpha2FSS: true}) func TestContentLibraryItem(t *testing.T) { - _ = intgTests - suite.Register(t, "ContentLibraryItem controller suite", nil /*intgTests*/, unitTests) + suite.Register(t, "ContentLibraryItem controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/virtualmachine/v1alpha2/virtualmachine_controller_suite_test.go b/controllers/virtualmachine/v1alpha2/virtualmachine_controller_suite_test.go index f410d1927..3c9c44dbf 100644 --- a/controllers/virtualmachine/v1alpha2/virtualmachine_controller_suite_test.go +++ b/controllers/virtualmachine/v1alpha2/virtualmachine_controller_suite_test.go @@ -12,23 +12,23 @@ import ( virtualmachine "github.com/vmware-tanzu/vm-operator/controllers/virtualmachine/v1alpha2" ctrlContext "github.com/vmware-tanzu/vm-operator/pkg/context" + "github.com/vmware-tanzu/vm-operator/pkg/lib" providerfake "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/fake" "github.com/vmware-tanzu/vm-operator/test/builder" ) var intgFakeVMProvider = providerfake.NewVMProviderA2() -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( virtualmachine.AddToManager, func(ctx *ctrlContext.ControllerManagerContext, _ ctrlmgr.Manager) error { ctx.VMProviderA2 = intgFakeVMProvider return nil }, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestVirtualMachine(t *testing.T) { - _ = intgTests - suite.Register(t, "VirtualMachine controller suite", nil /*intgTests*/, unitTests) + suite.Register(t, "VirtualMachine controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/virtualmachineclass/v1alpha2/virtualmachineclass_controller_suite_test.go b/controllers/virtualmachineclass/v1alpha2/virtualmachineclass_controller_suite_test.go index 763fce280..b71649384 100644 --- a/controllers/virtualmachineclass/v1alpha2/virtualmachineclass_controller_suite_test.go +++ b/controllers/virtualmachineclass/v1alpha2/virtualmachineclass_controller_suite_test.go @@ -9,18 +9,18 @@ import ( . "github.com/onsi/ginkgo" virtualmachineclass "github.com/vmware-tanzu/vm-operator/controllers/virtualmachineclass/v1alpha2" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/pkg/manager" "github.com/vmware-tanzu/vm-operator/test/builder" ) -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( virtualmachineclass.AddToManager, manager.InitializeProvidersNoopFn, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestVirtualMachineClass(t *testing.T) { - _ = intgTests - suite.Register(t, "VirtualMachineClass controller suite", nil /*intgTests*/, unitTests) + suite.Register(t, "VirtualMachineClass controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/virtualmachinepublishrequest/v1alpha2/virtualmachinepublishrequest_controller_suite_test.go b/controllers/virtualmachinepublishrequest/v1alpha2/virtualmachinepublishrequest_controller_suite_test.go index 883f5d5f1..ba83dad4c 100644 --- a/controllers/virtualmachinepublishrequest/v1alpha2/virtualmachinepublishrequest_controller_suite_test.go +++ b/controllers/virtualmachinepublishrequest/v1alpha2/virtualmachinepublishrequest_controller_suite_test.go @@ -25,12 +25,12 @@ var suite = builder.NewTestSuiteForControllerWithFSS( ctx.VMProviderA2 = intgFakeVMProvider return nil }, - map[string]bool{lib.VMImageRegistryFSS: true}, -) + map[string]bool{ + lib.VMImageRegistryFSS: true, + lib.VMServiceV1Alpha2FSS: true}) func TestVirtualMachinePublishRequest(t *testing.T) { - _ = intgTests - suite.Register(t, "VirtualMachinePublishRequest controller suite", nil /*intgTests*/, unitTests) + suite.Register(t, "VirtualMachinePublishRequest controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/virtualmachineservice/v1alpha2/virtualmachineservice_controller_suite_test.go b/controllers/virtualmachineservice/v1alpha2/virtualmachineservice_controller_suite_test.go index 56fe0fe85..0a3aae520 100644 --- a/controllers/virtualmachineservice/v1alpha2/virtualmachineservice_controller_suite_test.go +++ b/controllers/virtualmachineservice/v1alpha2/virtualmachineservice_controller_suite_test.go @@ -9,18 +9,19 @@ import ( . "github.com/onsi/ginkgo" virtualmachineservice "github.com/vmware-tanzu/vm-operator/controllers/virtualmachineservice/v1alpha2" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/pkg/manager" "github.com/vmware-tanzu/vm-operator/test/builder" ) -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( virtualmachineservice.AddToManager, manager.InitializeProvidersNoopFn, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestVirtualMachineService(t *testing.T) { - _ = intgTests - suite.Register(t, "VirtualMachineService controller suite", nil /*intgTests*/, unitTests) + + suite.Register(t, "VirtualMachineService controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/virtualmachinesetresourcepolicy/v1alpha2/virtualmachinesetresourcepolicy_controller_suite_test.go b/controllers/virtualmachinesetresourcepolicy/v1alpha2/virtualmachinesetresourcepolicy_controller_suite_test.go index 26abe5824..60099a848 100644 --- a/controllers/virtualmachinesetresourcepolicy/v1alpha2/virtualmachinesetresourcepolicy_controller_suite_test.go +++ b/controllers/virtualmachinesetresourcepolicy/v1alpha2/virtualmachinesetresourcepolicy_controller_suite_test.go @@ -12,23 +12,24 @@ import ( virtualmachinesetresourcepolicy "github.com/vmware-tanzu/vm-operator/controllers/virtualmachinesetresourcepolicy/v1alpha2" ctrlContext "github.com/vmware-tanzu/vm-operator/pkg/context" + "github.com/vmware-tanzu/vm-operator/pkg/lib" providerfake "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/fake" "github.com/vmware-tanzu/vm-operator/test/builder" ) var intgFakeVMProvider = providerfake.NewVMProviderA2() -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( virtualmachinesetresourcepolicy.AddToManager, func(ctx *ctrlContext.ControllerManagerContext, _ ctrlmgr.Manager) error { ctx.VMProviderA2 = intgFakeVMProvider return nil }, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestVirtualMachineSetResourcePolicy(t *testing.T) { - _ = intgTests - suite.Register(t, "VirtualMachineSetResourcePolicy controller suite", nil /*intgTests*/, unitTests) + + suite.Register(t, "VirtualMachineSetResourcePolicy controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/controllers/volume/v1alpha2/volume_controller_suite_test.go b/controllers/volume/v1alpha2/volume_controller_suite_test.go index d7e9b76c0..db79c2135 100644 --- a/controllers/volume/v1alpha2/volume_controller_suite_test.go +++ b/controllers/volume/v1alpha2/volume_controller_suite_test.go @@ -12,23 +12,24 @@ import ( volume "github.com/vmware-tanzu/vm-operator/controllers/volume/v1alpha2" ctrlContext "github.com/vmware-tanzu/vm-operator/pkg/context" + "github.com/vmware-tanzu/vm-operator/pkg/lib" providerfake "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/fake" "github.com/vmware-tanzu/vm-operator/test/builder" ) var intgFakeVMProvider = providerfake.NewVMProviderA2() -var suite = builder.NewTestSuiteForController( +var suite = builder.NewTestSuiteForControllerWithFSS( volume.AddToManager, func(ctx *ctrlContext.ControllerManagerContext, _ ctrlmgr.Manager) error { ctx.VMProviderA2 = intgFakeVMProvider return nil }, -) + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestVolume(t *testing.T) { - _ = intgTests - suite.Register(t, "Volume controller suite", nil /*intgTests*/, unitTests) + + suite.Register(t, "Volume controller suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/pkg/manager/manager.go b/pkg/manager/manager.go index fa661206e..c1d05aca6 100644 --- a/pkg/manager/manager.go +++ b/pkg/manager/manager.go @@ -24,7 +24,9 @@ import ( cnsv1alpha1 "github.com/vmware-tanzu/vm-operator/external/vsphere-csi-driver/pkg/syncer/cnsoperator/apis/cnsnodevmattachment/v1alpha1" vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha1" + vmopv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" "github.com/vmware-tanzu/vm-operator/pkg/context" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/pkg/record" "github.com/vmware-tanzu/vm-operator/pkg/vmprovider/providers/vsphere" ) @@ -49,6 +51,10 @@ func New(opts Options) (Manager, error) { _ = netopv1alpha1.AddToScheme(opts.Scheme) _ = topologyv1.AddToScheme(opts.Scheme) _ = imgregv1a1.AddToScheme(opts.Scheme) + + if lib.IsVMServiceV1Alpha2FSSEnabled() { + _ = vmopv1alpha2.AddToScheme(opts.Scheme) + } // +kubebuilder:scaffold:scheme // controller-runtime Client creates an Informer for each resource that we watch. diff --git a/test/builder/test_suite.go b/test/builder/test_suite.go index 359b08528..89d345f87 100644 --- a/test/builder/test_suite.go +++ b/test/builder/test_suite.go @@ -28,6 +28,7 @@ import ( apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" "k8s.io/klog/v2" "k8s.io/klog/v2/klogr" @@ -37,6 +38,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/yaml" + vmopv1alpha2 "github.com/vmware-tanzu/vm-operator/api/v1alpha2" "github.com/vmware-tanzu/vm-operator/controllers/util/remote" "github.com/vmware-tanzu/vm-operator/pkg/builder" ctrlCtx "github.com/vmware-tanzu/vm-operator/pkg/context" @@ -107,15 +109,6 @@ func (s *TestSuite) GetLogger() logr.Logger { return logf.Log } -func getCrdPaths(crdPaths ...string) []string { - rootDir := testutil.GetRootDirOrDie() - - return append(crdPaths, - filepath.Join(rootDir, "config", "crd", "bases"), - filepath.Join(rootDir, "config", "crd", "external-crds"), - ) -} - // NewTestSuite returns a new test suite used for unit and/or integration test. func NewTestSuite() *TestSuite { return NewTestSuiteForController( @@ -158,7 +151,7 @@ func NewTestSuiteForControllerWithFSS(addToManagerFn pkgmgr.AddToManagerFunc, initProvidersFn: initProvidersFn, fssMap: fssMap, } - testSuite.init(getCrdPaths()) + testSuite.init() return testSuite } @@ -171,7 +164,19 @@ func NewTestSuiteForValidatingWebhook( newValidatorFn builder.ValidatorFunc, webhookName string) *TestSuite { - return newTestSuiteForWebhook(addToManagerFn, newValidatorFn, nil, webhookName) + return newTestSuiteForWebhook(addToManagerFn, newValidatorFn, nil, webhookName, map[string]bool{}) +} + +// NewTestSuiteForValidatingWebhookwithFSS returns a new test suite used for unit and +// integration testing validating webhooks created using the "pkg/builder" +// package with FSS set. +func NewTestSuiteForValidatingWebhookwithFSS( + addToManagerFn pkgmgr.AddToManagerFunc, + newValidatorFn builder.ValidatorFunc, + webhookName string, + fssMap map[string]bool) *TestSuite { + + return newTestSuiteForWebhook(addToManagerFn, newValidatorFn, nil, webhookName, fssMap) } // NewTestSuiteForMutatingWebhook returns a new test suite used for unit and @@ -182,14 +187,27 @@ func NewTestSuiteForMutatingWebhook( newMutatorFn builder.MutatorFunc, webhookName string) *TestSuite { - return newTestSuiteForWebhook(addToManagerFn, nil, newMutatorFn, webhookName) + return newTestSuiteForWebhook(addToManagerFn, nil, newMutatorFn, webhookName, map[string]bool{}) +} + +// NewTestSuiteForMutatingWebhookwithFSS returns a new test suite used for unit and +// integration testing mutating webhooks created using the "pkg/builder" +// package with FSS set. +func NewTestSuiteForMutatingWebhookwithFSS( + addToManagerFn pkgmgr.AddToManagerFunc, + newMutatorFn builder.MutatorFunc, + webhookName string, + fssMap map[string]bool) *TestSuite { + + return newTestSuiteForWebhook(addToManagerFn, nil, newMutatorFn, webhookName, fssMap) } func newTestSuiteForWebhook( addToManagerFn pkgmgr.AddToManagerFunc, newValidatorFn builder.ValidatorFunc, newMutatorFn builder.MutatorFunc, - webhookName string) *TestSuite { + webhookName string, + fssMap map[string]bool) *TestSuite { testSuite := &TestSuite{ Context: context.Background(), @@ -197,6 +215,7 @@ func newTestSuiteForWebhook( addToManagerFn: addToManagerFn, initProvidersFn: pkgmgr.InitializeProvidersNoopFn, webhookName: webhookName, + fssMap: fssMap, } if newValidatorFn != nil { @@ -213,18 +232,28 @@ func newTestSuiteForWebhook( } testSuite.certDir = certDir - testSuite.init(getCrdPaths()) + testSuite.init() return testSuite } -func (s *TestSuite) init(crdPaths []string) { +func (s *TestSuite) init() { // Initialize the test flags. s.flags = flags + rootDir := testutil.GetRootDirOrDie() + + crds, err := LoadCRDs(filepath.Join(rootDir, "config", "crd", "bases")) + if err != nil { + panic(err) + } + if s.flags.IntegrationTestsEnabled { s.envTest = envtest.Environment{ - CRDDirectoryPaths: crdPaths, + CRDs: s.applyFeatureStatesToCRDs(crds), + CRDDirectoryPaths: []string{ + filepath.Join(rootDir, "config", "crd", "external-crds"), + }, BinaryAssetsDirectory: filepath.Join(testutil.GetRootDirOrDie(), "hack", "tools", "bin"), } } @@ -320,12 +349,20 @@ func (s *TestSuite) AfterSuite() { func (s *TestSuite) createManager() { var err error - s.manager, err = pkgmgr.New(pkgmgr.Options{ + opts := pkgmgr.Options{ KubeConfig: s.config, MetricsAddr: "0", AddToManager: s.addToManagerFn, InitializeProviders: s.initProvidersFn, - }) + } + + if enabled, ok := s.fssMap[lib.VMServiceV1Alpha2FSS]; ok && enabled { + opts.Scheme = runtime.NewScheme() + _ = vmopv1alpha2.AddToScheme(opts.Scheme) + } + + s.manager, err = pkgmgr.New(opts) + Expect(err).NotTo(HaveOccurred()) Expect(s.manager).ToNot(BeNil()) } @@ -442,6 +479,7 @@ func (s *TestSuite) beforeSuiteForIntegrationTesting() { s.UpdateCRDScope(crd, "Cluster") } } + // TODO: Include NamespacedVMClass related changes }) // If one or more webhooks are being tested then go ahead and generate a @@ -512,6 +550,18 @@ func (s *TestSuite) afterSuiteForIntegrationTesting() { }) } +func (s *TestSuite) applyFeatureStatesToCRDs(in []*apiextensionsv1.CustomResourceDefinition) []*apiextensionsv1.CustomResourceDefinition { + out := make([]*apiextensionsv1.CustomResourceDefinition, 0) + for i := range in { + crd := applyFeatureStateFnsToCRD( + *in[i], + s.fssMap, + applyV1Alpha2FSSToCRD) + out = append(out, &crd) + } + return out +} + func (s *TestSuite) GetInstalledCRD(crdName string) *apiextensionsv1.CustomResourceDefinition { for _, crd := range s.envTest.CRDs { if crd.Name == crdName { diff --git a/test/builder/util.go b/test/builder/util.go index 42df786a4..b1ac9ece5 100644 --- a/test/builder/util.go +++ b/test/builder/util.go @@ -4,25 +4,34 @@ package builder import ( + "bufio" + "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" + "io" + "io/ioutil" + "path/filepath" "github.com/google/uuid" corev1 "k8s.io/api/core/v1" storagev1 "k8s.io/api/storage/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/sets" + k8syaml "k8s.io/apimachinery/pkg/util/yaml" + "sigs.k8s.io/yaml" imgregv1a1 "github.com/vmware-tanzu/image-registry-operator-api/api/v1alpha1" - topologyv1 "github.com/vmware-tanzu/vm-operator/external/tanzu-topology/api/v1alpha1" - vmopv1 "github.com/vmware-tanzu/vm-operator/api/v1alpha1" + topologyv1 "github.com/vmware-tanzu/vm-operator/external/tanzu-topology/api/v1alpha1" + "github.com/vmware-tanzu/vm-operator/pkg/lib" ) const ( @@ -533,3 +542,121 @@ func DummyClusterContentLibrary(name, uuid string) *imgregv1a1.ClusterContentLib }, } } + +func applyFeatureStateFnsToCRD( + crd apiextensionsv1.CustomResourceDefinition, + fssMap map[string]bool, + fns ...func(apiextensionsv1.CustomResourceDefinition, map[string]bool) apiextensionsv1.CustomResourceDefinition) apiextensionsv1.CustomResourceDefinition { + + for i := range fns { + crd = fns[i](crd, fssMap) + } + return crd +} + +func applyV1Alpha2FSSToCRD( + crd apiextensionsv1.CustomResourceDefinition, + fssMap map[string]bool) apiextensionsv1.CustomResourceDefinition { + + idxV1a1 := indexOfVersion(crd, "v1alpha1") + idxV1a2 := indexOfVersion(crd, "v1alpha2") + + if enabled, ok := fssMap[lib.VMServiceV1Alpha2FSS]; ok && enabled { + // Whether the v1a2 version of this CRD is the storage version + // depends on existence of the v1a2 version of this CRD. + if idxV1a1 >= 0 { + crd.Spec.Versions[idxV1a1].Storage = !(idxV1a2 >= 0) + crd.Spec.Versions[idxV1a1].Served = true + } + + // If there is a v1a2 version of this CRD, it is the storage version. + if idxV1a2 >= 0 { + crd.Spec.Versions[idxV1a2].Storage = true + crd.Spec.Versions[idxV1a2].Served = true + } + } else if idxV1a1 >= 0 { + crd.Spec.Versions[idxV1a1].Storage = true + crd.Spec.Versions[idxV1a1].Served = true + + // If there is a v1a2 version of this CRD, remove it. + if idxV1a2 >= 0 { + copy(crd.Spec.Versions[idxV1a2:], crd.Spec.Versions[idxV1a2+1:]) + var zeroVal apiextensionsv1.CustomResourceDefinitionVersion + crd.Spec.Versions[len(crd.Spec.Versions)-1] = zeroVal + crd.Spec.Versions = crd.Spec.Versions[:len(crd.Spec.Versions)-1] + } + } + + return crd +} + +func indexOfVersion( + crd apiextensionsv1.CustomResourceDefinition, + version string) int { + + for i := range crd.Spec.Versions { + if crd.Spec.Versions[i].Name == version { + return i + } + } + return -1 +} + +func LoadCRDs(rootFilePath string) ([]*apiextensionsv1.CustomResourceDefinition, error) { + // Read the CRD files. + files, err := ioutil.ReadDir(rootFilePath) + if err != nil { + return nil, err + } + + // Valid file extensions for CRDs. + crdExts := sets.NewString(".json", ".yaml", ".yml") + + var out []*apiextensionsv1.CustomResourceDefinition + for i := range files { + if !crdExts.Has(filepath.Ext(files[i].Name())) { + continue + } + + docs, err := readDocuments(filepath.Join(rootFilePath, files[i].Name())) + if err != nil { + return nil, err + } + + for _, d := range docs { + var crd apiextensionsv1.CustomResourceDefinition + if err = yaml.Unmarshal(d, &crd); err != nil { + return nil, err + } + if crd.Spec.Names.Kind == "" || crd.Spec.Group == "" { + continue + } + out = append(out, &crd) + } + } + return out, nil +} + +// readDocuments reads documents from file +// copied from https://github.com/kubernetes-sigs/controller-runtime/blob/5bf44d2ffd6201703508e11fbae74fcedc5ce148/pkg/envtest/crd.go#L434-L458 +func readDocuments(fp string) ([][]byte, error) { + //nolint:gosec + b, err := ioutil.ReadFile(fp) + if err != nil { + return nil, err + } + docs := [][]byte{} + reader := k8syaml.NewYAMLReader(bufio.NewReader(bytes.NewReader(b))) + for { + // Read document + doc, err := reader.Read() + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + docs = append(docs, doc) + } + return docs, nil +} diff --git a/webhooks/virtualmachine/v1alpha2/mutation/virtualmachine_mutator_suite_test.go b/webhooks/virtualmachine/v1alpha2/mutation/virtualmachine_mutator_suite_test.go index 9addb7ee7..8a4616ba5 100644 --- a/webhooks/virtualmachine/v1alpha2/mutation/virtualmachine_mutator_suite_test.go +++ b/webhooks/virtualmachine/v1alpha2/mutation/virtualmachine_mutator_suite_test.go @@ -9,19 +9,20 @@ import ( . "github.com/onsi/ginkgo" "github.com/onsi/ginkgo/extensions/table" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachine/v1alpha2/mutation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForMutatingWebhook( +var suite = builder.NewTestSuiteForMutatingWebhookwithFSS( mutation.AddToManager, mutation.NewMutator, - "default.mutating.virtualmachine.v1alpha2.vmoperator.vmware.com") + "default.mutating.virtualmachine.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Mutating webhook suite", nil /*intgTests*/, uniTests) + suite.Register(t, "Mutating webhook suite", intgTests, uniTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachine/v1alpha2/validation/virtualmachine_validator_suite_test.go b/webhooks/virtualmachine/v1alpha2/validation/virtualmachine_validator_suite_test.go index 9411e716c..8dbc42fe7 100644 --- a/webhooks/virtualmachine/v1alpha2/validation/virtualmachine_validator_suite_test.go +++ b/webhooks/virtualmachine/v1alpha2/validation/virtualmachine_validator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachine/v1alpha2/validation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForValidatingWebhook( +var suite = builder.NewTestSuiteForValidatingWebhookwithFSS( validation.AddToManager, validation.NewValidator, - "default.validating.virtualmachine.v1alpha2.vmoperator.vmware.com") + "default.validating.virtualmachine.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Validation webhook suite", nil /*intgTests*/, unitTests) + suite.Register(t, "Validation webhook suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachineclass/v1alpha2/mutation/virtualmachineclass_mutator_suite_test.go b/webhooks/virtualmachineclass/v1alpha2/mutation/virtualmachineclass_mutator_suite_test.go index 9c3831732..4c099e5d0 100644 --- a/webhooks/virtualmachineclass/v1alpha2/mutation/virtualmachineclass_mutator_suite_test.go +++ b/webhooks/virtualmachineclass/v1alpha2/mutation/virtualmachineclass_mutator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachineclass/v1alpha2/mutation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForMutatingWebhook( +var suite = builder.NewTestSuiteForMutatingWebhookwithFSS( mutation.AddToManager, mutation.NewMutator, - "default.mutating.virtualmachineclass.v1alpha2.vmoperator.vmware.com") + "default.mutating.virtualmachineclass.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Mutating webhook suite", nil /*intgTests*/, uniTests) + suite.Register(t, "Mutating webhook suite", intgTests, uniTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachineclass/v1alpha2/validation/virtualmachineclass_validator_suite_test.go b/webhooks/virtualmachineclass/v1alpha2/validation/virtualmachineclass_validator_suite_test.go index c66b4fc13..b2740b5a9 100644 --- a/webhooks/virtualmachineclass/v1alpha2/validation/virtualmachineclass_validator_suite_test.go +++ b/webhooks/virtualmachineclass/v1alpha2/validation/virtualmachineclass_validator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachineclass/v1alpha2/validation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForValidatingWebhook( +var suite = builder.NewTestSuiteForValidatingWebhookwithFSS( validation.AddToManager, validation.NewValidator, - "default.validating.virtualmachineclass.v1alpha2.vmoperator.vmware.com") + "default.validating.virtualmachineclass.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Validation webhook suite", nil /*intgTests*/, unitTests) + suite.Register(t, "Validation webhook suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachinepublishrequest/v1alpha2/validation/virtualmachinepublishrequest_validator_suite_test.go b/webhooks/virtualmachinepublishrequest/v1alpha2/validation/virtualmachinepublishrequest_validator_suite_test.go index af26e91bb..560f0b65a 100644 --- a/webhooks/virtualmachinepublishrequest/v1alpha2/validation/virtualmachinepublishrequest_validator_suite_test.go +++ b/webhooks/virtualmachinepublishrequest/v1alpha2/validation/virtualmachinepublishrequest_validator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachinepublishrequest/v1alpha2/validation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForValidatingWebhook( +var suite = builder.NewTestSuiteForValidatingWebhookwithFSS( validation.AddToManager, validation.NewValidator, - "default.validating.virtualmachinepublishrequest.v1alpha2.vmoperator.vmware.com") + "default.validating.virtualmachinepublishrequest.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Validation webhook suite", nil /*intgTests*/, unitTests) + suite.Register(t, "Validation webhook suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachineservice/v1alpha2/mutation/virtualmachineservice_mutator_suite_test.go b/webhooks/virtualmachineservice/v1alpha2/mutation/virtualmachineservice_mutator_suite_test.go index 2571a88fa..d7cbc7efc 100644 --- a/webhooks/virtualmachineservice/v1alpha2/mutation/virtualmachineservice_mutator_suite_test.go +++ b/webhooks/virtualmachineservice/v1alpha2/mutation/virtualmachineservice_mutator_suite_test.go @@ -8,18 +8,19 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachineservice/v1alpha2/mutation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForMutatingWebhook( +var suite = builder.NewTestSuiteForMutatingWebhookwithFSS( mutation.AddToManager, mutation.NewMutator, - "default.mutating.virtualmachineservice.v1alpha2.vmoperator.vmware.com") + "default.mutating.virtualmachineservice.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests suite.Register(t, "Mutating webhook suite", intgTests, uniTests) } diff --git a/webhooks/virtualmachineservice/v1alpha2/validation/virtualmachineservice_validator_suite_test.go b/webhooks/virtualmachineservice/v1alpha2/validation/virtualmachineservice_validator_suite_test.go index 82e70aec1..a655f5650 100644 --- a/webhooks/virtualmachineservice/v1alpha2/validation/virtualmachineservice_validator_suite_test.go +++ b/webhooks/virtualmachineservice/v1alpha2/validation/virtualmachineservice_validator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachineservice/v1alpha2/validation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForValidatingWebhook( +var suite = builder.NewTestSuiteForValidatingWebhookwithFSS( validation.AddToManager, validation.NewValidator, - "default.validating.virtualmachineservice.v1alpha2.vmoperator.vmware.com") + "default.validating.virtualmachineservice.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Validation webhook suite", nil /*intgTests*/, unitTests) + suite.Register(t, "Validation webhook suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite) diff --git a/webhooks/virtualmachinesetresourcepolicy/v1alpha2/validation/virtualmachinesetresourcepolicy_validator_suite_test.go b/webhooks/virtualmachinesetresourcepolicy/v1alpha2/validation/virtualmachinesetresourcepolicy_validator_suite_test.go index 41bf6e075..b93406dde 100644 --- a/webhooks/virtualmachinesetresourcepolicy/v1alpha2/validation/virtualmachinesetresourcepolicy_validator_suite_test.go +++ b/webhooks/virtualmachinesetresourcepolicy/v1alpha2/validation/virtualmachinesetresourcepolicy_validator_suite_test.go @@ -8,19 +8,20 @@ import ( . "github.com/onsi/ginkgo" + "github.com/vmware-tanzu/vm-operator/pkg/lib" "github.com/vmware-tanzu/vm-operator/test/builder" "github.com/vmware-tanzu/vm-operator/webhooks/virtualmachinesetresourcepolicy/v1alpha2/validation" ) // suite is used for unit and integration testing this webhook. -var suite = builder.NewTestSuiteForValidatingWebhook( +var suite = builder.NewTestSuiteForValidatingWebhookwithFSS( validation.AddToManager, validation.NewValidator, - "default.validating.virtualmachinesetresourcepolicy.v1alpha2.vmoperator.vmware.com") + "default.validating.virtualmachinesetresourcepolicy.v1alpha2.vmoperator.vmware.com", + map[string]bool{lib.VMServiceV1Alpha2FSS: true}) func TestWebhook(t *testing.T) { - _ = intgTests - suite.Register(t, "Validation webhook suite", nil /*intgTests*/, unitTests) + suite.Register(t, "Validation webhook suite", intgTests, unitTests) } var _ = BeforeSuite(suite.BeforeSuite)