in cli_tools/common/utils/validation/validation_utils.go [141:182]
func ValidateStruct(s interface{}) error {
validate := validator.New()
// Register new validators.
if err := validate.RegisterValidation("gce_disk_image_name", func(fl validator.FieldLevel) bool {
return ValidateImageName(fl.Field().String()) == nil
}); err != nil {
panic(err)
}
// Allow the error message's field name to be customized via a `name` struct tag.
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
if name, found := fld.Tag.Lookup("name"); found {
return name
}
return fld.Name
})
// Run validation.
err := validate.Struct(s)
if err == nil {
return nil
}
// If validation fails:
// 1. Surface the first error.
// 2. Create a new error message. This ensures sensitive information
// is not leaked to anonymous logs.
var verr validator.ValidationErrors
if errors.As(err, &verr) && len(verr) > 0 {
firstErr := verr[0]
switch firstErr.Tag() {
case "required":
return errors.New(firstErr.Field() + " has to be specified")
case "gce_disk_image_name":
return ValidateImageName(firstErr.Value().(string))
}
}
// Panic to ensure that CLI arguments are not leaked. To safely show an argument
// to a user, inject it into a string template using `daisy.Errf`.
panic(fmt.Sprintf("Customize error: %v", err))
}