From 16c8bfa33d676465560d3a2e01819e83f3cba3bc Mon Sep 17 00:00:00 2001 From: Pankti Shah Date: Mon, 16 Oct 2023 12:53:53 -0700 Subject: [PATCH] Validate worker node kubernetes version with the template name in the spec - modular upgrade scenario --- pkg/providers/cloudstack/validator.go | 28 +++++++++++++----- pkg/providers/cloudstack/validator_test.go | 34 +++++++++++++--------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/pkg/providers/cloudstack/validator.go b/pkg/providers/cloudstack/validator.go index ee65d17a21036..adac6ea82f351 100644 --- a/pkg/providers/cloudstack/validator.go +++ b/pkg/providers/cloudstack/validator.go @@ -118,6 +118,11 @@ func (v *Validator) ValidateClusterMachineConfigs(ctx context.Context, clusterSp return fmt.Errorf("cannot find CloudStackMachineConfig %v for control plane", clusterSpec.Cluster.Spec.ControlPlaneConfiguration.MachineGroupRef.Name) } + // validate template field of each CloudStackMachineConfigs with the cluster spec kubernetes version. + if err := v.validateTemplateMatchesKubernetesVersion(ctx, controlPlaneMachineConfig.Spec.Template.Name, string(clusterSpec.Cluster.Spec.KubernetesVersion)); err != nil { + return fmt.Errorf("machine config %s validation failed: %v", controlPlaneMachineConfig.Name, err) + } + if clusterSpec.Cluster.Spec.ExternalEtcdConfiguration != nil { etcdMachineConfig := etcdMachineConfig(clusterSpec) if etcdMachineConfig == nil { @@ -130,15 +135,22 @@ func (v *Validator) ValidateClusterMachineConfigs(ctx context.Context, clusterSp if !ok { return fmt.Errorf("cannot find CloudStackMachineConfig %v for worker nodes", workerNodeGroupConfiguration.MachineGroupRef.Name) } + + version := string(clusterSpec.Cluster.Spec.KubernetesVersion) + // validate template field of worker group spec with the kubernetes version of each workerNodeGroup - in case of modular upgrade. + if workerNodeGroupConfiguration.KubernetesVersion != nil { + version = string(*workerNodeGroupConfiguration.KubernetesVersion) + } + templateName := clusterSpec.CloudStackMachineConfigs[workerNodeGroupConfiguration.MachineGroupRef.Name].Spec.Template.Name + if err := v.validateTemplateMatchesKubernetesVersion(ctx, templateName, version); err != nil { + return fmt.Errorf("machine config %s validation failed: %v", workerNodeGroupConfiguration.Name, err) + } } for _, machineConfig := range clusterSpec.CloudStackMachineConfigs { if err := v.validateMachineConfig(ctx, clusterSpec.CloudStackDatacenter, machineConfig); err != nil { return fmt.Errorf("machine config %s validation failed: %v", machineConfig.Name, err) } - if err := v.validateTemplateMatchesKubernetesVersion(ctx, machineConfig, clusterSpec); err != nil { - return fmt.Errorf("machine config %s validation failed: %v", machineConfig.Name, err) - } } logger.MarkPass("Validated cluster Machine Configs") @@ -194,18 +206,18 @@ func (v *Validator) validateMachineConfig(ctx context.Context, datacenterConfig return nil } -func (v *Validator) validateTemplateMatchesKubernetesVersion(ctx context.Context, machineConfig *anywherev1.CloudStackMachineConfig, spec *cluster.Spec) error { +func (v *Validator) validateTemplateMatchesKubernetesVersion(ctx context.Context, templateName string, kubernetesVersionName string) error { // Replace 1.23, 1-23, 1_23 to 123 in the template name string. templateReplacer := strings.NewReplacer("-", "", ".", "", "_", "") - templateName := templateReplacer.Replace(machineConfig.Spec.Template.Name) + template := templateReplacer.Replace(templateName) // Replace 1-23 to 123 in the kubernetesversion string. replacer := strings.NewReplacer(".", "") - kubernetesVersion := replacer.Replace(string(spec.Cluster.Spec.KubernetesVersion)) + kubernetesVersion := replacer.Replace(string(kubernetesVersionName)) // This will return an error if the template name does not contain specified kubernetes version. // For ex if the kubernetes version is 1.23, // the template name should include 1.23 or 1-23, 1_23 or 123 i.e. kubernetes-1-23-eks in the string. - if !strings.Contains(templateName, kubernetesVersion) { - return fmt.Errorf("invalid template: cluster kubernetes version is %s but template for machineconfig %s is %s. If the kubernetes version is 1.23, the template name should include 1.23, 1_23, 1-23 or 123", string(spec.Cluster.Spec.KubernetesVersion), machineConfig.Name, machineConfig.Spec.Template.Name) + if !strings.Contains(template, kubernetesVersion) { + return fmt.Errorf("invalid template: cluster kubernetes version is %s but template is %s. If the kubernetes version is 1.23, the template name should include 1.23, 1_23, 1-23 or 123", string(kubernetesVersionName), templateName) } return nil } diff --git a/pkg/providers/cloudstack/validator_test.go b/pkg/providers/cloudstack/validator_test.go index 9e8a3989426e8..fb2f9a4e15dbc 100644 --- a/pkg/providers/cloudstack/validator_test.go +++ b/pkg/providers/cloudstack/validator_test.go @@ -306,26 +306,32 @@ func TestValidateCloudStackMachineConfig(t *testing.T) { } } -func TestValidateTemplateMatchesKubernetesVersionError(t *testing.T) { +func TestValidateClusterMachineConfigsError(t *testing.T) { ctx := context.Background() cmk := mocks.NewMockProviderCmkClient(gomock.NewController(t)) clusterSpec := test.NewFullClusterSpec(t, path.Join(testDataDir, testClusterConfigMainFilename)) - config, err := cluster.ParseConfigFromFile(path.Join(testDataDir, testClusterConfigMainFilename)) - if err != nil { - t.Fatalf("unable to get machine configs from file: %v", err) - } - machineConfigs := config.CloudStackMachineConfigs - if err != nil { - t.Fatalf("unable to get machine configs from file %s", testClusterConfigMainFilename) - } clusterSpec.Cluster.Spec.KubernetesVersion = "1.22" + validator := NewValidator(cmk, &DummyNetClient{}, true) - for _, machineConfig := range machineConfigs { - err := validator.validateTemplateMatchesKubernetesVersion(ctx, machineConfig, clusterSpec) - if err == nil { - t.Fatalf("failed to validate CloudStackMachineConfig: %v", err) - } + err := validator.ValidateClusterMachineConfigs(ctx, clusterSpec) + if err == nil { + t.Fatalf("validation should not pass: %v", err) + } +} + +func TestValidateClusterMachineConfigsModularUpgradeError(t *testing.T) { + ctx := context.Background() + cmk := mocks.NewMockProviderCmkClient(gomock.NewController(t)) + clusterSpec := test.NewFullClusterSpec(t, path.Join(testDataDir, testClusterConfigMainFilename)) + kube122 := v1alpha1.KubernetesVersion("1.22") + clusterSpec.Cluster.Spec.WorkerNodeGroupConfigurations[0].KubernetesVersion = &kube122 + + validator := NewValidator(cmk, &DummyNetClient{}, true) + + err := validator.ValidateClusterMachineConfigs(ctx, clusterSpec) + if err == nil { + t.Fatalf("validation should not pass: %v", err) } }