mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-15 06:01:50 +00:00
feedback
This commit is contained in:
@@ -93,7 +93,6 @@ func NewValidator(s *schema.Structural, isResourceRoot bool, perCallLimit uint64
|
|||||||
// exist. declType is expected to be a CEL DeclType corresponding to the structural schema.
|
// exist. declType is expected to be a CEL DeclType corresponding to the structural schema.
|
||||||
// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input.
|
// perCallLimit was added for testing purpose only. Callers should always use const PerCallLimit from k8s.io/apiserver/pkg/apis/cel/config.go as input.
|
||||||
func validator(validationSchema, nodeSchema *schema.Structural, isResourceRoot bool, declType *cel.DeclType, perCallLimit uint64) *Validator {
|
func validator(validationSchema, nodeSchema *schema.Structural, isResourceRoot bool, declType *cel.DeclType, perCallLimit uint64) *Validator {
|
||||||
|
|
||||||
compilationSchema := *nodeSchema
|
compilationSchema := *nodeSchema
|
||||||
compilationSchema.XValidations = validationSchema.XValidations
|
compilationSchema.XValidations = validationSchema.XValidations
|
||||||
compiledRules, err := Compile(&compilationSchema, declType, perCallLimit, environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion(), true), StoredExpressionsEnvLoader())
|
compiledRules, err := Compile(&compilationSchema, declType, perCallLimit, environment.MustBaseEnvSet(environment.DefaultCompatibilityVersion(), true), StoredExpressionsEnvLoader())
|
||||||
@@ -291,7 +290,6 @@ func nestedToStructural(nested *schema.NestedValueValidation) *schema.Structural
|
|||||||
}
|
}
|
||||||
|
|
||||||
return structuralConversion
|
return structuralConversion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Validator) validate(ctx context.Context, fldPath *field.Path, obj, oldObj interface{}, correlation ratchetingOptions, costBudget int64) (errs field.ErrorList, remainingBudget int64) {
|
func (s *Validator) validate(ctx context.Context, fldPath *field.Path, obj, oldObj interface{}, correlation ratchetingOptions, costBudget int64) (errs field.ErrorList, remainingBudget int64) {
|
||||||
|
@@ -22,8 +22,15 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
// validateStructuralCompleteness checks that every specified field or array in s is also specified
|
// validateStructuralCompleteness checks that all value validations in s have
|
||||||
// outside of value validation.
|
// a structural counterpart so that every value validation applies to a value
|
||||||
|
// with a known schema:
|
||||||
|
// - validations for specific properties must have that property (or additionalProperties under an option) structurally defined
|
||||||
|
// - additionalProperties validations must have additionalProperties defined in the structural portion of the schema corresponding to that node
|
||||||
|
// - Items validations must have also have a corresponding items structurally
|
||||||
|
//
|
||||||
|
// The "structural" portion of the schema refers to all nodes in the
|
||||||
|
// schema traversible without following any NestedValueValidations.
|
||||||
func validateStructuralCompleteness(s *Structural, fldPath *field.Path, opts ValidationOptions) field.ErrorList {
|
func validateStructuralCompleteness(s *Structural, fldPath *field.Path, opts ValidationOptions) field.ErrorList {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil
|
return nil
|
||||||
@@ -69,17 +76,22 @@ func validateNestedValueValidationCompleteness(v *NestedValueValidation, s *Stru
|
|||||||
allErrs = append(allErrs, validateValueValidationCompleteness(&v.ValueValidation, s, sPath, vPath, opts)...)
|
allErrs = append(allErrs, validateValueValidationCompleteness(&v.ValueValidation, s, sPath, vPath, opts)...)
|
||||||
allErrs = append(allErrs, validateNestedValueValidationCompleteness(v.Items, s.Items, sPath.Child("items"), vPath.Child("items"), opts)...)
|
allErrs = append(allErrs, validateNestedValueValidationCompleteness(v.Items, s.Items, sPath.Child("items"), vPath.Child("items"), opts)...)
|
||||||
|
|
||||||
var additionalPropertiesSchema *Structural
|
var sAdditionalPropertiesSchema *Structural
|
||||||
if s.AdditionalProperties != nil && s.AdditionalProperties.Structural != nil {
|
if s.AdditionalProperties != nil {
|
||||||
additionalPropertiesSchema = s.AdditionalProperties.Structural
|
sAdditionalPropertiesSchema = s.AdditionalProperties.Structural
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, vFld := range v.Properties {
|
for k, vFld := range v.Properties {
|
||||||
if sFld, ok := s.Properties[k]; !ok {
|
if sFld, ok := s.Properties[k]; !ok {
|
||||||
if additionalPropertiesSchema == nil || !opts.AllowValidationPropertiesWithAdditionalProperties {
|
if sAdditionalPropertiesSchema == nil || !opts.AllowValidationPropertiesWithAdditionalProperties {
|
||||||
allErrs = append(allErrs, field.Required(sPath.Child("properties").Key(k), fmt.Sprintf("because it is defined in %s", vPath.Child("properties").Key(k))))
|
allErrs = append(allErrs, field.Required(sPath.Child("properties").Key(k), fmt.Sprintf("because it is defined in %s", vPath.Child("properties").Key(k))))
|
||||||
} else {
|
} else {
|
||||||
allErrs = append(allErrs, validateNestedValueValidationCompleteness(&vFld, additionalPropertiesSchema, sPath.Child("additionalProperties"), vPath.Child("properties").Key(k), opts)...)
|
// Allow validations on specific properties if there exists an
|
||||||
|
// additionalProperties structural schema specified instead of
|
||||||
|
// direct properties
|
||||||
|
// NOTE: This does not allow `additionalProperties: true` structural
|
||||||
|
// schema to be combined with specific property validations.
|
||||||
|
allErrs = append(allErrs, validateNestedValueValidationCompleteness(&vFld, sAdditionalPropertiesSchema, sPath.Child("additionalProperties"), vPath.Child("properties").Key(k), opts)...)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
allErrs = append(allErrs, validateNestedValueValidationCompleteness(&vFld, &sFld, sPath.Child("properties").Key(k), vPath.Child("properties").Key(k), opts)...)
|
allErrs = append(allErrs, validateNestedValueValidationCompleteness(&vFld, &sFld, sPath.Child("properties").Key(k), vPath.Child("properties").Key(k), opts)...)
|
||||||
|
@@ -78,7 +78,7 @@ type ValidationOptions struct {
|
|||||||
// * additionalProperties at the root is not allowed.
|
// * additionalProperties at the root is not allowed.
|
||||||
func ValidateStructural(fldPath *field.Path, s *Structural) field.ErrorList {
|
func ValidateStructural(fldPath *field.Path, s *Structural) field.ErrorList {
|
||||||
return ValidateStructuralWithOptions(fldPath, s, ValidationOptions{
|
return ValidateStructuralWithOptions(fldPath, s, ValidationOptions{
|
||||||
// This widens the schema for CRDs, so first few releases will still
|
// This would widen the schema for CRD if set to true, so first few releases will still
|
||||||
// not admit any. But it can still be used by libraries and
|
// not admit any. But it can still be used by libraries and
|
||||||
// declarative validation for native types
|
// declarative validation for native types
|
||||||
AllowNestedAdditionalProperties: false,
|
AllowNestedAdditionalProperties: false,
|
||||||
|
Reference in New Issue
Block a user