mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-18 22:40:35 +00:00
Add cohort support to +k8s:subfield
Given:
```
// +k8s:subfield(name)=+k8s:optional
// +k8s:subfield(name)=+k8s:format=dns-label
// +k8s:subfield(generateName)=+k8s:optional
// +k8s:subfield(generateName)=+k8s:format=dns-label
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
```
...we get:
```
errs = append(errs,
func(fldPath *field.Path, obj, oldObj *metav1.ObjectMeta) (errs field.ErrorList) {
func() { // cohort name
if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.OptionalValue); len (e) != 0 {
return // do not proceed
}
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "name", func(o *metav1.ObjectMeta) *string { return &o.Name }, validate.DNSLabel)...)
}()
func() { // cohort generateName
if e := validate.Subfield(ctx, op, fldPath, obj, oldObj, "generateName", func(o *metav1.ObjectMeta) *string { return &o.GenerateName }, validate.OptionalValue); len(e) != 0
{
return // do not proceed
}
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "generateName", func(o *metav1.ObjectMeta) *string { return &o.GenerateName }, validate.DNSLabel)...)
}()
return
}(fldPath.Child("metadata"), &obj.ObjectMeta, safe.Field(oldObj, func(oldObj *corev1.ReplicationController) *metav1.ObjectMeta { return &oldObj.ObjectMeta }))...)
```
It is worth noting that this only works one level deep:
```
// +k8s:subfield(foo)=+k8s:subfield(bar)=+k8s:optional
// +k8s:subfield(foo)=+k8s:subfield(bar)=+k8s:format=dns-label
Field StructType
```
...will generate one cohort ("foo") with two distinct calls to Subfield,
so the optional will not short-circuit format. If we need deeper
cohorting we need to either make subfield take multiple field names
(e.g. `subfield(foo.bar)` or `subbfield(foo, bar)`) or we need to
accumulate "structure" in addition to validator calls. This is similar
to how we handle multiple `eachVal` tags - each one iterates the list.
This commit is contained in:
@@ -70,12 +70,16 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intField", func(o *SubStruct) *int { return &o.IntField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intPtrField", func(o *SubStruct) *int { return o.IntPtrField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntPtrField")
|
||||
})...)
|
||||
func() { // cohort intField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intField", func(o *SubStruct) *int { return &o.IntField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort intPtrField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intPtrField", func(o *SubStruct) *int { return o.IntPtrField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntPtrField")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("subStructField"), &obj.SubStructField, safe.Field(oldObj, func(oldObj *Struct) *SubStruct { return &oldObj.SubStructField }))...)
|
||||
|
||||
@@ -85,12 +89,16 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
// Validate_StructWithSubfield validates an instance of StructWithSubfield according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StructWithSubfield(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *StructWithSubfield) (errs field.ErrorList) {
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intField", func(o *StructWithSubfield) *int { return &o.IntField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intPtrField", func(o *StructWithSubfield) *int { return o.IntPtrField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntPtrField")
|
||||
})...)
|
||||
func() { // cohort intField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intField", func(o *StructWithSubfield) *int { return &o.IntField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort intPtrField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "intPtrField", func(o *StructWithSubfield) *int { return o.IntPtrField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *int) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field IntPtrField")
|
||||
})...)
|
||||
}()
|
||||
|
||||
// field StructWithSubfield.TypeMeta has no validation
|
||||
// field StructWithSubfield.IntField has no validation
|
||||
|
||||
@@ -62,9 +62,11 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *InnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-subfield")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *InnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-subfield")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structField"), &obj.StructField, safe.Field(oldObj, func(oldObj *Struct) *InnerStruct { return &oldObj.StructField }))...)
|
||||
|
||||
@@ -79,9 +81,11 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
return // do not proceed
|
||||
}
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *InnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-subfield-ptr")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *InnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-subfield-ptr")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structPtrField"), obj.StructPtrField, safe.Field(oldObj, func(oldObj *Struct) *InnerStruct { return oldObj.StructPtrField }))...)
|
||||
|
||||
@@ -157,9 +161,11 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
// Validate_ValidatedInnerStruct validates an instance of ValidatedInnerStruct according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ValidatedInnerStruct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *ValidatedInnerStruct) (errs field.ErrorList) {
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *ValidatedInnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-typedef-struct")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *ValidatedInnerStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.NEQ(ctx, op, fldPath, obj, oldObj, "disallowed-typedef-struct")
|
||||
})...)
|
||||
}()
|
||||
|
||||
// field ValidatedInnerStruct.StringField has no validation
|
||||
return errs
|
||||
|
||||
@@ -28,14 +28,16 @@ var localSchemeBuilder = testscheme.New()
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="StructField.StructField"
|
||||
// +k8s:subfield(sliceField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="StructField.SliceField"
|
||||
// +k8s:subfield(mapField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="StructField.MapField"
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructField.StructField 1"
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructField.StructField 2"
|
||||
// +k8s:subfield(sliceField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructField.SliceField"
|
||||
// +k8s:subfield(mapField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructField.MapField"
|
||||
StructField OtherStruct `json:"structField"`
|
||||
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="StructPtrField.StructField"
|
||||
// +k8s:subfield(sliceField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="StructPtrField.SliceField"
|
||||
// +k8s:subfield(mapField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="StructPtrField.MapField"
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructPtrField.StructField 1"
|
||||
// +k8s:subfield(structField)=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructPtrField.StructField 2"
|
||||
// +k8s:subfield(sliceField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructPtrField.SliceField"
|
||||
// +k8s:subfield(mapField)=+k8s:eachVal=+k8s:subfield(stringField)=+k8s:validateFalse="Struct.StructPtrField.MapField"
|
||||
StructPtrField *OtherStruct `json:"structPtrField"`
|
||||
}
|
||||
|
||||
|
||||
@@ -49,15 +49,15 @@ func Test(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}).ExpectValidateFalseByPath(map[string][]string{
|
||||
"structField.structField.stringField": {"StructField.StructField"},
|
||||
"structField.sliceField[0].stringField": {"StructField.SliceField"},
|
||||
"structField.sliceField[1].stringField": {"StructField.SliceField"},
|
||||
"structField.mapField[a].stringField": {"StructField.MapField"},
|
||||
"structField.mapField[b].stringField": {"StructField.MapField"},
|
||||
"structPtrField.structField.stringField": {"StructPtrField.StructField"},
|
||||
"structPtrField.sliceField[0].stringField": {"StructPtrField.SliceField"},
|
||||
"structPtrField.sliceField[1].stringField": {"StructPtrField.SliceField"},
|
||||
"structPtrField.mapField[a].stringField": {"StructPtrField.MapField"},
|
||||
"structPtrField.mapField[b].stringField": {"StructPtrField.MapField"},
|
||||
"structField.structField.stringField": {"Struct.StructField.StructField 1", "Struct.StructField.StructField 2"},
|
||||
"structField.sliceField[0].stringField": {"Struct.StructField.SliceField"},
|
||||
"structField.sliceField[1].stringField": {"Struct.StructField.SliceField"},
|
||||
"structField.mapField[a].stringField": {"Struct.StructField.MapField"},
|
||||
"structField.mapField[b].stringField": {"Struct.StructField.MapField"},
|
||||
"structPtrField.structField.stringField": {"Struct.StructPtrField.StructField 1", "Struct.StructPtrField.StructField 2"},
|
||||
"structPtrField.sliceField[0].stringField": {"Struct.StructPtrField.SliceField"},
|
||||
"structPtrField.sliceField[1].stringField": {"Struct.StructPtrField.SliceField"},
|
||||
"structPtrField.mapField[a].stringField": {"Struct.StructPtrField.MapField"},
|
||||
"structPtrField.mapField[b].stringField": {"Struct.StructPtrField.MapField"},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,25 +62,36 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructField.StructField")
|
||||
})
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []SmallStruct { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []SmallStruct) field.ErrorList {
|
||||
return validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
func() { // cohort structField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructField.SliceField")
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructField.StructField 1")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]SmallStruct { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]SmallStruct) field.ErrorList {
|
||||
return validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructField.MapField")
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructField.StructField 2")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort sliceField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []SmallStruct { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []SmallStruct) field.ErrorList {
|
||||
return validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructField.SliceField")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort mapField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]SmallStruct { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]SmallStruct) field.ErrorList {
|
||||
return validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructField.MapField")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structField"), &obj.StructField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return &oldObj.StructField }))...)
|
||||
|
||||
@@ -92,25 +103,36 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructPtrField.StructField")
|
||||
})
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []SmallStruct { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []SmallStruct) field.ErrorList {
|
||||
return validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
func() { // cohort structField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructPtrField.SliceField")
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructPtrField.StructField 1")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]SmallStruct { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]SmallStruct) field.ErrorList {
|
||||
return validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "StructPtrField.MapField")
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructPtrField.StructField 2")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort sliceField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []SmallStruct { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []SmallStruct) field.ErrorList {
|
||||
return validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructPtrField.SliceField")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort mapField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]SmallStruct { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]SmallStruct) field.ErrorList {
|
||||
return validate.EachMapVal(ctx, op, fldPath, obj, oldObj, validate.DirectEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *SmallStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "Struct.StructPtrField.MapField")
|
||||
})
|
||||
})
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structPtrField"), obj.StructPtrField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return oldObj.StructPtrField }))...)
|
||||
|
||||
|
||||
@@ -60,9 +60,11 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *other.StructType) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.(other.StructType).StringField")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *other.StructType) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.(other.StructType).StringField")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(safe.Value(fldPath, func() *field.Path { return fldPath.Child("other.StructType") }), &obj.StructType, safe.Field(oldObj, func(oldObj *Struct) *other.StructType { return &oldObj.StructType }))...)
|
||||
|
||||
|
||||
@@ -28,14 +28,16 @@ var localSchemeBuilder = testscheme.New()
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructField.StringField"
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructField.StringField 1"
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructField.StringField 2"
|
||||
// +k8s:subfield(pointerField)=+k8s:validateFalse="subfield Struct.StructField.PointerField"
|
||||
// +k8s:subfield(structField)=+k8s:validateFalse="subfield Struct.StructField.StructField"
|
||||
// +k8s:subfield(sliceField)=+k8s:validateFalse="subfield Struct.StructField.SliceField"
|
||||
// +k8s:subfield(mapField)=+k8s:validateFalse="subfield Struct.StructField.MapField"
|
||||
StructField OtherStruct `json:"structField"`
|
||||
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructPtrField.StringField"
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructPtrField.StringField 1"
|
||||
// +k8s:subfield(stringField)=+k8s:validateFalse="subfield Struct.StructPtrField.StringField 2"
|
||||
// +k8s:subfield(pointerField)=+k8s:validateFalse="subfield Struct.StructPtrField.PointerField"
|
||||
// +k8s:subfield(structField)=+k8s:validateFalse="subfield Struct.StructPtrField.StructField"
|
||||
// +k8s:subfield(sliceField)=+k8s:validateFalse="subfield Struct.StructPtrField.SliceField"
|
||||
|
||||
@@ -41,15 +41,15 @@ func Test(t *testing.T) {
|
||||
MapField: map[string]string{},
|
||||
},
|
||||
}).ExpectValidateFalseByPath(map[string][]string{
|
||||
"structField.stringField": {"subfield Struct.StructField.StringField"},
|
||||
"structPtrField.stringField": {"subfield Struct.StructPtrField.StringField"},
|
||||
"structField.stringField": {"subfield Struct.StructField.StringField 1", "subfield Struct.StructField.StringField 2"},
|
||||
"structField.pointerField": {"subfield Struct.StructField.PointerField"},
|
||||
"structPtrField.pointerField": {"subfield Struct.StructPtrField.PointerField"},
|
||||
"structField.structField": {"subfield Struct.StructField.StructField"},
|
||||
"structPtrField.structField": {"subfield Struct.StructPtrField.StructField"},
|
||||
"structField.sliceField": {"subfield Struct.StructField.SliceField"},
|
||||
"structPtrField.sliceField": {"subfield Struct.StructPtrField.SliceField"},
|
||||
"structField.mapField": {"subfield Struct.StructField.MapField"},
|
||||
"structPtrField.stringField": {"subfield Struct.StructPtrField.StringField 1", "subfield Struct.StructPtrField.StringField 2"},
|
||||
"structPtrField.pointerField": {"subfield Struct.StructPtrField.PointerField"},
|
||||
"structPtrField.structField": {"subfield Struct.StructPtrField.StructField"},
|
||||
"structPtrField.sliceField": {"subfield Struct.StructPtrField.SliceField"},
|
||||
"structPtrField.mapField": {"subfield Struct.StructPtrField.MapField"},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,21 +62,34 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.StringField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "pointerField", func(o *OtherStruct) *string { return o.PointerField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.PointerField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.StructField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []string { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.SliceField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]string { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.MapField")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.StringField 1")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.StringField 2")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort pointerField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "pointerField", func(o *OtherStruct) *string { return o.PointerField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.PointerField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort structField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.StructField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort sliceField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []string { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.SliceField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort mapField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]string { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructField.MapField")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structField"), &obj.StructField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return &oldObj.StructField }))...)
|
||||
|
||||
@@ -88,21 +101,34 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.StringField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "pointerField", func(o *OtherStruct) *string { return o.PointerField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.PointerField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.StructField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []string { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.SliceField")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]string { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.MapField")
|
||||
})...)
|
||||
func() { // cohort stringField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.StringField 1")
|
||||
})...)
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "stringField", func(o *OtherStruct) *string { return &o.StringField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.StringField 2")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort pointerField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "pointerField", func(o *OtherStruct) *string { return o.PointerField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.PointerField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort structField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "structField", func(o *OtherStruct) *SmallStruct { return &o.StructField }, validate.DirectEqualPtr, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *SmallStruct) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.StructField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort sliceField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "sliceField", func(o *OtherStruct) []string { return o.SliceField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj []string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.SliceField")
|
||||
})...)
|
||||
}()
|
||||
func() { // cohort mapField
|
||||
errs = append(errs, validate.Subfield(ctx, op, fldPath, obj, oldObj, "mapField", func(o *OtherStruct) map[string]string { return o.MapField }, validate.SemanticDeepEqual, func(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj map[string]string) field.ErrorList {
|
||||
return validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "subfield Struct.StructPtrField.MapField")
|
||||
})...)
|
||||
}()
|
||||
return
|
||||
}(fldPath.Child("structPtrField"), obj.StructPtrField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return oldObj.StructPtrField }))...)
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ func (stv subfieldTagValidator) GetValidations(context Context, tag codetags.Tag
|
||||
|
||||
for _, vfn := range validations.Functions {
|
||||
f := Function(subfieldTagName, vfn.Flags, validateSubfield, subname, getFn, equivArg, WrapperFunction{vfn, submemb.Type})
|
||||
f.Cohort = subname
|
||||
result.AddFunction(f)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user