validator icon indicating copy to clipboard operation
validator copied to clipboard

bug: Getting `Bad field type v1.Duration` on v10.15.0+

Open jonathan-innis opened this issue 2 years ago • 4 comments

  • [x] I have looked at the documentation here first?
  • [x] I have looked at the examples provided that may showcase my question here?

Package version eg. v9, v10:

Error starts occurring on v10.15.0 No errors present on v10.14.1

Issue, Question or Enhancement:

When validating a metav1.Duration struct, we are receiving an error with the validation that we previously never received

  [PANICKED] Test Panicked
  In [It] at: /Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/baked_in.go:2079 @ 08/18/23 00:08:21.25

  Bad field type v1.Duration

  Full Stack Trace
    github.com/go-playground/validator/v10.isGte({0x105ab3970, 0x1400098f680})
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/baked_in.go:2079 +0x440
    github.com/go-playground/validator/v10.hasMinOf({0x105ab3970?, 0x1400098f680?})
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/baked_in.go:2162 +0x24
    github.com/go-playground/validator/v10.wrapFunc.func1({0x1400098f680?, 0x105aba000?}, {0x105ab3970?, 0x1400098f680?})
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/baked_in.go:43 +0x34
    github.com/go-playground/validator/v10.(*validate).traverseField(0x1400098f680, {0x105aafb68, 0x14000190018}, {0x105a726c0?, 0x140001cd680?, 0x14000756868?}, {0x105a7cce0?, 0x140001cd690?, 0x120?}, {0x140000aad00, ...}, ...)
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/validator.go:180 +0xab4
    github.com/go-playground/validator/v10.(*validate).validateStruct(0x1400098f680, {0x105aafb68, 0x14000190018}, {0x105a726c0?, 0x140001cd680?, 0x0?}, {0x105a726c0?, 0x140001cd680?, 0x104c360e8?}, {0x105aba000?, ...}, ...)
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/validator.go:77 +0x51c
    github.com/go-playground/validator/v10.(*Validate).StructCtx(0x140002daa10, {0x105aafb68, 0x14000190018}, {0x105a726c0, 0x140001cd680})
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/validator_instance.go:389 +0x3cc
    github.com/go-playground/validator/v10.(*Validate).Struct(...)
    	/Users/joinnis/go/pkg/mod/github.com/go-playground/validator/[email protected]/validator_instance.go:362
    github.com/aws/karpenter/pkg/apis/settings.Settings.Validate({{0x0, 0x0}, 0x140005a3b48, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, 0x0, ...})
    	/Users/joinnis/github/karpenter/pkg/apis/settings/settings.go:110 +0x138
    github.com/aws/karpenter/pkg/apis/settings.(*Settings).Inject(0x140005b9dc0, {0x105aafbd8, 0x1400075e060}, 0x14000756e38)
    	/Users/joinnis/github/karpenter/pkg/apis/settings/settings.go:94 +0x388
    github.com/aws/karpenter/pkg/apis/settings_test.glob..func1.9()
    	/Users/joinnis/github/karpenter/pkg/apis/settings/suite_test.go:203 +0xdc

Code sample, to showcase or reproduce:

package main 

type Settings struct {
  d *metav1.Duration
}

func (s Settings) Validate() error {
  return validator.New().Struct(s)
}

func main() {
  s = Settings{d: &metav1.Duration{Duration: time.Second}}
  s.Validate()
}

jonathan-innis avatar Aug 18 '23 07:08 jonathan-innis

related to #1142

Nested struct validation was not supported in previous version, hence why no error was returned.

However, support extends only to a few tags including the ones that check against zero values such as required and excluded_with. This does not include tags like min.

If you need more complex validation, you must register your own custom tag. Ex.:

func main() {
	type Settings struct {
		D *metav1.Duration `validate:"metamin=15m"`
	}

	v := validator.New()
	if err := v.RegisterValidation("metamin", func(fl validator.FieldLevel) bool {
		duration, ok := fl.Field().Interface().(metav1.Duration)
		if !ok {
			return false
		}

		return v.Var(duration.Duration, "min="+fl.Param()) == nil
	}); err != nil {
		panic(err)
	}

	// valid
	s1 := Settings{&metav1.Duration{time.Minute * 15}}
	if err := v.Struct(s1); err != nil {
		panic(err)
	}

	// invalid
	s2 := Settings{&metav1.Duration{time.Minute * 14}}
	if err := v.Struct(s2); err != nil {
		panic(err)
	}
}

Also, it's worth noting that struct fields must be exported in order for them to get validated.

MysteriousPotato avatar Aug 18 '23 22:08 MysteriousPotato

Is this the code you're having an issue with? https://github.com/aws/karpenter/blob/a87ed30c8e60d6be25ce10fb058ad66c6174edab/pkg/apis/settings/settings.go#L57

Example doesn't clearly demonstrate an issue.

deankarn avatar Aug 18 '23 23:08 deankarn

@jonathan-innis can we consolidate the conversation here :) https://github.com/go-playground/validator/issues/1142

deankarn avatar Aug 19 '23 00:08 deankarn