mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-08 03:33:56 +00:00
Remove the gate "SkipReadOnlyValidationGCE"
One less GCE-specifc wart in the codebase.
This commit is contained in:
parent
f8930f980d
commit
ae01c2126f
@ -280,7 +280,7 @@ func ValidateControllerRevisionUpdate(newHistory, oldHistory *apps.ControllerRev
|
|||||||
// ValidateDaemonSet tests if required fields in the DaemonSet are set.
|
// ValidateDaemonSet tests if required fields in the DaemonSet are set.
|
||||||
func ValidateDaemonSet(ds *apps.DaemonSet, opts apivalidation.PodValidationOptions) field.ErrorList {
|
func ValidateDaemonSet(ds *apps.DaemonSet, opts apivalidation.PodValidationOptions) field.ErrorList {
|
||||||
allErrs := apivalidation.ValidateObjectMeta(&ds.ObjectMeta, true, ValidateDaemonSetName, field.NewPath("metadata"))
|
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
|
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 {
|
func ValidateDaemonSetUpdate(ds, oldDS *apps.DaemonSet, opts apivalidation.PodValidationOptions) field.ErrorList {
|
||||||
allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata"))
|
allErrs := apivalidation.ValidateObjectMetaUpdate(&ds.ObjectMeta, &oldDS.ObjectMeta, field.NewPath("metadata"))
|
||||||
allErrs = append(allErrs, ValidateDaemonSetSpecUpdate(&ds.Spec, &oldDS.Spec, field.NewPath("spec"))...)
|
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
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ func ValidateDaemonSetStatusUpdate(ds, oldDS *apps.DaemonSet) field.ErrorList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ValidateDaemonSetSpec tests if required fields in the DaemonSetSpec are set.
|
// 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{}
|
allErrs := field.ErrorList{}
|
||||||
labelSelectorValidationOpts := unversionedvalidation.LabelSelectorValidationOptions{AllowInvalidLabelValueInSelector: opts.AllowInvalidLabelValueInSelector}
|
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)...)
|
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().
|
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||||
if spec.Template.Spec.RestartPolicy != api.RestartPolicyAlways {
|
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)}))
|
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 {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector"))
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector"))
|
||||||
} else {
|
} else {
|
||||||
// oldSpec is not empty, pass oldSpec.template
|
allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"), opts)...)
|
||||||
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, ValidateDeploymentStrategy(&spec.Strategy, fldPath.Child("strategy"))...)
|
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 {
|
if err != nil {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector"))
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("selector"), spec.Selector, "invalid label selector"))
|
||||||
} else {
|
} else {
|
||||||
// oldSpec is not empty, pass oldSpec.template.
|
allErrs = append(allErrs, ValidatePodTemplateSpecForReplicaSet(&spec.Template, selector, spec.Replicas, fldPath.Child("template"), opts)...)
|
||||||
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)...)
|
|
||||||
}
|
}
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidatePodTemplateSpecForReplicaSet validates the given template and ensures that it is in accordance with the desired selector and replicas.
|
// 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{}
|
allErrs := field.ErrorList{}
|
||||||
if template == nil {
|
if template == nil {
|
||||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||||
@ -758,15 +742,6 @@ func ValidatePodTemplateSpecForReplicaSet(template, oldTemplate *api.PodTemplate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpec(template, fldPath, opts)...)
|
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().
|
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||||
if template.Spec.RestartPolicy != api.RestartPolicyAlways {
|
if template.Spec.RestartPolicy != api.RestartPolicyAlways {
|
||||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
|
allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []string{string(api.RestartPolicyAlways)}))
|
||||||
|
@ -1572,10 +1572,9 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
type dsUpdateTest struct {
|
type dsUpdateTest struct {
|
||||||
old apps.DaemonSet
|
old apps.DaemonSet
|
||||||
update apps.DaemonSet
|
update apps.DaemonSet
|
||||||
expectedErrNum int
|
expectedErrNum int
|
||||||
enableSkipReadOnlyValidationGCE bool
|
|
||||||
}
|
}
|
||||||
successCases := map[string]dsUpdateTest{
|
successCases := map[string]dsUpdateTest{
|
||||||
"no change": {
|
"no change": {
|
||||||
@ -1729,7 +1728,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Read-write volume verification": {
|
"Read-write volume verification": {
|
||||||
enableSkipReadOnlyValidationGCE: true,
|
|
||||||
old: apps.DaemonSet{
|
old: apps.DaemonSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.DaemonSetSpec{
|
Spec: apps.DaemonSetSpec{
|
||||||
@ -1756,7 +1754,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, successCase := range successCases {
|
for testName, successCase := range successCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
successCase.update.ObjectMeta.ResourceVersion = "2"
|
successCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
@ -1848,32 +1845,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedErrNum: 1,
|
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": {
|
"invalid update strategy": {
|
||||||
old: apps.DaemonSet{
|
old: apps.DaemonSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
@ -1977,7 +1948,6 @@ func TestValidateDaemonSetUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, errorCase := range errorCases {
|
for testName, errorCase := range errorCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
@ -2645,10 +2615,9 @@ func TestValidateDeploymentUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
type depUpdateTest struct {
|
type depUpdateTest struct {
|
||||||
old apps.Deployment
|
old apps.Deployment
|
||||||
update apps.Deployment
|
update apps.Deployment
|
||||||
expectedErrNum int
|
expectedErrNum int
|
||||||
enableSkipReadOnlyValidationGCE bool
|
|
||||||
}
|
}
|
||||||
successCases := map[string]depUpdateTest{
|
successCases := map[string]depUpdateTest{
|
||||||
"positive replicas": {
|
"positive replicas": {
|
||||||
@ -2671,7 +2640,6 @@ func TestValidateDeploymentUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Read-write volume verification": {
|
"Read-write volume verification": {
|
||||||
enableSkipReadOnlyValidationGCE: true,
|
|
||||||
old: apps.Deployment{
|
old: apps.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.DeploymentSpec{
|
Spec: apps.DeploymentSpec{
|
||||||
@ -2693,7 +2661,6 @@ func TestValidateDeploymentUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, successCase := range successCases {
|
for testName, successCase := range successCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
successCase.update.ObjectMeta.ResourceVersion = "2"
|
successCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
@ -2710,26 +2677,6 @@ func TestValidateDeploymentUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
errorCases := map[string]depUpdateTest{
|
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": {
|
"invalid selector": {
|
||||||
old: apps.Deployment{
|
old: apps.Deployment{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
||||||
@ -2793,7 +2740,6 @@ func TestValidateDeploymentUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, errorCase := range errorCases {
|
for testName, errorCase := range errorCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
@ -3074,10 +3020,9 @@ func TestValidateReplicaSetUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
type rcUpdateTest struct {
|
type rcUpdateTest struct {
|
||||||
old apps.ReplicaSet
|
old apps.ReplicaSet
|
||||||
update apps.ReplicaSet
|
update apps.ReplicaSet
|
||||||
expectedErrNum int
|
expectedErrNum int
|
||||||
enableSkipReadOnlyValidationGCE bool
|
|
||||||
}
|
}
|
||||||
successCases := map[string]rcUpdateTest{
|
successCases := map[string]rcUpdateTest{
|
||||||
"positive replicas": {
|
"positive replicas": {
|
||||||
@ -3098,7 +3043,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Read-write volume verification": {
|
"Read-write volume verification": {
|
||||||
enableSkipReadOnlyValidationGCE: true,
|
|
||||||
old: apps.ReplicaSet{
|
old: apps.ReplicaSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||||
Spec: apps.ReplicaSetSpec{
|
Spec: apps.ReplicaSetSpec{
|
||||||
@ -3118,7 +3062,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, successCase := range successCases {
|
for testName, successCase := range successCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, successCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
successCase.old.ObjectMeta.ResourceVersion = "1"
|
successCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
successCase.update.ObjectMeta.ResourceVersion = "2"
|
successCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
@ -3136,24 +3079,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
errorCases := map[string]rcUpdateTest{
|
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": {
|
"invalid selector": {
|
||||||
old: apps.ReplicaSet{
|
old: apps.ReplicaSet{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
ObjectMeta: metav1.ObjectMeta{Name: "", Namespace: metav1.NamespaceDefault},
|
||||||
@ -3211,7 +3136,6 @@ func TestValidateReplicaSetUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for testName, errorCase := range errorCases {
|
for testName, errorCase := range errorCases {
|
||||||
t.Run(testName, func(t *testing.T) {
|
t.Run(testName, func(t *testing.T) {
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SkipReadOnlyValidationGCE, errorCase.enableSkipReadOnlyValidationGCE)()
|
|
||||||
// ResourceVersion is required for updates.
|
// ResourceVersion is required for updates.
|
||||||
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
errorCase.old.ObjectMeta.ResourceVersion = "1"
|
||||||
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
errorCase.update.ObjectMeta.ResourceVersion = "2"
|
||||||
|
@ -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.
|
// 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{}
|
allErrs := field.ErrorList{}
|
||||||
if template == nil {
|
if template == nil {
|
||||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||||
@ -5924,14 +5924,6 @@ func ValidatePodTemplateSpecForRC(template, oldTemplate *core.PodTemplateSpec, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
allErrs = append(allErrs, ValidatePodTemplateSpec(template, fldPath, opts)...)
|
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().
|
// RestartPolicy has already been first-order validated as per ValidatePodTemplateSpec().
|
||||||
if template.Spec.RestartPolicy != core.RestartPolicyAlways {
|
if template.Spec.RestartPolicy != core.RestartPolicyAlways {
|
||||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("spec", "restartPolicy"), template.Spec.RestartPolicy, []core.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, ValidateNonnegativeField(int64(spec.MinReadySeconds), fldPath.Child("minReadySeconds"))...)
|
||||||
allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...)
|
allErrs = append(allErrs, ValidateNonEmptySelector(spec.Selector, fldPath.Child("selector"))...)
|
||||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
allErrs = append(allErrs, ValidateNonnegativeField(int64(spec.Replicas), fldPath.Child("replicas"))...)
|
||||||
// oldSpec is not empty, pass oldSpec.template.
|
allErrs = append(allErrs, ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, fldPath.Child("template"), opts)...)
|
||||||
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)...)
|
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5975,33 +5962,6 @@ func ValidatePodTemplateSpec(spec *core.PodTemplateSpec, fldPath *field.Path, op
|
|||||||
return allErrs
|
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
|
// ValidateTaintsInNodeAnnotations tests that the serialized taints in Node.Annotations has valid data
|
||||||
func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
func ValidateTaintsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
@ -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) {
|
func TestHugePagesIsolation(t *testing.T) {
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
pod *core.Pod
|
pod *core.Pod
|
||||||
|
@ -135,13 +135,6 @@ const (
|
|||||||
// Allow the usage of options to fine-tune the cpumanager policies.
|
// Allow the usage of options to fine-tune the cpumanager policies.
|
||||||
CPUManagerPolicyOptions featuregate.Feature = "CPUManagerPolicyOptions"
|
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
|
// owner: @trierra
|
||||||
// alpha: v1.23
|
// alpha: v1.23
|
||||||
//
|
//
|
||||||
@ -1038,8 +1031,6 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
|
|
||||||
CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha},
|
CSIVolumeHealth: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
SkipReadOnlyValidationGCE: {Default: true, PreRelease: featuregate.Deprecated}, // remove in 1.31
|
|
||||||
|
|
||||||
CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha},
|
CloudControllerManagerWebhook: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
|
||||||
ContainerCheckpoint: {Default: true, PreRelease: featuregate.Beta},
|
ContainerCheckpoint: {Default: true, PreRelease: featuregate.Beta},
|
||||||
|
Loading…
Reference in New Issue
Block a user