Merge pull request #137846 from lalitc375/required-forbidden

Add tests for +k8s:required and +k8s:forbidden validation tags
This commit is contained in:
Kubernetes Prow Robot
2026-03-19 02:14:30 +05:30
committed by GitHub
6 changed files with 1308 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:validation-gen=TypeMeta
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
// This is a test package.
// +k8s:validation-gen-nolint
package forbidden
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
var localSchemeBuilder = testscheme.New()
type Struct struct {
TypeMeta int
// +k8s:forbidden
StringField string `json:"stringField"`
// +k8s:forbidden
StringPtrField *string `json:"stringPtrField"`
// +k8s:forbidden
StringTypedefField StringType `json:"stringTypedefField"`
// +k8s:forbidden
StringTypedefPtrField *StringType `json:"stringTypedefPtrField"`
// +k8s:forbidden
IntField int `json:"intField"`
// +k8s:forbidden
IntPtrField *int `json:"intPtrField"`
// +k8s:forbidden
IntTypedefField IntType `json:"intTypedefField"`
// +k8s:forbidden
IntTypedefPtrField *IntType `json:"intTypedefPtrField"`
// +k8s:forbidden
BoolField bool `json:"boolField"`
// +k8s:forbidden
FloatField float64 `json:"floatField"`
// +k8s:forbidden
ByteField byte `json:"byteField"`
// +k8s:forbidden
OtherStructPtrField *OtherStruct `json:"otherStructPtrField"`
// +k8s:forbidden
SliceField []string `json:"sliceField"`
// +k8s:forbidden
SliceTypedefField SliceType `json:"sliceTypedefField"`
// +k8s:forbidden
ByteArrayField []byte `json:"byteArrayField"`
// +k8s:forbidden
MapField map[string]string `json:"mapField"`
// +k8s:forbidden
MapTypedefField MapType `json:"mapTypedefField"`
}
type StringType string
type IntType int
type OtherStruct struct{}
type SliceType []string
type MapType map[string]string

View File

@@ -0,0 +1,91 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package forbidden
import (
"testing"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/utils/ptr"
)
func Test(t *testing.T) {
st := localSchemeBuilder.Test(t)
st.Value(&Struct{
// All zero-values (nil slices/maps).
}).ExpectValid()
st.Value(&Struct{
// Explicit zero-values and empty slices/maps.
StringField: "",
StringPtrField: nil,
StringTypedefField: "",
StringTypedefPtrField: nil,
IntField: 0,
IntPtrField: nil,
IntTypedefField: 0,
IntTypedefPtrField: nil,
BoolField: false,
FloatField: 0.0,
ByteField: 0,
OtherStructPtrField: nil,
SliceField: []string{},
SliceTypedefField: SliceType{},
ByteArrayField: []byte{},
MapField: map[string]string{},
MapTypedefField: MapType{},
}).ExpectValid()
st.Value(&Struct{
StringField: "abc",
StringPtrField: ptr.To("xyz"),
StringTypedefField: StringType("abc"),
StringTypedefPtrField: ptr.To(StringType("xyz")),
IntField: 123,
IntPtrField: ptr.To(456),
IntTypedefField: IntType(123),
IntTypedefPtrField: ptr.To(IntType(456)),
BoolField: true,
FloatField: 1.23,
ByteField: 'a',
OtherStructPtrField: &OtherStruct{},
SliceField: []string{"a", "b"},
SliceTypedefField: SliceType([]string{"a", "b"}),
ByteArrayField: []byte("abc"),
MapField: map[string]string{"a": "b", "c": "d"},
MapTypedefField: MapType(map[string]string{"a": "b", "c": "d"}),
}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField(), field.ErrorList{
field.Forbidden(field.NewPath("stringField"), ""),
field.Forbidden(field.NewPath("stringPtrField"), ""),
field.Forbidden(field.NewPath("stringTypedefField"), ""),
field.Forbidden(field.NewPath("stringTypedefPtrField"), ""),
field.Forbidden(field.NewPath("intField"), ""),
field.Forbidden(field.NewPath("intPtrField"), ""),
field.Forbidden(field.NewPath("intTypedefField"), ""),
field.Forbidden(field.NewPath("intTypedefPtrField"), ""),
field.Forbidden(field.NewPath("boolField"), ""),
field.Forbidden(field.NewPath("floatField"), ""),
field.Forbidden(field.NewPath("byteField"), ""),
field.Forbidden(field.NewPath("otherStructPtrField"), ""),
field.Forbidden(field.NewPath("sliceField"), ""),
field.Forbidden(field.NewPath("sliceTypedefField"), ""),
field.Forbidden(field.NewPath("byteArrayField"), ""),
field.Forbidden(field.NewPath("mapField"), ""),
field.Forbidden(field.NewPath("mapTypedefField"), ""),
})
}

