validation: Handle presence of MaxSurge on DaemonSet

When the maxsurge daemonset gate is disabled, the registry and validation
must properly handle stripping the field. In the special case where that
would leave the MaxUnavailable field set to 0, we must set it to 1 which
is the default value.
This commit is contained in:
Clayton Coleman
2020-11-09 10:30:05 -05:00
parent 4a23269778
commit c37c93f47a
6 changed files with 462 additions and 7 deletions

View File

@@ -28,9 +28,11 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/kubernetes/pkg/apis/apps"
api "k8s.io/kubernetes/pkg/apis/core"
apivalidation "k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/features"
)
// ValidateStatefulSetName can be used to check whether the given StatefulSet name is valid.
@@ -343,14 +345,35 @@ func ValidateDaemonSetSpec(spec *apps.DaemonSetSpec, fldPath *field.Path, opts a
// ValidateRollingUpdateDaemonSet validates a given RollingUpdateDaemonSet.
func ValidateRollingUpdateDaemonSet(rollingUpdate *apps.RollingUpdateDaemonSet, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 {
// MaxUnavailable cannot be 0.
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "cannot be 0"))
var allErrs field.ErrorList
if utilfeature.DefaultFeatureGate.Enabled(features.DaemonSetUpdateSurge) {
// Validate both fields are positive ints or have a percentage value
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fldPath.Child("maxSurge"))...)
// Validate that MaxUnavailable and MaxSurge are not more than 100%.
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxSurge, fldPath.Child("maxSurge"))...)
// Validate exactly one of MaxSurge or MaxUnavailable is non-zero
hasUnavailable := getIntOrPercentValue(rollingUpdate.MaxUnavailable) != 0
hasSurge := getIntOrPercentValue(rollingUpdate.MaxSurge) != 0
switch {
case hasUnavailable && hasSurge:
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxSurge"), rollingUpdate.MaxSurge, "may not be set when maxUnavailable is non-zero"))
case !hasUnavailable && !hasSurge:
allErrs = append(allErrs, field.Required(fldPath.Child("maxUnavailable"), "cannot be 0 when maxSurge is 0"))
}
} else {
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 {
// MaxUnavailable cannot be 0.
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxUnavailable"), rollingUpdate.MaxUnavailable, "cannot be 0"))
}
// Validate that MaxUnavailable is not more than 100%.
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
}
// Validate that MaxUnavailable is not more than 100%.
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fldPath.Child("maxUnavailable"))...)
return allErrs
}