Introduce DeclarativeValidationBeta and deprecate Takeover gate

This change introduces the DeclarativeValidationBeta feature gate in v1.36
as the global safety switch for Beta-stage validation rules and marks
DeclarativeValidationTakeover as deprecated.

Following KEP-5073.
This commit is contained in:
yongruilin 2026-02-06 23:48:21 +00:00
parent fc74562c38
commit 0c679cea68
4 changed files with 43 additions and 2 deletions

View file

@ -1973,8 +1973,13 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.36, remove in 1.39
},
genericfeatures.DeclarativeValidationBeta: {
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta},
},
genericfeatures.DeclarativeValidationTakeover: {
{Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Deprecated},
},
genericfeatures.DetectCacheInconsistency: {
@ -2452,6 +2457,7 @@ var defaultKubernetesFeatureGateDependencies = map[featuregate.Feature][]feature
genericfeatures.DeclarativeValidation: {},
genericfeatures.DeclarativeValidationBeta: {genericfeatures.DeclarativeValidation},
genericfeatures.DeclarativeValidationTakeover: {genericfeatures.DeclarativeValidation},
genericfeatures.DetectCacheInconsistency: {},

View file

@ -128,13 +128,32 @@ const (
// Enables running declarative validation of APIs, where declared. When enabled, APIs with
// declarative validation rules will validate objects using the generated
// declarative validation code and compare the results to the regular imperative validation.
// See DeclarativeValidationTakeover for more.
// See DeclarativeValidationBeta for more.
DeclarativeValidation featuregate.Feature = "DeclarativeValidation"
// owner: @jpbetz @aaron-prindle @yongruilin
// kep: http://kep.k8s.io/5073
// beta: v1.36
//
// This feature gate acts as the Global Safety Switch for Beta-stage validation rules (+k8s:beta).
// It allows cluster admins to disable enforcement for validations in the Beta stage if
// regressions are found, forcing them back to Shadow mode.
// In Shadow mode, declarative validation is executed and mismatches against handwritten
// validation are logged as metrics, but failures do not reject requests.
// Handwritten validation remains authoritative and enforced.
// Enforcement logic for resources using WithDeclarativeEnforcement():
// - Standard tags (no prefix): Always Enforced (Bypasses this gate).
// - Beta tags (+k8s:beta): Enforced when this gate is enabled (default), otherwise Shadowed.
// - Alpha tags (+k8s:alpha): Always Shadowed.
// This gate has no effect if the master DeclarativeValidation feature gate is disabled.
DeclarativeValidationBeta featuregate.Feature = "DeclarativeValidationBeta"
// owner: @jpbetz @aaron-prindle @yongruilin
// kep: http://kep.k8s.io/5073
// beta: v1.33
//
// Deprecated: in favor of DeclarativeValidationBeta.
//
// When enabled, declarative validation errors are returned directly to the caller,
// replacing hand-written validation errors for rules that have declarative implementations.
// When disabled, hand-written validation errors are always returned, effectively putting
@ -375,8 +394,13 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // GA and LockToDefault in 1.36, remove in 1.39
},
DeclarativeValidationBeta: {
{Version: version.MustParse("1.36"), Default: true, PreRelease: featuregate.Beta},
},
DeclarativeValidationTakeover: {
{Version: version.MustParse("1.33"), Default: false, PreRelease: featuregate.Beta},
{Version: version.MustParse("1.36"), Default: false, PreRelease: featuregate.Deprecated},
},
DetectCacheInconsistency: {

View file

@ -61,7 +61,8 @@
| DRAResourceClaimDeviceStatus | :ballot_box_with_check: 1.33+ | | 1.32 | 1.33 | | | | [code](https://cs.k8s.io/?q=%5CbDRAResourceClaimDeviceStatus%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDRAResourceClaimDeviceStatus%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DRASchedulerFilterTimeout | :ballot_box_with_check: 1.34+ | | | 1.34 | | | DynamicResourceAllocation | [code](https://cs.k8s.io/?q=%5CbDRASchedulerFilterTimeout%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDRASchedulerFilterTimeout%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DeclarativeValidation | :ballot_box_with_check: 1.33+ | :closed_lock_with_key: 1.36+ | | 1.331.35 | 1.36 | | | [code](https://cs.k8s.io/?q=%5CbDeclarativeValidation%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDeclarativeValidation%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DeclarativeValidationTakeover | | | | 1.33 | | | DeclarativeValidation | [code](https://cs.k8s.io/?q=%5CbDeclarativeValidationTakeover%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDeclarativeValidationTakeover%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DeclarativeValidationBeta | :ballot_box_with_check: 1.36+ | | | 1.36 | | | DeclarativeValidation | [code](https://cs.k8s.io/?q=%5CbDeclarativeValidationBeta%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDeclarativeValidationBeta%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DeclarativeValidationTakeover | | | | 1.331.35 | | 1.36 | DeclarativeValidation | [code](https://cs.k8s.io/?q=%5CbDeclarativeValidationTakeover%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDeclarativeValidationTakeover%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DeploymentReplicaSetTerminatingReplicas | :ballot_box_with_check: 1.35+ | | 1.331.34 | 1.35 | | | | [code](https://cs.k8s.io/?q=%5CbDeploymentReplicaSetTerminatingReplicas%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDeploymentReplicaSetTerminatingReplicas%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DetectCacheInconsistency | :ballot_box_with_check: 1.34+ | | | 1.34 | | | | [code](https://cs.k8s.io/?q=%5CbDetectCacheInconsistency%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDetectCacheInconsistency%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |
| DisableAllocatorDualWrite | :ballot_box_with_check: 1.34+ | :closed_lock_with_key: 1.35+ | 1.311.32 | 1.33 | 1.34 | | MultiCIDRServiceAllocator | [code](https://cs.k8s.io/?q=%5CbDisableAllocatorDualWrite%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/kubernetes) [KEPs](https://cs.k8s.io/?q=%5CbDisableAllocatorDualWrite%5Cb&i=nope&files=&excludeFiles=CHANGELOG&repos=kubernetes/enhancements) |

View file

@ -413,12 +413,22 @@
lockToDefault: true
preRelease: GA
version: "1.36"
- name: DeclarativeValidationBeta
versionedSpecs:
- default: true
lockToDefault: false
preRelease: Beta
version: "1.36"
- name: DeclarativeValidationTakeover
versionedSpecs:
- default: false
lockToDefault: false
preRelease: Beta
version: "1.33"
- default: false
lockToDefault: false
preRelease: Deprecated
version: "1.36"
- name: DeploymentReplicaSetTerminatingReplicas
versionedSpecs:
- default: false