Validate deployment
This commit is contained in:
@@ -17,6 +17,8 @@ limitations under the License.
|
||||
package validation
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
apivalidation "k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/expapi"
|
||||
@@ -156,3 +158,102 @@ func ValidateDaemonSpec(spec *expapi.DaemonSpec) errs.ValidationErrorList {
|
||||
func ValidateDaemonName(name string, prefix bool) (bool, string) {
|
||||
return apivalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
// Validates that the given name can be used as a deployment name.
|
||||
func ValidateDeploymentName(name string, prefix bool) (bool, string) {
|
||||
return apivalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
func ValidatePositiveIntOrPercent(intOrPercent util.IntOrString, fieldName string) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
if intOrPercent.Kind == util.IntstrString {
|
||||
if !util.IsValidPercent(intOrPercent.StrVal) {
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrPercent, "value should be int(5) or percentage(5%)"))
|
||||
}
|
||||
|
||||
} else if intOrPercent.Kind == util.IntstrInt {
|
||||
allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(intOrPercent.IntVal), fieldName)...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func getPercentValue(intOrStringValue util.IntOrString) (int, bool) {
|
||||
if intOrStringValue.Kind != util.IntstrString || !util.IsValidPercent(intOrStringValue.StrVal) {
|
||||
return 0, false
|
||||
}
|
||||
value, _ := strconv.Atoi(intOrStringValue.StrVal[:len(intOrStringValue.StrVal)-1])
|
||||
return value, true
|
||||
}
|
||||
|
||||
func getIntOrPercentValue(intOrStringValue util.IntOrString) int {
|
||||
value, isPercent := getPercentValue(intOrStringValue)
|
||||
if isPercent {
|
||||
return value
|
||||
}
|
||||
return intOrStringValue.IntVal
|
||||
}
|
||||
|
||||
func IsNotMoreThan100Percent(intOrStringValue util.IntOrString, fieldName string) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
value, isPercent := getPercentValue(intOrStringValue)
|
||||
if !isPercent || value <= 100 {
|
||||
return nil
|
||||
}
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid(fieldName, intOrStringValue, "should not be more than 100%"))
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateRollingUpdateDeployment(rollingUpdate *expapi.RollingUpdateDeployment, fieldName string) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxUnavailable, fieldName+"maxUnavailable")...)
|
||||
allErrs = append(allErrs, ValidatePositiveIntOrPercent(rollingUpdate.MaxSurge, fieldName+".maxSurge")...)
|
||||
if getIntOrPercentValue(rollingUpdate.MaxUnavailable) == 0 && getIntOrPercentValue(rollingUpdate.MaxSurge) == 0 {
|
||||
// Both MaxSurge and MaxUnavailable cannot be zero.
|
||||
allErrs = append(allErrs, errs.NewFieldInvalid(fieldName+".maxUnavailable", rollingUpdate.MaxUnavailable, "cannot be 0 when maxSurge is 0 as well"))
|
||||
}
|
||||
// Validate that MaxUnavailable is not more than 100%.
|
||||
allErrs = append(allErrs, IsNotMoreThan100Percent(rollingUpdate.MaxUnavailable, fieldName+".maxUnavailable")...)
|
||||
allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(rollingUpdate.MinReadySeconds), fieldName+".minReadySeconds")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateDeploymentStrategy(strategy *expapi.DeploymentStrategy, fieldName string) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
if strategy.RollingUpdate == nil {
|
||||
return allErrs
|
||||
}
|
||||
switch strategy.Type {
|
||||
case expapi.DeploymentRecreate:
|
||||
allErrs = append(allErrs, errs.NewFieldForbidden("rollingUpdate", "rollingUpdate should be nil when strategy type is "+expapi.DeploymentRecreate))
|
||||
case expapi.DeploymentRollingUpdate:
|
||||
allErrs = append(allErrs, ValidateRollingUpdateDeployment(strategy.RollingUpdate, "rollingUpdate")...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// Validates given deployment spec.
|
||||
func ValidateDeploymentSpec(spec *expapi.DeploymentSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateNonEmptySelector(spec.Selector, "selector")...)
|
||||
allErrs = append(allErrs, apivalidation.ValidatePositiveField(int64(spec.Replicas), "replicas")...)
|
||||
allErrs = append(allErrs, apivalidation.ValidatePodTemplateSpecForRC(spec.Template, spec.Selector, spec.Replicas, "template")...)
|
||||
allErrs = append(allErrs, ValidateDeploymentStrategy(&spec.Strategy, "strategy")...)
|
||||
if spec.UniqueLabelKey != nil {
|
||||
allErrs = append(allErrs, apivalidation.ValidateLabelName(*spec.UniqueLabelKey, "uniqueLabel")...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateDeploymentUpdate(old, update *expapi.Deployment) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMetaUpdate(&update.ObjectMeta, &old.ObjectMeta).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDeploymentSpec(&update.Spec).Prefix("spec")...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateDeployment(obj *expapi.Deployment) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
allErrs = append(allErrs, apivalidation.ValidateObjectMeta(&obj.ObjectMeta, true, ValidateDeploymentName).Prefix("metadata")...)
|
||||
allErrs = append(allErrs, ValidateDeploymentSpec(&obj.Spec).Prefix("spec")...)
|
||||
return allErrs
|
||||
}
|
||||
|
Reference in New Issue
Block a user