mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-12-24 16:57:27 +00:00
Merge pull request #127094 from sreeram-venkitesh/4818-allow-zero-for-prestop-hook
KEP-4818: Relaxed validation for allowing zero in PreStop hook sleep action
This commit is contained in:
@@ -3068,52 +3068,52 @@ func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResource
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateLivenessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateLivenessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath, opts)...)
|
||||
if probe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateReadinessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateReadinessProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath, opts)...)
|
||||
if probe.TerminationGracePeriodSeconds != nil {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("terminationGracePeriodSeconds"), probe.TerminationGracePeriodSeconds, "must not be set for readinessProbes"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateStartupProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateStartupProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath)...)
|
||||
allErrs = append(allErrs, validateProbe(probe, gracePeriod, fldPath, opts)...)
|
||||
if probe.SuccessThreshold != 1 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("successThreshold"), probe.SuccessThreshold, "must be 1"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateProbe(probe *core.Probe, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if probe == nil {
|
||||
return allErrs
|
||||
}
|
||||
allErrs = append(allErrs, validateHandler(handlerFromProbe(&probe.ProbeHandler), gracePeriod, fldPath)...)
|
||||
allErrs = append(allErrs, validateHandler(handlerFromProbe(&probe.ProbeHandler), gracePeriod, fldPath, opts)...)
|
||||
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.InitialDelaySeconds), fldPath.Child("initialDelaySeconds"))...)
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(int64(probe.TimeoutSeconds), fldPath.Child("timeoutSeconds"))...)
|
||||
@@ -3169,14 +3169,21 @@ func handlerFromLifecycle(lh *core.LifecycleHandler) commonHandler {
|
||||
}
|
||||
}
|
||||
|
||||
func validateSleepAction(sleep *core.SleepAction, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateSleepAction(sleep *core.SleepAction, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrors := field.ErrorList{}
|
||||
// We allow gracePeriod to be nil here because the pod in which this SleepAction
|
||||
// is defined might have an invalid grace period defined, and we don't want to
|
||||
// flag another error here when the real problem will already be flagged.
|
||||
if gracePeriod != nil && sleep.Seconds <= 0 || sleep.Seconds > *gracePeriod {
|
||||
invalidStr := fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d)", *gracePeriod)
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, sleep.Seconds, invalidStr))
|
||||
if opts.AllowPodLifecycleSleepActionZeroValue {
|
||||
if gracePeriod != nil && (sleep.Seconds < 0 || sleep.Seconds > *gracePeriod) {
|
||||
invalidStr := fmt.Sprintf("must be non-negative and less than terminationGracePeriodSeconds (%d)", *gracePeriod)
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, sleep.Seconds, invalidStr))
|
||||
}
|
||||
} else {
|
||||
if gracePeriod != nil && (sleep.Seconds <= 0 || sleep.Seconds > *gracePeriod) {
|
||||
invalidStr := fmt.Sprintf("must be greater than 0 and less than terminationGracePeriodSeconds (%d). Enable AllowPodLifecycleSleepActionZeroValue feature gate for zero sleep.", *gracePeriod)
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, sleep.Seconds, invalidStr))
|
||||
}
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
@@ -3289,7 +3296,7 @@ func validateTCPSocketAction(tcp *core.TCPSocketAction, fldPath *field.Path) fie
|
||||
func validateGRPCAction(grpc *core.GRPCAction, fldPath *field.Path) field.ErrorList {
|
||||
return ValidatePortNumOrName(intstr.FromInt32(grpc.Port), fldPath.Child("port"))
|
||||
}
|
||||
func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
numHandlers := 0
|
||||
allErrors := field.ErrorList{}
|
||||
if handler.Exec != nil {
|
||||
@@ -3329,7 +3336,7 @@ func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.P
|
||||
allErrors = append(allErrors, field.Forbidden(fldPath.Child("sleep"), "may not specify more than 1 handler type"))
|
||||
} else {
|
||||
numHandlers++
|
||||
allErrors = append(allErrors, validateSleepAction(handler.Sleep, gracePeriod, fldPath.Child("sleep"))...)
|
||||
allErrors = append(allErrors, validateSleepAction(handler.Sleep, gracePeriod, fldPath.Child("sleep"), opts)...)
|
||||
}
|
||||
}
|
||||
if numHandlers == 0 {
|
||||
@@ -3338,13 +3345,13 @@ func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.P
|
||||
return allErrors
|
||||
}
|
||||
|
||||
func validateLifecycle(lifecycle *core.Lifecycle, gracePeriod *int64, fldPath *field.Path) field.ErrorList {
|
||||
func validateLifecycle(lifecycle *core.Lifecycle, gracePeriod *int64, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if lifecycle.PostStart != nil {
|
||||
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PostStart), gracePeriod, fldPath.Child("postStart"))...)
|
||||
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PostStart), gracePeriod, fldPath.Child("postStart"), opts)...)
|
||||
}
|
||||
if lifecycle.PreStop != nil {
|
||||
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PreStop), gracePeriod, fldPath.Child("preStop"))...)
|
||||
allErrs = append(allErrs, validateHandler(handlerFromLifecycle(lifecycle.PreStop), gracePeriod, fldPath.Child("preStop"), opts)...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
@@ -3523,11 +3530,11 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
|
||||
switch {
|
||||
case restartAlways:
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, idxPath.Child("lifecycle"))...)
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, idxPath.Child("lifecycle"), opts)...)
|
||||
}
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, idxPath.Child("livenessProbe"))...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, idxPath.Child("readinessProbe"))...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, idxPath.Child("startupProbe"))...)
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, idxPath.Child("livenessProbe"), opts)...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, idxPath.Child("readinessProbe"), opts)...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, idxPath.Child("startupProbe"), opts)...)
|
||||
|
||||
default:
|
||||
// These fields are disallowed for init containers.
|
||||
@@ -3655,11 +3662,11 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
|
||||
// Regular init container and ephemeral container validation will return
|
||||
// field.Forbidden() for these paths.
|
||||
if ctr.Lifecycle != nil {
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, path.Child("lifecycle"))...)
|
||||
allErrs = append(allErrs, validateLifecycle(ctr.Lifecycle, gracePeriod, path.Child("lifecycle"), opts)...)
|
||||
}
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, path.Child("livenessProbe"))...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, path.Child("readinessProbe"))...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, path.Child("startupProbe"))...)
|
||||
allErrs = append(allErrs, validateLivenessProbe(ctr.LivenessProbe, gracePeriod, path.Child("livenessProbe"), opts)...)
|
||||
allErrs = append(allErrs, validateReadinessProbe(ctr.ReadinessProbe, gracePeriod, path.Child("readinessProbe"), opts)...)
|
||||
allErrs = append(allErrs, validateStartupProbe(ctr.StartupProbe, gracePeriod, path.Child("startupProbe"), opts)...)
|
||||
|
||||
// These fields are disallowed for regular containers
|
||||
if ctr.RestartPolicy != nil {
|
||||
@@ -4049,6 +4056,8 @@ type PodValidationOptions struct {
|
||||
AllowRelaxedEnvironmentVariableValidation bool
|
||||
// Allow the use of a relaxed DNS search
|
||||
AllowRelaxedDNSSearchValidation bool
|
||||
// Allows zero value for Pod Lifecycle Sleep Action
|
||||
AllowPodLifecycleSleepActionZeroValue bool
|
||||
}
|
||||
|
||||
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
|
||||
|
||||
Reference in New Issue
Block a user