diff --git a/api/v1/runtime_types.go b/api/v1/runtime_types.go index 1e6af618..39137abf 100644 --- a/api/v1/runtime_types.go +++ b/api/v1/runtime_types.go @@ -139,17 +139,17 @@ type RuntimeStatus struct { } type RuntimeShoot struct { - Name string `json:"name"` - Purpose gardener.ShootPurpose `json:"purpose"` - PlatformRegion string `json:"platformRegion"` - Region string `json:"region"` - LicenceType *string `json:"licenceType,omitempty"` - SecretBindingName string `json:"secretBindingName"` - EnforceSeedLocation *bool `json:"enforceSeedLocation,omitempty"` - Kubernetes Kubernetes `json:"kubernetes,omitempty"` - Provider Provider `json:"provider"` - Networking Networking `json:"networking"` - ControlPlane gardener.ControlPlane `json:"controlPlane"` + Name string `json:"name"` + Purpose gardener.ShootPurpose `json:"purpose"` + PlatformRegion string `json:"platformRegion"` + Region string `json:"region"` + LicenceType *string `json:"licenceType,omitempty"` + SecretBindingName string `json:"secretBindingName"` + EnforceSeedLocation *bool `json:"enforceSeedLocation,omitempty"` + Kubernetes Kubernetes `json:"kubernetes,omitempty"` + Provider Provider `json:"provider"` + Networking Networking `json:"networking"` + ControlPlane *gardener.ControlPlane `json:"controlPlane,omitempty"` } type Kubernetes struct { diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index a96109e4..9221ecb8 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -372,7 +372,11 @@ func (in *RuntimeShoot) DeepCopyInto(out *RuntimeShoot) { in.Kubernetes.DeepCopyInto(&out.Kubernetes) in.Provider.DeepCopyInto(&out.Provider) in.Networking.DeepCopyInto(&out.Networking) - in.ControlPlane.DeepCopyInto(&out.ControlPlane) + if in.ControlPlane != nil { + in, out := &in.ControlPlane, &out.ControlPlane + *out = new(v1beta1.ControlPlane) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuntimeShoot. diff --git a/config/crd/bases/infrastructuremanager.kyma-project.io_runtimes.yaml b/config/crd/bases/infrastructuremanager.kyma-project.io_runtimes.yaml index 5ca78a3b..034516ab 100644 --- a/config/crd/bases/infrastructuremanager.kyma-project.io_runtimes.yaml +++ b/config/crd/bases/infrastructuremanager.kyma-project.io_runtimes.yaml @@ -997,7 +997,6 @@ spec: secretBindingName: type: string required: - - controlPlane - name - networking - platformRegion diff --git a/hack/runtime-migrator/input/runtimeids_sample.json b/hack/runtime-migrator/input/runtimeids_sample.json index e9a0cc0d..5425693e 100644 --- a/hack/runtime-migrator/input/runtimeids_sample.json +++ b/hack/runtime-migrator/input/runtimeids_sample.json @@ -1,4 +1,3 @@ { - c65d5c9b-b321-4481-b567-d331d769ff1c, - 61e18f65-6c82-4fdd-97dc-cf51bfbbbeb2 + 7c6b4bd3-09d3-462f-b27c-992727b62eec, } diff --git a/hack/runtime-migrator/main.go b/hack/runtime-migrator/main.go index 97791825..ca5adcef 100644 --- a/hack/runtime-migrator/main.go +++ b/hack/runtime-migrator/main.go @@ -166,7 +166,6 @@ func saveRuntime(ctx context.Context, cfg migrator.Config, runtime v1.Runtime, g func createRuntime(ctx context.Context, shoot v1beta1.Shoot, cfg migrator.Config, provider kubeconfig.Provider) (v1.Runtime, error) { var subjects = getAdministratorsList(ctx, provider, shoot.Name) var oidcConfig = getOidcConfig(shoot) - var hAFailureToleranceType = getFailureToleranceType(shoot) var licenceType = shoot.Annotations["kcp.provisioner.kyma-project.io/licence-type"] labels, err := getAllRuntimeLabels(ctx, shoot, cfg.Client) if err != nil { @@ -210,17 +209,12 @@ func createRuntime(ctx context.Context, shoot v1beta1.Shoot, cfg migrator.Config Workers: shoot.Spec.Provider.Workers, }, Networking: v1.Networking{ + Type: shoot.Spec.Networking.Type, Pods: *shoot.Spec.Networking.Pods, Nodes: *shoot.Spec.Networking.Nodes, Services: *shoot.Spec.Networking.Services, }, - ControlPlane: v1beta1.ControlPlane{ - HighAvailability: &v1beta1.HighAvailability{ - FailureTolerance: v1beta1.FailureTolerance{ - Type: hAFailureToleranceType, - }, - }, - }, + ControlPlane: getControlPlane(shoot), }, Security: v1.Security{ Administrators: subjects, @@ -280,23 +274,29 @@ func getShootList(ctx context.Context, cfg migrator.Config, gardenerNamespace st return list } -func getFailureToleranceType(shoot v1beta1.Shoot) v1beta1.FailureToleranceType { +func getControlPlane(shoot v1beta1.Shoot) *v1beta1.ControlPlane { if shoot.Spec.ControlPlane != nil { if shoot.Spec.ControlPlane.HighAvailability != nil { - return shoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type + return &v1beta1.ControlPlane{HighAvailability: &v1beta1.HighAvailability{ + FailureTolerance: v1beta1.FailureTolerance{ + Type: shoot.Spec.ControlPlane.HighAvailability.FailureTolerance.Type, + }, + }, + } } } - return "" + + return nil } func getAdministratorsList(ctx context.Context, provider kubeconfig.Provider, shootName string) []string { - var kubeconfig, err = provider.Fetch(ctx, shootName) - if kubeconfig == "" { + var clusterKubeconfig, err = provider.Fetch(ctx, shootName) + if clusterKubeconfig == "" { log.Printf("Failed to get dynamic kubeconfig for shoot %s, %s\n", shootName, err.Error()) return []string{} } - restClientConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(kubeconfig)) + restClientConfig, err := clientcmd.RESTConfigFromKubeConfig([]byte(clusterKubeconfig)) if err != nil { log.Printf("Failed to create REST client from kubeconfig - %s\n", err) return []string{} @@ -311,7 +311,8 @@ func getAdministratorsList(ctx context.Context, provider kubeconfig.Provider, sh LabelSelector: "reconciler.kyma-project.io/managed-by=reconciler,app=kyma", }) - var subjects = []string{} + subjects := make([]string, 0) + for _, clusterRoleBinding := range clusterRoleBindings.Items { for _, subject := range clusterRoleBinding.Subjects { subjects = append(subjects, subject.Name) @@ -395,8 +396,14 @@ func getAllRuntimeLabels(ctx context.Context, shoot v1beta1.Shoot, getClient mig return map[string]string{}, errors.Wrap(clientErr, fmt.Sprintf("Failed to get GardenerClient for shoot %s - %s\n", shoot.Name, clientErr)) } gardenerCluster := v1.GardenerCluster{} - shootKey := types.NamespacedName{Name: shoot.Name, Namespace: "kcp-system"} - getGardenerCRerr := k8sClient.Get(ctx, shootKey, &gardenerCluster) + + kymaID, found := shoot.Annotations["kcp.provisioner.kyma-project.io/runtime-id"] + if !found { + return nil, errors.New("Runtime ID not found in shoot annotations") + } + + gardenerCRKey := types.NamespacedName{Name: kymaID, Namespace: "kcp-system"} + getGardenerCRerr := k8sClient.Get(ctx, gardenerCRKey, &gardenerCluster) if getGardenerCRerr != nil { var errMsg = fmt.Sprintf("Failed to retrieve GardenerCluster CR for shoot %s\n", shoot.Name) return map[string]string{}, errors.Wrap(getGardenerCRerr, errMsg) @@ -410,7 +417,8 @@ func getAllRuntimeLabels(ctx context.Context, shoot v1beta1.Shoot, getClient mig enrichedRuntimeLabels["kyma-project.io/region"] = gardenerCluster.Labels["kyma-project.io/region"] enrichedRuntimeLabels["kyma-project.io/shoot-name"] = gardenerCluster.Labels["kyma-project.io/shoot-name"] enrichedRuntimeLabels["operator.kyma-project.io/kyma-name"] = gardenerCluster.Labels["operator.kyma-project.io/kyma-name"] - + // The runtime CR should be controlled by the KIM + enrichedRuntimeLabels["kyma-project.io/controlled-by-provisioner"] = "false" // add custom label for the migrator enrichedRuntimeLabels[migratorLabel] = "true" diff --git a/hack/shoot-comparator/go.mod b/hack/shoot-comparator/go.mod index 2f6be242..b1374110 100644 --- a/hack/shoot-comparator/go.mod +++ b/hack/shoot-comparator/go.mod @@ -6,8 +6,11 @@ require ( github.com/gardener/gardener v1.98.0 github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 + github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 + gopkg.in/yaml.v3 v3.0.1 + k8s.io/apimachinery v0.29.6 sigs.k8s.io/yaml v1.4.0 ) @@ -31,10 +34,8 @@ require ( golang.org/x/tools v0.22.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.29.6 // indirect k8s.io/apiextensions-apiserver v0.29.6 // indirect - k8s.io/apimachinery v0.29.6 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/hack/shoot-comparator/pkg/shoot/extensionmatcher.go b/hack/shoot-comparator/pkg/shoot/extensionmatcher.go new file mode 100644 index 00000000..fa7a1179 --- /dev/null +++ b/hack/shoot-comparator/pkg/shoot/extensionmatcher.go @@ -0,0 +1,71 @@ +package shoot + +import ( + "fmt" + "github.com/gardener/gardener/pkg/apis/core/v1beta1" + "github.com/onsi/gomega" + "github.com/onsi/gomega/types" + "reflect" + "sort" + "strings" +) + +type ExtensionMatcher struct { + toMatch interface{} + fails []string +} + +func NewExtensionMatcher(i interface{}) types.GomegaMatcher { + return &ExtensionMatcher{ + toMatch: i, + } +} + +func (m *ExtensionMatcher) Match(actual interface{}) (success bool, err error) { + aExtensions, err := getExtension(actual) + if err != nil { + return false, err + } + + eExtensions, err := getExtension(m.toMatch) + if err != nil { + return false, err + } + + sort.Sort(Extensions(aExtensions)) + sort.Sort(Extensions(eExtensions)) + + return gomega.BeComparableTo(eExtensions).Match(aExtensions) +} + +func getExtension(i interface{}) ([]v1beta1.Extension, error) { + switch v := i.(type) { + case []v1beta1.Extension: + return v, nil + + default: + return []v1beta1.Extension{}, fmt.Errorf(`%w: %s`, errInvalidType, reflect.TypeOf(v)) + } +} + +type Extensions []v1beta1.Extension + +func (e Extensions) Len() int { + return len(e) +} + +func (e Extensions) Less(i, j int) bool { + return e[i].Type < e[j].Type +} + +func (e Extensions) Swap(i, j int) { + e[i], e[j] = e[j], e[i] +} + +func (m *ExtensionMatcher) NegatedFailureMessage(_ interface{}) string { + return "expected should not equal actual" +} + +func (m *ExtensionMatcher) FailureMessage(_ interface{}) string { + return strings.Join(m.fails, "\n") +} diff --git a/hack/shoot-comparator/pkg/shoot/extensionmatcher_test.go b/hack/shoot-comparator/pkg/shoot/extensionmatcher_test.go new file mode 100644 index 00000000..ed8ffb36 --- /dev/null +++ b/hack/shoot-comparator/pkg/shoot/extensionmatcher_test.go @@ -0,0 +1,106 @@ +package shoot + +import ( + "fmt" + "github.com/gardener/gardener/pkg/apis/core/v1beta1" + . "github.com/onsi/ginkgo/v2" //nolint:revive + . "github.com/onsi/gomega" //nolint:revive + "k8s.io/apimachinery/pkg/runtime" +) + +var _ = Describe(":: extension matcher :: ", func() { + emptyExt := make([]v1beta1.Extension, 0) + + DescribeTable( + "checking invalid args :: ", + testExtensionInvalidArgs, + Entry("when actual is not of Extension type", v1beta1.Shoot{}, emptyExt), + Entry("when expected is not of Extension type", emptyExt, v1beta1.Shoot{}), + Entry("when actual is nil", nil, emptyExt), + Entry("when expected is nil", emptyExt, nil), + ) + + dnsExtEnabled := getDNSExtension(false, true) + dnsExtDisabled := getDNSExtension(true, false) + networkingExtDisabled := getNetworkingExtension(true) + certificateExtEnabled := getCertificateExtension(false, true) + + DescribeTable( + "checking results :: ", + testExtensionResults, + Entry( + "should match empty values", + emptyExt, + emptyExt, + true, + ), + Entry( + "should match identical tables", + []v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled}, + []v1beta1.Extension{networkingExtDisabled, certificateExtEnabled, dnsExtEnabled}, + true, + ), + Entry( + "should detect extension differs", + []v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled}, + []v1beta1.Extension{dnsExtDisabled, networkingExtDisabled, certificateExtEnabled}, + false, + ), + Entry( + "should detect redundant extension", + []v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled}, + []v1beta1.Extension{networkingExtDisabled, certificateExtEnabled}, + false, + ), + Entry( + "should detect missing extension", + []v1beta1.Extension{networkingExtDisabled, certificateExtEnabled}, + []v1beta1.Extension{dnsExtEnabled, networkingExtDisabled, certificateExtEnabled}, + false, + ), + ) +}) + +func testExtensionInvalidArgs(actual, expected interface{}) { + matcher := NewExtensionMatcher(expected) + _, err := matcher.Match(actual) + Expect(err).To(HaveOccurred()) +} + +func testExtensionResults(actual, expected interface{}, expectedMatch bool) { + matcher := NewExtensionMatcher(expected) + actualMatch, err := matcher.Match(actual) + Expect(err).ShouldNot(HaveOccurred()) + Expect(actualMatch).Should(Equal(expectedMatch), matcher.FailureMessage(actual)) +} + +func getDNSExtension(disabled bool, replicationEnabled bool) v1beta1.Extension { + json := fmt.Sprintf(`{apiVersion: "service.dns.extensions.gardener.cloud/v1alpha1", kind: "DNSConfig", dnsProviderReplication: {enabled: %v}}`, replicationEnabled) + + return v1beta1.Extension{ + Type: "shoot-dns-service", + Disabled: &disabled, + ProviderConfig: &runtime.RawExtension{ + Raw: []byte(json), + }, + } +} + +func getNetworkingExtension(disabled bool) v1beta1.Extension { + return v1beta1.Extension{ + Type: "shoot-networking-service", + Disabled: &disabled, + } +} + +func getCertificateExtension(disabled bool, shootIssuersEnabled bool) v1beta1.Extension { + json := fmt.Sprintf(`{apiVersion: "service.cert.extensions.gardener.cloud/v1alpha1", kind: "CertConfig", shootIssuers: {enabled: %v}}`, shootIssuersEnabled) + + return v1beta1.Extension{ + Type: "shoot-cert-service", + Disabled: &disabled, + ProviderConfig: &runtime.RawExtension{ + Raw: []byte(json), + }, + } +} diff --git a/hack/shoot-comparator/pkg/shoot/matcher.go b/hack/shoot-comparator/pkg/shoot/matcher.go index 4202f08d..d4d3bd71 100644 --- a/hack/shoot-comparator/pkg/shoot/matcher.go +++ b/hack/shoot-comparator/pkg/shoot/matcher.go @@ -67,138 +67,140 @@ func (m *Matcher) Match(actual interface{}) (success bool, err error) { // Note: we define separate matchers for each field to make input more readable // Annotations are not matched as they are not relevant for the comparison ; both KIM, and Provisioner have different set of annotations for _, matcher := range []matcher{ - { - GomegaMatcher: gomega.Equal(eShoot.TypeMeta), - expected: aShoot.TypeMeta, - }, - { - GomegaMatcher: gomega.Equal(eShoot.Name), + // We need to skip comparing type meta as Provisioner doesn't set it. + // It is simpler to skip it than to make fix in the Provisioner. + //{ + // GomegaMatcher: gomega.BeComparableTo(eShoot.TypeMeta), + // expected: aShoot.TypeMeta, + //}, + { + GomegaMatcher: gomega.BeComparableTo(eShoot.Name), expected: aShoot.Name, path: "metadata/name", }, { - GomegaMatcher: gomega.Equal(eShoot.Namespace), + GomegaMatcher: gomega.BeComparableTo(eShoot.Namespace), expected: aShoot.Namespace, path: "metadata/namespace", }, { - GomegaMatcher: gomega.Equal(eShoot.Labels), + GomegaMatcher: gomega.BeComparableTo(eShoot.Labels), expected: aShoot.Labels, path: "metadata/labels", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Addons), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Addons), expected: aShoot.Spec.Addons, path: "spec/Addons", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.CloudProfileName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.CloudProfileName), expected: aShoot.Spec.CloudProfileName, path: "spec/CloudProfileName", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.DNS), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.DNS), expected: aShoot.Spec.DNS, path: "spec/DNS", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Extensions), + GomegaMatcher: NewExtensionMatcher(eShoot.Spec.Extensions), expected: aShoot.Spec.Extensions, path: "spec/Extensions", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Hibernation), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Hibernation), expected: aShoot.Spec.Hibernation, path: "spec/Hibernation", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Kubernetes), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Kubernetes), expected: aShoot.Spec.Kubernetes, path: "spec/Kubernetes", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Networking), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Networking), expected: aShoot.Spec.Networking, path: "spec/Networking", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Maintenance), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Maintenance), expected: aShoot.Spec.Maintenance, path: "spec/Maintenance", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Monitoring), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Monitoring), expected: aShoot.Spec.Monitoring, path: "spec/Monitoring", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Provider), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Provider), expected: aShoot.Spec.Provider, path: "spec/Provider", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Purpose), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Purpose), expected: aShoot.Spec.Purpose, path: "spec/Purpose", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Region), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Region), expected: aShoot.Spec.Region, path: "spec/Region", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.SecretBindingName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.SecretBindingName), expected: aShoot.Spec.SecretBindingName, path: "spec/SecretBindingName", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.SeedName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.SeedName), expected: aShoot.Spec.SeedName, path: "spec/SeedName", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.SeedSelector), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.SeedSelector), expected: aShoot.Spec.SeedSelector, path: "spec/SeedSelector", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Resources), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Resources), expected: aShoot.Spec.Resources, path: "spec/Resources", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.Tolerations), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.Tolerations), expected: aShoot.Spec.Tolerations, path: "spec/Tolerations", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.ExposureClassName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.ExposureClassName), expected: aShoot.Spec.ExposureClassName, path: "spec/ExposureClassName", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.SystemComponents), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.SystemComponents), expected: aShoot.Spec.SystemComponents, path: "spec/SystemComponents", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.ControlPlane), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.ControlPlane), expected: aShoot.Spec.ControlPlane, path: "spec/ControlPlane", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.SchedulerName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.SchedulerName), expected: aShoot.Spec.SchedulerName, path: "spec/SchedulerName", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.CloudProfile), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.CloudProfile), expected: aShoot.Spec.CloudProfile, path: "spec/CloudProfile", }, { - GomegaMatcher: gomega.Equal(eShoot.Spec.CredentialsBindingName), + GomegaMatcher: gomega.BeComparableTo(eShoot.Spec.CredentialsBindingName), expected: aShoot.Spec.CredentialsBindingName, path: "spec/CredentialsBindingName", }, diff --git a/hack/shoot-comparator/scripts/manifests/job.yaml b/hack/shoot-comparator/scripts/manifests/job.yaml index 8b14c190..32a23102 100644 --- a/hack/shoot-comparator/scripts/manifests/job.yaml +++ b/hack/shoot-comparator/scripts/manifests/job.yaml @@ -47,7 +47,7 @@ spec: # You can specify a date when the comparison should start from. The date should be in RFC3339 format. # - --fromDate # - 2024-07-31T20:04:29Z - image: europe-docker.pkg.dev/kyma-project/dev/shoot-comparator:PR-321 + image: europe-docker.pkg.dev/kyma-project/dev/shoot-comparator:PR-329 name: compare-shoots resources: {} securityContext: diff --git a/internal/gardener/shoot/converter.go b/internal/gardener/shoot/converter.go index 2767ad87..d8195f44 100644 --- a/internal/gardener/shoot/converter.go +++ b/internal/gardener/shoot/converter.go @@ -108,7 +108,7 @@ func (c Converter) ToShoot(runtime imv1.Runtime) (gardener.Shoot, error) { Pods: &runtime.Spec.Shoot.Networking.Pods, Services: &runtime.Spec.Shoot.Networking.Services, }, - ControlPlane: &runtime.Spec.Shoot.ControlPlane, + ControlPlane: runtime.Spec.Shoot.ControlPlane, }, } diff --git a/internal/gardener/shoot/converter_test.go b/internal/gardener/shoot/converter_test.go index b6ad26ee..d0be7181 100644 --- a/internal/gardener/shoot/converter_test.go +++ b/internal/gardener/shoot/converter_test.go @@ -30,7 +30,7 @@ func TestConverter(t *testing.T) { assert.Equal(t, runtime.Spec.Shoot.Purpose, *shoot.Spec.Purpose) assert.Equal(t, runtime.Spec.Shoot.Region, shoot.Spec.Region) assert.Equal(t, runtime.Spec.Shoot.SecretBindingName, *shoot.Spec.SecretBindingName) - assert.Equal(t, runtime.Spec.Shoot.ControlPlane, *shoot.Spec.ControlPlane) + assert.Equal(t, runtime.Spec.Shoot.ControlPlane, shoot.Spec.ControlPlane) assert.Equal(t, runtime.Spec.Shoot.Networking.Nodes, *shoot.Spec.Networking.Nodes) assert.Equal(t, runtime.Spec.Shoot.Networking.Pods, *shoot.Spec.Networking.Pods) assert.Equal(t, runtime.Spec.Shoot.Networking.Services, *shoot.Spec.Networking.Services) @@ -111,7 +111,7 @@ func fixRuntime() imv1.Runtime { Nodes: "10.250.0.0/16", Services: "100.104.0.0/13", }, - ControlPlane: gardener.ControlPlane{ + ControlPlane: &gardener.ControlPlane{ HighAvailability: &gardener.HighAvailability{ FailureTolerance: gardener.FailureTolerance{ Type: gardener.FailureToleranceTypeZone,