diff --git a/charts/internal/cloud-provider-config/Chart.yaml b/charts/internal/cloud-provider-config/Chart.yaml deleted file mode 100644 index 72db75452..000000000 --- a/charts/internal/cloud-provider-config/Chart.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -description: Helm chart for kubernetes cloud-provider-config -name: cloud-provider-config -version: 0.1.0 diff --git a/charts/internal/cloud-provider-config/values.yaml b/charts/internal/cloud-provider-config/values.yaml deleted file mode 100644 index 33906d680..000000000 --- a/charts/internal/cloud-provider-config/values.yaml +++ /dev/null @@ -1 +0,0 @@ -cloudConfig: diff --git a/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/alicloud-ccm-deployment.yaml b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/deployment.yaml similarity index 94% rename from charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/alicloud-ccm-deployment.yaml rename to charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/deployment.yaml index 370380771..956736793 100644 --- a/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/alicloud-ccm-deployment.yaml +++ b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/deployment.yaml @@ -81,8 +81,6 @@ spec: mountPath: /var/lib/cloud-controller-manager - name: cloud-provider-config mountPath: /etc/kubernetes/cloudprovider - - name: cloudprovider - mountPath: /srv/cloudprovider dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler @@ -92,8 +90,5 @@ spec: secret: secretName: cloud-controller-manager - name: cloud-provider-config - configMap: - name: cloud-provider-config - - name: cloudprovider secret: - secretName: cloudprovider + secretName: cloud-provider-config diff --git a/charts/internal/cloud-provider-config/templates/cloud-provider-config.yaml b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/secret-config.yaml similarity index 54% rename from charts/internal/cloud-provider-config/templates/cloud-provider-config.yaml rename to charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/secret-config.yaml index 5643350a4..095479d0a 100644 --- a/charts/internal/cloud-provider-config/templates/cloud-provider-config.yaml +++ b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/templates/secret-config.yaml @@ -1,8 +1,8 @@ apiVersion: v1 -kind: ConfigMap +type: Opaque +kind: Secret metadata: name: cloud-provider-config namespace: {{ .Release.Namespace }} data: - cloudprovider.conf: | - {{ .Values.cloudConfig | indent 4 }} + cloudprovider.conf: {{ .Values.cloudConfig | b64enc }} diff --git a/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/values.yaml b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/values.yaml index b7c255a27..02bacea85 100644 --- a/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/values.yaml +++ b/charts/internal/seed-controlplane/charts/alicloud-cloud-controller-manager/values.yaml @@ -16,3 +16,4 @@ resources: limits: cpu: 250m memory: 300Mi +cloudConfig: json-values diff --git a/docs/usage-as-end-user.md b/docs/usage-as-end-user.md index 3fcb83119..7e40901a1 100644 --- a/docs/usage-as-end-user.md +++ b/docs/usage-as-end-user.md @@ -70,16 +70,11 @@ An example `ControlPlaneConfig` for the Alicloud extension looks as follows: ```yaml apiVersion: alicloud.provider.extensions.gardener.cloud/v1alpha1 kind: ControlPlaneConfig -zone: eu-central-1a cloudControllerManager: featureGates: CustomResourceValidation: true ``` -The `zone` field tells the cloud-controller-manager in which zone it should mainly operate. -You can still create clusters in multiple availability zones, however, the cloud-controller-manager requires one "main" zone. -:warning: You always have to specify this field! - The `cloudControllerManager.featureGates` contains a map of explicitly enabled or disabled feature gates. For production usage it's not recommend to use this field at all as you can enable alpha features or disable beta/stable features, potentially impacting the cluster stability. If you don't want to configure anything for the `cloudControllerManager` simply omit the key in the YAML specification. @@ -112,7 +107,6 @@ spec: controlPlaneConfig: apiVersion: alicloud.provider.extensions.gardener.cloud/v1alpha1 kind: ControlPlaneConfig - zone: eu-central-1a workers: - name: worker-xoluy machine: diff --git a/hack/api-reference/api.md b/hack/api-reference/api.md index 83325000e..9fcd9ede1 100644 --- a/hack/api-reference/api.md +++ b/hack/api-reference/api.md @@ -97,17 +97,6 @@ string -zone
- -string - - - -