View File

@@ -0,0 +1,432 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by validation-gen. DO NOT EDIT.
package forbidden
import (
context "context"
fmt "fmt"
equality "k8s.io/apimachinery/pkg/api/equality"
operation "k8s.io/apimachinery/pkg/api/operation"
safe "k8s.io/apimachinery/pkg/api/safe"
validate "k8s.io/apimachinery/pkg/api/validate"
field "k8s.io/apimachinery/pkg/util/validation/field"
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
)
func init() { localSchemeBuilder.Register(RegisterValidations) }
// RegisterValidations adds validation functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterValidations(scheme *testscheme.Scheme) error {
// type Struct
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
return nil
}
// Validate_Struct validates an instance of Struct according
// to declarative validation rules in the API schema.
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
// field Struct.TypeMeta has no validation
// field Struct.StringField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("stringField"), &obj.StringField, safe.Field(oldObj, func(oldObj *Struct) *string { return &oldObj.StringField }), oldObj != nil)...)
// field Struct.StringPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("stringPtrField"), obj.StringPtrField, safe.Field(oldObj, func(oldObj *Struct) *string { return oldObj.StringPtrField }), oldObj != nil)...)
// field Struct.StringTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *StringType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("stringTypedefField"), &obj.StringTypedefField, safe.Field(oldObj, func(oldObj *Struct) *StringType { return &oldObj.StringTypedefField }), oldObj != nil)...)
// field Struct.StringTypedefPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *StringType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("stringTypedefPtrField"), obj.StringTypedefPtrField, safe.Field(oldObj, func(oldObj *Struct) *StringType { return oldObj.StringTypedefPtrField }), oldObj != nil)...)
// field Struct.IntField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *int, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("intField"), &obj.IntField, safe.Field(oldObj, func(oldObj *Struct) *int { return &oldObj.IntField }), oldObj != nil)...)
// field Struct.IntPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *int, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("intPtrField"), obj.IntPtrField, safe.Field(oldObj, func(oldObj *Struct) *int { return oldObj.IntPtrField }), oldObj != nil)...)
// field Struct.IntTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *IntType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("intTypedefField"), &obj.IntTypedefField, safe.Field(oldObj, func(oldObj *Struct) *IntType { return &oldObj.IntTypedefField }), oldObj != nil)...)
// field Struct.IntTypedefPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *IntType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("intTypedefPtrField"), obj.IntTypedefPtrField, safe.Field(oldObj, func(oldObj *Struct) *IntType { return oldObj.IntTypedefPtrField }), oldObj != nil)...)
// field Struct.BoolField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *bool, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("boolField"), &obj.BoolField, safe.Field(oldObj, func(oldObj *Struct) *bool { return &oldObj.BoolField }), oldObj != nil)...)
// field Struct.FloatField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *float64, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("floatField"), &obj.FloatField, safe.Field(oldObj, func(oldObj *Struct) *float64 { return &oldObj.FloatField }), oldObj != nil)...)
// field Struct.ByteField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *byte, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("byteField"), &obj.ByteField, safe.Field(oldObj, func(oldObj *Struct) *byte { return &oldObj.ByteField }), oldObj != nil)...)
// field Struct.OtherStructPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *OtherStruct, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("otherStructPtrField"), obj.OtherStructPtrField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return oldObj.OtherStructPtrField }), oldObj != nil)...)
// field Struct.SliceField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("sliceField"), obj.SliceField, safe.Field(oldObj, func(oldObj *Struct) []string { return oldObj.SliceField }), oldObj != nil)...)
// field Struct.SliceTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj SliceType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("sliceTypedefField"), obj.SliceTypedefField, safe.Field(oldObj, func(oldObj *Struct) SliceType { return oldObj.SliceTypedefField }), oldObj != nil)...)
// field Struct.ByteArrayField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []byte, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("byteArrayField"), obj.ByteArrayField, safe.Field(oldObj, func(oldObj *Struct) []byte { return oldObj.ByteArrayField }), oldObj != nil)...)
// field Struct.MapField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj map[string]string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("mapField"), obj.MapField, safe.Field(oldObj, func(oldObj *Struct) map[string]string { return oldObj.MapField }), oldObj != nil)...)
// field Struct.MapTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj MapType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.ForbiddenMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if e := validate.OptionalMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
return
}(fldPath.Child("mapTypedefField"), obj.MapTypedefField, safe.Field(oldObj, func(oldObj *Struct) MapType { return oldObj.MapTypedefField }), oldObj != nil)...)
return errs
}

