...

Source file src/sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/validation/field/errors.go

Documentation: sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/validation/field

     1  // Code generated by k8scopy from k8s.io/apimachinery@v0.19.8; DO NOT EDIT.
     2  // File content copied from k8s.io/apimachinery@v0.19.8/pkg/util/validation/field/errors.go
     3  
     4  /*
     5  Copyright 2014 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package field
    21  
    22  import (
    23  	"fmt"
    24  	"reflect"
    25  	"strconv"
    26  	"strings"
    27  
    28  	utilerrors "sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/errors"
    29  	"sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/sets"
    30  )
    31  
    32  // Error is an implementation of the 'error' interface, which represents a
    33  // field-level validation error.
    34  type Error struct {
    35  	Type     ErrorType
    36  	Field    string
    37  	BadValue interface{}
    38  	Detail   string
    39  }
    40  
    41  var _ error = &Error{}
    42  
    43  // Error implements the error interface.
    44  func (v *Error) Error() string {
    45  	return fmt.Sprintf("%s: %s", v.Field, v.ErrorBody())
    46  }
    47  
    48  // ErrorBody returns the error message without the field name.  This is useful
    49  // for building nice-looking higher-level error reporting.
    50  func (v *Error) ErrorBody() string {
    51  	var s string
    52  	switch v.Type {
    53  	case ErrorTypeRequired, ErrorTypeForbidden, ErrorTypeTooLong, ErrorTypeInternal:
    54  		s = v.Type.String()
    55  	default:
    56  		value := v.BadValue
    57  		valueType := reflect.TypeOf(value)
    58  		if value == nil || valueType == nil {
    59  			value = "null"
    60  		} else if valueType.Kind() == reflect.Ptr {
    61  			if reflectValue := reflect.ValueOf(value); reflectValue.IsNil() {
    62  				value = "null"
    63  			} else {
    64  				value = reflectValue.Elem().Interface()
    65  			}
    66  		}
    67  		switch t := value.(type) {
    68  		case int64, int32, float64, float32, bool:
    69  			// use simple printer for simple types
    70  			s = fmt.Sprintf("%s: %v", v.Type, value)
    71  		case string:
    72  			s = fmt.Sprintf("%s: %q", v.Type, t)
    73  		case fmt.Stringer:
    74  			// anything that defines String() is better than raw struct
    75  			s = fmt.Sprintf("%s: %s", v.Type, t.String())
    76  		default:
    77  			// fallback to raw struct
    78  			// TODO: internal types have panic guards against json.Marshalling to prevent
    79  			// accidental use of internal types in external serialized form.  For now, use
    80  			// %#v, although it would be better to show a more expressive output in the future
    81  			s = fmt.Sprintf("%s: %#v", v.Type, value)
    82  		}
    83  	}
    84  	if len(v.Detail) != 0 {
    85  		s += fmt.Sprintf(": %s", v.Detail)
    86  	}
    87  	return s
    88  }
    89  
    90  // ErrorType is a machine readable value providing more detail about why
    91  // a field is invalid.  These values are expected to match 1-1 with
    92  // CauseType in api/types.go.
    93  type ErrorType string
    94  
    95  // TODO: These values are duplicated in api/types.go, but there's a circular dep.  Fix it.
    96  const (
    97  	// ErrorTypeNotFound is used to report failure to find a requested value
    98  	// (e.g. looking up an ID).  See NotFound().
    99  	ErrorTypeNotFound ErrorType = "FieldValueNotFound"
   100  	// ErrorTypeRequired is used to report required values that are not
   101  	// provided (e.g. empty strings, null values, or empty arrays).  See
   102  	// Required().
   103  	ErrorTypeRequired ErrorType = "FieldValueRequired"
   104  	// ErrorTypeDuplicate is used to report collisions of values that must be
   105  	// unique (e.g. unique IDs).  See Duplicate().
   106  	ErrorTypeDuplicate ErrorType = "FieldValueDuplicate"
   107  	// ErrorTypeInvalid is used to report malformed values (e.g. failed regex
   108  	// match, too long, out of bounds).  See Invalid().
   109  	ErrorTypeInvalid ErrorType = "FieldValueInvalid"
   110  	// ErrorTypeNotSupported is used to report unknown values for enumerated
   111  	// fields (e.g. a list of valid values).  See NotSupported().
   112  	ErrorTypeNotSupported ErrorType = "FieldValueNotSupported"
   113  	// ErrorTypeForbidden is used to report valid (as per formatting rules)
   114  	// values which would be accepted under some conditions, but which are not
   115  	// permitted by the current conditions (such as security policy).  See
   116  	// Forbidden().
   117  	ErrorTypeForbidden ErrorType = "FieldValueForbidden"
   118  	// ErrorTypeTooLong is used to report that the given value is too long.
   119  	// This is similar to ErrorTypeInvalid, but the error will not include the
   120  	// too-long value.  See TooLong().
   121  	ErrorTypeTooLong ErrorType = "FieldValueTooLong"
   122  	// ErrorTypeTooMany is used to report "too many". This is used to
   123  	// report that a given list has too many items. This is similar to FieldValueTooLong,
   124  	// but the error indicates quantity instead of length.
   125  	ErrorTypeTooMany ErrorType = "FieldValueTooMany"
   126  	// ErrorTypeInternal is used to report other errors that are not related
   127  	// to user input.  See InternalError().
   128  	ErrorTypeInternal ErrorType = "InternalError"
   129  )
   130  
   131  // String converts a ErrorType into its corresponding canonical error message.
   132  func (t ErrorType) String() string {
   133  	switch t {
   134  	case ErrorTypeNotFound:
   135  		return "Not found"
   136  	case ErrorTypeRequired:
   137  		return "Required value"
   138  	case ErrorTypeDuplicate:
   139  		return "Duplicate value"
   140  	case ErrorTypeInvalid:
   141  		return "Invalid value"
   142  	case ErrorTypeNotSupported:
   143  		return "Unsupported value"
   144  	case ErrorTypeForbidden:
   145  		return "Forbidden"
   146  	case ErrorTypeTooLong:
   147  		return "Too long"
   148  	case ErrorTypeTooMany:
   149  		return "Too many"
   150  	case ErrorTypeInternal:
   151  		return "Internal error"
   152  	default:
   153  		panic(fmt.Sprintf("unrecognized validation error: %q", string(t)))
   154  	}
   155  }
   156  
   157  // NotFound returns a *Error indicating "value not found".  This is
   158  // used to report failure to find a requested value (e.g. looking up an ID).
   159  func NotFound(field *Path, value interface{}) *Error {
   160  	return &Error{ErrorTypeNotFound, field.String(), value, ""}
   161  }
   162  
   163  // Required returns a *Error indicating "value required".  This is used
   164  // to report required values that are not provided (e.g. empty strings, null
   165  // values, or empty arrays).
   166  func Required(field *Path, detail string) *Error {
   167  	return &Error{ErrorTypeRequired, field.String(), "", detail}
   168  }
   169  
   170  // Duplicate returns a *Error indicating "duplicate value".  This is
   171  // used to report collisions of values that must be unique (e.g. names or IDs).
   172  func Duplicate(field *Path, value interface{}) *Error {
   173  	return &Error{ErrorTypeDuplicate, field.String(), value, ""}
   174  }
   175  
   176  // Invalid returns a *Error indicating "invalid value".  This is used
   177  // to report malformed values (e.g. failed regex match, too long, out of bounds).
   178  func Invalid(field *Path, value interface{}, detail string) *Error {
   179  	return &Error{ErrorTypeInvalid, field.String(), value, detail}
   180  }
   181  
   182  // NotSupported returns a *Error indicating "unsupported value".
   183  // This is used to report unknown values for enumerated fields (e.g. a list of
   184  // valid values).
   185  func NotSupported(field *Path, value interface{}, validValues []string) *Error {
   186  	detail := ""
   187  	if validValues != nil && len(validValues) > 0 {
   188  		quotedValues := make([]string, len(validValues))
   189  		for i, v := range validValues {
   190  			quotedValues[i] = strconv.Quote(v)
   191  		}
   192  		detail = "supported values: " + strings.Join(quotedValues, ", ")
   193  	}
   194  	return &Error{ErrorTypeNotSupported, field.String(), value, detail}
   195  }
   196  
   197  // Forbidden returns a *Error indicating "forbidden".  This is used to
   198  // report valid (as per formatting rules) values which would be accepted under
   199  // some conditions, but which are not permitted by current conditions (e.g.
   200  // security policy).
   201  func Forbidden(field *Path, detail string) *Error {
   202  	return &Error{ErrorTypeForbidden, field.String(), "", detail}
   203  }
   204  
   205  // TooLong returns a *Error indicating "too long".  This is used to
   206  // report that the given value is too long.  This is similar to
   207  // Invalid, but the returned error will not include the too-long
   208  // value.
   209  func TooLong(field *Path, value interface{}, maxLength int) *Error {
   210  	return &Error{ErrorTypeTooLong, field.String(), value, fmt.Sprintf("must have at most %d bytes", maxLength)}
   211  }
   212  
   213  // TooMany returns a *Error indicating "too many". This is used to
   214  // report that a given list has too many items. This is similar to TooLong,
   215  // but the returned error indicates quantity instead of length.
   216  func TooMany(field *Path, actualQuantity, maxQuantity int) *Error {
   217  	return &Error{ErrorTypeTooMany, field.String(), actualQuantity, fmt.Sprintf("must have at most %d items", maxQuantity)}
   218  }
   219  
   220  // InternalError returns a *Error indicating "internal error".  This is used
   221  // to signal that an error was found that was not directly related to user
   222  // input.  The err argument must be non-nil.
   223  func InternalError(field *Path, err error) *Error {
   224  	return &Error{ErrorTypeInternal, field.String(), nil, err.Error()}
   225  }
   226  
   227  // ErrorList holds a set of Errors.  It is plausible that we might one day have
   228  // non-field errors in this same umbrella package, but for now we don't, so
   229  // we can keep it simple and leave ErrorList here.
   230  type ErrorList []*Error
   231  
   232  // NewErrorTypeMatcher returns an errors.Matcher that returns true
   233  // if the provided error is a Error and has the provided ErrorType.
   234  func NewErrorTypeMatcher(t ErrorType) utilerrors.Matcher {
   235  	return func(err error) bool {
   236  		if e, ok := err.(*Error); ok {
   237  			return e.Type == t
   238  		}
   239  		return false
   240  	}
   241  }
   242  
   243  // ToAggregate converts the ErrorList into an errors.Aggregate.
   244  func (list ErrorList) ToAggregate() utilerrors.Aggregate {
   245  	errs := make([]error, 0, len(list))
   246  	errorMsgs := sets.NewString()
   247  	for _, err := range list {
   248  		msg := fmt.Sprintf("%v", err)
   249  		if errorMsgs.Has(msg) {
   250  			continue
   251  		}
   252  		errorMsgs.Insert(msg)
   253  		errs = append(errs, err)
   254  	}
   255  	return utilerrors.NewAggregate(errs)
   256  }
   257  
   258  func fromAggregate(agg utilerrors.Aggregate) ErrorList {
   259  	errs := agg.Errors()
   260  	list := make(ErrorList, len(errs))
   261  	for i := range errs {
   262  		list[i] = errs[i].(*Error)
   263  	}
   264  	return list
   265  }
   266  
   267  // Filter removes items from the ErrorList that match the provided fns.
   268  func (list ErrorList) Filter(fns ...utilerrors.Matcher) ErrorList {
   269  	err := utilerrors.FilterOut(list.ToAggregate(), fns...)
   270  	if err == nil {
   271  		return nil
   272  	}
   273  	// FilterOut takes an Aggregate and returns an Aggregate
   274  	return fromAggregate(err.(utilerrors.Aggregate))
   275  }
   276  

View as plain text