Zone is the Alicloud zone

- - - - cloudControllerManager
diff --git a/pkg/alicloud/types.go b/pkg/alicloud/types.go index f4a32cdfa..40339b17d 100644 --- a/pkg/alicloud/types.go +++ b/pkg/alicloud/types.go @@ -48,8 +48,6 @@ const ( // TODO In the future, the bucket name should come from a BackupBucket resource (see https://github.com/gardener/gardener/blob/master/docs/proposals/02-backupinfra.md) BucketName = "bucketName" - // CloudProviderConfigName is the name of the configmap containing the cloud provider config. - CloudProviderConfigName = "cloud-provider-config" // MachineControllerManagerName is a constant for the name of the machine-controller-manager. MachineControllerManagerName = "machine-controller-manager" // MachineControllerManagerVpaName is the name of the VerticalPodAutoscaler of the machine-controller-manager deployment. diff --git a/pkg/apis/alicloud/helper/helper.go b/pkg/apis/alicloud/helper/helper.go index f69f47df0..cac9cd45e 100644 --- a/pkg/apis/alicloud/helper/helper.go +++ b/pkg/apis/alicloud/helper/helper.go @@ -32,6 +32,18 @@ func FindVSwitchForPurposeAndZone(vswitches []api.VSwitch, purpose api.Purpose, return nil, fmt.Errorf("no vswitch with purpose %q in zone %q found", purpose, zone) } +// FindVSwitchForPurpose takes a list of vswitches and tries to find the first entry +// whose purpose matches with the given purpose. If no such entry is found then +// an error will be returned. +func FindVSwitchForPurpose(vswitches []api.VSwitch, purpose api.Purpose) (*api.VSwitch, error) { + for _, vswitch := range vswitches { + if vswitch.Purpose == purpose { + return &vswitch, nil + } + } + return nil, fmt.Errorf("no vswitch with purpose %q found", purpose) +} + // FindSecurityGroupByPurpose takes a list of security groups and tries to find the first entry // whose purpose matches with the given purpose. If no such entry is found then an error will be // returned. diff --git a/pkg/apis/alicloud/helper/helper_test.go b/pkg/apis/alicloud/helper/helper_test.go index b81783f49..6fba14656 100644 --- a/pkg/apis/alicloud/helper/helper_test.go +++ b/pkg/apis/alicloud/helper/helper_test.go @@ -30,7 +30,6 @@ var _ = Describe("Helper", func() { purpose api.Purpose = "foo" purposeWrong api.Purpose = "baz" ) - DescribeTable("#FindVSwitchForPurposeAndZone", func(vswitches []api.VSwitch, purpose api.Purpose, zone string, expectedVSwitch *api.VSwitch, expectErr bool) { subnet, err := FindVSwitchForPurposeAndZone(vswitches, purpose, zone) @@ -44,6 +43,18 @@ var _ = Describe("Helper", func() { Entry("entry exists", []api.VSwitch{{ID: "bar", Purpose: purposeWrong, Zone: "europe"}}, purposeWrong, "europe", &api.VSwitch{ID: "bar", Purpose: purposeWrong, Zone: "europe"}, false), ) + DescribeTable("#FindVSwitchForPurpose", + func(vswitches []api.VSwitch, purpose api.Purpose, expectedVSwitch *api.VSwitch, expectErr bool) { + subnet, err := FindVSwitchForPurpose(vswitches, purpose) + expectResults(subnet, expectedVSwitch, err, expectErr) + }, + + Entry("list is nil", nil, purpose, nil, true), + Entry("empty list", []api.VSwitch{}, purpose, nil, true), + Entry("entry not found (no purpose)", []api.VSwitch{{ID: "bar", Purpose: purposeWrong, Zone: "europe"}}, purpose, nil, true), + Entry("entry exists", []api.VSwitch{{ID: "bar", Purpose: purposeWrong, Zone: "europe"}}, purposeWrong, &api.VSwitch{ID: "bar", Purpose: purposeWrong, Zone: "europe"}, false), + ) + DescribeTable("#FindSecurityGroupByPurpose", func(securityGroups []api.SecurityGroup, purpose api.Purpose, expectedSecurityGroup *api.SecurityGroup, expectErr bool) { securityGroup, err := FindSecurityGroupByPurpose(securityGroups, purpose) diff --git a/pkg/apis/alicloud/types_controlplane.go b/pkg/apis/alicloud/types_controlplane.go index 5d3324136..8749eee2b 100644 --- a/pkg/apis/alicloud/types_controlplane.go +++ b/pkg/apis/alicloud/types_controlplane.go @@ -24,9 +24,6 @@ import ( type ControlPlaneConfig struct { metav1.TypeMeta - // Zone is the Alicloud zone - Zone string - // CloudControllerManager contains configuration settings for the cloud-controller-manager. CloudControllerManager *CloudControllerManagerConfig } diff --git a/pkg/apis/alicloud/v1alpha1/types_controlplane.go b/pkg/apis/alicloud/v1alpha1/types_controlplane.go index e9f5a4bf9..70d855e88 100644 --- a/pkg/apis/alicloud/v1alpha1/types_controlplane.go +++ b/pkg/apis/alicloud/v1alpha1/types_controlplane.go @@ -25,9 +25,6 @@ import ( type ControlPlaneConfig struct { metav1.TypeMeta `json:",inline"` - // Zone is the Alicloud zone - Zone string `json:"zone"` - // CloudControllerManager contains configuration settings for the cloud-controller-manager. // +optional CloudControllerManager *CloudControllerManagerConfig `json:"cloudControllerManager,omitempty"` diff --git a/pkg/apis/alicloud/v1alpha1/zz_generated.conversion.go b/pkg/apis/alicloud/v1alpha1/zz_generated.conversion.go index f6659c406..1e845cbd4 100644 --- a/pkg/apis/alicloud/v1alpha1/zz_generated.conversion.go +++ b/pkg/apis/alicloud/v1alpha1/zz_generated.conversion.go @@ -239,7 +239,6 @@ func Convert_alicloud_CloudProfileConfig_To_v1alpha1_CloudProfileConfig(in *alic } func autoConvert_v1alpha1_ControlPlaneConfig_To_alicloud_ControlPlaneConfig(in *ControlPlaneConfig, out *alicloud.ControlPlaneConfig, s conversion.Scope) error { - out.Zone = in.Zone out.CloudControllerManager = (*alicloud.CloudControllerManagerConfig)(unsafe.Pointer(in.CloudControllerManager)) return nil } @@ -250,7 +249,6 @@ func Convert_v1alpha1_ControlPlaneConfig_To_alicloud_ControlPlaneConfig(in *Cont } func autoConvert_alicloud_ControlPlaneConfig_To_v1alpha1_ControlPlaneConfig(in *alicloud.ControlPlaneConfig, out *ControlPlaneConfig, s conversion.Scope) error { - out.Zone = in.Zone out.CloudControllerManager = (*CloudControllerManagerConfig)(unsafe.Pointer(in.CloudControllerManager)) return nil } diff --git a/pkg/apis/alicloud/validation/controlplane.go b/pkg/apis/alicloud/validation/controlplane.go deleted file mode 100644 index cc7971566..000000000 --- a/pkg/apis/alicloud/validation/controlplane.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validation - -import ( - apisalicloud "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud" - - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - apivalidation "k8s.io/apimachinery/pkg/api/validation" - "k8s.io/apimachinery/pkg/util/validation/field" -) - -// ValidateControlPlaneConfig validates a ControlPlaneConfig object. -func ValidateControlPlaneConfig(controlPlaneConfig *apisalicloud.ControlPlaneConfig, region string, regions []gardencorev1beta1.Region) field.ErrorList { - allErrs := field.ErrorList{} - - if len(controlPlaneConfig.Zone) == 0 { - allErrs = append(allErrs, field.Required(field.NewPath("zone"), "must provide the name of a zone in this region")) - } else if ok, validZones := validateZoneConstraints(regions, region, controlPlaneConfig.Zone, ""); !ok { - allErrs = append(allErrs, field.NotSupported(field.NewPath("zone"), controlPlaneConfig.Zone, validZones)) - } - - return allErrs -} - -// ValidateControlPlaneConfigUpdate validates a ControlPlaneConfig object. -func ValidateControlPlaneConfigUpdate(oldConfig, newConfig *apisalicloud.ControlPlaneConfig, region string, regions []gardencorev1beta1.Region) field.ErrorList { - allErrs := field.ErrorList{} - - allErrs = append(allErrs, apivalidation.ValidateImmutableField(newConfig.Zone, oldConfig.Zone, field.NewPath("zone"))...) - - return allErrs -} - -func validateZoneConstraints(regions []gardencorev1beta1.Region, region, zone, oldZone string) (bool, []string) { - if zone == oldZone { - return true, nil - } - - validValues := []string{} - - for _, r := range regions { - if r.Name != region { - continue - } - - for _, z := range r.Zones { - validValues = append(validValues, z.Name) - if z.Name == zone { - return true, nil - } - } - } - - return false, validValues -} diff --git a/pkg/apis/alicloud/validation/controlplane_test.go b/pkg/apis/alicloud/validation/controlplane_test.go deleted file mode 100644 index bbead709e..000000000 --- a/pkg/apis/alicloud/validation/controlplane_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package validation_test - -import ( - apisalicloud "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud" - . "github.com/gardener/gardener-extension-provider-alicloud/pkg/apis/alicloud/validation" - - gardencorev1beta1 "github.com/gardener/gardener/pkg/apis/core/v1beta1" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" - "k8s.io/apimachinery/pkg/util/validation/field" -) - -var _ = Describe("ControlPlaneConfig validation", func() { - var ( - region = "foo" - zone = "some-zone" - - regions = []gardencorev1beta1.Region{ - { - Name: region, - Zones: []gardencorev1beta1.AvailabilityZone{ - {Name: zone}, - }, - }, - } - - controlPlane *apisalicloud.ControlPlaneConfig - ) - - BeforeEach(func() { - controlPlane = &apisalicloud.ControlPlaneConfig{ - Zone: zone, - } - }) - - Describe("#ValidateControlPlaneConfig", func() { - It("should return no errors for a valid configuration", func() { - Expect(ValidateControlPlaneConfig(controlPlane, region, regions)).To(BeEmpty()) - }) - - It("should require the name of a zone", func() { - controlPlane.Zone = "" - - errorList := ValidateControlPlaneConfig(controlPlane, region, regions) - - Expect(errorList).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{ - "Type": Equal(field.ErrorTypeRequired), - "Field": Equal("zone"), - })))) - }) - - It("should require a name of a zone that is part of the regions", func() { - controlPlane.Zone = "bar" - - errorList := ValidateControlPlaneConfig(controlPlane, region, regions) - - Expect(errorList).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{ - "Type": Equal(field.ErrorTypeNotSupported), - "Field": Equal("zone"), - })))) - }) - }) - - Describe("#ValidateControlPlaneConfigUpdate", func() { - It("should return no errors for an unchanged config", func() { - Expect(ValidateControlPlaneConfigUpdate(controlPlane, controlPlane, region, regions)).To(BeEmpty()) - }) - - It("should forbid changing the zone", func() { - newControlPlane := controlPlane.DeepCopy() - newControlPlane.Zone = "foo" - - errorList := ValidateControlPlaneConfigUpdate(controlPlane, newControlPlane, region, regions) - - Expect(errorList).To(ConsistOf(PointTo(MatchFields(IgnoreExtras, Fields{ - "Type": Equal(field.ErrorTypeInvalid), - "Field": Equal("zone"), - })))) - }) - }) -}) diff --git a/pkg/controller/controlplane/add.go b/pkg/controller/controlplane/add.go index 5b0373f8e..5a4f34a3a 100644 --- a/pkg/controller/controlplane/add.go +++ b/pkg/controller/controlplane/add.go @@ -48,9 +48,9 @@ type AddOptions struct { // The opts.Reconciler is being set with a newly instantiated actuator. func AddToManagerWithOptions(mgr manager.Manager, opts AddOptions) error { return controlplane.Add(mgr, controlplane.AddArgs{ - Actuator: genericactuator.NewActuator(alicloud.Name, controlPlaneSecrets, nil, configChart, controlPlaneChart, controlPlaneShootChart, + Actuator: genericactuator.NewActuator(alicloud.Name, controlPlaneSecrets, nil, nil, controlPlaneChart, controlPlaneShootChart, storageClassChart, nil, NewValuesProvider(logger), extensionscontroller.ChartRendererFactoryFunc(util.NewChartRendererForShoot), - imagevector.ImageVector(), alicloud.CloudProviderConfigName, opts.ShootWebhooks, mgr.GetWebhookServer().Port, logger), + imagevector.ImageVector(), "", opts.ShootWebhooks, mgr.GetWebhookServer().Port, logger), ControllerOptions: opts.Controller, Predicates: controlplane.DefaultPredicates(opts.IgnoreOperationAnnotation), Type: alicloud.Type, diff --git a/pkg/controller/controlplane/clean_old_resources.go b/pkg/controller/controlplane/clean_old_resources.go new file mode 100644 index 000000000..0eaf1a99b --- /dev/null +++ b/pkg/controller/controlplane/clean_old_resources.go @@ -0,0 +1,33 @@ +// Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.package controlplane + +package controlplane + +import ( + "context" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +func (vp *valuesProvider) deleteCloudProviderConfig(ctx context.Context, ns string) error { + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns, + Name: "cloud-provider-config", + }, + } + + return client.IgnoreNotFound(vp.Client().Delete(ctx, cm)) +} diff --git a/pkg/controller/controlplane/valuesprovider.go b/pkg/controller/controlplane/valuesprovider.go index ecb618c1d..1614dda12 100644 --- a/pkg/controller/controlplane/valuesprovider.go +++ b/pkg/controller/controlplane/valuesprovider.go @@ -120,17 +120,6 @@ var controlPlaneSecrets = &secrets.Secrets{ }, } -var configChart = &chart.Chart{ - Name: "cloud-provider-config", - Path: filepath.Join(alicloud.InternalChartsPath, "cloud-provider-config"), - Objects: []*chart.Object{ - { - Type: &corev1.ConfigMap{}, - Name: alicloud.CloudProviderConfigName, - }, - }, -} - var controlPlaneChart = &chart.Chart{ Name: "seed-controlplane", Path: filepath.Join(alicloud.InternalChartsPath, "seed-controlplane"), @@ -141,6 +130,7 @@ var controlPlaneChart = &chart.Chart{ Objects: []*chart.Object{ {Type: &corev1.Service{}, Name: "cloud-controller-manager"}, {Type: &appsv1.Deployment{}, Name: "cloud-controller-manager"}, + {Type: &corev1.Secret{}, Name: "cloud-provider-config"}, {Type: &corev1.ConfigMap{}, Name: "cloud-controller-manager-monitoring-config"}, }, }, @@ -224,36 +214,6 @@ type valuesProvider struct { logger logr.Logger } -// GetConfigChartValues returns the values for the config chart applied by the generic actuator. -func (vp *valuesProvider) GetConfigChartValues( - ctx context.Context, - cp *extensionsv1alpha1.ControlPlane, - cluster *extensionscontroller.Cluster, -) (map[string]interface{}, error) { - // Decode providerConfig - cpConfig := &apisalicloud.ControlPlaneConfig{} - if cp.Spec.ProviderConfig != nil { - if _, _, err := vp.Decoder().Decode(cp.Spec.ProviderConfig.Raw, nil, cpConfig); err != nil { - return nil, errors.Wrapf(err, "could not decode providerConfig of controlplane '%s'", util.ObjectName(cp)) - } - } - - // Decode infrastructureProviderStatus - infraStatus := &apisalicloud.InfrastructureStatus{} - if _, _, err := vp.Decoder().Decode(cp.Spec.InfrastructureProviderStatus.Raw, nil, infraStatus); err != nil { - return nil, errors.Wrapf(err, "could not decode infrastructureProviderStatus of controlplane '%s'", util.ObjectName(cp)) - } - - // Get credentials from the referenced secret - credentials, err := alicloud.ReadCredentialsFromSecretRef(ctx, vp.Client(), &cp.Spec.SecretRef) - if err != nil { - return nil, errors.Wrapf(err, "could not read credentials from secret referred by controlplane '%s'", util.ObjectName(cp)) - } - - // Get config chart values - return getConfigChartValues(cpConfig, infraStatus, cp, credentials) -} - // GetControlPlaneChartValues returns the values for the control plane chart applied by the generic actuator. func (vp *valuesProvider) GetControlPlaneChartValues( ctx context.Context, @@ -269,9 +229,12 @@ func (vp *valuesProvider) GetControlPlaneChartValues( return nil, errors.Wrapf(err, "could not decode providerConfig of controlplane '%s'", util.ObjectName(cp)) } } - + // TODO: Remove this code in next version. Delete old config + if err := vp.deleteCloudProviderConfig(ctx, cp.Namespace); err != nil { + return nil, err + } // Get control plane chart values - return getControlPlaneChartValues(cpConfig, cp, cluster, checksums, scaledDown) + return vp.getControlPlaneChartValues(ctx, cpConfig, cp, cluster, checksums, scaledDown) } // GetControlPlaneShootChartValues returns the values for the control plane shoot chart applied by the generic actuator. @@ -308,17 +271,26 @@ type cloudConfig struct { } } -// getConfigChartValues collects and returns the configuration chart values. -func getConfigChartValues( - cpConfig *apisalicloud.ControlPlaneConfig, - infraStatus *apisalicloud.InfrastructureStatus, +func (vp *valuesProvider) getCloudControllerManagerConfigFileContent( + ctx context.Context, cp *extensionsv1alpha1.ControlPlane, - credentials *alicloud.Credentials, -) (map[string]interface{}, error) { - // Find first vswitch with purpose "nodes" in the specified zone - vswitch, err := helper.FindVSwitchForPurposeAndZone(infraStatus.VPC.VSwitches, apisalicloud.PurposeNodes, cpConfig.Zone) +) (string, error) { + // Decode infrastructureProviderStatus + infraStatus := &apisalicloud.InfrastructureStatus{} + if _, _, err := vp.Decoder().Decode(cp.Spec.InfrastructureProviderStatus.Raw, nil, infraStatus); err != nil { + return "", errors.Wrapf(err, "could not decode infrastructureProviderStatus of controlplane '%s'", util.ObjectName(cp)) + } + + // Get credentials from the referenced secret + credentials, err := alicloud.ReadCredentialsFromSecretRef(ctx, vp.Client(), &cp.Spec.SecretRef) if err != nil { - return nil, errors.Wrapf(err, "could not determine vswitch from infrastructureProviderStatus of controlplane '%s'", util.ObjectName(cp)) + return "", errors.Wrapf(err, "could not read credentials from secret referred by controlplane '%s'", util.ObjectName(cp)) + } + + // Find first vswitch with purpose "nodes" + vswitch, err := helper.FindVSwitchForPurpose(infraStatus.VPC.VSwitches, apisalicloud.PurposeNodes) + if err != nil { + return "", errors.Wrapf(err, "could not determine vswitch from infrastructureProviderStatus of controlplane '%s'", util.ObjectName(cp)) } // Initialize cloud config @@ -334,23 +306,25 @@ func getConfigChartValues( cfgJSON, err := json.Marshal(cfg) if err != nil { - return nil, errors.Wrapf(err, "could not marshal cloud config to JSON for controlplane '%s'", util.ObjectName(cp)) + return "", errors.Wrapf(err, "could not marshal cloud config to JSON for controlplane '%s'", util.ObjectName(cp)) } - // Collect config chart values - return map[string]interface{}{ - "cloudConfig": string(cfgJSON), - }, nil + return string(cfgJSON), nil } // getControlPlaneChartValues collects and returns the control plane chart values. -func getControlPlaneChartValues( +func (vp *valuesProvider) getControlPlaneChartValues( + ctx context.Context, cpConfig *apisalicloud.ControlPlaneConfig, cp *extensionsv1alpha1.ControlPlane, cluster *extensionscontroller.Cluster, checksums map[string]string, scaledDown bool, ) (map[string]interface{}, error) { + ccmConfig, err := vp.getCloudControllerManagerConfigFileContent(ctx, cp) + if err != nil { + return nil, errors.Wrapf(err, "could not build cloud controller config file content for controlplain '%s", util.ObjectName(cp)) + } values := map[string]interface{}{ "alicloud-cloud-controller-manager": map[string]interface{}{ "replicas": extensionscontroller.GetControlPlaneReplicas(cluster, scaledDown, 1), @@ -359,12 +333,12 @@ func getControlPlaneChartValues( "podNetwork": extensionscontroller.GetPodNetwork(cluster), "podAnnotations": map[string]interface{}{ "checksum/secret-cloud-controller-manager": checksums["cloud-controller-manager"], - "checksum/secret-cloudprovider": checksums[v1beta1constants.SecretNameCloudProvider], - "checksum/configmap-cloud-provider-config": checksums[alicloud.CloudProviderConfigName], + "checksum/secret-cloud-provider-config": checksums["cloud-provider-config"], }, "podLabels": map[string]interface{}{ v1beta1constants.LabelPodMaintenanceRestart: "true", }, + "cloudConfig": ccmConfig, }, "csi-alicloud": map[string]interface{}{ "replicas": extensionscontroller.GetControlPlaneReplicas(cluster, scaledDown, 1), diff --git a/pkg/controller/controlplane/valuesprovider_test.go b/pkg/controller/controlplane/valuesprovider_test.go index d73fd40a3..65b66796d 100644 --- a/pkg/controller/controlplane/valuesprovider_test.go +++ b/pkg/controller/controlplane/valuesprovider_test.go @@ -63,7 +63,6 @@ var _ = Describe("ValuesProvider", func() { DefaultSpec: extensionsv1alpha1.DefaultSpec{ ProviderConfig: &runtime.RawExtension{ Raw: encode(&apisalicloud.ControlPlaneConfig{ - Zone: "eu-central-1a", CloudControllerManager: &apisalicloud.CloudControllerManagerConfig{ FeatureGates: map[string]bool{ "CustomResourceValidation": true, @@ -106,6 +105,14 @@ var _ = Describe("ValuesProvider", func() { }, } + // TODO remove cpMap in next version + cpConfigmap = &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: "cloud-provider-config", + }, + } + cpSecretKey = client.ObjectKey{Namespace: namespace, Name: v1beta1constants.SecretNameCloudProvider} cpSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ @@ -121,7 +128,7 @@ var _ = Describe("ValuesProvider", func() { checksums = map[string]string{ v1beta1constants.SecretNameCloudProvider: "8bafb35ff1ac60275d62e1cbd495aceb511fb354f74a20f7d06ecb48b3a68432", - alicloud.CloudProviderConfigName: "08a7bc7fe8f59b055f173145e211760a83f02cf89635cef26ebb351378635606", + "cloud-provider-config": "08a7bc7fe8f59b055f173145e211760a83f02cf89635cef26ebb351378635606", "cloud-controller-manager": "3d791b164a808638da9a8df03924be2a41e34cd664e42231c00fe369e3588272", "csi-attacher": "2da58ad61c401a2af779a909d22fb42eed93a1524cbfdab974ceedb413fcb914", "csi-provisioner": "f75b42d40ab501428c383dfb2336cb1fc892bbee1fc1d739675171e4acc4d911", @@ -129,10 +136,6 @@ var _ = Describe("ValuesProvider", func() { "csi-resizer": "5df115bd53f09da2d6d27bfb048c14dabd14a66608cfdba5ecd2d0687889cc6a", } - configChartValues = map[string]interface{}{ - "cloudConfig": `{"Global":{"KubernetesClusterTag":"test","clusterID":"test","uid":"","vpcid":"vpc-1234","region":"eu-central-1","zoneid":"eu-central-1a","vswitchid":"vswitch-acbd1234","accessKeyID":"Zm9v","accessKeySecret":"YmFy"}}`, - } - controlPlaneChartValues = map[string]interface{}{ "alicloud-cloud-controller-manager": map[string]interface{}{ "replicas": 1, @@ -141,12 +144,12 @@ var _ = Describe("ValuesProvider", func() { "podNetwork": cidr, "podAnnotations": map[string]interface{}{ "checksum/secret-cloud-controller-manager": "3d791b164a808638da9a8df03924be2a41e34cd664e42231c00fe369e3588272", - "checksum/secret-cloudprovider": "8bafb35ff1ac60275d62e1cbd495aceb511fb354f74a20f7d06ecb48b3a68432", - "checksum/configmap-cloud-provider-config": "08a7bc7fe8f59b055f173145e211760a83f02cf89635cef26ebb351378635606", + "checksum/secret-cloud-provider-config": "08a7bc7fe8f59b055f173145e211760a83f02cf89635cef26ebb351378635606", }, "podLabels": map[string]interface{}{ "maintenance.gardener.cloud/restart": "true", }, + "cloudConfig": "{\"Global\":{\"KubernetesClusterTag\":\"test\",\"clusterID\":\"test\",\"uid\":\"\",\"vpcid\":\"vpc-1234\",\"region\":\"eu-central-1\",\"zoneid\":\"eu-central-1a\",\"vswitchid\":\"vswitch-acbd1234\",\"accessKeyID\":\"Zm9v\",\"accessKeySecret\":\"YmFy\"}}", "featureGates": map[string]bool{ "CustomResourceValidation": true, }, @@ -188,12 +191,12 @@ var _ = Describe("ValuesProvider", func() { ctrl.Finish() }) - Describe("#GetConfigChartValues", func() { - It("should return correct config chart values", func() { + Describe("#GetControlPlaneChartValues", func() { + It("should return correct control plane chart values", func() { // Create mock client client := mockclient.NewMockClient(ctrl) client.EXPECT().Get(context.TODO(), cpSecretKey, &corev1.Secret{}).DoAndReturn(clientGet(cpSecret)) - + client.EXPECT().Delete(context.TODO(), cpConfigmap).DoAndReturn(clientDeleteSuccess()) // Create valuesProvider vp := NewValuesProvider(logger) err := vp.(inject.Scheme).InjectScheme(scheme) @@ -201,20 +204,6 @@ var _ = Describe("ValuesProvider", func() { err = vp.(inject.Client).InjectClient(client) Expect(err).NotTo(HaveOccurred()) - // Call GetConfigChartValues method and check the result - values, err := vp.GetConfigChartValues(context.TODO(), cp, cluster) - Expect(err).NotTo(HaveOccurred()) - Expect(values).To(Equal(configChartValues)) - }) - }) - - Describe("#GetControlPlaneChartValues", func() { - It("should return correct control plane chart values", func() { - // Create valuesProvider - vp := NewValuesProvider(logger) - err := vp.(inject.Scheme).InjectScheme(scheme) - Expect(err).NotTo(HaveOccurred()) - // Call GetControlPlaneChartValues method and check the result values, err := vp.GetControlPlaneChartValues(context.TODO(), cp, cluster, checksums, false) Expect(err).NotTo(HaveOccurred()) @@ -233,7 +222,7 @@ var _ = Describe("ValuesProvider", func() { err := vp.(inject.Client).InjectClient(client) Expect(err).NotTo(HaveOccurred()) - // Call GetControlPlaneChartValues method and check the result + // Call GetControlPlaneShootChartValues method and check the result values, err := vp.GetControlPlaneShootChartValues(context.TODO(), cp, cluster, checksums) Expect(err).NotTo(HaveOccurred()) Expect(values).To(Equal(controlPlaneShootChartValues)) @@ -246,6 +235,12 @@ func encode(obj runtime.Object) []byte { return data } +func clientDeleteSuccess() interface{} { + return func(ctx context.Context, cm runtime.Object) error { + return nil + } +} + func clientGet(result runtime.Object) interface{} { return func(ctx context.Context, key client.ObjectKey, obj runtime.Object) error { switch obj.(type) { diff --git a/test/tm/generator.go b/test/tm/generator.go index b74d5f491..d73b96895 100644 --- a/test/tm/generator.go +++ b/test/tm/generator.go @@ -72,7 +72,6 @@ func main() { APIVersion: v1alpha1.SchemeGroupVersion.String(), Kind: reflect.TypeOf(v1alpha1.ControlPlaneConfig{}).Name(), }, - Zone: *zone, } if err := generator.MarshalAndWriteConfig(*infrastructureProviderConfigPath, infra); err != nil {