diff --git a/pkg/apis/apps/validation/validation.go b/pkg/apis/apps/validation/validation.go index 8c10a956f13..717751d0049 100644 --- a/pkg/apis/apps/validation/validation.go +++ b/pkg/apis/apps/validation/validation.go @@ -280,7 +280,7 @@ func ValidateControllerRevisionUpdate(newHistory, oldHistory *apps.ControllerRev // ValidateDaemonSet tests if required fields in the DaemonSet are set. func ValidateDaemonSet(ds *apps.DaemonSet, opts apivalidation.PodValidationOptions) field.ErrorList { allErrs := apivalidation.ValidateObjectMeta(&ds.ObjectMeta, true, ValidateDaemonSetName, field.NewPath("metadata")) - allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, nil, field.NewPath("spec"), opts)...) + allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"), opts)...) return allErrs } @@ -288,7 +288,7 @@ func ValidateDaemonSet(ds *apps.DaemonSet, opts apivalidation.PodValidationOptio func ValidateDaemonSetUpdate(ds, oldDS *apps.DaemonSet, opts apivalidation.PodValidationOptions) field.ErrorList { allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata")) allErrs = append(allErrs, ValidateDaemonSetSpecUpdate(&ds.Spec, &oldDS.Spec, field.NewPath("spec"))...) - allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, &oldDS.Spec, field.NewPath("spec"), opts)...) + allErrs = append(allErrs, ValidateDaemonSetSpec(&ds.Spec, field.NewPath("spec"), opts)...) return allErrs } @@ -344,7 +344,7 @@ func ValidateDaemonSetStatusUpdate(ds, oldDS *apps.DaemonSet) field.ErrorList { } // ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set. -func ValidateDaemonSetSpec(spec, oldSpec *apps.DaemonSetSpec, fldPath *field.Path, opts apivalidation.PodValidationOptions) field.ErrorList { +func ValidateDaemonSetSpec(spec *apps.DaemonSetSpec, fldPath *field.Path, opts apivalidation.PodValidationOptions) field.ErrorList { allErrs := field.ErrorList{} labelSelectorValidationOpts := unversionedvalidation.LabelSelectorValidationOptions{AllowInvalidLabelValueInSelector: opts.AllowInvalidLabelValueInSelector} @@ -359,12 +359,6 @@ func ValidateDaemonSetSpec(spec, oldSpec *apps.DaemonSetSpec, fldPath *field.Pat } allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(&spec.Template, fldPath.Child("template"), opts)...) - // get rid of apivalidation.ValidateReadOnlyPersistentDisks,stop passing oldSpec to this function - var oldVols []api.Volume - if oldSpec != nil { - oldVols = oldSpec.Template.Spec.Volumes // +k8s:verify-mutation:reason=clone - } - allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(spec.Template.Spec.Volumes, oldVols, fldPath.Child("template", "spec", "volumes"))...) // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways { allErrs = append(allErrs, field.NotSupported(fldPath.Child("template", "spec", "restartPolicy"), spec.Template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) @@ -566,12 +560,7 @@ func ValidateDeploymentSpec(spec, oldSpec *apps.DeploymentSpec, fldPath *field.P if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) } else { - // oldSpec is not empty, pass oldSpec.template - var oldTemplate *api.PodTemplateSpec - if oldSpec != nil { - oldTemplate = &oldSpec.Template // +k8s:verify-mutation:reason=clone - } - allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, oldTemplate, selector, spec.Replicas, fldPath.Child("template"), opts)...) + allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"), opts)...) } allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...) @@ -734,18 +723,13 @@ func ValidateReplicaSetSpec(spec, oldSpec *apps.ReplicaSetSpec, fldPath *field.P if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector")) } else { - // oldSpec is not empty, pass oldSpec.template. - var oldTemplate *api.PodTemplateSpec - if oldSpec != nil { - oldTemplate = &oldSpec.Template // +k8s:verify-mutation:reason=clone - } - allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, oldTemplate, selector, spec.Replicas, fldPath.Child("template"), opts)...) + allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"), opts)...) } return allErrs } // ValidatePodTemplateSpecForReplicaSet validates the given template and ensures that it is in accordance with the desired selector and replicas. -func ValidatePodTemplateSpecForReplicaSet(template, oldTemplate *api.PodTemplateSpec, selector labels.Selector, replicas int32, fldPath *field.Path, opts apivalidation.PodValidationOptions) field.ErrorList { +func ValidatePodTemplateSpecForReplicaSet(template *api.PodTemplateSpec, selector labels.Selector, replicas int32, fldPath *field.Path, opts apivalidation.PodValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if template == nil { allErrs = append(allErrs, field.Required(fldPath, "")) @@ -758,15 +742,6 @@ func ValidatePodTemplateSpecForReplicaSet(template, oldTemplate *api.PodTemplate } } allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(template, fldPath, opts)...) - // Daemons run on more than one node, Cancel verification of read and write volumes. - // get rid of apivalidation.ValidateReadOnlyPersistentDisks,stop passing oldTemplate to this function - var oldVols []api.Volume - if oldTemplate != nil { - oldVols = oldTemplate.Spec.Volumes // +k8s:verify-mutation:reason=clone - } - if replicas > 1 { - allErrs = append(allErrs, apivalidation.ValidateReadOnlyPersistentDisks(template.Spec.Volumes, oldVols, fldPath.Child("spec", "volumes"))...) - } // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if template.Spec.RestartPolicy != api.RestartPolicyAlways { allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)})) diff --git a/pkg/apis/apps/validation/validation_test.go b/pkg/apis/apps/validation/validation_test.go index 8fed2a6ead5..5ae051ed9e1 100644 --- a/pkg/apis/apps/validation/validation_test.go +++ b/pkg/apis/apps/validation/validation_test.go @@ -1572,10 +1572,9 @@ func TestValidateDaemonSetUpdate(t *testing.T) { }, } type dsUpdateTest struct { - old apps.DaemonSet - update apps.DaemonSet - expectedErrNum int - enableSkipReadOnlyValidationGCE bool + old apps.DaemonSet + update apps.DaemonSet + expectedErrNum int } successCases := map[string]dsUpdateTest{ "no change": { @@ -1729,7 +1728,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) { }, }, "Read-write volume verification": { - enableSkipReadOnlyValidationGCE: true, old: apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: apps.DaemonSetSpec{ @@ -1756,7 +1754,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) { } for testName, successCase := range successCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. successCase.old.ObjectMeta.ResourceVersion = "1" successCase.update.ObjectMeta.ResourceVersion = "2" @@ -1848,32 +1845,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) { }, expectedErrNum: 1, }, - "invalid read-write volume": { - enableSkipReadOnlyValidationGCE: false, - old: apps.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: apps.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 1, - Template: validPodTemplateAbc.Template, - UpdateStrategy: apps.DaemonSetUpdateStrategy{ - Type: apps.OnDeleteDaemonSetStrategyType, - }, - }, - }, - update: apps.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: apps.DaemonSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validSelector}, - TemplateGeneration: 2, - Template: readWriteVolumePodTemplate.Template, - UpdateStrategy: apps.DaemonSetUpdateStrategy{ - Type: apps.OnDeleteDaemonSetStrategyType, - }, - }, - }, - expectedErrNum: 1, - }, "invalid update strategy": { old: apps.DaemonSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, @@ -1977,7 +1948,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) { } for testName, errorCase := range errorCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. errorCase.old.ObjectMeta.ResourceVersion = "1" errorCase.update.ObjectMeta.ResourceVersion = "2" @@ -2645,10 +2615,9 @@ func TestValidateDeploymentUpdate(t *testing.T) { }, } type depUpdateTest struct { - old apps.Deployment - update apps.Deployment - expectedErrNum int - enableSkipReadOnlyValidationGCE bool + old apps.Deployment + update apps.Deployment + expectedErrNum int } successCases := map[string]depUpdateTest{ "positive replicas": { @@ -2671,7 +2640,6 @@ func TestValidateDeploymentUpdate(t *testing.T) { }, }, "Read-write volume verification": { - enableSkipReadOnlyValidationGCE: true, old: apps.Deployment{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: apps.DeploymentSpec{ @@ -2693,7 +2661,6 @@ func TestValidateDeploymentUpdate(t *testing.T) { } for testName, successCase := range successCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. successCase.old.ObjectMeta.ResourceVersion = "1" successCase.update.ObjectMeta.ResourceVersion = "2" @@ -2710,26 +2677,6 @@ func TestValidateDeploymentUpdate(t *testing.T) { } }) errorCases := map[string]depUpdateTest{ - "more than one read/write": { - old: apps.Deployment{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: apps.DeploymentSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - Strategy: apps.DeploymentStrategy{Type: apps.RecreateDeploymentStrategyType}, - }, - }, - update: apps.Deployment{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: apps.DeploymentSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - Strategy: apps.DeploymentStrategy{Type: apps.RecreateDeploymentStrategyType}, - }, - }, - expectedErrNum: 2, - }, "invalid selector": { old: apps.Deployment{ ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, @@ -2793,7 +2740,6 @@ func TestValidateDeploymentUpdate(t *testing.T) { } for testName, errorCase := range errorCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. errorCase.old.ObjectMeta.ResourceVersion = "1" errorCase.update.ObjectMeta.ResourceVersion = "2" @@ -3074,10 +3020,9 @@ func TestValidateReplicaSetUpdate(t *testing.T) { }, } type rcUpdateTest struct { - old apps.ReplicaSet - update apps.ReplicaSet - expectedErrNum int - enableSkipReadOnlyValidationGCE bool + old apps.ReplicaSet + update apps.ReplicaSet + expectedErrNum int } successCases := map[string]rcUpdateTest{ "positive replicas": { @@ -3098,7 +3043,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) { }, }, "Read-write volume verification": { - enableSkipReadOnlyValidationGCE: true, old: apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, Spec: apps.ReplicaSetSpec{ @@ -3118,7 +3062,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) { } for testName, successCase := range successCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. successCase.old.ObjectMeta.ResourceVersion = "1" successCase.update.ObjectMeta.ResourceVersion = "2" @@ -3136,24 +3079,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) { }) } errorCases := map[string]rcUpdateTest{ - "more than one read/write": { - old: apps.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, - Spec: apps.ReplicaSetSpec{ - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: validPodTemplate.Template, - }, - }, - update: apps.ReplicaSet{ - ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, - Spec: apps.ReplicaSetSpec{ - Replicas: 2, - Selector: &metav1.LabelSelector{MatchLabels: validLabels}, - Template: readWriteVolumePodTemplate.Template, - }, - }, - expectedErrNum: 2, - }, "invalid selector": { old: apps.ReplicaSet{ ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault}, @@ -3211,7 +3136,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) { } for testName, errorCase := range errorCases { t.Run(testName, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)() // ResourceVersion is required for updates. errorCase.old.ObjectMeta.ResourceVersion = "1" errorCase.update.ObjectMeta.ResourceVersion = "2" diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index ecccf969492..492001a2735 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -5910,7 +5910,7 @@ func ValidateNonEmptySelector(selectorMap map[string]string, fldPath *field.Path } // Validates the given template and ensures that it is in accordance with the desired selector and replicas. -func ValidatePodTemplateSpecForRC(template, oldTemplate *core.PodTemplateSpec, selectorMap map[string]string, replicas int32, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { +func ValidatePodTemplateSpecForRC(template *core.PodTemplateSpec, selectorMap map[string]string, replicas int32, fldPath *field.Path, opts PodValidationOptions) field.ErrorList { allErrs := field.ErrorList{} if template == nil { allErrs = append(allErrs, field.Required(fldPath, "")) @@ -5924,14 +5924,6 @@ func ValidatePodTemplateSpecForRC(template, oldTemplate *core.PodTemplateSpec, s } } allErrs = append(allErrs, ValidatePodTemplateSpec(template, fldPath, opts)...) - // get rid of apivalidation.ValidateReadOnlyPersistentDisks,stop passing oldTemplate to this function - var oldVols []core.Volume - if oldTemplate != nil { - oldVols = oldTemplate.Spec.Volumes // +k8s:verify-mutation:reason=clone - } - if replicas > 1 { - allErrs = append(allErrs, ValidateReadOnlyPersistentDisks(template.Spec.Volumes, oldVols, fldPath.Child("spec", "volumes"))...) - } // RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec(). if template.Spec.RestartPolicy != core.RestartPolicyAlways { allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []core.RestartPolicy{core.RestartPolicyAlways})) @@ -5949,12 +5941,7 @@ func ValidateReplicationControllerSpec(spec, oldSpec *core.ReplicationController allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...) allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...) allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...) - // oldSpec is not empty, pass oldSpec.template. - var oldTemplate *core.PodTemplateSpec - if oldSpec != nil { - oldTemplate = oldSpec.Template // +k8s:verify-mutation:reason=clone - } - allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, oldTemplate, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...) + allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...) return allErrs } @@ -5975,33 +5962,6 @@ func ValidatePodTemplateSpec(spec *core.PodTemplateSpec, fldPath *field.Path, op return allErrs } -// ValidateReadOnlyPersistentDisks stick this AFTER the short-circuit checks -func ValidateReadOnlyPersistentDisks(volumes, oldVolumes []core.Volume, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - - if utilfeature.DefaultFeatureGate.Enabled(features.SkipReadOnlyValidationGCE) { - return field.ErrorList{} - } - - isWriteablePD := func(vol *core.Volume) bool { - return vol.GCEPersistentDisk != nil && !vol.GCEPersistentDisk.ReadOnly - } - - for i := range oldVolumes { - if isWriteablePD(&oldVolumes[i]) { - return field.ErrorList{} - } - } - - for i := range volumes { - idxPath := fldPath.Index(i) - if isWriteablePD(&volumes[i]) { - allErrs = append(allErrs, field.Invalid(idxPath.Child("gcePersistentDisk", "readOnly"), false, "must be true for replicated pods > 1; GCE PD can only be mounted on multiple machines if it is read-only")) - } - } - return allErrs -} - // ValidateTaintsInNodeAnnotations tests that the serialized taints in Node.Annotations has valid data func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index 6b837f21164..d84c34c3087 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -5400,99 +5400,6 @@ func TestValidateVolumes(t *testing.T) { } -func TestValidateReadOnlyPersistentDisks(t *testing.T) { - cases := []struct { - name string - volumes []core.Volume - oldVolume []core.Volume - gateValue bool - expectError bool - }{{ - name: "gate on, read-only disk, nil old", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume(nil), - expectError: false, - }, { - name: "gate off, read-only disk, nil old", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume(nil), - expectError: false, - }, { - name: "gate on, read-write, nil old", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - oldVolume: []core.Volume(nil), - expectError: false, - }, { - name: "gate off, read-write, nil old", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - oldVolume: []core.Volume(nil), - expectError: true, - }, { - name: "gate on, new read-only and old read-write", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - expectError: false, - }, { - name: "gate off, new read-only and old read-write", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - expectError: false, - }, { - name: "gate on, new read-write and old read-write", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - expectError: false, - }, { - name: "gate off, new read-write and old read-write", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - expectError: false, - }, { - name: "gate on, new read-only and old read-only", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - expectError: false, - }, { - name: "gate off, new read-only and old read-only", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - expectError: false, - }, { - name: "gate on, new read-write and old read-only", - gateValue: true, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - expectError: false, - }, { - name: "gate off, new read-write and old read-only", - gateValue: false, - volumes: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: false}}}}, - oldVolume: []core.Volume{{VolumeSource: core.VolumeSource{GCEPersistentDisk: &core.GCEPersistentDiskVolumeSource{ReadOnly: true}}}}, - expectError: true, - }, - } - for _, testCase := range cases { - t.Run(testCase.name, func(t *testing.T) { - fidPath := field.NewPath("testField") - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, testCase.gateValue)() - errs := ValidateReadOnlyPersistentDisks(testCase.volumes, testCase.oldVolume, fidPath) - if !testCase.expectError && len(errs) != 0 { - t.Errorf("expected success, got:%v", errs) - } - }) - } -} - func TestHugePagesIsolation(t *testing.T) { testCases := map[string]struct { pod *core.Pod diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 87aeca3fd2f..07cc6e29097 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -135,13 +135,6 @@ const ( // Allow the usage of options to fine-tune the cpumanager policies. CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions" - // owner: @mfordjody - // alpha: v1.26 - // - // Bypasses obsolete validation that GCP volumes are read-only when used in - // Deployments. - SkipReadOnlyValidationGCE featuregate.Feature = "SkipReadOnlyValidationGCE" - // owner: @trierra // alpha: v1.23 // @@ -1038,8 +1031,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha}, - SkipReadOnlyValidationGCE: {Default: true, PreRelease: featuregate.Deprecated}, // remove in 1.31 - CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha}, ContainerCheckpoint: {Default: true, PreRelease: featuregate.Beta},