func ValidateStruct()

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))
}