mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Disallow optional/required on non-pointer structs
This commit is contained in:
		@@ -35,9 +35,7 @@ type Struct struct {
 | 
				
			|||||||
	// +k8s:validateFalse="field Struct.StringPtrField"
 | 
						// +k8s:validateFalse="field Struct.StringPtrField"
 | 
				
			||||||
	StringPtrField *string `json:"stringPtrField"`
 | 
						StringPtrField *string `json:"stringPtrField"`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// +k8s:optional
 | 
						// non-pointer struct fields cannot be optional
 | 
				
			||||||
	// +k8s:validateFalse="field Struct.OtherStructField"
 | 
					 | 
				
			||||||
	OtherStructField OtherStruct `json:"otherStructField"`
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// +k8s:optional
 | 
						// +k8s:optional
 | 
				
			||||||
	// +k8s:validateFalse="field Struct.OtherStructPtrField"
 | 
						// +k8s:validateFalse="field Struct.OtherStructPtrField"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,21 +27,17 @@ func Test(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	st.Value(&Struct{
 | 
						st.Value(&Struct{
 | 
				
			||||||
		// All zero-values.
 | 
							// All zero-values.
 | 
				
			||||||
	}).ExpectValidateFalseByPath(map[string][]string{
 | 
						}).ExpectValid()
 | 
				
			||||||
		"otherStructField": {"type OtherStruct", "field Struct.OtherStructField"}, // optional for structs is just documentation
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	st.Value(&Struct{
 | 
						st.Value(&Struct{
 | 
				
			||||||
		StringField:         "abc",
 | 
							StringField:         "abc",
 | 
				
			||||||
		StringPtrField:      ptr.To("xyz"),
 | 
							StringPtrField:      ptr.To("xyz"),
 | 
				
			||||||
		OtherStructField:    OtherStruct{},
 | 
					 | 
				
			||||||
		OtherStructPtrField: &OtherStruct{},
 | 
							OtherStructPtrField: &OtherStruct{},
 | 
				
			||||||
		SliceField:          []string{"a", "b"},
 | 
							SliceField:          []string{"a", "b"},
 | 
				
			||||||
		MapField:            map[string]string{"a": "b", "c": "d"},
 | 
							MapField:            map[string]string{"a": "b", "c": "d"},
 | 
				
			||||||
	}).ExpectValidateFalseByPath(map[string][]string{
 | 
						}).ExpectValidateFalseByPath(map[string][]string{
 | 
				
			||||||
		"stringField":         {"field Struct.StringField"},
 | 
							"stringField":         {"field Struct.StringField"},
 | 
				
			||||||
		"stringPtrField":      {"field Struct.StringPtrField"},
 | 
							"stringPtrField":      {"field Struct.StringPtrField"},
 | 
				
			||||||
		"otherStructField":    {"type OtherStruct", "field Struct.OtherStructField"},
 | 
					 | 
				
			||||||
		"otherStructPtrField": {"type OtherStruct", "field Struct.OtherStructPtrField"},
 | 
							"otherStructPtrField": {"type OtherStruct", "field Struct.OtherStructPtrField"},
 | 
				
			||||||
		"sliceField":          {"field Struct.SliceField"},
 | 
							"sliceField":          {"field Struct.SliceField"},
 | 
				
			||||||
		"mapField":            {"field Struct.MapField"},
 | 
							"mapField":            {"field Struct.MapField"},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -76,15 +76,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field
 | 
				
			|||||||
			return
 | 
								return
 | 
				
			||||||
		}(fldPath.Child("stringPtrField"), obj.StringPtrField, safe.Field(oldObj, func(oldObj *Struct) *string { return oldObj.StringPtrField }))...)
 | 
							}(fldPath.Child("stringPtrField"), obj.StringPtrField, safe.Field(oldObj, func(oldObj *Struct) *string { return oldObj.StringPtrField }))...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// field Struct.OtherStructField
 | 
					 | 
				
			||||||
	errs = append(errs,
 | 
					 | 
				
			||||||
		func(fldPath *field.Path, obj, oldObj *OtherStruct) (errs field.ErrorList) {
 | 
					 | 
				
			||||||
			errs = append(errs, validate.FixedResult(ctx, op, fldPath, obj, oldObj, false, "field Struct.OtherStructField")...)
 | 
					 | 
				
			||||||
			// optional non-pointer structs are purely documentation
 | 
					 | 
				
			||||||
			errs = append(errs, Validate_OtherStruct(ctx, op, fldPath, obj, oldObj)...)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}(fldPath.Child("otherStructField"), &obj.OtherStructField, safe.Field(oldObj, func(oldObj *Struct) *OtherStruct { return &oldObj.OtherStructField }))...)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// field Struct.OtherStructPtrField
 | 
						// field Struct.OtherStructPtrField
 | 
				
			||||||
	errs = append(errs,
 | 
						errs = append(errs,
 | 
				
			||||||
		func(fldPath *field.Path, obj, oldObj *OtherStruct) (errs field.ErrorList) {
 | 
							func(fldPath *field.Path, obj, oldObj *OtherStruct) (errs field.ErrorList) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,10 +97,12 @@ func (requirednessTagValidator) doRequired(context Context) (Validations, error)
 | 
				
			|||||||
	case types.Pointer:
 | 
						case types.Pointer:
 | 
				
			||||||
		return Validations{Functions: []FunctionGen{Function(requiredTagName, ShortCircuit, requiredPointerValidator)}}, nil
 | 
							return Validations{Functions: []FunctionGen{Function(requiredTagName, ShortCircuit, requiredPointerValidator)}}, nil
 | 
				
			||||||
	case types.Struct:
 | 
						case types.Struct:
 | 
				
			||||||
		// The +required tag on a non-pointer struct is only for documentation.
 | 
							// The +k8s:required tag on a non-pointer struct is not supported.
 | 
				
			||||||
		// We don't perform validation here and defer the validation to
 | 
							// If you encounter this error and believe you have a valid use case
 | 
				
			||||||
		// the struct's fields.
 | 
							// for forbiddening a non-pointer struct, please let us know! We need
 | 
				
			||||||
		return Validations{Comments: []string{"required non-pointer structs are purely documentation"}}, nil
 | 
							// to understand your scenario to determine if we need to adjust
 | 
				
			||||||
 | 
							// this behavior or provide alternative validation mechanisms.
 | 
				
			||||||
 | 
							return Validations{}, fmt.Errorf("non-pointer structs cannot use the %q tag", requiredTagName)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Validations{Functions: []FunctionGen{Function(requiredTagName, ShortCircuit, requiredValueValidator)}}, nil
 | 
						return Validations{Functions: []FunctionGen{Function(requiredTagName, ShortCircuit, requiredValueValidator)}}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -125,11 +127,12 @@ func (requirednessTagValidator) doOptional(context Context) (Validations, error)
 | 
				
			|||||||
	case types.Pointer:
 | 
						case types.Pointer:
 | 
				
			||||||
		return Validations{Functions: []FunctionGen{Function(optionalTagName, ShortCircuit|NonError, optionalPointerValidator)}}, nil
 | 
							return Validations{Functions: []FunctionGen{Function(optionalTagName, ShortCircuit|NonError, optionalPointerValidator)}}, nil
 | 
				
			||||||
	case types.Struct:
 | 
						case types.Struct:
 | 
				
			||||||
		// Specifying that a non-pointer struct is optional doesn't actually
 | 
							// The +k8s:optional tag on a non-pointer struct is not supported.
 | 
				
			||||||
		// make sense technically almost ever, and is better described as a
 | 
							// If you encounter this error and believe you have a valid use case
 | 
				
			||||||
		// union inside the struct. It does, however, make sense as
 | 
							// for forbiddening a non-pointer struct, please let us know! We need
 | 
				
			||||||
		// documentation.
 | 
							// to understand your scenario to determine if we need to adjust
 | 
				
			||||||
		return Validations{Comments: []string{"optional non-pointer structs are purely documentation"}}, nil
 | 
							// this behavior or provide alternative validation mechanisms.
 | 
				
			||||||
 | 
							return Validations{}, fmt.Errorf("non-pointer structs cannot use the %q tag", optionalTagName)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Validations{Functions: []FunctionGen{Function(optionalTagName, ShortCircuit|NonError, optionalValueValidator)}}, nil
 | 
						return Validations{Functions: []FunctionGen{Function(optionalTagName, ShortCircuit|NonError, optionalValueValidator)}}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -174,7 +177,7 @@ func (requirednessTagValidator) doForbidden(context Context) (Validations, error
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
		}, nil
 | 
							}, nil
 | 
				
			||||||
	case types.Struct:
 | 
						case types.Struct:
 | 
				
			||||||
		// The +forbidden tag on a non-pointer struct is not supported.
 | 
							// The +k8s:forbidden tag on a non-pointer struct is not supported.
 | 
				
			||||||
		// If you encounter this error and believe you have a valid use case
 | 
							// If you encounter this error and believe you have a valid use case
 | 
				
			||||||
		// for forbiddening a non-pointer struct, please let us know! We need
 | 
							// for forbiddening a non-pointer struct, please let us know! We need
 | 
				
			||||||
		// to understand your scenario to determine if we need to adjust
 | 
							// to understand your scenario to determine if we need to adjust
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user