View File

@@ -0,0 +1,115 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// +k8s:validation-gen=TypeMeta
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
// This is a test package.
// +k8s:validation-gen-nolint
package required
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
var localSchemeBuilder = testscheme.New()
type Struct struct {
TypeMeta int
// +k8s:required
// +k8s:validateFalse="field Struct.StringField"
StringField string `json:"stringField"`
// +k8s:required
// +k8s:validateFalse="field Struct.StringPtrField"
StringPtrField *string `json:"stringPtrField"`
// +k8s:required
// +k8s:validateFalse="field Struct.StringTypedefField"
StringTypedefField StringType `json:"stringTypedefField"`
// +k8s:required
// +k8s:validateFalse="field Struct.StringTypedefPtrField"
StringTypedefPtrField *StringType `json:"stringTypedefPtrField"`
// +k8s:required
// +k8s:validateFalse="field Struct.IntField"
IntField int `json:"intField"`
// +k8s:required
// +k8s:validateFalse="field Struct.IntPtrField"
IntPtrField *int `json:"intPtrField"`
// +k8s:required
// +k8s:validateFalse="field Struct.IntTypedefField"
IntTypedefField IntType `json:"intTypedefField"`
// +k8s:required
// +k8s:validateFalse="field Struct.IntTypedefPtrField"
IntTypedefPtrField *IntType `json:"intTypedefPtrField"`
// +k8s:required
// +k8s:validateFalse="field Struct.BoolField"
BoolField bool `json:"boolField"`
// +k8s:required
// +k8s:validateFalse="field Struct.FloatField"
FloatField float64 `json:"floatField"`
// +k8s:required
// +k8s:validateFalse="field Struct.ByteField"
ByteField byte `json:"byteField"`
// non-pointer struct fields cannot be required or optional
// +k8s:required
// +k8s:validateFalse="field Struct.OtherStructPtrField"
OtherStructPtrField *OtherStruct `json:"otherStructPtrField"`
// +k8s:required
// +k8s:validateFalse="field Struct.SliceField"
SliceField []string `json:"sliceField"`
// +k8s:required
// +k8s:validateFalse="field Struct.SliceTypedefField"
SliceTypedefField SliceType `json:"sliceTypedefField"`
// +k8s:required
// +k8s:validateFalse="field Struct.ByteArrayField"
ByteArrayField []byte `json:"byteArrayField"`
// +k8s:required
// +k8s:validateFalse="field Struct.MapField"
MapField map[string]string `json:"mapField"`
// +k8s:required
// +k8s:validateFalse="field Struct.MapTypedefField"
MapTypedefField MapType `json:"mapTypedefField"`
}
// +k8s:validateFalse="type StringType"
type StringType string
// +k8s:validateFalse="type IntType"
type IntType int
// +k8s:validateFalse="type OtherStruct"
type OtherStruct struct{}
// +k8s:validateFalse="type SliceType"
type SliceType []string
// +k8s:validateFalse="type MapType"
type MapType map[string]string

