Validate deployment

This commit is contained in:
nikhiljindal
2015-08-25 12:07:03 -07:00
parent 2321d9ee26
commit 92f373a4b6
9 changed files with 375 additions and 139 deletions

View File

@@ -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
}