// PodConstraintsFunc verifies that all required resources are present on the pod // In addition, it validates that the resources are valid (i.e. requests < limits) func PodConstraintsFunc(required []api.ResourceName, object runtime.Object) error { pod, ok := object.(*api.Pod) if !ok { return fmt.Errorf("Unexpected input object %v", object) } // Pod level resources are often set during admission control // As a consequence, we want to verify that resources are valid prior // to ever charging quota prematurely in case they are not. allErrs := field.ErrorList{} fldPath := field.NewPath("spec").Child("containers") for i, ctr := range pod.Spec.Containers { allErrs = append(allErrs, validation.ValidateResourceRequirements(&ctr.Resources, fldPath.Index(i).Child("resources"))...) } fldPath = field.NewPath("spec").Child("initContainers") for i, ctr := range pod.Spec.InitContainers { allErrs = append(allErrs, validation.ValidateResourceRequirements(&ctr.Resources, fldPath.Index(i).Child("resources"))...) } if len(allErrs) > 0 { return allErrs.ToAggregate() } // TODO: fix this when we have pod level cgroups // since we do not yet pod level requests/limits, we need to ensure each // container makes an explict request or limit for a quota tracked resource requiredSet := quota.ToSet(required) missingSet := sets.NewString() for i := range pod.Spec.Containers { enforcePodContainerConstraints(&pod.Spec.Containers[i], requiredSet, missingSet) } for i := range pod.Spec.InitContainers { enforcePodContainerConstraints(&pod.Spec.InitContainers[i], requiredSet, missingSet) } if len(missingSet) == 0 { return nil } return fmt.Errorf("must specify %s", strings.Join(missingSet.List(), ",")) }
func validateDeploymentStrategy(strategy *deployapi.DeploymentStrategy, pod *kapi.PodSpec, fldPath *field.Path) field.ErrorList { errs := field.ErrorList{} if len(strategy.Type) == 0 { errs = append(errs, field.Required(fldPath.Child("type"), "")) } if strategy.CustomParams != nil { errs = append(errs, validateCustomParams(strategy.CustomParams, fldPath.Child("customParams"))...) } switch strategy.Type { case deployapi.DeploymentStrategyTypeRecreate: if strategy.RecreateParams != nil { errs = append(errs, validateRecreateParams(strategy.RecreateParams, pod, fldPath.Child("recreateParams"))...) } case deployapi.DeploymentStrategyTypeRolling: if strategy.RollingParams == nil { errs = append(errs, field.Required(fldPath.Child("rollingParams"), "")) } else { errs = append(errs, validateRollingParams(strategy.RollingParams, pod, fldPath.Child("rollingParams"))...) } case deployapi.DeploymentStrategyTypeCustom: if strategy.CustomParams == nil { errs = append(errs, field.Required(fldPath.Child("customParams"), "")) } if strategy.RollingParams != nil { errs = append(errs, validateRollingParams(strategy.RollingParams, pod, fldPath.Child("rollingParams"))...) } if strategy.RecreateParams != nil { errs = append(errs, validateRecreateParams(strategy.RecreateParams, pod, fldPath.Child("recreateParams"))...) } case "": errs = append(errs, field.Required(fldPath.Child("type"), "strategy type is required")) default: errs = append(errs, field.Invalid(fldPath.Child("type"), strategy.Type, "unsupported strategy type, use \"Custom\" instead and specify your own strategy")) } if strategy.Labels != nil { errs = append(errs, unversionedvalidation.ValidateLabels(strategy.Labels, fldPath.Child("labels"))...) } if strategy.Annotations != nil { errs = append(errs, validation.ValidateAnnotations(strategy.Annotations, fldPath.Child("annotations"))...) } errs = append(errs, validation.ValidateResourceRequirements(&strategy.Resources, fldPath.Child("resources"))...) return errs }
func validateDeploymentStrategy(strategy *deployapi.DeploymentStrategy, pod *kapi.PodSpec, fldPath *field.Path) field.ErrorList { errs := field.ErrorList{} if len(strategy.Type) == 0 { errs = append(errs, field.Required(fldPath.Child("type"), "")) } if strategy.CustomParams != nil { errs = append(errs, validateCustomParams(strategy.CustomParams, fldPath.Child("customParams"))...) } switch strategy.Type { case deployapi.DeploymentStrategyTypeRecreate: if strategy.RecreateParams != nil { errs = append(errs, validateRecreateParams(strategy.RecreateParams, pod, fldPath.Child("recreateParams"))...) } case deployapi.DeploymentStrategyTypeRolling: if strategy.RollingParams == nil { errs = append(errs, field.Required(fldPath.Child("rollingParams"), "")) } else { errs = append(errs, validateRollingParams(strategy.RollingParams, pod, fldPath.Child("rollingParams"))...) } case deployapi.DeploymentStrategyTypeCustom: if strategy.CustomParams == nil { errs = append(errs, field.Required(fldPath.Child("customParams"), "")) } if strategy.RollingParams != nil { errs = append(errs, validateRollingParams(strategy.RollingParams, pod, fldPath.Child("rollingParams"))...) } if strategy.RecreateParams != nil { errs = append(errs, validateRecreateParams(strategy.RecreateParams, pod, fldPath.Child("recreateParams"))...) } case "": errs = append(errs, field.Required(fldPath.Child("type"), "strategy type is required")) default: errs = append(errs, field.Invalid(fldPath.Child("type"), strategy.Type, "unsupported strategy type, use \"Custom\" instead and specify your own strategy")) } if strategy.Labels != nil { errs = append(errs, unversionedvalidation.ValidateLabels(strategy.Labels, fldPath.Child("labels"))...) } if strategy.Annotations != nil { errs = append(errs, validation.ValidateAnnotations(strategy.Annotations, fldPath.Child("annotations"))...) } errs = append(errs, validation.ValidateResourceRequirements(&strategy.Resources, fldPath.Child("resources"))...) if strategy.ActiveDeadlineSeconds != nil { errs = append(errs, kapivalidation.ValidateNonnegativeField(*strategy.ActiveDeadlineSeconds, fldPath.Child("activeDeadlineSeconds"))...) var timeoutSeconds *int64 if strategy.RollingParams != nil { timeoutSeconds = strategy.RollingParams.TimeoutSeconds } else if strategy.RecreateParams != nil { timeoutSeconds = strategy.RecreateParams.TimeoutSeconds } if timeoutSeconds != nil && *strategy.ActiveDeadlineSeconds <= *timeoutSeconds { errs = append(errs, field.Invalid(fldPath.Child("activeDeadlineSeconds"), *strategy.ActiveDeadlineSeconds, "activeDeadlineSeconds must be greater than timeoutSeconds")) } } return errs }