diff --git a/common/pkg/testutils/capitest/patches.go b/common/pkg/testutils/capitest/patches.go index fa817d25f..cffaaabf5 100644 --- a/common/pkg/testutils/capitest/patches.go +++ b/common/pkg/testutils/capitest/patches.go @@ -92,6 +92,52 @@ func ValidateGeneratePatches[T mutation.GeneratePatches]( DescribeTable("Patches", testFunc, testArgs) } +// TODO(shalinpatel): AssertGeneratePatches is a replacement of ValidateGeneratePatches function. +// remove ValidateGeneratePatches once all the shared test cases are moved to their own patch package. +func AssertGeneratePatches[T mutation.GeneratePatches]( + t GinkgoTInterface, + handlerCreator func() T, + tt *PatchTestDef, +) { + t.Helper() + + g := gomega.NewWithT(t) + h := handlerCreator() + req := &runtimehooksv1.GeneratePatchesRequest{ + Variables: tt.Vars, + Items: []runtimehooksv1.GeneratePatchesRequestItem{ + tt.RequestItem, + { + HolderReference: runtimehooksv1.HolderReference{ + APIVersion: capiv1.GroupVersion.String(), + Kind: "Cluster", + Namespace: request.Namespace, + Name: request.ClusterName, + }, + }, + }, + } + resp := &runtimehooksv1.GeneratePatchesResponse{} + h.GeneratePatches(context.Background(), req, resp) + expectedStatus := runtimehooksv1.ResponseStatusSuccess + if tt.ExpectedFailure { + expectedStatus = runtimehooksv1.ResponseStatusFailure + } + g.Expect(resp.Status). + To(gomega.Equal(expectedStatus), fmt.Sprintf("Message: %s", resp.Message)) + + if len(tt.ExpectedPatchMatchers) == 0 { + g.Expect(resp.Items).To(gomega.BeEmpty()) + return + } + g.Expect(resp.Items).To(containPatches(&tt.RequestItem, tt.ExpectedPatchMatchers...)) + + if len(tt.UnexpectedPatchMatchers) > 0 { + g.Expect(resp.Items). + ToNot(containPatches(&tt.RequestItem, tt.UnexpectedPatchMatchers...)) + } +} + // VariableWithValue returns a runtimehooksv1.Variable with the passed name and value. func VariableWithValue( variableName string, diff --git a/pkg/handlers/aws/mutation/ami/inject_control_plane_test.go b/pkg/handlers/aws/mutation/ami/inject_control_plane_test.go new file mode 100644 index 000000000..638446022 --- /dev/null +++ b/pkg/handlers/aws/mutation/ami/inject_control_plane_test.go @@ -0,0 +1,100 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package ami + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" +) + +var _ = Describe("Generate AMI patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "AMI set for control plane", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.AMISpec{ID: "ami-controlplane"}, + clusterconfig.MetaControlPlaneConfigName, + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/ami/id", + ValueMatcher: gomega.Equal("ami-controlplane"), + }, + }, + }, + { + Name: "AMI lookup format set for control plane", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.AMISpec{ + Lookup: &v1alpha1.AMILookup{ + Format: "test-{{.kubernetesVersion}}-format", + Org: "1234", + BaseOS: "testOS", + }, + }, + clusterconfig.MetaControlPlaneConfigName, + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/imageLookupFormat", + ValueMatcher: gomega.Equal("test-{{.kubernetesVersion}}-format"), + }, + { + Operation: "add", + Path: "/spec/template/spec/imageLookupOrg", + ValueMatcher: gomega.Equal("1234"), + }, + { + Operation: "add", + Path: "/spec/template/spec/imageLookupBaseOS", + ValueMatcher: gomega.Equal("testOS"), + }, + }, + UnexpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/ami/id", + ValueMatcher: gomega.Equal(""), + }, + }, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/ami/inject_suite_test.go b/pkg/handlers/aws/mutation/ami/inject_suite_test.go new file mode 100644 index 000000000..bb77ba57e --- /dev/null +++ b/pkg/handlers/aws/mutation/ami/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package ami + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestAMIPatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "AMI patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/aws/mutation/ami/tests/generate_patches.go b/pkg/handlers/aws/mutation/ami/inject_worker_test.go similarity index 52% rename from pkg/handlers/aws/mutation/ami/tests/generate_patches.go rename to pkg/handlers/aws/mutation/ami/inject_worker_test.go index 36f86066b..237f0963a 100644 --- a/pkg/handlers/aws/mutation/ami/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/ami/inject_worker_test.go @@ -1,11 +1,10 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package ami import ( - "testing" - + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -14,99 +13,23 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" ) -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "AMI set for control plane", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.AMISpec{ID: "ami-controlplane"}, - variablePath..., - ), - }, - RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/ami/id", - ValueMatcher: gomega.Equal("ami-controlplane"), - }, - }, - }, - capitest.PatchTestDef{ - Name: "AMI lookup format set for control plane", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.AMISpec{ - Lookup: &v1alpha1.AMILookup{ - Format: "test-{{.kubernetesVersion}}-format", - Org: "12345", - BaseOS: "testOS", - }, - }, - variablePath..., - ), - }, - RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/imageLookupFormat", - ValueMatcher: gomega.Equal("test-{{.kubernetesVersion}}-format"), - }, - { - Operation: "add", - Path: "/spec/template/spec/imageLookupOrg", - ValueMatcher: gomega.Equal("12345"), - }, - { - Operation: "add", - Path: "/spec/template/spec/imageLookupBaseOS", - ValueMatcher: gomega.Equal("testOS"), - }, - }, - UnexpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/ami/id", - ValueMatcher: gomega.Equal(""), - }, - }, - }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +var _ = Describe("Generate AMI patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "AMI set for workers", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + workerconfig.MetaVariableName, v1alpha1.AMISpec{ID: "ami-controlplane"}, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), capitest.VariableWithValue( "builtin", @@ -124,11 +47,11 @@ func TestWorkerGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "AMI lookup format set for worker", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + workerconfig.MetaVariableName, v1alpha1.AMISpec{ Lookup: &v1alpha1.AMILookup{ Format: "test-{{.kubernetesVersion}}-format", @@ -136,8 +59,8 @@ func TestWorkerGeneratePatches( BaseOS: "testOS", }, }, - - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), capitest.VariableWithValue( "builtin", @@ -172,5 +95,17 @@ func TestWorkerGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/cni/calico/tests/generate_patches.go b/pkg/handlers/aws/mutation/cni/calico/inject_test.go similarity index 89% rename from pkg/handlers/aws/mutation/cni/calico/tests/generate_patches.go rename to pkg/handlers/aws/mutation/cni/calico/inject_test.go index d9bf7be65..2bba0f09f 100644 --- a/pkg/handlers/aws/mutation/cni/calico/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/cni/calico/inject_test.go @@ -1,13 +1,13 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package calico import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - "github.com/onsi/gomega/format" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" capav1 "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2" @@ -15,34 +15,33 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +func TestCalicoPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "AWS Calico CNI ingress mutator suite") +} - format.MaxLength = 0 - format.TruncatedDiff = false +var _ = Describe("Generate AWS Calico CNI ingress patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "provider set with AWSClusterTemplate", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.CNI{ Provider: v1alpha1.CNIProviderCalico, }, - variablePath..., + "addons", + v1alpha1.CNIVariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -101,15 +100,16 @@ func TestGeneratePatches( ), }}, }, - capitest.PatchTestDef{ + { Name: "provider set with AWSClusterTemplate pre-existing rules", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.CNI{ Provider: v1alpha1.CNIProviderCalico, }, - variablePath..., + "addons", + v1alpha1.CNIVariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem( @@ -193,15 +193,16 @@ func TestGeneratePatches( ), }}, }, - capitest.PatchTestDef{ + { Name: "provider set with AWSClusterTemplate conflicting pre-existing rules", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.CNI{ Provider: v1alpha1.CNIProviderCalico, }, - variablePath..., + "addons", + v1alpha1.CNIVariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem( @@ -273,5 +274,17 @@ func TestGeneratePatches( ), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/controlplaneloadbalancer/tests/generate_patches.go b/pkg/handlers/aws/mutation/controlplaneloadbalancer/inject_test.go similarity index 65% rename from pkg/handlers/aws/mutation/controlplaneloadbalancer/tests/generate_patches.go rename to pkg/handlers/aws/mutation/controlplaneloadbalancer/inject_test.go index f799d0624..60a5c4ec5 100644 --- a/pkg/handlers/aws/mutation/controlplaneloadbalancer/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/controlplaneloadbalancer/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package controlplaneloadbalancer import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -14,31 +15,33 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +func TestControlPlaneLoadBalancerPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "AWS ControlPlane LoadBalancer mutator suite") +} + +var _ = Describe("Generate AWS ControlPlane LoadBalancer patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "ControlPlaneLoadbalancer scheme set to internet-facing", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.AWSLoadBalancerSpec{ Scheme: &capav1.ELBSchemeInternetFacing, }, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -50,15 +53,16 @@ func TestGeneratePatches( ), }}, }, - capitest.PatchTestDef{ + { Name: "ControlPlaneLoadbalancer scheme set to internal", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.AWSLoadBalancerSpec{ Scheme: &capav1.ELBSchemeInternal, }, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -70,5 +74,17 @@ func TestGeneratePatches( ), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/iaminstanceprofile/inject_control_plane_test.go b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_control_plane_test.go new file mode 100644 index 000000000..11d7b0ed9 --- /dev/null +++ b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_control_plane_test.go @@ -0,0 +1,58 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package iaminstanceprofile + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" +) + +var _ = Describe("Generate IAMInstanceProfile patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "iamInstanceProfile for control plane set", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + "control-plane.cluster-api-provider-aws.sigs.k8s.io", + clusterconfig.MetaControlPlaneConfigName, + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/iamInstanceProfile", + ValueMatcher: gomega.Equal("control-plane.cluster-api-provider-aws.sigs.k8s.io"), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/iaminstanceprofile/inject_suite_test.go b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_suite_test.go new file mode 100644 index 000000000..6cf5402dc --- /dev/null +++ b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package iaminstanceprofile + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestIAMInstnaceProfilePatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "IAMInstanceProfile patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/aws/mutation/iaminstanceprofile/tests/generate_patches.go b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_worker_test.go similarity index 50% rename from pkg/handlers/aws/mutation/iaminstanceprofile/tests/generate_patches.go rename to pkg/handlers/aws/mutation/iaminstanceprofile/inject_worker_test.go index 6f36d196f..a3044de6d 100644 --- a/pkg/handlers/aws/mutation/iaminstanceprofile/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/iaminstanceprofile/inject_worker_test.go @@ -1,74 +1,38 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package iaminstanceprofile import ( - "testing" - + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" ) -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +var _ = Describe("Generate IAMInstanceProfile patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ - Name: "iamInstanceProfile set", + { + Name: "iamInstanceProfile for worker set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, - "control-plane.cluster-api-provider-aws.sigs.k8s.io", - variablePath..., - ), - }, - RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/iamInstanceProfile", - ValueMatcher: gomega.Equal("control-plane.cluster-api-provider-aws.sigs.k8s.io"), - }}, - }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "iamInstanceProfile set", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, + workerconfig.MetaVariableName, "nodes.cluster-api-provider-aws.sigs.k8s.io", - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), capitest.VariableWithValue( "builtin", @@ -84,5 +48,17 @@ func TestWorkerGeneratePatches( ValueMatcher: gomega.Equal("nodes.cluster-api-provider-aws.sigs.k8s.io"), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/instancetype/inject_control_plane_test.go b/pkg/handlers/aws/mutation/instancetype/inject_control_plane_test.go new file mode 100644 index 000000000..e13189a47 --- /dev/null +++ b/pkg/handlers/aws/mutation/instancetype/inject_control_plane_test.go @@ -0,0 +1,58 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package instancetype + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" +) + +var _ = Describe("Generate InstanceType patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "instanceType for controlplane set", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + "m5.xlarge", + clusterconfig.MetaControlPlaneConfigName, + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "replace", + Path: "/spec/template/spec/instanceType", + ValueMatcher: gomega.Equal("m5.xlarge"), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/instancetype/inject_suite_test.go b/pkg/handlers/aws/mutation/instancetype/inject_suite_test.go new file mode 100644 index 000000000..393d232d7 --- /dev/null +++ b/pkg/handlers/aws/mutation/instancetype/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package instancetype + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestInstanceTypePatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "InstanceType patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/aws/mutation/instancetype/tests/generate_patches.go b/pkg/handlers/aws/mutation/instancetype/inject_worker_test.go similarity index 50% rename from pkg/handlers/aws/mutation/instancetype/tests/generate_patches.go rename to pkg/handlers/aws/mutation/instancetype/inject_worker_test.go index ef9959535..03cbec647 100644 --- a/pkg/handlers/aws/mutation/instancetype/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/instancetype/inject_worker_test.go @@ -1,74 +1,38 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package instancetype import ( - "testing" - + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" ) -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +var _ = Describe("Generate InstanceType patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ - Name: "instanceType set", + { + Name: "instanceType for workers set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, - "m5.xlarge", - variablePath..., - ), - }, - RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "replace", - Path: "/spec/template/spec/instanceType", - ValueMatcher: gomega.Equal("m5.xlarge"), - }}, - }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "instanceType set", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, + workerconfig.MetaVariableName, "m5.2xlarge", - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), capitest.VariableWithValue( "builtin", @@ -84,5 +48,17 @@ func TestWorkerGeneratePatches( ValueMatcher: gomega.Equal("m5.2xlarge"), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/metapatch_handler_test.go b/pkg/handlers/aws/mutation/metapatch_handler_test.go deleted file mode 100644 index f8c7f1c0f..000000000 --- a/pkg/handlers/aws/mutation/metapatch_handler_test.go +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "testing" - - "sigs.k8s.io/controller-runtime/pkg/manager" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/ami" - amitests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/ami/tests" - calicotests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/cni/calico/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/controlplaneloadbalancer" - controlplaneloadbalancertests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/controlplaneloadbalancer/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/iaminstanceprofile" - iaminstanceprofiletests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/iaminstanceprofile/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/instancetype" - instancetypetests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/instancetype/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/network" - networktests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/network/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/region" - regiontests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/region/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" - auditpolicytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/auditpolicy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd" - etcdtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans" - extraapiservercertsanstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy" - httpproxytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries" - imageregistrycredentialstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries/credentials/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository" - kubernetesimagerepositorytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors" - globalimageregistrymirrortests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/users" - userstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/users/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" -) - -func metaPatchGeneratorFunc(mgr manager.Manager) func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaPatchHandler(mgr).(mutation.GeneratePatches) - } -} - -func workerPatchGeneratorFunc() func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaWorkerPatchHandler().(mutation.GeneratePatches) - } -} - -func TestGeneratePatches(t *testing.T) { - t.Parallel() - - mgr := testEnv.Manager - - regiontests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - v1alpha1.AWSVariableName, - region.VariableName, - ) - - iaminstanceprofiletests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - v1alpha1.AWSVariableName, - iaminstanceprofile.VariableName, - ) - - iaminstanceprofiletests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - v1alpha1.AWSVariableName, - iaminstanceprofile.VariableName, - ) - - instancetypetests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - v1alpha1.AWSVariableName, - instancetype.VariableName, - ) - - instancetypetests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - v1alpha1.AWSVariableName, - instancetype.VariableName, - ) - - calicotests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - "addons", - v1alpha1.CNIVariableName, - ) - - auditpolicytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - ) - - httpproxytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - httpproxy.VariableName, - ) - - etcdtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - etcd.VariableName, - ) - - extraapiservercertsanstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - extraapiservercertsans.VariableName, - ) - - kubernetesimagerepositorytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - kubernetesimagerepository.VariableName, - ) - - imageregistrycredentialstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - imageregistries.VariableName, - ) - - globalimageregistrymirrortests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - mirrors.GlobalMirrorVariableName, - ) - - amitests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - v1alpha1.AWSVariableName, - ami.VariableName, - ) - - amitests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - v1alpha1.AWSVariableName, - ami.VariableName, - ) - - networktests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - v1alpha1.AWSVariableName, - network.VariableName, - ) - - controlplaneloadbalancertests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - v1alpha1.AWSVariableName, - controlplaneloadbalancer.VariableName, - ) - - userstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - users.VariableName, - ) -} diff --git a/pkg/handlers/aws/mutation/network/tests/generate_patches.go b/pkg/handlers/aws/mutation/network/inject_test.go similarity index 69% rename from pkg/handlers/aws/mutation/network/tests/generate_patches.go rename to pkg/handlers/aws/mutation/network/inject_test.go index 09dcdfd78..f91185cf3 100644 --- a/pkg/handlers/aws/mutation/network/tests/generate_patches.go +++ b/pkg/handlers/aws/mutation/network/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package network import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,33 +14,35 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +func TestNetworkPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "AWS Network mutator suite") +} + +var _ = Describe("Generate AWS Network patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "VPC ID set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.AWSNetwork{ VPC: &v1alpha1.VPC{ ID: "vpc-1234", }, }, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -49,11 +52,11 @@ func TestGeneratePatches( ValueMatcher: gomega.Equal("vpc-1234"), }}, }, - capitest.PatchTestDef{ + { Name: "Subnet IDs set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.AWSNetwork{ Subnets: v1alpha1.Subnets{ {ID: "subnet-1"}, @@ -61,7 +64,8 @@ func TestGeneratePatches( {ID: "subnet-3"}, }, }, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -71,11 +75,11 @@ func TestGeneratePatches( ValueMatcher: gomega.HaveLen(3), }}, }, - capitest.PatchTestDef{ + { Name: "both VPC ID and Subnet IDs set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.AWSNetwork{ VPC: &v1alpha1.VPC{ ID: "vpc-1234", @@ -86,7 +90,8 @@ func TestGeneratePatches( {ID: "subnet-3"}, }, }, - variablePath..., + v1alpha1.AWSVariableName, + VariableName, ), }, RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), @@ -100,5 +105,17 @@ func TestGeneratePatches( ValueMatcher: gomega.HaveLen(3), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/region/inject_test.go b/pkg/handlers/aws/mutation/region/inject_test.go index 4f76e95ea..d38da4eda 100644 --- a/pkg/handlers/aws/mutation/region/inject_test.go +++ b/pkg/handlers/aws/mutation/region/inject_test.go @@ -7,16 +7,18 @@ import ( "testing" . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" + "github.com/onsi/gomega" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - regiontests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/aws/mutation/region/tests" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) func TestRegionPatch(t *testing.T) { - RegisterFailHandler(Fail) + gomega.RegisterFailHandler(Fail) RunSpecs(t, "AWS Region mutator suite") } @@ -25,11 +27,39 @@ var _ = Describe("Generate AWS Region patches", func() { patchGenerator := func() mutation.GeneratePatches { return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) } - regiontests.TestGeneratePatches( - GinkgoT(), - patchGenerator, - clusterconfig.MetaVariableName, - v1alpha1.AWSVariableName, - VariableName, - ) + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "region set", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + "a-specific-region", + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/region", + ValueMatcher: gomega.Equal("a-specific-region"), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } }) diff --git a/pkg/handlers/aws/mutation/region/tests/generate_patches.go b/pkg/handlers/aws/mutation/region/tests/generate_patches.go deleted file mode 100644 index 883d603c5..000000000 --- a/pkg/handlers/aws/mutation/region/tests/generate_patches.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package tests - -import ( - . "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" -) - -func TestGeneratePatches( - t GinkgoTInterface, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "region set", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - "a-specific-region", - variablePath..., - ), - }, - RequestItem: request.NewAWSClusterTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/region", - ValueMatcher: gomega.Equal("a-specific-region"), - }}, - }, - ) -} diff --git a/pkg/handlers/aws/mutation/securitygroups/inject_control_plane_test.go b/pkg/handlers/aws/mutation/securitygroups/inject_control_plane_test.go new file mode 100644 index 000000000..8c67e96f2 --- /dev/null +++ b/pkg/handlers/aws/mutation/securitygroups/inject_control_plane_test.go @@ -0,0 +1,75 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package securitygroups + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + "k8s.io/utils/ptr" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" +) + +var _ = Describe("Generate SecurityGroup patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "SecurityGroups for controlplane set", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.AdditionalSecurityGroup{ + {ID: ptr.To("sg-1")}, + {ID: ptr.To("sg-2")}, + {ID: ptr.To("sg-3")}, + }, + clusterconfig.MetaControlPlaneConfigName, + v1alpha1.AWSVariableName, + VariableName, + ), + }, + RequestItem: request.NewCPAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/additionalSecurityGroups", + ValueMatcher: gomega.HaveLen(3), + }, + // TODO(shalinpatel): add matcher to check if all SG are set + // { + // Operation: "add", + // Path: "/spec/template/spec/additionalSecurityGroups", + // ValueMatcher: gomega.ContainElements( + // gomega.HaveKeyWithValue("id", "sg-1"), + // gomega.HaveKeyWithValue("id", "sg-2"), + // gomega.HaveKeyWithValue("id", "sg-3"), + // ), + // }, + }, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/securitygroups/inject_suite_test.go b/pkg/handlers/aws/mutation/securitygroups/inject_suite_test.go new file mode 100644 index 000000000..09ae3ad05 --- /dev/null +++ b/pkg/handlers/aws/mutation/securitygroups/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package securitygroups + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestSecurityGroupsPatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "AWS security groups patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/aws/mutation/securitygroups/inject_worker_test.go b/pkg/handlers/aws/mutation/securitygroups/inject_worker_test.go new file mode 100644 index 000000000..2e4d90844 --- /dev/null +++ b/pkg/handlers/aws/mutation/securitygroups/inject_worker_test.go @@ -0,0 +1,81 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package securitygroups + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/utils/ptr" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" +) + +var _ = Describe("Generate AWS SecurityGroups patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "SecurityGroups for workers set", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + workerconfig.MetaVariableName, + v1alpha1.AdditionalSecurityGroup{ + {ID: ptr.To("sg-1")}, + {ID: ptr.To("sg-2")}, + {ID: ptr.To("sg-3")}, + }, + v1alpha1.AWSVariableName, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), + }, + ), + }, + RequestItem: request.NewWorkerAWSMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/additionalSecurityGroups", + ValueMatcher: gomega.HaveLen(3), + }, + // TODO(shalinpatel): add matcher to check if all SG are set + // { + // Operation: "add", + // Path: "/spec/template/spec/additionalSecurityGroups", + // ValueMatcher: gomega.ContainElements( + // gomega.HaveKeyWithValue("id", "sg-1"), + // gomega.HaveKeyWithValue("id", "sg-2"), + // gomega.HaveKeyWithValue("id", "sg-3"), + // ), + // }, + }, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/aws/mutation/suite_test.go b/pkg/handlers/aws/mutation/suite_test.go deleted file mode 100644 index 5188c91c7..000000000 --- a/pkg/handlers/aws/mutation/suite_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "context" - "fmt" - "testing" - - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" -) - -var ( - testEnv *helpers.TestEnvironment - ctx = ctrl.SetupSignalHandler() -) - -func TestMain(m *testing.M) { - setupCtx, cancel := context.WithCancel(ctx) - setup(setupCtx) - defer teardown(cancel) - m.Run() -} - -func setup(ctx context.Context) { - testEnvConfig := helpers.NewTestEnvironmentConfiguration() - var err error - testEnv, err = testEnvConfig.Build() - if err != nil { - panic(err) - } - go func() { - fmt.Println("Starting the manager") - if err := testEnv.StartManager(ctx); err != nil { - panic(fmt.Sprintf("Failed to start the envtest manager: %v", err)) - } - }() -} - -func teardown(cancel context.CancelFunc) { - cancel() - if err := testEnv.Stop(); err != nil { - panic(fmt.Sprintf("Failed to stop envtest: %v", err)) - } -} diff --git a/pkg/handlers/docker/mutation/customimage/inject_control_plane_test.go b/pkg/handlers/docker/mutation/customimage/inject_control_plane_test.go new file mode 100644 index 000000000..fa40cbd5d --- /dev/null +++ b/pkg/handlers/docker/mutation/customimage/inject_control_plane_test.go @@ -0,0 +1,77 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package customimage + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + dockerclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/clusterconfig" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" +) + +var _ = Describe("Docker CustomImage patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "image unset for control plane", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{Raw: []byte(`{"controlPlane": {"version": "v1.2.3"}}`)}, + ), + }, + RequestItem: request.NewCPDockerMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/customImage", + ValueMatcher: gomega.Equal("ghcr.io/mesosphere/kind-node:v1.2.3"), + }}, + }, + { + Name: "image set for control plane", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + "a-specific-image", + clusterconfig.MetaControlPlaneConfigName, + dockerclusterconfig.DockerVariableName, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), + }, + ), + }, + RequestItem: request.NewCPDockerMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/customImage", + ValueMatcher: gomega.Equal("a-specific-image"), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/docker/mutation/customimage/inject_suite_test.go b/pkg/handlers/docker/mutation/customimage/inject_suite_test.go new file mode 100644 index 000000000..9f17edd7c --- /dev/null +++ b/pkg/handlers/docker/mutation/customimage/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package customimage + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestCustomImagePatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Docker CustomImage patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/docker/mutation/customimage/inject_worker_test.go b/pkg/handlers/docker/mutation/customimage/inject_worker_test.go new file mode 100644 index 000000000..b13f582d7 --- /dev/null +++ b/pkg/handlers/docker/mutation/customimage/inject_worker_test.go @@ -0,0 +1,80 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package customimage + +import ( + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + dockerworkerconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/workerconfig" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" +) + +var _ = Describe("Docker CustomImage patches for workers", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "image unset for workers", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte( + `{"machineDeployment": {"class": "a-worker", "version": "v1.2.3"}}`, + ), + }, + ), + }, + RequestItem: request.NewWorkerDockerMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/customImage", + ValueMatcher: gomega.Equal("ghcr.io/mesosphere/kind-node:v1.2.3"), + }}, + }, + { + Name: "image set for workers", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + workerconfig.MetaVariableName, + "a-specific-image", + dockerworkerconfig.DockerVariableName, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), + }, + ), + }, + RequestItem: request.NewWorkerDockerMachineTemplateRequestItem("1234"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/customImage", + ValueMatcher: gomega.Equal("a-specific-image"), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/docker/mutation/customimage/tests/generate_patches.go b/pkg/handlers/docker/mutation/customimage/tests/generate_patches.go deleted file mode 100644 index 7b1b9b6e4..000000000 --- a/pkg/handlers/docker/mutation/customimage/tests/generate_patches.go +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package tests - -import ( - "testing" - - "github.com/onsi/gomega" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" -) - -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "image unset for control plane", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{Raw: []byte(`{"controlPlane": {"version": "v1.2.3"}}`)}, - ), - }, - RequestItem: request.NewCPDockerMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/customImage", - ValueMatcher: gomega.Equal("ghcr.io/mesosphere/kind-node:v1.2.3"), - }}, - }, - capitest.PatchTestDef{ - Name: "image set for control plane", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - "a-specific-image", - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{ - Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), - }, - ), - }, - RequestItem: request.NewCPDockerMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/customImage", - ValueMatcher: gomega.Equal("a-specific-image"), - }}, - }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "image unset for workers", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{ - Raw: []byte( - `{"machineDeployment": {"class": "a-worker", "version": "v1.2.3"}}`, - ), - }, - ), - }, - RequestItem: request.NewWorkerDockerMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/customImage", - ValueMatcher: gomega.Equal("ghcr.io/mesosphere/kind-node:v1.2.3"), - }}, - }, - capitest.PatchTestDef{ - Name: "image set for workers", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - "a-specific-image", - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{ - Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), - }, - ), - }, - RequestItem: request.NewWorkerDockerMachineTemplateRequestItem("1234"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/customImage", - ValueMatcher: gomega.Equal("a-specific-image"), - }}, - }, - ) -} diff --git a/pkg/handlers/docker/mutation/metapatch_handler_test.go b/pkg/handlers/docker/mutation/metapatch_handler_test.go deleted file mode 100644 index cdcd81994..000000000 --- a/pkg/handlers/docker/mutation/metapatch_handler_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "testing" - - "sigs.k8s.io/controller-runtime/pkg/manager" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - dockerclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/clusterconfig" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/mutation/customimage" - customimagetests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/mutation/customimage/tests" - dockerworkerconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/docker/workerconfig" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" - auditpolicytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/auditpolicy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd" - etcdtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans" - extraapiservercertsanstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy" - httpproxytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries" - imageregistrycredentialstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries/credentials/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository" - kubernetesimagerepositorytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors" - globalimageregistrymirrortests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/users" - userstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/users/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" -) - -func metaPatchGeneratorFunc(mgr manager.Manager) func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaPatchHandler(mgr).(mutation.GeneratePatches) - } -} - -func workerPatchGeneratorFunc() func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaWorkerPatchHandler().(mutation.GeneratePatches) - } -} - -func TestGeneratePatches(t *testing.T) { - t.Parallel() - - mgr := testEnv.Manager - - customimagetests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - dockerclusterconfig.DockerVariableName, - customimage.VariableName, - ) - - customimagetests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - dockerworkerconfig.DockerVariableName, - customimage.VariableName, - ) - - auditpolicytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - ) - - httpproxytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - httpproxy.VariableName, - ) - - etcdtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - etcd.VariableName, - ) - - extraapiservercertsanstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - extraapiservercertsans.VariableName, - ) - - kubernetesimagerepositorytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - kubernetesimagerepository.VariableName, - ) - - imageregistrycredentialstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - imageregistries.VariableName, - ) - - globalimageregistrymirrortests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - mirrors.GlobalMirrorVariableName, - ) - - userstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - users.VariableName, - ) -} diff --git a/pkg/handlers/docker/mutation/suite_test.go b/pkg/handlers/docker/mutation/suite_test.go deleted file mode 100644 index 5188c91c7..000000000 --- a/pkg/handlers/docker/mutation/suite_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "context" - "fmt" - "testing" - - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" -) - -var ( - testEnv *helpers.TestEnvironment - ctx = ctrl.SetupSignalHandler() -) - -func TestMain(m *testing.M) { - setupCtx, cancel := context.WithCancel(ctx) - setup(setupCtx) - defer teardown(cancel) - m.Run() -} - -func setup(ctx context.Context) { - testEnvConfig := helpers.NewTestEnvironmentConfiguration() - var err error - testEnv, err = testEnvConfig.Build() - if err != nil { - panic(err) - } - go func() { - fmt.Println("Starting the manager") - if err := testEnv.StartManager(ctx); err != nil { - panic(fmt.Sprintf("Failed to start the envtest manager: %v", err)) - } - }() -} - -func teardown(cancel context.CancelFunc) { - cancel() - if err := testEnv.Stop(); err != nil { - panic(fmt.Sprintf("Failed to stop envtest: %v", err)) - } -} diff --git a/pkg/handlers/generic/mutation/auditpolicy/tests/generate_patches.go b/pkg/handlers/generic/mutation/auditpolicy/inject_test.go similarity index 76% rename from pkg/handlers/generic/mutation/auditpolicy/tests/generate_patches.go rename to pkg/handlers/generic/mutation/auditpolicy/inject_test.go index 3380817f2..685707528 100644 --- a/pkg/handlers/generic/mutation/auditpolicy/tests/generate_patches.go +++ b/pkg/handlers/generic/mutation/auditpolicy/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package auditpolicy import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" @@ -13,18 +14,21 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" ) -func TestGeneratePatches( - t *testing.T, generatorFunc func() mutation.GeneratePatches, -) { - t.Helper() +func TestAuditPolicyPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Audit Policy mutator suite") +} + +var _ = Describe("Generate Audit Policy patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "auditpolicy set for KubeadmControlPlaneTemplate", RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ @@ -71,5 +75,13 @@ func TestGeneratePatches( ), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) diff --git a/pkg/handlers/generic/mutation/etcd/tests/generate_patches.go b/pkg/handlers/generic/mutation/etcd/inject_test.go similarity index 76% rename from pkg/handlers/generic/mutation/etcd/tests/generate_patches.go rename to pkg/handlers/generic/mutation/etcd/inject_test.go index 833a86ede..f71925b33 100644 --- a/pkg/handlers/generic/mutation/etcd/tests/generate_patches.go +++ b/pkg/handlers/generic/mutation/etcd/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package etcd import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,34 +14,35 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +func TestEtcdPolicyPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "etcd mutator suite") +} + +var _ = Describe("Generate etcd patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "etcd imageRepository and imageTag set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.Etcd{ Image: &v1alpha1.Image{ Repository: "my-registry.io/my-org/my-repo", Tag: "v3.5.99_custom.0", }, }, - variablePath..., + VariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -60,17 +62,17 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "etcd imageRepository set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.Etcd{ Image: &v1alpha1.Image{ Repository: "my-registry.io/my-org/my-repo", }, }, - variablePath..., + VariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -89,17 +91,17 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "etcd imageTag set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.Etcd{ Image: &v1alpha1.Image{ Tag: "v3.5.99_custom.0", }, }, - variablePath..., + VariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -118,5 +120,13 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) diff --git a/pkg/handlers/generic/mutation/extraapiservercertsans/tests/generate_patches.go b/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go similarity index 60% rename from pkg/handlers/generic/mutation/extraapiservercertsans/tests/generate_patches.go rename to pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go index d70beb7ad..3c4cb3745 100644 --- a/pkg/handlers/generic/mutation/extraapiservercertsans/tests/generate_patches.go +++ b/pkg/handlers/generic/mutation/extraapiservercertsans/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package extraapiservercertsans import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,29 +14,30 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestExtraAPIServerCertSANsPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Extra API server certificate mutator suite") +} + +var _ = Describe("Generate Extra API server certificate patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "extra API server cert SANs set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.ExtraAPIServerCertSANs{"a.b.c.example.com", "d.e.f.example.com"}, - variablePath..., + VariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -51,5 +53,13 @@ func TestGeneratePatches( ), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) diff --git a/pkg/handlers/generic/mutation/httpproxy/inject_test.go b/pkg/handlers/generic/mutation/httpproxy/inject_test.go index 13f183394..0b697397c 100644 --- a/pkg/handlers/generic/mutation/httpproxy/inject_test.go +++ b/pkg/handlers/generic/mutation/httpproxy/inject_test.go @@ -9,11 +9,15 @@ import ( . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" + "k8s.io/apiserver/pkg/storage/names" capiv1 "sigs.k8s.io/cluster-api/api/v1beta1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" - httpproxy "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy/tests" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" ) @@ -201,10 +205,83 @@ var _ = Describe("Generate HTTPProxy Patches", func() { "", NewPatch(testEnv.Client)).(mutation.GeneratePatches) } - httpproxy.TestGeneratePatches( - GinkgoT(), - patchGenerator, - clusterconfig.MetaVariableName, - VariableName, - ) + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "http proxy set for KubeadmConfigTemplate generic worker", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.HTTPProxy{ + HTTP: "http://example.com", + HTTPS: "https://example.com", + AdditionalNo: []string{"no-proxy.example.com"}, + }, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + map[string]any{ + "machineDeployment": map[string]any{ + "class": names.SimpleNameGenerator.GenerateName("worker-"), + }, + }, + ), + }, + RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/systemd/system/containerd.service.d/http-proxy.conf", + ), + gomega.HaveKeyWithValue( + "path", "/etc/systemd/system/kubelet.service.d/http-proxy.conf", + ), + ), + }}, + }, + { + Name: "http proxy set for KubeadmControlPlaneTemplate", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.HTTPProxy{ + HTTP: "http://example.com", + HTTPS: "https://example.com", + AdditionalNo: []string{"no-proxy.example.com"}, + }, + VariableName, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/systemd/system/containerd.service.d/http-proxy.conf", + ), + gomega.HaveKeyWithValue( + "path", "/etc/systemd/system/kubelet.service.d/http-proxy.conf", + ), + ), + }}, + }, + } + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } }) diff --git a/pkg/handlers/generic/mutation/httpproxy/tests/generate_patches.go b/pkg/handlers/generic/mutation/httpproxy/tests/generate_patches.go deleted file mode 100644 index 302cc96d3..000000000 --- a/pkg/handlers/generic/mutation/httpproxy/tests/generate_patches.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package tests - -import ( - . "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" - "k8s.io/apiserver/pkg/storage/names" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" -) - -func TestGeneratePatches( - t GinkgoTInterface, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "http proxy set for KubeadmConfigTemplate generic worker", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.HTTPProxy{ - HTTP: "http://example.com", - HTTPS: "https://example.com", - AdditionalNo: []string{"no-proxy.example.com"}, - }, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - map[string]any{ - "machineDeployment": map[string]any{ - "class": names.SimpleNameGenerator.GenerateName("worker-"), - }, - }, - ), - }, - RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/systemd/system/containerd.service.d/http-proxy.conf", - ), - gomega.HaveKeyWithValue( - "path", "/etc/systemd/system/kubelet.service.d/http-proxy.conf", - ), - ), - }}, - }, - capitest.PatchTestDef{ - Name: "http proxy set for KubeadmControlPlaneTemplate", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.HTTPProxy{ - HTTP: "http://example.com", - HTTPS: "https://example.com", - AdditionalNo: []string{"no-proxy.example.com"}, - }, - variablePath..., - ), - }, - RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/systemd/system/containerd.service.d/http-proxy.conf", - ), - gomega.HaveKeyWithValue( - "path", "/etc/systemd/system/kubelet.service.d/http-proxy.conf", - ), - ), - }}, - }, - ) -} diff --git a/pkg/handlers/generic/mutation/imageregistries/credentials/inject_test.go b/pkg/handlers/generic/mutation/imageregistries/credentials/inject_test.go index e51af2b70..76498969e 100644 --- a/pkg/handlers/generic/mutation/imageregistries/credentials/inject_test.go +++ b/pkg/handlers/generic/mutation/imageregistries/credentials/inject_test.go @@ -6,7 +6,26 @@ package credentials import ( "testing" + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apiserver/pkg/storage/names" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" +) + +const ( + validSecretName = "myregistry-credentials" + registryStaticCredentialsSecretSuffix = "registry-creds" ) func Test_needImageRegistryCredentialsConfiguration(t *testing.T) { @@ -100,3 +119,330 @@ func Test_needImageRegistryCredentialsConfiguration(t *testing.T) { }) } } + +func TestImageRegistriesPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Image registry mutator suite") +} + +var _ = Describe("Generate Image registry patches", func() { + patchGenerator := func() mutation.GeneratePatches { + // Always initialize the testEnv variable in the closure. + // This will allow ginkgo to initialize testEnv variable during test execution time. + testEnv := helpers.TestEnv + // use direct client instead of controller client. This will allow the patch handler to read k8s object + // that are written by the tests. + // Test cases writes credentials secret that the mutator handler reads. + // Using direct client will enable reading it immediately. + client, err := testEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + return mutation.NewMetaGeneratePatchesHandler("", NewPatch(client)).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "files added in KubeadmControlPlaneTemplate for ECR without a Secret", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ImageRegistries{ + v1alpha1.ImageRegistry{ + URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", + }, + }, + imageregistries.VariableName, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/cre/install-kubelet-credential-providers.sh", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/image-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", + ), + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/preKubeadmCommands", + ValueMatcher: gomega.ContainElement( + "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/initConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-bin-dir", + "/etc/kubernetes/image-credential-provider/", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/joinConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-config", + "/etc/kubernetes/image-credential-provider-config.yaml", + ), + }, + }, + }, + { + Name: "files added in KubeadmControlPlaneTemplate for registry with a Secret", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ImageRegistries{ + v1alpha1.ImageRegistry{ + URL: "https://registry.example.com", + Credentials: &v1alpha1.RegistryCredentials{ + SecretRef: &corev1.LocalObjectReference{ + Name: validSecretName, + }, + }, + }, + }, + imageregistries.VariableName, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequest( + "", + "test-kubeadmconfigtemplate", + ), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/cre/install-kubelet-credential-providers.sh", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/image-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/static-image-credentials.json", + ), + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/preKubeadmCommands", + ValueMatcher: gomega.ContainElement( + "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/initConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-bin-dir", + "/etc/kubernetes/image-credential-provider/", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/joinConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-config", + "/etc/kubernetes/image-credential-provider-config.yaml", + ), + }, + }, + }, + { + Name: "files added in KubeadmConfigTemplate for ECR without a Secret", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ImageRegistries{ + v1alpha1.ImageRegistry{ + URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", + }, + }, + imageregistries.VariableName, + ), + capitest.VariableWithValue( + "builtin", + map[string]any{ + "machineDeployment": map[string]any{ + "class": names.SimpleNameGenerator.GenerateName("worker-"), + }, + }, + ), + }, + RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/cre/install-kubelet-credential-providers.sh", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/image-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", + ), + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/preKubeadmCommands", + ValueMatcher: gomega.ContainElement( + "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/joinConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-bin-dir", + "/etc/kubernetes/image-credential-provider/", + ), + }, + }, + }, + { + Name: "files added in KubeadmConfigTemplate for registry with a Secret", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ImageRegistries{ + v1alpha1.ImageRegistry{ + URL: "https://registry.example.com", + Credentials: &v1alpha1.RegistryCredentials{ + SecretRef: &corev1.LocalObjectReference{ + Name: validSecretName, + }, + }, + }, + }, + imageregistries.VariableName, + ), + capitest.VariableWithValue( + "builtin", + map[string]any{ + "machineDeployment": map[string]any{ + "class": names.SimpleNameGenerator.GenerateName("worker-"), + }, + }, + ), + }, + RequestItem: request.NewKubeadmConfigTemplateRequest("", "test-kubeadmconfigtemplate"), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ + { + Operation: "add", + Path: "/spec/template/spec/files", + ValueMatcher: gomega.ContainElements( + gomega.HaveKeyWithValue( + "path", "/etc/cre/install-kubelet-credential-providers.sh", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/image-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", + ), + gomega.HaveKeyWithValue( + "path", "/etc/kubernetes/static-image-credentials.json", + ), + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/preKubeadmCommands", + ValueMatcher: gomega.ContainElement( + "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", + ), + }, + { + Operation: "add", + Path: "/spec/template/spec/joinConfiguration/nodeRegistration/kubeletExtraArgs", + ValueMatcher: gomega.HaveKeyWithValue( + "image-credential-provider-bin-dir", + "/etc/kubernetes/image-credential-provider/", + ), + }, + }, + }, + { + Name: "error for a registry with no credentials", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + v1alpha1.ImageRegistries{ + v1alpha1.ImageRegistry{ + URL: "https://registry.example.com", + }, + }, + imageregistries.VariableName, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), + ExpectedFailure: true, + }, + } + + // Create credentials secret before each test + BeforeEach(func(ctx SpecContext) { + client, err := helpers.TestEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(client.Create( + ctx, + newRegistryCredentialsSecret(validSecretName, request.Namespace), + )).To(gomega.BeNil()) + }) + + // Delete credentials secret after each test + AfterEach(func(ctx SpecContext) { + client, err := helpers.TestEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(client.Delete( + ctx, + newRegistryCredentialsSecret(validSecretName, request.Namespace), + )).To(gomega.BeNil()) + }) + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) + +func newRegistryCredentialsSecret(name, namespace string) *corev1.Secret { + secretData := map[string][]byte{ + "username": []byte("myuser"), + "password": []byte("mypassword"), + } + return &corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Secret", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: secretData, + Type: corev1.SecretTypeOpaque, + } +} diff --git a/pkg/handlers/generic/mutation/imageregistries/credentials/tests/generate_patches.go b/pkg/handlers/generic/mutation/imageregistries/credentials/tests/generate_patches.go deleted file mode 100644 index 05b797312..000000000 --- a/pkg/handlers/generic/mutation/imageregistries/credentials/tests/generate_patches.go +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package tests - -import ( - "context" - "testing" - - "github.com/onsi/gomega" - "github.com/stretchr/testify/require" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apiserver/pkg/storage/names" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" -) - -const ( - validSecretName = "myregistry-credentials" - registryStaticCredentialsSecretSuffix = "registry-creds" -) - -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - fakeClient client.Client, - variableName string, - variablePath ...string, -) { - t.Helper() - - require.NoError( - t, - fakeClient.Create( - context.Background(), - newRegistryCredentialsSecret(validSecretName, request.Namespace), - ), - ) - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "files added in KubeadmControlPlaneTemplate for ECR without a Secret", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.ImageRegistries{ - v1alpha1.ImageRegistry{ - URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", - }, - }, - variablePath..., - ), - }, - RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/cre/install-kubelet-credential-providers.sh", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/image-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", - ), - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/preKubeadmCommands", - ValueMatcher: gomega.ContainElement( - "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/initConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-bin-dir", - "/etc/kubernetes/image-credential-provider/", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/joinConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-config", - "/etc/kubernetes/image-credential-provider-config.yaml", - ), - }, - }, - }, - capitest.PatchTestDef{ - Name: "files added in KubeadmControlPlaneTemplate for registry with a Secret", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.ImageRegistries{ - v1alpha1.ImageRegistry{ - URL: "https://registry.example.com", - Credentials: &v1alpha1.RegistryCredentials{ - SecretRef: &corev1.LocalObjectReference{ - Name: validSecretName, - }, - }, - }, - }, - variablePath..., - ), - }, - RequestItem: request.NewKubeadmControlPlaneTemplateRequest( - "", - "test-kubeadmconfigtemplate", - ), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/cre/install-kubelet-credential-providers.sh", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/image-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/static-image-credentials.json", - ), - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/preKubeadmCommands", - ValueMatcher: gomega.ContainElement( - "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/initConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-bin-dir", - "/etc/kubernetes/image-credential-provider/", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/joinConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-config", - "/etc/kubernetes/image-credential-provider-config.yaml", - ), - }, - }, - }, - capitest.PatchTestDef{ - Name: "files added in KubeadmConfigTemplate for ECR without a Secret", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.ImageRegistries{ - v1alpha1.ImageRegistry{ - URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", - }, - }, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - map[string]any{ - "machineDeployment": map[string]any{ - "class": names.SimpleNameGenerator.GenerateName("worker-"), - }, - }, - ), - }, - RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/cre/install-kubelet-credential-providers.sh", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/image-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", - ), - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/preKubeadmCommands", - ValueMatcher: gomega.ContainElement( - "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/joinConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-bin-dir", - "/etc/kubernetes/image-credential-provider/", - ), - }, - }, - }, - capitest.PatchTestDef{ - Name: "files added in KubeadmConfigTemplate for registry with a Secret", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.ImageRegistries{ - v1alpha1.ImageRegistry{ - URL: "https://registry.example.com", - Credentials: &v1alpha1.RegistryCredentials{ - SecretRef: &corev1.LocalObjectReference{ - Name: validSecretName, - }, - }, - }, - }, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - map[string]any{ - "machineDeployment": map[string]any{ - "class": names.SimpleNameGenerator.GenerateName("worker-"), - }, - }, - ), - }, - RequestItem: request.NewKubeadmConfigTemplateRequest("", "test-kubeadmconfigtemplate"), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{ - { - Operation: "add", - Path: "/spec/template/spec/files", - ValueMatcher: gomega.ContainElements( - gomega.HaveKeyWithValue( - "path", "/etc/cre/install-kubelet-credential-providers.sh", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/image-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/dynamic-credential-provider-config.yaml", - ), - gomega.HaveKeyWithValue( - "path", "/etc/kubernetes/static-image-credentials.json", - ), - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/preKubeadmCommands", - ValueMatcher: gomega.ContainElement( - "/bin/bash /etc/cre/install-kubelet-credential-providers.sh", - ), - }, - { - Operation: "add", - Path: "/spec/template/spec/joinConfiguration/nodeRegistration/kubeletExtraArgs", - ValueMatcher: gomega.HaveKeyWithValue( - "image-credential-provider-bin-dir", - "/etc/kubernetes/image-credential-provider/", - ), - }, - }, - }, - capitest.PatchTestDef{ - Name: "error for a registry with no credentials", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - v1alpha1.ImageRegistries{ - v1alpha1.ImageRegistry{ - URL: "https://registry.example.com", - }, - }, - variablePath..., - ), - }, - RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), - ExpectedFailure: true, - }, - ) -} - -func newRegistryCredentialsSecret(name, namespace string) *corev1.Secret { - secretData := map[string][]byte{ - "username": []byte("myuser"), - "password": []byte("mypassword"), - } - return &corev1.Secret{ - TypeMeta: metav1.TypeMeta{ - APIVersion: "v1", - Kind: "Secret", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Data: secretData, - Type: corev1.SecretTypeOpaque, - } -} diff --git a/pkg/handlers/generic/mutation/kubernetesimagerepository/tests/generate_patches.go b/pkg/handlers/generic/mutation/kubernetesimagerepository/inject_test.go similarity index 58% rename from pkg/handlers/generic/mutation/kubernetesimagerepository/tests/generate_patches.go rename to pkg/handlers/generic/mutation/kubernetesimagerepository/inject_test.go index eefe534c2..e29d47aa7 100644 --- a/pkg/handlers/generic/mutation/kubernetesimagerepository/tests/generate_patches.go +++ b/pkg/handlers/generic/mutation/kubernetesimagerepository/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package kubernetesimagerepository import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,29 +14,30 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestKubernetesImageRepositoryPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Kubernetes Image Repository mutator suite") +} + +var _ = Describe("Generate Kubernetes Image Repository patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "kubernetesImageRepository set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.KubernetesImageRepository("my-registry.io/my-org/my-repo"), - variablePath..., + VariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -48,5 +50,13 @@ func TestGeneratePatches( ), }}, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) diff --git a/pkg/handlers/generic/mutation/mirrors/tests/generate_patches.go b/pkg/handlers/generic/mutation/mirrors/inject_test.go similarity index 76% rename from pkg/handlers/generic/mutation/mirrors/tests/generate_patches.go rename to pkg/handlers/generic/mutation/mirrors/inject_test.go index dd3a040a2..3e7c9106d 100644 --- a/pkg/handlers/generic/mutation/mirrors/tests/generate_patches.go +++ b/pkg/handlers/generic/mutation/mirrors/inject_test.go @@ -1,24 +1,24 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package mirrors import ( - "context" "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apiserver/pkg/storage/names" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - "sigs.k8s.io/controller-runtime/pkg/client" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" ) const ( @@ -29,35 +29,35 @@ const ( workerRegistryAsMirrorCreds = "kubeadmConfigTemplateRegistryAsMirrorCreds" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - fakeClient client.Client, - variableName string, - variablePath ...string, -) { - t.Helper() +func TestMirrorsPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Global mirror mutator suite") +} - require.NoError( - t, - fakeClient.Create( - context.Background(), - newMirrorSecret(validMirrorCASecretName, request.Namespace), - ), - ) +var _ = Describe("Generate Global mirror patches", func() { + patchGenerator := func() mutation.GeneratePatches { + // Always initialize the testEnv variable in the closure. + // This will allow ginkgo to initialize testEnv variable during test execution time. + testEnv := helpers.TestEnv + // use direct client instead of controller client. This will allow the patch handler to read k8s object + // that are written by the tests. + // Test cases writes credentials secret that the mutator handler reads. + // Using direct client will enable reading it immediately. + client, err := testEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + return mutation.NewMetaGeneratePatchesHandler("", NewPatch(client)).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "files added in KubeadmControlPlaneTemplate for registry with mirror without CA Certificate", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.GlobalImageRegistryMirror{ URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", }, - variablePath..., + GlobalMirrorVariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -90,11 +90,11 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "files added in KubeadmControlPlaneTemplate for registry with mirror with CA Certificate", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.GlobalImageRegistryMirror{ URL: "https://registry.example.com", Credentials: &v1alpha1.RegistryCredentials{ @@ -103,7 +103,7 @@ func TestGeneratePatches( }, }, }, - variablePath..., + GlobalMirrorVariableName, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequest("", cpRegistryAsMirrorCreds), @@ -139,15 +139,15 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "files added in KubeadmConfigTemplate for registry mirror wihthout CA certificate", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.GlobalImageRegistryMirror{ URL: "https://123456789.dkr.ecr.us-east-1.amazonaws.com", }, - variablePath..., + GlobalMirrorVariableName, ), capitest.VariableWithValue( "builtin", @@ -188,11 +188,11 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "files added in KubeadmConfigTemplate for registry mirror with secret for CA certificate", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.GlobalImageRegistryMirror{ URL: "https://registry.example.com", Credentials: &v1alpha1.RegistryCredentials{ @@ -201,7 +201,7 @@ func TestGeneratePatches( }, }, }, - variablePath..., + GlobalMirrorVariableName, ), capitest.VariableWithValue( "builtin", @@ -245,8 +245,36 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // Create credentials secret before each test + BeforeEach(func(ctx SpecContext) { + client, err := helpers.TestEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(client.Create( + ctx, + newMirrorSecret(validMirrorCASecretName, request.Namespace), + )).To(gomega.BeNil()) + }) + + // Delete credentials secret after each test + AfterEach(func(ctx SpecContext) { + client, err := helpers.TestEnv.GetK8sClient() + gomega.Expect(err).To(gomega.BeNil()) + gomega.Expect(client.Delete( + ctx, + newMirrorSecret(validMirrorCASecretName, request.Namespace), + )).To(gomega.BeNil()) + }) + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) func newMirrorSecret(name, namespace string) *corev1.Secret { secretData := map[string][]byte{ diff --git a/pkg/handlers/generic/mutation/users/inject_test.go b/pkg/handlers/generic/mutation/users/inject_test.go index 22eb1c812..924321800 100644 --- a/pkg/handlers/generic/mutation/users/inject_test.go +++ b/pkg/handlers/generic/mutation/users/inject_test.go @@ -7,10 +7,18 @@ import ( "testing" "github.com/google/go-cmp/cmp" + . "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" + "k8s.io/apiserver/pkg/storage/names" "k8s.io/utils/ptr" bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" ) func Test_generateBootstrapUser(t *testing.T) { @@ -114,3 +122,83 @@ func Test_generateBootstrapUser(t *testing.T) { }) } } + +var ( + testUser1 = v1alpha1.User{ + Name: "complete", + HashedPassword: "password", + SSHAuthorizedKeys: []string{ + "key1", + "key2", + }, + Sudo: "ALL=(ALL) NOPASSWD:ALL", + } + testUser2 = v1alpha1.User{ + Name: "onlyname", + } +) + +func TestUsersPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Users mutator suite") +} + +var _ = Describe("Generate Users patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "users set for KubeadmControlPlaneTemplate", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + []v1alpha1.User{testUser1, testUser2}, + VariableName, + ), + }, + RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/kubeadmConfigSpec/users", + ValueMatcher: gomega.HaveLen(2), + }}, + }, + { + Name: "users set for KubeadmConfigTemplate generic worker", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + clusterconfig.MetaVariableName, + []v1alpha1.User{testUser1, testUser2}, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + map[string]any{ + "machineDeployment": map[string]any{ + "class": names.SimpleNameGenerator.GenerateName("worker-"), + }, + }, + ), + }, + RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), + ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ + Operation: "add", + Path: "/spec/template/spec/users", + ValueMatcher: gomega.HaveLen(2), + }}, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches(GinkgoT(), patchGenerator, &tt) + }) + } +}) diff --git a/pkg/handlers/generic/mutation/users/tests/generate_patches.go b/pkg/handlers/generic/mutation/users/tests/generate_patches.go deleted file mode 100644 index 2eff072f5..000000000 --- a/pkg/handlers/generic/mutation/users/tests/generate_patches.go +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2023 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package tests - -import ( - "testing" - - "github.com/onsi/gomega" - "k8s.io/apiserver/pkg/storage/names" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/api/v1alpha1" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" -) - -var ( - testUser1 = v1alpha1.User{ - Name: "complete", - HashedPassword: "password", - SSHAuthorizedKeys: []string{ - "key1", - "key2", - }, - Sudo: "ALL=(ALL) NOPASSWD:ALL", - } - testUser2 = v1alpha1.User{ - Name: "onlyname", - } -) - -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "users set for KubeadmControlPlaneTemplate", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - []v1alpha1.User{testUser1, testUser2}, - variablePath..., - ), - }, - RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/kubeadmConfigSpec/users", - ValueMatcher: gomega.HaveLen(2), - }}, - }, - ) - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "users set for KubeadmConfigTemplate generic worker", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - []v1alpha1.User{testUser1, testUser2}, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - map[string]any{ - "machineDeployment": map[string]any{ - "class": names.SimpleNameGenerator.GenerateName("worker-"), - }, - }, - ), - }, - RequestItem: request.NewKubeadmConfigTemplateRequestItem(""), - ExpectedPatchMatchers: []capitest.JSONPatchMatcher{{ - Operation: "add", - Path: "/spec/template/spec/users", - ValueMatcher: gomega.HaveLen(2), - }}, - }, - ) -} diff --git a/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go similarity index 56% rename from pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go index 8a93eb8f5..6ae946e79 100644 --- a/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/controlplaneendpoint/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package controlplaneendpoint import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -13,32 +14,35 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestControlPlaneEndpointPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix ControlPlane endpoint suite") +} + +var _ = Describe("Generate Nutanix ControlPlane endpoint patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "ControlPlaneEndpoint set to valid host and port", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, clusterv1.APIEndpoint{ Host: "10.20.100.10", Port: 6443, }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -55,5 +59,17 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go similarity index 72% rename from pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go index 9e38b6214..3d05ef071 100644 --- a/pkg/handlers/nutanix/mutation/machinedetails/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_control_plane_test.go @@ -1,13 +1,11 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package machinedetails import ( - "testing" - + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/utils/ptr" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" @@ -17,6 +15,8 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) var ( @@ -96,66 +96,40 @@ var ( } ) -func TestControlPlaneGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() +var _ = Describe("Generate Nutanix Machine Details patches for ControlPlane", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewControlPlanePatch()).(mutation.GeneratePatches) + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "all fields set for control-plane", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, variableWithAllFieldsSet, - variablePath..., + clusterconfig.MetaControlPlaneConfigName, + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewCPNutanixMachineTemplateRequestItem(""), ExpectedPatchMatchers: matchersForAllFieldsSet, }, - ) -} - -func TestWorkerGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() + } - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ - Name: "unset variable", - }, - capitest.PatchTestDef{ - Name: "all fields set for workers", - Vars: []runtimehooksv1.Variable{ - capitest.VariableWithValue( - variableName, - variableWithAllFieldsSet, - variablePath..., - ), - capitest.VariableWithValue( - "builtin", - apiextensionsv1.JSON{ - Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), - }, - ), - }, - RequestItem: request.NewWorkerNutanixMachineTemplateRequestItem(""), - ExpectedPatchMatchers: matchersForAllFieldsSet, - }, - ) -} + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go new file mode 100644 index 000000000..0bc40008e --- /dev/null +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_suite_test.go @@ -0,0 +1,16 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package machinedetails + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestMachineDetailsPatch(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix Machine Details patches for ControlPlane and Workers suite") +} diff --git a/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go b/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go new file mode 100644 index 000000000..9481bf960 --- /dev/null +++ b/pkg/handlers/nutanix/mutation/machinedetails/inject_worker_test.go @@ -0,0 +1,59 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package machinedetails + +import ( + . "github.com/onsi/ginkgo/v2" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" +) + +var _ = Describe("Generate Nutanix Machine Details patches for Worker", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewWorkerPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { + Name: "unset variable", + }, + { + Name: "all fields set for workers", + Vars: []runtimehooksv1.Variable{ + capitest.VariableWithValue( + workerconfig.MetaVariableName, + variableWithAllFieldsSet, + nutanixclusterconfig.NutanixVariableName, + VariableName, + ), + capitest.VariableWithValue( + "builtin", + apiextensionsv1.JSON{ + Raw: []byte(`{"machineDeployment": {"class": "a-worker"}}`), + }, + ), + }, + RequestItem: request.NewWorkerNutanixMachineTemplateRequestItem(""), + ExpectedPatchMatchers: matchersForAllFieldsSet, + }, + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/metapatch_handler_test.go b/pkg/handlers/nutanix/mutation/metapatch_handler_test.go deleted file mode 100644 index 4216bc2cb..000000000 --- a/pkg/handlers/nutanix/mutation/metapatch_handler_test.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2024 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "testing" - - "sigs.k8s.io/controller-runtime/pkg/manager" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" - auditpolicytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/auditpolicy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd" - etcdtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/etcd/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans" - extraapiservercertsanstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/extraapiservercertsans/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy" - httpproxytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/httpproxy/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries" - imageregistrycredentialstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/imageregistries/credentials/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository" - kubernetesimagerepositorytests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/kubernetesimagerepository/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors" - globalimageregistrymirrortests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/mutation/mirrors/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/workerconfig" - nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/controlplaneendpoint" - controlplaneendpointtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/controlplaneendpoint/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/machinedetails" - machinedetailstests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/machinedetails/tests" - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/prismcentralendpoint" - prismcentralendpointtests "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests" -) - -func metaPatchGeneratorFunc(mgr manager.Manager) func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaPatchHandler(mgr).(mutation.GeneratePatches) - } -} - -func workerPatchGeneratorFunc() func() mutation.GeneratePatches { - return func() mutation.GeneratePatches { - return MetaWorkerPatchHandler().(mutation.GeneratePatches) - } -} - -func TestGeneratePatches(t *testing.T) { - t.Parallel() - - mgr := testEnv.Manager - - controlplaneendpointtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - controlplaneendpoint.VariableName, - ) - - prismcentralendpointtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - prismcentralendpoint.VariableName, - ) - - machinedetailstests.TestControlPlaneGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - clusterconfig.MetaControlPlaneConfigName, - nutanixclusterconfig.NutanixVariableName, - machinedetails.VariableName, - ) - - machinedetailstests.TestWorkerGeneratePatches( - t, - workerPatchGeneratorFunc(), - workerconfig.MetaVariableName, - nutanixclusterconfig.NutanixVariableName, - machinedetails.VariableName, - ) - - auditpolicytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - ) - - httpproxytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - httpproxy.VariableName, - ) - - etcdtests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - etcd.VariableName, - ) - - extraapiservercertsanstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - extraapiservercertsans.VariableName, - ) - - kubernetesimagerepositorytests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - clusterconfig.MetaVariableName, - kubernetesimagerepository.VariableName, - ) - - imageregistrycredentialstests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - imageregistries.VariableName, - ) - - globalimageregistrymirrortests.TestGeneratePatches( - t, - metaPatchGeneratorFunc(mgr), - mgr.GetClient(), - clusterconfig.MetaVariableName, - mirrors.GlobalMirrorVariableName, - ) -} diff --git a/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go b/pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go similarity index 80% rename from pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go rename to pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go index 0b9003fc1..83d9f431e 100644 --- a/pkg/handlers/nutanix/mutation/prismcentralendpoint/tests/generate_patches.go +++ b/pkg/handlers/nutanix/mutation/prismcentralendpoint/inject_test.go @@ -1,11 +1,12 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package tests +package prismcentralendpoint import ( "testing" + . "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" "k8s.io/utils/ptr" @@ -15,30 +16,33 @@ import ( "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/mutation" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest" "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/common/pkg/testutils/capitest/request" + "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/clusterconfig" + nutanixclusterconfig "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/pkg/handlers/nutanix/clusterconfig" ) // //nolint:lll // just a long string const testCertBundle = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVjekNDQTF1Z0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRUUZBRC4uQWtHQTFVRUJoTUNSMEl4CkV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGREFTQmdOVkJBb1RDMC4uMEVnVEhSa01UY3dOUVlEClZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbWx0WVhKNUlFTmxjbi4uWFJwYjI0Z1FYVjBhRzl5CmFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRXgwWkRBZUZ3MHdNRC4uVFV3TVRaYUZ3MHdNVEF5Ck1EUXhPVFV3TVRaYU1JR0hNUXN3Q1FZRFZRUUdFd0pIUWpFVE1CRUdBMS4uMjl0WlMxVGRHRjBaVEVVCk1CSUdBMVVFQ2hNTFFtVnpkQ0JEUVNCTWRHUXhOekExQmdOVkJBc1RMay4uREVnVUhWaWJHbGpJRkJ5CmFXMWhjbmtnUTJWeWRHbG1hV05oZEdsdmJpQkJkWFJvYjNKcGRIa3hGRC4uQU1UQzBKbGMzUWdRMEVnClRIUmtNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZy4uVHoybXI3U1ppQU1mUXl1CnZCak05T2lKalJhelhCWjFCalA1Q0UvV20vUnI1MDBQUksrTGg5eDVlSi4uL0FOQkUwc1RLMFpzREdNCmFrMm0xZzdvcnVJM2RZM1ZIcUl4RlR6MFRhMWQrTkFqd25MZTRuT2I3Ly4uazA1U2hoQnJKR0JLS3hiCjhuMTA0by81cDhIQXNaUGR6YkZNSXlOakp6Qk0ybzV5NUExM3dpTGl0RS4uZnlZa1F6YXhDdzBBd3psCmtWSGlJeUN1YUY0d2o1NzFwU3prdjZzdis0SURNYlQvWHBDbzhMNndUYS4uc2grZXRMRDZGdFRqWWJiCnJ2WjhSUU0xdGxLZG9NSGcycXhyYUFWKytITkJZbU5XczBkdUVkalViSi4uWEk5VHRuUzRvMUNrajdQCk9mbGppUUlEQVFBQm80SG5NSUhrTUIwR0ExVWREZ1FXQkJROHVyTUNSTC4uNUFrSXA5TkpISnc1VENCCnRBWURWUjBqQklHc01JR3BnQlE4dXJNQ1JMWVlNSFVLVTVBa0lwOU5KSC4uYVNCaWpDQmh6RUxNQWtHCkExVUVCaE1DUjBJeEV6QVJCZ05WQkFnVENsTnZiV1V0VTNSaGRHVXhGRC4uQW9UQzBKbGMzUWdRMEVnClRIUmtNVGN3TlFZRFZRUUxFeTVEYkdGemN5QXhJRkIxWW14cFl5QlFjbS4uRU5sY25ScFptbGpZWFJwCmIyNGdRWFYwYUc5eWFYUjVNUlF3RWdZRFZRUURFd3RDWlhOMElFTkJJRS4uREFNQmdOVkhSTUVCVEFECkFRSC9NQTBHQ1NxR1NJYjNEUUVCQkFVQUE0SUJBUUMxdVlCY3NTbmN3QS4uRENzUWVyNzcyQzJ1Y3BYCnhRVUUvQzBwV1dtNmdEa3dkNUQwRFNNREpScVYvd2VvWjR3QzZCNzNmNS4uYkxoR1lIYVhKZVNENktyClhjb093TGRTYUdtSllzbExLWkIzWklERXAwd1lUR2hndGViNkpGaVR0bi4uc2YyeGRyWWZQQ2lJQjdnCkJNQVY3R3pkYzRWc3BTNmxqckFoYmlpYXdkQmlRbFFtc0JlRno5SmtGNC4uYjNsOEJvR04rcU1hNTZZCkl0OHVuYTJnWTRsMk8vL29uODhyNUlXSmxtMUwwb0E4ZTRmUjJ5ckJIWC4uYWRzR2VGS2t5TnJ3R2kvCjd2UU1mWGRHc1JyWE5HUkduWCt2V0RaMy96V0kwam9EdENrTm5xRXBWbi4uSG9YCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=" -func TestGeneratePatches( - t *testing.T, - generatorFunc func() mutation.GeneratePatches, - variableName string, - variablePath ...string, -) { - t.Helper() - capitest.ValidateGeneratePatches( - t, - generatorFunc, - capitest.PatchTestDef{ +func TestPrismCentralEndpointPatch(t *testing.T) { + gomega.RegisterFailHandler(Fail) + RunSpecs(t, "Nutanix Prism Central Endpoint mutator suite") +} + +var _ = Describe("Generate Nutanix Prism Central Endpoint patches", func() { + patchGenerator := func() mutation.GeneratePatches { + return mutation.NewMetaGeneratePatchesHandler("", NewPatch()).(mutation.GeneratePatches) + } + + testDefs := []capitest.PatchTestDef{ + { Name: "unset variable", }, - capitest.PatchTestDef{ + { Name: "all required fields set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.NutanixPrismCentralEndpointSpec{ Host: "prism-central.nutanix.com", Port: 9441, @@ -47,7 +51,8 @@ func TestGeneratePatches( Name: "credentials", }, }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -68,11 +73,11 @@ func TestGeneratePatches( }, }, }, - capitest.PatchTestDef{ + { Name: "additional trust bundle is set", Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( - variableName, + clusterconfig.MetaVariableName, v1alpha1.NutanixPrismCentralEndpointSpec{ Host: "prism-central.nutanix.com", Port: 9441, @@ -82,7 +87,8 @@ func TestGeneratePatches( }, AdditionalTrustBundle: ptr.To(testCertBundle), }, - variablePath..., + nutanixclusterconfig.NutanixVariableName, + VariableName, ), }, RequestItem: request.NewNutanixClusterTemplateRequestItem(""), @@ -104,5 +110,17 @@ func TestGeneratePatches( }, }, }, - ) -} + } + + // create test node for each case + for testIdx := range testDefs { + tt := testDefs[testIdx] + It(tt.Name, func() { + capitest.AssertGeneratePatches( + GinkgoT(), + patchGenerator, + &tt, + ) + }) + } +}) diff --git a/pkg/handlers/nutanix/mutation/suite_test.go b/pkg/handlers/nutanix/mutation/suite_test.go deleted file mode 100644 index 5188c91c7..000000000 --- a/pkg/handlers/nutanix/mutation/suite_test.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 D2iQ, Inc. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package mutation - -import ( - "context" - "fmt" - "testing" - - ctrl "sigs.k8s.io/controller-runtime" - - "github.com/d2iq-labs/cluster-api-runtime-extensions-nutanix/test/helpers" -) - -var ( - testEnv *helpers.TestEnvironment - ctx = ctrl.SetupSignalHandler() -) - -func TestMain(m *testing.M) { - setupCtx, cancel := context.WithCancel(ctx) - setup(setupCtx) - defer teardown(cancel) - m.Run() -} - -func setup(ctx context.Context) { - testEnvConfig := helpers.NewTestEnvironmentConfiguration() - var err error - testEnv, err = testEnvConfig.Build() - if err != nil { - panic(err) - } - go func() { - fmt.Println("Starting the manager") - if err := testEnv.StartManager(ctx); err != nil { - panic(fmt.Sprintf("Failed to start the envtest manager: %v", err)) - } - }() -} - -func teardown(cancel context.CancelFunc) { - cancel() - if err := testEnv.Stop(); err != nil { - panic(fmt.Sprintf("Failed to stop envtest: %v", err)) - } -} diff --git a/test/helpers/environment.go b/test/helpers/environment.go index 9d0e48263..a8a69cd38 100644 --- a/test/helpers/environment.go +++ b/test/helpers/environment.go @@ -9,27 +9,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "k8s.io/klog/v2" - "k8s.io/klog/v2/textlogger" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/log" ) var TestEnv *TestEnvironment // Initialize the test environment. BeforeSuite will be only executed if this package is loaded by the test. var _ = BeforeSuite(func(ctx SpecContext) { - By("Initialize loggers for testing") - // Uninitialized logger spits stacktrace as warning during test execution - logger := textlogger.NewLogger(textlogger.NewConfig()) - // use klog as the internal logger for this envtest environment. - log.SetLogger(logger) - // additionally force all of the controllers to use the Ginkgo logger. - ctrl.SetLogger(logger) - klog.InitFlags(nil) - // add logger for ginkgo - klog.SetOutput(GinkgoWriter) - By("Starting test environment") testEnvConfig := NewTestEnvironmentConfiguration() var err error diff --git a/test/helpers/envtest.go b/test/helpers/envtest.go index 190b8f009..9801cf740 100644 --- a/test/helpers/envtest.go +++ b/test/helpers/envtest.go @@ -130,6 +130,13 @@ func (t *TestEnvironmentConfiguration) Build() (*TestEnvironment, error) { }, nil } +// GetK8sClient returns a “live” k8s client that does will not invoke against controller cache. +// If a test is writeing an object, they are not immediately available to read since controller caches +// are not synchronized yet. +func (t *TestEnvironment) GetK8sClient() (client.Client, error) { + return client.New(t.Manager.GetConfig(), client.Options{Scheme: scheme.Scheme}) +} + // StartManager starts the test controller against the local API server. func (t *TestEnvironment) StartManager(ctx context.Context) error { return t.Manager.Start(ctx)