in internal/api/validate.go [60:196]
func NewValidator() *validator.Validate {
var err error
validate := validator.New(validator.WithRequiredStructEnabled())
// Use "json" struct tags for alternate field names.
// Alternate field names will be used in validation errors.
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
return GetJSONTagName(field.Tag)
})
// Register ARM-mandated enumeration types.
validate.RegisterAlias("enum_managedserviceidentitytype", EnumValidateTag(
arm.ManagedServiceIdentityTypeNone,
arm.ManagedServiceIdentityTypeSystemAssigned,
arm.ManagedServiceIdentityTypeSystemAssignedUserAssigned,
arm.ManagedServiceIdentityTypeUserAssigned))
validate.RegisterAlias("enum_subscriptionstate", EnumValidateTag(
arm.SubscriptionStateRegistered,
arm.SubscriptionStateUnregistered,
arm.SubscriptionStateWarned,
arm.SubscriptionStateDeleted,
arm.SubscriptionStateSuspended))
// Use this for string fields specifying an ARO-HCP API version.
err = validate.RegisterValidation("api_version", func(fl validator.FieldLevel) bool {
field := fl.Field()
if field.Kind() != reflect.String {
panic("String type required for api_version")
}
_, ok := Lookup(field.String())
return ok
})
if err != nil {
panic(err)
}
// Use this for string fields that must be a valid Kubernetes qualified name.
err = validate.RegisterValidation("k8s_qualified_name", func(fl validator.FieldLevel) bool {
field := fl.Field()
if field.Kind() != reflect.String {
panic("String type required for k8s_qualified_name")
}
return len(k8svalidation.IsQualifiedName(field.String())) == 0
})
if err != nil {
panic(err)
}
// Use this for string fields that must be a valid Kubernetes label value.
err = validate.RegisterValidation("k8s_label_value", func(fl validator.FieldLevel) bool {
field := fl.Field()
if field.Kind() != reflect.String {
panic("String type required for k8s_label_value")
}
return len(k8svalidation.IsValidLabelValue(field.String())) == 0
})
if err != nil {
panic(err)
}
// Use this for version ID fields that might begin with "openshift-v".
err = validate.RegisterValidation("openshift_version", func(fl validator.FieldLevel) bool {
field := fl.Field()
if field.Kind() != reflect.String {
panic("String type required for openshift_version")
}
_, err := NewOpenShiftVersion(field.String())
return err == nil
})
if err != nil {
panic(err)
}
// Use this for string fields providing PEM encoded certificates.
err = validate.RegisterValidation("pem_certificates", func(fl validator.FieldLevel) bool {
field := fl.Field()
if field.Kind() != reflect.String {
panic("String type required for pem_certificates")
}
return x509.NewCertPool().AppendCertsFromPEM([]byte(field.String()))
})
if err != nil {
panic(err)
}
// Use this for fields required in PUT requests. Do not apply to read-only fields.
err = validate.RegisterValidation("required_for_put", func(fl validator.FieldLevel) bool {
val := fl.Top().FieldByName("Method")
if val.IsZero() {
panic("Method field not found for required_for_put")
}
if val.String() != http.MethodPut {
return true
}
// This is replicating the implementation of "required".
// See https://github.com/go-playground/validator/issues/492
// Sounds like "hasValue" is unlikely to be exported and
// "validate.Var" does not seem like a safe alternative.
field := fl.Field()
_, kind, nullable := fl.ExtractType(field)
switch kind {
case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
return !field.IsNil()
default:
if nullable && field.Interface() != nil {
return true
}
return field.IsValid() && !field.IsZero()
}
})
if err != nil {
panic(err)
}
// Use this for string fields specifying an Azure resource ID.
// The optional argument further enforces a specific resource type.
err = validate.RegisterValidation("resource_id", func(fl validator.FieldLevel) bool {
field := fl.Field()
param := fl.Param()
if field.Kind() != reflect.String {
panic("String type required for resource_id")
}
resourceID, err := azcorearm.ParseResourceID(field.String())
if err != nil {
return false
}
resourceType := resourceID.ResourceType.String()
return param == "" || strings.EqualFold(resourceType, param)
})
if err != nil {
panic(err)
}
return validate
}