mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
ReplicationController: Enable declarative validation
After declarative validation is enabled in the ReplicationController strategy in this way, the generated declarative validation code in pkg/apis/core/v1/zz.generated.validations.go will be run when the strategy validates ReplicationController. Co-authored-by: Tim Hockin <thockin@google.com> Co-authored-by: Aaron Prindle <aprindle@google.com> Co-authored-by: Yongrui Lin <yongrlin@google.com> Co-authored-by: David Eads <deads@redhat.com>
This commit is contained in:
parent
e856356225
commit
5a5ed81e1f
@ -37,11 +37,13 @@ import (
|
|||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
apistorage "k8s.io/apiserver/pkg/storage"
|
apistorage "k8s.io/apiserver/pkg/storage"
|
||||||
"k8s.io/apiserver/pkg/storage/names"
|
"k8s.io/apiserver/pkg/storage/names"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/api/pod"
|
"k8s.io/kubernetes/pkg/api/pod"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||||
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -123,7 +125,27 @@ func (rcStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object)
|
|||||||
func (rcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
func (rcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||||
controller := obj.(*api.ReplicationController)
|
controller := obj.(*api.ReplicationController)
|
||||||
opts := pod.GetValidationOptionsFromPodTemplate(controller.Spec.Template, nil)
|
opts := pod.GetValidationOptionsFromPodTemplate(controller.Spec.Template, nil)
|
||||||
return corevalidation.ValidateReplicationController(controller, opts)
|
|
||||||
|
// Run imperative validation
|
||||||
|
allErrs := corevalidation.ValidateReplicationController(controller, opts)
|
||||||
|
|
||||||
|
// If DeclarativeValidation feature gate is enabled, also run declarative validation
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidation) {
|
||||||
|
// Determine if takeover is enabled
|
||||||
|
takeover := utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidationTakeover)
|
||||||
|
|
||||||
|
// Run declarative validation with panic recovery
|
||||||
|
declarativeErrs := rest.ValidateDeclarativelyWithRecovery(ctx, nil, legacyscheme.Scheme, controller, takeover)
|
||||||
|
|
||||||
|
// Compare imperative and declarative errors and log + emit metric if there's a mismatch
|
||||||
|
rest.CompareDeclarativeErrorsAndEmitMismatches(ctx, allErrs, declarativeErrs, takeover)
|
||||||
|
|
||||||
|
// Only apply declarative errors if takeover is enabled
|
||||||
|
if takeover {
|
||||||
|
allErrs = append(allErrs.RemoveCoveredByDeclarative(), declarativeErrs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningsOnCreate returns warnings for the creation of the given object.
|
// WarningsOnCreate returns warnings for the creation of the given object.
|
||||||
@ -153,6 +175,8 @@ func (rcStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) f
|
|||||||
newRc := obj.(*api.ReplicationController)
|
newRc := obj.(*api.ReplicationController)
|
||||||
|
|
||||||
opts := pod.GetValidationOptionsFromPodTemplate(newRc.Spec.Template, oldRc.Spec.Template)
|
opts := pod.GetValidationOptionsFromPodTemplate(newRc.Spec.Template, oldRc.Spec.Template)
|
||||||
|
// FIXME: Calling both validator functions here results in redundant calls to ValidateReplicationControllerSpec.
|
||||||
|
// This should be fixed to avoid the redundant calls, but carefully.
|
||||||
validationErrorList := corevalidation.ValidateReplicationController(newRc, opts)
|
validationErrorList := corevalidation.ValidateReplicationController(newRc, opts)
|
||||||
updateErrorList := corevalidation.ValidateReplicationControllerUpdate(newRc, oldRc, opts)
|
updateErrorList := corevalidation.ValidateReplicationControllerUpdate(newRc, oldRc, opts)
|
||||||
errs := append(validationErrorList, updateErrorList...)
|
errs := append(validationErrorList, updateErrorList...)
|
||||||
@ -174,6 +198,23 @@ func (rcStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If DeclarativeValidation feature gate is enabled, also run declarative validation
|
||||||
|
if utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidation) {
|
||||||
|
// Determine if takeover is enabled
|
||||||
|
takeover := utilfeature.DefaultFeatureGate.Enabled(features.DeclarativeValidationTakeover)
|
||||||
|
|
||||||
|
// Run declarative update validation with panic recovery
|
||||||
|
declarativeErrs := rest.ValidateUpdateDeclarativelyWithRecovery(ctx, nil, legacyscheme.Scheme, newRc, oldRc, takeover)
|
||||||
|
|
||||||
|
// Compare imperative and declarative errors and emit metric if there's a mismatch
|
||||||
|
rest.CompareDeclarativeErrorsAndEmitMismatches(ctx, errs, declarativeErrs, takeover)
|
||||||
|
|
||||||
|
// Only apply declarative errors if takeover is enabled
|
||||||
|
if takeover {
|
||||||
|
errs = append(errs.RemoveCoveredByDeclarative(), declarativeErrs...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return errs
|
return errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user