View File

@@ -0,0 +1,127 @@
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package required
import (
"testing"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/utils/ptr"
)
func Test(t *testing.T) {
st := localSchemeBuilder.Test(t)
st.Value(&Struct{
// All zero-values (nil slices/maps).
}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField(), field.ErrorList{
field.Required(field.NewPath("stringField"), ""),
field.Required(field.NewPath("stringPtrField"), ""),
field.Required(field.NewPath("stringTypedefField"), ""),
field.Required(field.NewPath("stringTypedefPtrField"), ""),
field.Required(field.NewPath("intField"), ""),
field.Required(field.NewPath("intPtrField"), ""),
field.Required(field.NewPath("intTypedefField"), ""),
field.Required(field.NewPath("intTypedefPtrField"), ""),
field.Required(field.NewPath("boolField"), ""),
field.Required(field.NewPath("floatField"), ""),
field.Required(field.NewPath("byteField"), ""),
field.Required(field.NewPath("otherStructPtrField"), ""),
field.Required(field.NewPath("sliceField"), ""),
field.Required(field.NewPath("sliceTypedefField"), ""),
field.Required(field.NewPath("byteArrayField"), ""),
field.Required(field.NewPath("mapField"), ""),
field.Required(field.NewPath("mapTypedefField"), ""),
})
st.Value(&Struct{
// Explicit zero-values and empty slices/maps.
StringField: "",
StringPtrField: nil,
StringTypedefField: "",
StringTypedefPtrField: nil,
IntField: 0,
IntPtrField: nil,
IntTypedefField: 0,
IntTypedefPtrField: nil,
BoolField: false,
FloatField: 0.0,
ByteField: 0,
OtherStructPtrField: nil,
SliceField: []string{},
SliceTypedefField: SliceType{},
ByteArrayField: []byte{},
MapField: map[string]string{},
MapTypedefField: MapType{},
}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField(), field.ErrorList{
field.Required(field.NewPath("stringField"), ""),
field.Required(field.NewPath("stringPtrField"), ""),
field.Required(field.NewPath("stringTypedefField"), ""),
field.Required(field.NewPath("stringTypedefPtrField"), ""),
field.Required(field.NewPath("intField"), ""),
field.Required(field.NewPath("intPtrField"), ""),
field.Required(field.NewPath("intTypedefField"), ""),
field.Required(field.NewPath("intTypedefPtrField"), ""),
field.Required(field.NewPath("boolField"), ""),
field.Required(field.NewPath("floatField"), ""),
field.Required(field.NewPath("byteField"), ""),
field.Required(field.NewPath("otherStructPtrField"), ""),
field.Required(field.NewPath("sliceField"), ""),
field.Required(field.NewPath("sliceTypedefField"), ""),
field.Required(field.NewPath("byteArrayField"), ""),
field.Required(field.NewPath("mapField"), ""),
field.Required(field.NewPath("mapTypedefField"), ""),
})
st.Value(&Struct{
StringField: "abc",
StringPtrField: ptr.To("xyz"),
StringTypedefField: StringType("abc"),
StringTypedefPtrField: ptr.To(StringType("xyz")),
IntField: 123,
IntPtrField: ptr.To(456),
IntTypedefField: IntType(123),
IntTypedefPtrField: ptr.To(IntType(456)),
BoolField: true,
FloatField: 1.23,
ByteField: 'a',
OtherStructPtrField: &OtherStruct{},
SliceField: []string{"a", "b"},
SliceTypedefField: SliceType([]string{"a", "b"}),
ByteArrayField: []byte("abc"),
MapField: map[string]string{"a": "b", "c": "d"},
MapTypedefField: MapType(map[string]string{"a": "b", "c": "d"}),
}).ExpectValidateFalseByPath(map[string][]string{
"stringField": {"field Struct.StringField"},
"stringPtrField": {"field Struct.StringPtrField"},
"stringTypedefField": {"field Struct.StringTypedefField", "type StringType"},
"stringTypedefPtrField": {"field Struct.StringTypedefPtrField", "type StringType"},
"intField": {"field Struct.IntField"},
"intPtrField": {"field Struct.IntPtrField"},
"intTypedefField": {"field Struct.IntTypedefField", "type IntType"},
"intTypedefPtrField": {"field Struct.IntTypedefPtrField", "type IntType"},
"boolField": {"field Struct.BoolField"},
"floatField": {"field Struct.FloatField"},
"byteField": {"field Struct.ByteField"},
"otherStructPtrField": {"type OtherStruct", "field Struct.OtherStructPtrField"},
"sliceField": {"field Struct.SliceField"},
"sliceTypedefField": {"field Struct.SliceTypedefField", "type SliceType"},
"byteArrayField": {"field Struct.ByteArrayField"},
"mapField": {"field Struct.MapField"},
"mapTypedefField": {"field Struct.MapTypedefField", "type MapType"},
})
}

