diff --git a/pkg/apis/certificates/v1/zz_generated.validations.go b/pkg/apis/certificates/v1/zz_generated.validations.go index f24655e1aa5..8384e157fff 100644 --- a/pkg/apis/certificates/v1/zz_generated.validations.go +++ b/pkg/apis/certificates/v1/zz_generated.validations.go @@ -113,6 +113,7 @@ func Validate_CertificateSigningRequestStatus(ctx context.Context, op operation. // field certificatesv1.CertificateSigningRequestStatus.Conditions errs = append(errs, func(fldPath *field.Path, obj, oldObj []certificatesv1.CertificateSigningRequestCondition) (errs field.ErrorList) { + // Uniqueness validation is implemented via custom, handwritten validation // don't revalidate unchanged data if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { return nil diff --git a/pkg/apis/certificates/v1beta1/zz_generated.validations.go b/pkg/apis/certificates/v1beta1/zz_generated.validations.go index c7be9509d71..8ee94e7cf9d 100644 --- a/pkg/apis/certificates/v1beta1/zz_generated.validations.go +++ b/pkg/apis/certificates/v1beta1/zz_generated.validations.go @@ -113,6 +113,7 @@ func Validate_CertificateSigningRequestStatus(ctx context.Context, op operation. // field certificatesv1beta1.CertificateSigningRequestStatus.Conditions errs = append(errs, func(fldPath *field.Path, obj, oldObj []certificatesv1beta1.CertificateSigningRequestCondition) (errs field.ErrorList) { + // Uniqueness validation is implemented via custom, handwritten validation // don't revalidate unchanged data if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) { return nil diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/zero_defaults/zz_generated.validations.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/zero_defaults/zz_generated.validations.go index ae37bd15da6..573e76369aa 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/zero_defaults/zz_generated.validations.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/zero_defaults/zz_generated.validations.go @@ -57,11 +57,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field errs = append(errs, func(fldPath *field.Path, obj, oldObj *string) (errs field.ErrorList) { // optional value-type fields with zero-value defaults are purely documentation - // don't revalidate unchanged data - if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { - return nil - } - // call field-attached validations return }(fldPath.Child("stringField"), &obj.StringField, safe.Field(oldObj, func(oldObj *Struct) *string { return &oldObj.StringField }))...) @@ -85,11 +80,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field errs = append(errs, func(fldPath *field.Path, obj, oldObj *int) (errs field.ErrorList) { // optional value-type fields with zero-value defaults are purely documentation - // don't revalidate unchanged data - if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { - return nil - } - // call field-attached validations return }(fldPath.Child("intField"), &obj.IntField, safe.Field(oldObj, func(oldObj *Struct) *int { return &oldObj.IntField }))...) @@ -113,11 +103,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field errs = append(errs, func(fldPath *field.Path, obj, oldObj *bool) (errs field.ErrorList) { // optional value-type fields with zero-value defaults are purely documentation - // don't revalidate unchanged data - if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { - return nil - } - // call field-attached validations return }(fldPath.Child("boolField"), &obj.BoolField, safe.Field(oldObj, func(oldObj *Struct) *bool { return &oldObj.BoolField }))...) diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/unique/zz_generated.validations.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/unique/zz_generated.validations.go index a8b7754b49b..7e123da08ea 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/unique/zz_generated.validations.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/unique/zz_generated.validations.go @@ -106,7 +106,19 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field return }(fldPath.Child("atomicListUniqueMap"), obj.AtomicListUniqueMap, safe.Field(oldObj, func(oldObj *Struct) []Item { return oldObj.AtomicListUniqueMap }))...) - // field Struct.CustomUniqueListWithTypeSet has no validation - // field Struct.CustomUniqueListWithTypeMap has no validation + // field Struct.CustomUniqueListWithTypeSet + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []string) (errs field.ErrorList) { + // Uniqueness validation is implemented via custom, handwritten validation + return + }(fldPath.Child("customUniqueListWithTypeSet"), obj.CustomUniqueListWithTypeSet, safe.Field(oldObj, func(oldObj *Struct) []string { return oldObj.CustomUniqueListWithTypeSet }))...) + + // field Struct.CustomUniqueListWithTypeMap + errs = append(errs, + func(fldPath *field.Path, obj, oldObj []Item) (errs field.ErrorList) { + // Uniqueness validation is implemented via custom, handwritten validation + return + }(fldPath.Child("customUniqueListWithTypeMap"), obj.CustomUniqueListWithTypeMap, safe.Field(oldObj, func(oldObj *Struct) []Item { return oldObj.CustomUniqueListWithTypeMap }))...) + return errs } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/validation.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/validation.go index f9f3fbbf1b8..e659982c0f9 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/validation.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/validation.go @@ -1105,10 +1105,12 @@ func (g *genValidations) emitValidationForChild(c *generator.Context, thisChild fldRatchetingChecked := false if !validations.Empty() { emitComments(validations.Comments, bufsw) - emitRatchetingCheck(c, fld.childType, bufsw) - fldRatchetingChecked = true - bufsw.Do("// call field-attached validations\n", nil) - emitCallsToValidators(c, validations.Functions, bufsw) + if len(validations.Functions) > 0 { + emitRatchetingCheck(c, fld.childType, bufsw) + fldRatchetingChecked = true + bufsw.Do("// call field-attached validations\n", nil) + emitCallsToValidators(c, validations.Functions, bufsw) + } } // If the node is nil, this must be a type in a package we are not @@ -1132,11 +1134,14 @@ func (g *genValidations) emitValidationForChild(c *generator.Context, thisChild // validations, call its validation function. if validations := fld.fieldValIterations; g.hasValidations(fld.node.elem.node) && !validations.Empty() { emitComments(validations.Comments, bufsw) - if !fldRatchetingChecked { - emitRatchetingCheck(c, fld.childType, bufsw) - fldRatchetingChecked = true + if len(validations.Functions) > 0 { + if !fldRatchetingChecked { + emitRatchetingCheck(c, fld.childType, bufsw) + fldRatchetingChecked = true + } + emitCallsToValidators(c, validations.Functions, bufsw) } - emitCallsToValidators(c, validations.Functions, bufsw) + } // Descend into this field. g.emitValidationForChild(c, fld, bufsw) @@ -1145,21 +1150,25 @@ func (g *genValidations) emitValidationForChild(c *generator.Context, thisChild // validations, call its validation function. if validations := fld.fieldKeyIterations; g.hasValidations(fld.node.key.node) && !validations.Empty() { emitComments(validations.Comments, bufsw) - if !fldRatchetingChecked { - emitRatchetingCheck(c, fld.childType, bufsw) - fldRatchetingChecked = true + if len(validations.Functions) > 0 { + if !fldRatchetingChecked { + emitRatchetingCheck(c, fld.childType, bufsw) + fldRatchetingChecked = true + } + emitCallsToValidators(c, validations.Functions, bufsw) } - emitCallsToValidators(c, validations.Functions, bufsw) } // If this field is a map and the value-type has // validations, call its validation function. if validations := fld.fieldValIterations; g.hasValidations(fld.node.elem.node) && !validations.Empty() { emitComments(validations.Comments, bufsw) - if !fldRatchetingChecked { - emitRatchetingCheck(c, fld.childType, bufsw) - fldRatchetingChecked = true + if len(validations.Functions) > 0 { + if !fldRatchetingChecked { + emitRatchetingCheck(c, fld.childType, bufsw) + fldRatchetingChecked = true + } + emitCallsToValidators(c, validations.Functions, bufsw) } - emitCallsToValidators(c, validations.Functions, bufsw) } // Descend into this field. g.emitValidationForChild(c, fld, bufsw) diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/validators/list.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/validators/list.go index 1bc9ce5e6c8..4af73a195d4 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/validators/list.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/validators/list.go @@ -412,15 +412,14 @@ func (lv listValidator) GetValidations(context Context) (Validations, error) { if err := lv.check(lm); err != nil { return Validations{}, err } - + result := Validations{} if lm.customUnique { // Uniqueness validation is disabled in generated validation for this list. // It would defer to handwritten validation to check the uniqueness. - return Validations{}, nil + result.AddComment("Uniqueness validation is implemented via custom, handwritten validation") + return result, nil } - result := Validations{} - // Generate uniqueness checks for lists with higher-order semantics. if lm.semantic == semanticSet { // Only compare primitive values when possible. Slices and maps are not