@@ -3068,52 +3068,52 @@ func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResource
3068
3068
return allErrs
3069
3069
}
3070
3070
3071
- func validateLivenessProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3071
+ func validateLivenessProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3072
3072
allErrs := field.ErrorList {}
3073
3073
3074
3074
if probe == nil {
3075
3075
return allErrs
3076
3076
}
3077
- allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath )... )
3077
+ allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath , opts )... )
3078
3078
if probe .SuccessThreshold != 1 {
3079
3079
allErrs = append (allErrs , field .Invalid (fldPath .Child ("successThreshold" ), probe .SuccessThreshold , "must be 1" ))
3080
3080
}
3081
3081
return allErrs
3082
3082
}
3083
3083
3084
- func validateReadinessProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3084
+ func validateReadinessProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3085
3085
allErrs := field.ErrorList {}
3086
3086
3087
3087
if probe == nil {
3088
3088
return allErrs
3089
3089
}
3090
- allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath )... )
3090
+ allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath , opts )... )
3091
3091
if probe .TerminationGracePeriodSeconds != nil {
3092
3092
allErrs = append (allErrs , field .Invalid (fldPath .Child ("terminationGracePeriodSeconds" ), probe .TerminationGracePeriodSeconds , "must not be set for readinessProbes" ))
3093
3093
}
3094
3094
return allErrs
3095
3095
}
3096
3096
3097
- func validateStartupProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3097
+ func validateStartupProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3098
3098
allErrs := field.ErrorList {}
3099
3099
3100
3100
if probe == nil {
3101
3101
return allErrs
3102
3102
}
3103
- allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath )... )
3103
+ allErrs = append (allErrs , validateProbe (probe , gracePeriod , fldPath , opts )... )
3104
3104
if probe .SuccessThreshold != 1 {
3105
3105
allErrs = append (allErrs , field .Invalid (fldPath .Child ("successThreshold" ), probe .SuccessThreshold , "must be 1" ))
3106
3106
}
3107
3107
return allErrs
3108
3108
}
3109
3109
3110
- func validateProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3110
+ func validateProbe (probe * core.Probe , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3111
3111
allErrs := field.ErrorList {}
3112
3112
3113
3113
if probe == nil {
3114
3114
return allErrs
3115
3115
}
3116
- allErrs = append (allErrs , validateHandler (handlerFromProbe (& probe .ProbeHandler ), gracePeriod , fldPath )... )
3116
+ allErrs = append (allErrs , validateHandler (handlerFromProbe (& probe .ProbeHandler ), gracePeriod , fldPath , opts )... )
3117
3117
3118
3118
allErrs = append (allErrs , ValidateNonnegativeField (int64 (probe .InitialDelaySeconds ), fldPath .Child ("initialDelaySeconds" ))... )
3119
3119
allErrs = append (allErrs , ValidateNonnegativeField (int64 (probe .TimeoutSeconds ), fldPath .Child ("timeoutSeconds" ))... )
@@ -3169,14 +3169,21 @@ func handlerFromLifecycle(lh *core.LifecycleHandler) commonHandler {
3169
3169
}
3170
3170
}
3171
3171
3172
- func validateSleepAction (sleep * core.SleepAction , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3172
+ func validateSleepAction (sleep * core.SleepAction , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3173
3173
allErrors := field.ErrorList {}
3174
3174
// We allow gracePeriod to be nil here because the pod in which this SleepAction
3175
3175
// is defined might have an invalid grace period defined, and we don't want to
3176
3176
// flag another error here when the real problem will already be flagged.
3177
- if gracePeriod != nil && sleep .Seconds <= 0 || sleep .Seconds > * gracePeriod {
3178
- invalidStr := fmt .Sprintf ("must be greater than 0 and less than terminationGracePeriodSeconds (%d)" , * gracePeriod )
3179
- allErrors = append (allErrors , field .Invalid (fldPath , sleep .Seconds , invalidStr ))
3177
+ if opts .AllowPodLifecycleSleepActionZeroValue {
3178
+ if gracePeriod != nil && (sleep .Seconds < 0 || sleep .Seconds > * gracePeriod ) {
3179
+ invalidStr := fmt .Sprintf ("must be non-negative and less than terminationGracePeriodSeconds (%d)" , * gracePeriod )
3180
+ allErrors = append (allErrors , field .Invalid (fldPath , sleep .Seconds , invalidStr ))
3181
+ }
3182
+ } else {
3183
+ if gracePeriod != nil && (sleep .Seconds <= 0 || sleep .Seconds > * gracePeriod ) {
3184
+ invalidStr := fmt .Sprintf ("must be greater than 0 and less than terminationGracePeriodSeconds (%d). Enable AllowPodLifecycleSleepActionZeroValue feature gate for zero sleep." , * gracePeriod )
3185
+ allErrors = append (allErrors , field .Invalid (fldPath , sleep .Seconds , invalidStr ))
3186
+ }
3180
3187
}
3181
3188
return allErrors
3182
3189
}
@@ -3289,7 +3296,7 @@ func validateTCPSocketAction(tcp *core.TCPSocketAction, fldPath *field.Path) fie
3289
3296
func validateGRPCAction (grpc * core.GRPCAction , fldPath * field.Path ) field.ErrorList {
3290
3297
return ValidatePortNumOrName (intstr .FromInt32 (grpc .Port ), fldPath .Child ("port" ))
3291
3298
}
3292
- func validateHandler (handler commonHandler , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3299
+ func validateHandler (handler commonHandler , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3293
3300
numHandlers := 0
3294
3301
allErrors := field.ErrorList {}
3295
3302
if handler .Exec != nil {
@@ -3329,7 +3336,7 @@ func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.P
3329
3336
allErrors = append (allErrors , field .Forbidden (fldPath .Child ("sleep" ), "may not specify more than 1 handler type" ))
3330
3337
} else {
3331
3338
numHandlers ++
3332
- allErrors = append (allErrors , validateSleepAction (handler .Sleep , gracePeriod , fldPath .Child ("sleep" ))... )
3339
+ allErrors = append (allErrors , validateSleepAction (handler .Sleep , gracePeriod , fldPath .Child ("sleep" ), opts )... )
3333
3340
}
3334
3341
}
3335
3342
if numHandlers == 0 {
@@ -3338,13 +3345,13 @@ func validateHandler(handler commonHandler, gracePeriod *int64, fldPath *field.P
3338
3345
return allErrors
3339
3346
}
3340
3347
3341
- func validateLifecycle (lifecycle * core.Lifecycle , gracePeriod * int64 , fldPath * field.Path ) field.ErrorList {
3348
+ func validateLifecycle (lifecycle * core.Lifecycle , gracePeriod * int64 , fldPath * field.Path , opts PodValidationOptions ) field.ErrorList {
3342
3349
allErrs := field.ErrorList {}
3343
3350
if lifecycle .PostStart != nil {
3344
- allErrs = append (allErrs , validateHandler (handlerFromLifecycle (lifecycle .PostStart ), gracePeriod , fldPath .Child ("postStart" ))... )
3351
+ allErrs = append (allErrs , validateHandler (handlerFromLifecycle (lifecycle .PostStart ), gracePeriod , fldPath .Child ("postStart" ), opts )... )
3345
3352
}
3346
3353
if lifecycle .PreStop != nil {
3347
- allErrs = append (allErrs , validateHandler (handlerFromLifecycle (lifecycle .PreStop ), gracePeriod , fldPath .Child ("preStop" ))... )
3354
+ allErrs = append (allErrs , validateHandler (handlerFromLifecycle (lifecycle .PreStop ), gracePeriod , fldPath .Child ("preStop" ), opts )... )
3348
3355
}
3349
3356
return allErrs
3350
3357
}
@@ -3523,11 +3530,11 @@ func validateInitContainers(containers []core.Container, regularContainers []cor
3523
3530
switch {
3524
3531
case restartAlways :
3525
3532
if ctr .Lifecycle != nil {
3526
- allErrs = append (allErrs , validateLifecycle (ctr .Lifecycle , gracePeriod , idxPath .Child ("lifecycle" ))... )
3533
+ allErrs = append (allErrs , validateLifecycle (ctr .Lifecycle , gracePeriod , idxPath .Child ("lifecycle" ), opts )... )
3527
3534
}
3528
- allErrs = append (allErrs , validateLivenessProbe (ctr .LivenessProbe , gracePeriod , idxPath .Child ("livenessProbe" ))... )
3529
- allErrs = append (allErrs , validateReadinessProbe (ctr .ReadinessProbe , gracePeriod , idxPath .Child ("readinessProbe" ))... )
3530
- allErrs = append (allErrs , validateStartupProbe (ctr .StartupProbe , gracePeriod , idxPath .Child ("startupProbe" ))... )
3535
+ allErrs = append (allErrs , validateLivenessProbe (ctr .LivenessProbe , gracePeriod , idxPath .Child ("livenessProbe" ), opts )... )
3536
+ allErrs = append (allErrs , validateReadinessProbe (ctr .ReadinessProbe , gracePeriod , idxPath .Child ("readinessProbe" ), opts )... )
3537
+ allErrs = append (allErrs , validateStartupProbe (ctr .StartupProbe , gracePeriod , idxPath .Child ("startupProbe" ), opts )... )
3531
3538
3532
3539
default :
3533
3540
// These fields are disallowed for init containers.
@@ -3655,11 +3662,11 @@ func validateContainers(containers []core.Container, volumes map[string]core.Vol
3655
3662
// Regular init container and ephemeral container validation will return
3656
3663
// field.Forbidden() for these paths.
3657
3664
if ctr .Lifecycle != nil {
3658
- allErrs = append (allErrs , validateLifecycle (ctr .Lifecycle , gracePeriod , path .Child ("lifecycle" ))... )
3665
+ allErrs = append (allErrs , validateLifecycle (ctr .Lifecycle , gracePeriod , path .Child ("lifecycle" ), opts )... )
3659
3666
}
3660
- allErrs = append (allErrs , validateLivenessProbe (ctr .LivenessProbe , gracePeriod , path .Child ("livenessProbe" ))... )
3661
- allErrs = append (allErrs , validateReadinessProbe (ctr .ReadinessProbe , gracePeriod , path .Child ("readinessProbe" ))... )
3662
- allErrs = append (allErrs , validateStartupProbe (ctr .StartupProbe , gracePeriod , path .Child ("startupProbe" ))... )
3667
+ allErrs = append (allErrs , validateLivenessProbe (ctr .LivenessProbe , gracePeriod , path .Child ("livenessProbe" ), opts )... )
3668
+ allErrs = append (allErrs , validateReadinessProbe (ctr .ReadinessProbe , gracePeriod , path .Child ("readinessProbe" ), opts )... )
3669
+ allErrs = append (allErrs , validateStartupProbe (ctr .StartupProbe , gracePeriod , path .Child ("startupProbe" ), opts )... )
3663
3670
3664
3671
// These fields are disallowed for regular containers
3665
3672
if ctr .RestartPolicy != nil {
@@ -4049,6 +4056,8 @@ type PodValidationOptions struct {
4049
4056
AllowRelaxedEnvironmentVariableValidation bool
4050
4057
// Allow the use of a relaxed DNS search
4051
4058
AllowRelaxedDNSSearchValidation bool
4059
+ // Allows zero value for Pod Lifecycle Sleep Action
4060
+ AllowPodLifecycleSleepActionZeroValue bool
4052
4061
}
4053
4062
4054
4063
// validatePodMetadataAndSpec tests if required fields in the pod.metadata and pod.spec are set,
0 commit comments