View File

@@ -0,0 +1,452 @@
//go:build !ignore_autogenerated
// +build !ignore_autogenerated
/*
Copyright The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Code generated by validation-gen. DO NOT EDIT.
package required
import (
context "context"
fmt "fmt"
equality "k8s.io/apimachinery/pkg/api/equality"
operation "k8s.io/apimachinery/pkg/api/operation"
safe "k8s.io/apimachinery/pkg/api/safe"
validate "k8s.io/apimachinery/pkg/api/validate"
field "k8s.io/apimachinery/pkg/util/validation/field"
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
)
func init() { localSchemeBuilder.Register(RegisterValidations) }
// RegisterValidations adds validation functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterValidations(scheme *testscheme.Scheme) error {
// type Struct
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
switch op.Request.SubresourcePath() {
case "/":
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
}
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
})
return nil
}
// Validate_IntType validates an instance of IntType according
// to declarative validation rules in the API schema.
func Validate_IntType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *IntType) (errs field.ErrorList) {
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "type IntType")...)
return errs
}
// Validate_MapType validates an instance of MapType according
// to declarative validation rules in the API schema.
func Validate_MapType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj MapType) (errs field.ErrorList) {
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "type MapType")...)
return errs
}
// Validate_OtherStruct validates an instance of OtherStruct according
// to declarative validation rules in the API schema.
func Validate_OtherStruct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *OtherStruct) (errs field.ErrorList) {
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "type OtherStruct")...)
return errs
}
// Validate_SliceType validates an instance of SliceType according
// to declarative validation rules in the API schema.
func Validate_SliceType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj SliceType) (errs field.ErrorList) {
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "type SliceType")...)
return errs
}
// Validate_StringType validates an instance of StringType according
// to declarative validation rules in the API schema.
func Validate_StringType(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *StringType) (errs field.ErrorList) {
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "type StringType")...)
return errs
}
// Validate_Struct validates an instance of Struct according
// to declarative validation rules in the API schema.
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
// field Struct.TypeMeta has no validation
// field Struct.StringField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.StringField")...)
return
}(fldPath.Child("stringField"), &obj.StringField, safe.Field(oldObj, func(oldObj *Struct) *string { return &oldObj.StringField }), oldObj != nil)...)
// field Struct.StringPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.StringPtrField")...)
return
}(fldPath.Child("stringPtrField"), obj.StringPtrField, safe.Field(oldObj, func(oldObj *Struct) *string { return oldObj.StringPtrField }), oldObj != nil)...)
// field Struct.StringTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *StringType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.StringTypedefField")...)
// call the type's validation function
errs = append(errs, Validate_StringType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("stringTypedefField"), &obj.StringTypedefField, safe.Field(oldObj, func(oldObj *Struct) *StringType { return &oldObj.StringTypedefField }), oldObj != nil)...)
// field Struct.StringTypedefPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *StringType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.StringTypedefPtrField")...)
// call the type's validation function
errs = append(errs, Validate_StringType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("stringTypedefPtrField"), obj.StringTypedefPtrField, safe.Field(oldObj, func(oldObj *Struct) *StringType { return oldObj.StringTypedefPtrField }), oldObj != nil)...)
// field Struct.IntField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *int, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.IntField")...)
return
}(fldPath.Child("intField"), &obj.IntField, safe.Field(oldObj, func(oldObj *Struct) *int { return &oldObj.IntField }), oldObj != nil)...)
// field Struct.IntPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *int, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.IntPtrField")...)
return
}(fldPath.Child("intPtrField"), obj.IntPtrField, safe.Field(oldObj, func(oldObj *Struct) *int { return oldObj.IntPtrField }), oldObj != nil)...)
// field Struct.IntTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *IntType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.IntTypedefField")...)
// call the type's validation function
errs = append(errs, Validate_IntType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("intTypedefField"), &obj.IntTypedefField, safe.Field(oldObj, func(oldObj *Struct) *IntType { return &oldObj.IntTypedefField }), oldObj != nil)...)
// field Struct.IntTypedefPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *IntType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.IntTypedefPtrField")...)
// call the type's validation function
errs = append(errs, Validate_IntType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("intTypedefPtrField"), obj.IntTypedefPtrField, safe.Field(oldObj, func(oldObj *Struct) *IntType { return oldObj.IntTypedefPtrField }), oldObj != nil)...)
// field Struct.BoolField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *bool, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.BoolField")...)
return
}(fldPath.Child("boolField"), &obj.BoolField, safe.Field(oldObj, func(oldObj *Struct) *bool { return &oldObj.BoolField }), oldObj != nil)...)
// field Struct.FloatField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *float64, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.FloatField")...)
return
}(fldPath.Child("floatField"), &obj.FloatField, safe.Field(oldObj, func(oldObj *Struct) *float64 { return &oldObj.FloatField }), oldObj != nil)...)
// field Struct.ByteField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *byte, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.ByteField")...)
return
}(fldPath.Child("byteField"), &obj.ByteField, safe.Field(oldObj, func(oldObj *Struct) *byte { return &oldObj.ByteField }), oldObj != nil)...)
// field Struct.OtherStructPtrField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *OtherStruct, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.OtherStructPtrField")...)
// call the type's validation function
errs = append(errs, Validate_OtherStruct(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("otherStructPtrField"), obj.OtherStructPtrField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return oldObj.OtherStructPtrField }), oldObj != nil)...)
// field Struct.SliceField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.SliceField")...)
return
}(fldPath.Child("sliceField"), obj.SliceField, safe.Field(oldObj, func(oldObj *Struct) []string { return oldObj.SliceField }), oldObj != nil)...)
// field Struct.SliceTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj SliceType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.SliceTypedefField")...)
// call the type's validation function
errs = append(errs, Validate_SliceType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("sliceTypedefField"), obj.SliceTypedefField, safe.Field(oldObj, func(oldObj *Struct) SliceType { return oldObj.SliceTypedefField }), oldObj != nil)...)
// field Struct.ByteArrayField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj []byte, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredSlice(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.ByteArrayField")...)
return
}(fldPath.Child("byteArrayField"), obj.ByteArrayField, safe.Field(oldObj, func(oldObj *Struct) []byte { return oldObj.ByteArrayField }), oldObj != nil)...)
// field Struct.MapField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj map[string]string, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.MapField")...)
return
}(fldPath.Child("mapField"), obj.MapField, safe.Field(oldObj, func(oldObj *Struct) map[string]string { return oldObj.MapField }), oldObj != nil)...)
// field Struct.MapTypedefField
errs = append(errs,
func(fldPath *field.Path, obj, oldObj MapType, oldValueCorrelated bool) (errs field.ErrorList) {
// don't revalidate unchanged data
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
return nil
}
// call field-attached validations
earlyReturn := false
if e := validate.RequiredMap(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
errs = append(errs, e...)
earlyReturn = true
}
if earlyReturn {
return // do not proceed
}
errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.MapTypedefField")...)
// call the type's validation function
errs = append(errs, Validate_MapType(ctx, op, fldPath, obj, oldObj)...)
return
}(fldPath.Child("mapTypedefField"), obj.MapTypedefField, safe.Field(oldObj, func(oldObj *Struct) MapType { return oldObj.MapTypedefField }), oldObj != nil)...)
return errs
}