mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
rebase: update kubernetes to v1.23.0
updating go dependency to latest kubernetes released version i.e v1.23.0 Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
committed by
mergify[bot]
parent
42403e2ba7
commit
5762da3e91
210
vendor/k8s.io/apimachinery/pkg/runtime/converter.go
generated
vendored
210
vendor/k8s.io/apimachinery/pkg/runtime/converter.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -109,21 +110,141 @@ type unstructuredConverter struct {
|
||||
// to Go types via reflection. It performs mismatch detection automatically and is intended for use by external
|
||||
// test tools. Use DefaultUnstructuredConverter if you do not explicitly need mismatch detection.
|
||||
func NewTestUnstructuredConverter(comparison conversion.Equalities) UnstructuredConverter {
|
||||
return NewTestUnstructuredConverterWithValidation(comparison)
|
||||
}
|
||||
|
||||
// NewTestUnstrucutredConverterWithValidation allows for access to
|
||||
// FromUnstructuredWithValidation from within tests.
|
||||
func NewTestUnstructuredConverterWithValidation(comparison conversion.Equalities) *unstructuredConverter {
|
||||
return &unstructuredConverter{
|
||||
mismatchDetection: true,
|
||||
comparison: comparison,
|
||||
}
|
||||
}
|
||||
|
||||
// FromUnstructured converts an object from map[string]interface{} representation into a concrete type.
|
||||
// fromUnstructuredContext provides options for informing the converter
|
||||
// the state of its recursive walk through the conversion process.
|
||||
type fromUnstructuredContext struct {
|
||||
// isInlined indicates whether the converter is currently in
|
||||
// an inlined field or not to determine whether it should
|
||||
// validate the matchedKeys yet or only collect them.
|
||||
// This should only be set from `structFromUnstructured`
|
||||
isInlined bool
|
||||
// matchedKeys is a stack of the set of all fields that exist in the
|
||||
// concrete go type of the object being converted into.
|
||||
// This should only be manipulated via `pushMatchedKeyTracker`,
|
||||
// `recordMatchedKey`, or `popAndVerifyMatchedKeys`
|
||||
matchedKeys []map[string]struct{}
|
||||
// parentPath collects the path that the conversion
|
||||
// takes as it traverses the unstructured json map.
|
||||
// It is used to report the full path to any unknown
|
||||
// fields that the converter encounters.
|
||||
parentPath []string
|
||||
// returnUnknownFields indicates whether or not
|
||||
// unknown field errors should be collected and
|
||||
// returned to the caller
|
||||
returnUnknownFields bool
|
||||
// unknownFieldErrors are the collection of
|
||||
// the full path to each unknown field in the
|
||||
// object.
|
||||
unknownFieldErrors []error
|
||||
}
|
||||
|
||||
// pushMatchedKeyTracker adds a placeholder set for tracking
|
||||
// matched keys for the given level. This should only be
|
||||
// called from `structFromUnstructured`.
|
||||
func (c *fromUnstructuredContext) pushMatchedKeyTracker() {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
c.matchedKeys = append(c.matchedKeys, nil)
|
||||
}
|
||||
|
||||
// recordMatchedKey initializes the last element of matchedKeys
|
||||
// (if needed) and sets 'key'. This should only be called from
|
||||
// `structFromUnstructured`.
|
||||
func (c *fromUnstructuredContext) recordMatchedKey(key string) {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
last := len(c.matchedKeys) - 1
|
||||
if c.matchedKeys[last] == nil {
|
||||
c.matchedKeys[last] = map[string]struct{}{}
|
||||
}
|
||||
c.matchedKeys[last][key] = struct{}{}
|
||||
}
|
||||
|
||||
// popAndVerifyMatchedKeys pops the last element of matchedKeys,
|
||||
// checks the matched keys against the data, and adds unknown
|
||||
// field errors for any matched keys.
|
||||
// `mapValue` is the value of sv containing all of the keys that exist at this level
|
||||
// (ie. sv.MapKeys) in the source data.
|
||||
// `matchedKeys` are all the keys found for that level in the destination object.
|
||||
// This should only be called from `structFromUnstructured`.
|
||||
func (c *fromUnstructuredContext) popAndVerifyMatchedKeys(mapValue reflect.Value) {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
last := len(c.matchedKeys) - 1
|
||||
curMatchedKeys := c.matchedKeys[last]
|
||||
c.matchedKeys[last] = nil
|
||||
c.matchedKeys = c.matchedKeys[:last]
|
||||
for _, key := range mapValue.MapKeys() {
|
||||
if _, ok := curMatchedKeys[key.String()]; !ok {
|
||||
c.recordUnknownField(key.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *fromUnstructuredContext) recordUnknownField(field string) {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
pathLen := len(c.parentPath)
|
||||
c.pushKey(field)
|
||||
errPath := strings.Join(c.parentPath, "")
|
||||
c.parentPath = c.parentPath[:pathLen]
|
||||
c.unknownFieldErrors = append(c.unknownFieldErrors, fmt.Errorf(`unknown field "%s"`, errPath))
|
||||
}
|
||||
|
||||
func (c *fromUnstructuredContext) pushIndex(index int) {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
c.parentPath = append(c.parentPath, "[", strconv.Itoa(index), "]")
|
||||
}
|
||||
|
||||
func (c *fromUnstructuredContext) pushKey(key string) {
|
||||
if !c.returnUnknownFields {
|
||||
return
|
||||
}
|
||||
|
||||
if len(c.parentPath) > 0 {
|
||||
c.parentPath = append(c.parentPath, ".")
|
||||
}
|
||||
c.parentPath = append(c.parentPath, key)
|
||||
|
||||
}
|
||||
|
||||
// FromUnstructuredWIthValidation converts an object from map[string]interface{} representation into a concrete type.
|
||||
// It uses encoding/json/Unmarshaler if object implements it or reflection if not.
|
||||
func (c *unstructuredConverter) FromUnstructured(u map[string]interface{}, obj interface{}) error {
|
||||
// It takes a validationDirective that indicates how to behave when it encounters unknown fields.
|
||||
func (c *unstructuredConverter) FromUnstructuredWithValidation(u map[string]interface{}, obj interface{}, returnUnknownFields bool) error {
|
||||
t := reflect.TypeOf(obj)
|
||||
value := reflect.ValueOf(obj)
|
||||
if t.Kind() != reflect.Ptr || value.IsNil() {
|
||||
return fmt.Errorf("FromUnstructured requires a non-nil pointer to an object, got %v", t)
|
||||
}
|
||||
err := fromUnstructured(reflect.ValueOf(u), value.Elem())
|
||||
|
||||
fromUnstructuredContext := &fromUnstructuredContext{
|
||||
returnUnknownFields: returnUnknownFields,
|
||||
}
|
||||
err := fromUnstructured(reflect.ValueOf(u), value.Elem(), fromUnstructuredContext)
|
||||
if c.mismatchDetection {
|
||||
newObj := reflect.New(t.Elem()).Interface()
|
||||
newErr := fromUnstructuredViaJSON(u, newObj)
|
||||
@ -134,7 +255,23 @@ func (c *unstructuredConverter) FromUnstructured(u map[string]interface{}, obj i
|
||||
klog.Fatalf("FromUnstructured mismatch\nobj1: %#v\nobj2: %#v", obj, newObj)
|
||||
}
|
||||
}
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if returnUnknownFields && len(fromUnstructuredContext.unknownFieldErrors) > 0 {
|
||||
sort.Slice(fromUnstructuredContext.unknownFieldErrors, func(i, j int) bool {
|
||||
return fromUnstructuredContext.unknownFieldErrors[i].Error() <
|
||||
fromUnstructuredContext.unknownFieldErrors[j].Error()
|
||||
})
|
||||
return NewStrictDecodingError(fromUnstructuredContext.unknownFieldErrors)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromUnstructured converts an object from map[string]interface{} representation into a concrete type.
|
||||
// It uses encoding/json/Unmarshaler if object implements it or reflection if not.
|
||||
func (c *unstructuredConverter) FromUnstructured(u map[string]interface{}, obj interface{}) error {
|
||||
return c.FromUnstructuredWithValidation(u, obj, false)
|
||||
}
|
||||
|
||||
func fromUnstructuredViaJSON(u map[string]interface{}, obj interface{}) error {
|
||||
@ -145,7 +282,7 @@ func fromUnstructuredViaJSON(u map[string]interface{}, obj interface{}) error {
|
||||
return json.Unmarshal(data, obj)
|
||||
}
|
||||
|
||||
func fromUnstructured(sv, dv reflect.Value) error {
|
||||
func fromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error {
|
||||
sv = unwrapInterface(sv)
|
||||
if !sv.IsValid() {
|
||||
dv.Set(reflect.Zero(dv.Type()))
|
||||
@ -213,18 +350,19 @@ func fromUnstructured(sv, dv reflect.Value) error {
|
||||
|
||||
switch dt.Kind() {
|
||||
case reflect.Map:
|
||||
return mapFromUnstructured(sv, dv)
|
||||
return mapFromUnstructured(sv, dv, ctx)
|
||||
case reflect.Slice:
|
||||
return sliceFromUnstructured(sv, dv)
|
||||
return sliceFromUnstructured(sv, dv, ctx)
|
||||
case reflect.Ptr:
|
||||
return pointerFromUnstructured(sv, dv)
|
||||
return pointerFromUnstructured(sv, dv, ctx)
|
||||
case reflect.Struct:
|
||||
return structFromUnstructured(sv, dv)
|
||||
return structFromUnstructured(sv, dv, ctx)
|
||||
case reflect.Interface:
|
||||
return interfaceFromUnstructured(sv, dv)
|
||||
default:
|
||||
return fmt.Errorf("unrecognized type: %v", dt.Kind())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func fieldInfoFromField(structType reflect.Type, field int) *fieldInfo {
|
||||
@ -275,7 +413,7 @@ func unwrapInterface(v reflect.Value) reflect.Value {
|
||||
return v
|
||||
}
|
||||
|
||||
func mapFromUnstructured(sv, dv reflect.Value) error {
|
||||
func mapFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error {
|
||||
st, dt := sv.Type(), dv.Type()
|
||||
if st.Kind() != reflect.Map {
|
||||
return fmt.Errorf("cannot restore map from %v", st.Kind())
|
||||
@ -293,7 +431,7 @@ func mapFromUnstructured(sv, dv reflect.Value) error {
|
||||
for _, key := range sv.MapKeys() {
|
||||
value := reflect.New(dt.Elem()).Elem()
|
||||
if val := unwrapInterface(sv.MapIndex(key)); val.IsValid() {
|
||||
if err := fromUnstructured(val, value); err != nil {
|
||||
if err := fromUnstructured(val, value, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
@ -308,7 +446,7 @@ func mapFromUnstructured(sv, dv reflect.Value) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func sliceFromUnstructured(sv, dv reflect.Value) error {
|
||||
func sliceFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error {
|
||||
st, dt := sv.Type(), dv.Type()
|
||||
if st.Kind() == reflect.String && dt.Elem().Kind() == reflect.Uint8 {
|
||||
// We store original []byte representation as string.
|
||||
@ -340,15 +478,22 @@ func sliceFromUnstructured(sv, dv reflect.Value) error {
|
||||
return nil
|
||||
}
|
||||
dv.Set(reflect.MakeSlice(dt, sv.Len(), sv.Cap()))
|
||||
|
||||
pathLen := len(ctx.parentPath)
|
||||
defer func() {
|
||||
ctx.parentPath = ctx.parentPath[:pathLen]
|
||||
}()
|
||||
for i := 0; i < sv.Len(); i++ {
|
||||
if err := fromUnstructured(sv.Index(i), dv.Index(i)); err != nil {
|
||||
ctx.pushIndex(i)
|
||||
if err := fromUnstructured(sv.Index(i), dv.Index(i), ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.parentPath = ctx.parentPath[:pathLen]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func pointerFromUnstructured(sv, dv reflect.Value) error {
|
||||
func pointerFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error {
|
||||
st, dt := sv.Type(), dv.Type()
|
||||
|
||||
if st.Kind() == reflect.Ptr && sv.IsNil() {
|
||||
@ -358,38 +503,63 @@ func pointerFromUnstructured(sv, dv reflect.Value) error {
|
||||
dv.Set(reflect.New(dt.Elem()))
|
||||
switch st.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return fromUnstructured(sv.Elem(), dv.Elem())
|
||||
return fromUnstructured(sv.Elem(), dv.Elem(), ctx)
|
||||
default:
|
||||
return fromUnstructured(sv, dv.Elem())
|
||||
return fromUnstructured(sv, dv.Elem(), ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func structFromUnstructured(sv, dv reflect.Value) error {
|
||||
func structFromUnstructured(sv, dv reflect.Value, ctx *fromUnstructuredContext) error {
|
||||
st, dt := sv.Type(), dv.Type()
|
||||
if st.Kind() != reflect.Map {
|
||||
return fmt.Errorf("cannot restore struct from: %v", st.Kind())
|
||||
}
|
||||
|
||||
pathLen := len(ctx.parentPath)
|
||||
svInlined := ctx.isInlined
|
||||
defer func() {
|
||||
ctx.parentPath = ctx.parentPath[:pathLen]
|
||||
ctx.isInlined = svInlined
|
||||
}()
|
||||
if !svInlined {
|
||||
ctx.pushMatchedKeyTracker()
|
||||
}
|
||||
for i := 0; i < dt.NumField(); i++ {
|
||||
fieldInfo := fieldInfoFromField(dt, i)
|
||||
fv := dv.Field(i)
|
||||
|
||||
if len(fieldInfo.name) == 0 {
|
||||
// This field is inlined.
|
||||
if err := fromUnstructured(sv, fv); err != nil {
|
||||
// This field is inlined, recurse into fromUnstructured again
|
||||
// with the same set of matched keys.
|
||||
ctx.isInlined = true
|
||||
if err := fromUnstructured(sv, fv, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.isInlined = svInlined
|
||||
} else {
|
||||
// This field is not inlined so we recurse into
|
||||
// child field of sv corresponding to field i of
|
||||
// dv, with a new set of matchedKeys and updating
|
||||
// the parentPath to indicate that we are one level
|
||||
// deeper.
|
||||
ctx.recordMatchedKey(fieldInfo.name)
|
||||
value := unwrapInterface(sv.MapIndex(fieldInfo.nameValue))
|
||||
if value.IsValid() {
|
||||
if err := fromUnstructured(value, fv); err != nil {
|
||||
ctx.isInlined = false
|
||||
ctx.pushKey(fieldInfo.name)
|
||||
if err := fromUnstructured(value, fv, ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx.parentPath = ctx.parentPath[:pathLen]
|
||||
ctx.isInlined = svInlined
|
||||
} else {
|
||||
fv.Set(reflect.Zero(fv.Type()))
|
||||
}
|
||||
}
|
||||
}
|
||||
if !svInlined {
|
||||
ctx.popAndVerifyMatchedKeys(sv)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
33
vendor/k8s.io/apimachinery/pkg/runtime/error.go
generated
vendored
33
vendor/k8s.io/apimachinery/pkg/runtime/error.go
generated
vendored
@ -19,6 +19,7 @@ package runtime
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
@ -124,20 +125,30 @@ func IsMissingVersion(err error) bool {
|
||||
// strictDecodingError is a base error type that is returned by a strict Decoder such
|
||||
// as UniversalStrictDecoder.
|
||||
type strictDecodingError struct {
|
||||
message string
|
||||
data string
|
||||
errors []error
|
||||
}
|
||||
|
||||
// NewStrictDecodingError creates a new strictDecodingError object.
|
||||
func NewStrictDecodingError(message string, data string) error {
|
||||
func NewStrictDecodingError(errors []error) error {
|
||||
return &strictDecodingError{
|
||||
message: message,
|
||||
data: data,
|
||||
errors: errors,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *strictDecodingError) Error() string {
|
||||
return fmt.Sprintf("strict decoder error for %s: %s", e.data, e.message)
|
||||
var s strings.Builder
|
||||
s.WriteString("strict decoding error: ")
|
||||
for i, err := range e.errors {
|
||||
if i != 0 {
|
||||
s.WriteString(", ")
|
||||
}
|
||||
s.WriteString(err.Error())
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
func (e *strictDecodingError) Errors() []error {
|
||||
return e.errors
|
||||
}
|
||||
|
||||
// IsStrictDecodingError returns true if the error indicates that the provided object
|
||||
@ -149,3 +160,13 @@ func IsStrictDecodingError(err error) bool {
|
||||
_, ok := err.(*strictDecodingError)
|
||||
return ok
|
||||
}
|
||||
|
||||
// AsStrictDecodingError returns a strict decoding error
|
||||
// containing all the strictness violations.
|
||||
func AsStrictDecodingError(err error) (*strictDecodingError, bool) {
|
||||
if err == nil {
|
||||
return nil, false
|
||||
}
|
||||
strictErr, ok := err.(*strictDecodingError)
|
||||
return strictErr, ok
|
||||
}
|
||||
|
3
vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
generated
vendored
3
vendor/k8s.io/apimachinery/pkg/runtime/interfaces.go
generated
vendored
@ -125,6 +125,9 @@ type SerializerInfo struct {
|
||||
// PrettySerializer, if set, can serialize this object in a form biased towards
|
||||
// readability.
|
||||
PrettySerializer Serializer
|
||||
// StrictSerializer, if set, deserializes this object strictly,
|
||||
// erring on unknown fields.
|
||||
StrictSerializer Serializer
|
||||
// StreamSerializer, if set, describes the streaming serialization format
|
||||
// for this media type.
|
||||
StreamSerializer *StreamSerializerInfo
|
||||
|
24
vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
generated
vendored
24
vendor/k8s.io/apimachinery/pkg/runtime/scheme.go
generated
vendored
@ -99,7 +99,7 @@ func NewScheme() *Scheme {
|
||||
versionPriority: map[string][]string{},
|
||||
schemeName: naming.GetNameFromCallsite(internalPackages...),
|
||||
}
|
||||
s.converter = conversion.NewConverter(s.nameFunc)
|
||||
s.converter = conversion.NewConverter(nil)
|
||||
|
||||
// Enable couple default conversions by default.
|
||||
utilruntime.Must(RegisterEmbeddedConversions(s))
|
||||
@ -107,28 +107,6 @@ func NewScheme() *Scheme {
|
||||
return s
|
||||
}
|
||||
|
||||
// nameFunc returns the name of the type that we wish to use to determine when two types attempt
|
||||
// a conversion. Defaults to the go name of the type if the type is not registered.
|
||||
func (s *Scheme) nameFunc(t reflect.Type) string {
|
||||
// find the preferred names for this type
|
||||
gvks, ok := s.typeToGVK[t]
|
||||
if !ok {
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
for _, gvk := range gvks {
|
||||
internalGV := gvk.GroupVersion()
|
||||
internalGV.Version = APIVersionInternal // this is hacky and maybe should be passed in
|
||||
internalGVK := internalGV.WithKind(gvk.Kind)
|
||||
|
||||
if internalType, exists := s.gvkToType[internalGVK]; exists {
|
||||
return s.typeToGVK[internalType][0].Kind
|
||||
}
|
||||
}
|
||||
|
||||
return gvks[0].Kind
|
||||
}
|
||||
|
||||
// Converter allows access to the converter for the scheme
|
||||
func (s *Scheme) Converter() *conversion.Converter {
|
||||
return s.converter
|
||||
|
16
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
generated
vendored
16
vendor/k8s.io/apimachinery/pkg/runtime/serializer/codec_factory.go
generated
vendored
@ -40,6 +40,7 @@ type serializerType struct {
|
||||
|
||||
Serializer runtime.Serializer
|
||||
PrettySerializer runtime.Serializer
|
||||
StrictSerializer runtime.Serializer
|
||||
|
||||
AcceptStreamContentTypes []string
|
||||
StreamContentType string
|
||||
@ -70,10 +71,20 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
|
||||
)
|
||||
}
|
||||
|
||||
strictJSONSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: false, Pretty: false, Strict: true},
|
||||
)
|
||||
jsonSerializerType.StrictSerializer = strictJSONSerializer
|
||||
|
||||
yamlSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: true, Pretty: false, Strict: options.Strict},
|
||||
)
|
||||
strictYAMLSerializer := json.NewSerializerWithOptions(
|
||||
mf, scheme, scheme,
|
||||
json.SerializerOptions{Yaml: true, Pretty: false, Strict: true},
|
||||
)
|
||||
protoSerializer := protobuf.NewSerializer(scheme, scheme)
|
||||
protoRawSerializer := protobuf.NewRawSerializer(scheme, scheme)
|
||||
|
||||
@ -85,12 +96,16 @@ func newSerializersForScheme(scheme *runtime.Scheme, mf json.MetaFactory, option
|
||||
FileExtensions: []string{"yaml"},
|
||||
EncodesAsText: true,
|
||||
Serializer: yamlSerializer,
|
||||
StrictSerializer: strictYAMLSerializer,
|
||||
},
|
||||
{
|
||||
AcceptContentTypes: []string{runtime.ContentTypeProtobuf},
|
||||
ContentType: runtime.ContentTypeProtobuf,
|
||||
FileExtensions: []string{"pb"},
|
||||
Serializer: protoSerializer,
|
||||
// note, strict decoding is unsupported for protobuf,
|
||||
// fall back to regular serializing
|
||||
StrictSerializer: protoSerializer,
|
||||
|
||||
Framer: protobuf.LengthDelimitedFramer,
|
||||
StreamSerializer: protoRawSerializer,
|
||||
@ -187,6 +202,7 @@ func newCodecFactory(scheme *runtime.Scheme, serializers []serializerType) Codec
|
||||
EncodesAsText: d.EncodesAsText,
|
||||
Serializer: d.Serializer,
|
||||
PrettySerializer: d.PrettySerializer,
|
||||
StrictSerializer: d.StrictSerializer,
|
||||
}
|
||||
|
||||
mediaType, _, err := mime.ParseMediaType(info.MediaType)
|
||||
|
162
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
generated
vendored
162
vendor/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go
generated
vendored
@ -20,10 +20,8 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/modern-go/reflect2"
|
||||
kjson "sigs.k8s.io/json"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -68,6 +66,7 @@ func identifier(options SerializerOptions) runtime.Identifier {
|
||||
"name": "json",
|
||||
"yaml": strconv.FormatBool(options.Yaml),
|
||||
"pretty": strconv.FormatBool(options.Pretty),
|
||||
"strict": strconv.FormatBool(options.Strict),
|
||||
}
|
||||
identifier, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
@ -110,79 +109,6 @@ type Serializer struct {
|
||||
var _ runtime.Serializer = &Serializer{}
|
||||
var _ recognizer.RecognizingDecoder = &Serializer{}
|
||||
|
||||
type customNumberExtension struct {
|
||||
jsoniter.DummyExtension
|
||||
}
|
||||
|
||||
func (cne *customNumberExtension) CreateDecoder(typ reflect2.Type) jsoniter.ValDecoder {
|
||||
if typ.String() == "interface {}" {
|
||||
return customNumberDecoder{}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type customNumberDecoder struct {
|
||||
}
|
||||
|
||||
func (customNumberDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
|
||||
switch iter.WhatIsNext() {
|
||||
case jsoniter.NumberValue:
|
||||
var number jsoniter.Number
|
||||
iter.ReadVal(&number)
|
||||
i64, err := strconv.ParseInt(string(number), 10, 64)
|
||||
if err == nil {
|
||||
*(*interface{})(ptr) = i64
|
||||
return
|
||||
}
|
||||
f64, err := strconv.ParseFloat(string(number), 64)
|
||||
if err == nil {
|
||||
*(*interface{})(ptr) = f64
|
||||
return
|
||||
}
|
||||
iter.ReportError("DecodeNumber", err.Error())
|
||||
default:
|
||||
*(*interface{})(ptr) = iter.Read()
|
||||
}
|
||||
}
|
||||
|
||||
// CaseSensitiveJSONIterator returns a jsoniterator API that's configured to be
|
||||
// case-sensitive when unmarshalling, and otherwise compatible with
|
||||
// the encoding/json standard library.
|
||||
func CaseSensitiveJSONIterator() jsoniter.API {
|
||||
config := jsoniter.Config{
|
||||
EscapeHTML: true,
|
||||
SortMapKeys: true,
|
||||
ValidateJsonRawMessage: true,
|
||||
CaseSensitive: true,
|
||||
}.Froze()
|
||||
// Force jsoniter to decode number to interface{} via int64/float64, if possible.
|
||||
config.RegisterExtension(&customNumberExtension{})
|
||||
return config
|
||||
}
|
||||
|
||||
// StrictCaseSensitiveJSONIterator returns a jsoniterator API that's configured to be
|
||||
// case-sensitive, but also disallows unknown fields when unmarshalling. It is compatible with
|
||||
// the encoding/json standard library.
|
||||
func StrictCaseSensitiveJSONIterator() jsoniter.API {
|
||||
config := jsoniter.Config{
|
||||
EscapeHTML: true,
|
||||
SortMapKeys: true,
|
||||
ValidateJsonRawMessage: true,
|
||||
CaseSensitive: true,
|
||||
DisallowUnknownFields: true,
|
||||
}.Froze()
|
||||
// Force jsoniter to decode number to interface{} via int64/float64, if possible.
|
||||
config.RegisterExtension(&customNumberExtension{})
|
||||
return config
|
||||
}
|
||||
|
||||
// Private copies of jsoniter to try to shield against possible mutations
|
||||
// from outside. Still does not protect from package level jsoniter.Register*() functions - someone calling them
|
||||
// in some other library will mess with every usage of the jsoniter library in the whole program.
|
||||
// See https://github.com/json-iterator/go/issues/265
|
||||
var caseSensitiveJSONIterator = CaseSensitiveJSONIterator()
|
||||
var strictCaseSensitiveJSONIterator = StrictCaseSensitiveJSONIterator()
|
||||
|
||||
// gvkWithDefaults returns group kind and version defaulting from provided default
|
||||
func gvkWithDefaults(actual, defaultGVK schema.GroupVersionKind) schema.GroupVersionKind {
|
||||
if len(actual.Kind) == 0 {
|
||||
@ -237,8 +163,11 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
|
||||
types, _, err := s.typer.ObjectKinds(into)
|
||||
switch {
|
||||
case runtime.IsNotRegisteredError(err), isUnstructured:
|
||||
if err := caseSensitiveJSONIterator.Unmarshal(data, into); err != nil {
|
||||
strictErrs, err := s.unmarshal(into, data, originalData)
|
||||
if err != nil {
|
||||
return nil, actual, err
|
||||
} else if len(strictErrs) > 0 {
|
||||
return into, actual, runtime.NewStrictDecodingError(strictErrs)
|
||||
}
|
||||
return into, actual, nil
|
||||
case err != nil:
|
||||
@ -261,35 +190,12 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
|
||||
return nil, actual, err
|
||||
}
|
||||
|
||||
if err := caseSensitiveJSONIterator.Unmarshal(data, obj); err != nil {
|
||||
return nil, actual, err
|
||||
}
|
||||
|
||||
// If the deserializer is non-strict, return successfully here.
|
||||
if !s.options.Strict {
|
||||
return obj, actual, nil
|
||||
}
|
||||
|
||||
// In strict mode pass the data trough the YAMLToJSONStrict converter.
|
||||
// This is done to catch duplicate fields regardless of encoding (JSON or YAML). For JSON data,
|
||||
// the output would equal the input, unless there is a parsing error such as duplicate fields.
|
||||
// As we know this was successful in the non-strict case, the only error that may be returned here
|
||||
// is because of the newly-added strictness. hence we know we can return the typed strictDecoderError
|
||||
// the actual error is that the object contains duplicate fields.
|
||||
altered, err := yaml.YAMLToJSONStrict(originalData)
|
||||
strictErrs, err := s.unmarshal(obj, data, originalData)
|
||||
if err != nil {
|
||||
return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
|
||||
return nil, actual, err
|
||||
} else if len(strictErrs) > 0 {
|
||||
return obj, actual, runtime.NewStrictDecodingError(strictErrs)
|
||||
}
|
||||
// As performance is not an issue for now for the strict deserializer (one has regardless to do
|
||||
// the unmarshal twice), we take the sanitized, altered data that is guaranteed to have no duplicated
|
||||
// fields, and unmarshal this into a copy of the already-populated obj. Any error that occurs here is
|
||||
// due to that a matching field doesn't exist in the object. hence we can return a typed strictDecoderError,
|
||||
// the actual error is that the object contains unknown field.
|
||||
strictObj := obj.DeepCopyObject()
|
||||
if err := strictCaseSensitiveJSONIterator.Unmarshal(altered, strictObj); err != nil {
|
||||
return nil, actual, runtime.NewStrictDecodingError(err.Error(), string(originalData))
|
||||
}
|
||||
// Always return the same object as the non-strict serializer to avoid any deviations.
|
||||
return obj, actual, nil
|
||||
}
|
||||
|
||||
@ -303,7 +209,7 @@ func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
|
||||
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
if s.options.Yaml {
|
||||
json, err := caseSensitiveJSONIterator.Marshal(obj)
|
||||
json, err := json.Marshal(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -316,7 +222,7 @@ func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
}
|
||||
|
||||
if s.options.Pretty {
|
||||
data, err := caseSensitiveJSONIterator.MarshalIndent(obj, "", " ")
|
||||
data, err := json.MarshalIndent(obj, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -327,6 +233,50 @@ func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
return encoder.Encode(obj)
|
||||
}
|
||||
|
||||
// IsStrict indicates whether the serializer
|
||||
// uses strict decoding or not
|
||||
func (s *Serializer) IsStrict() bool {
|
||||
return s.options.Strict
|
||||
}
|
||||
|
||||
func (s *Serializer) unmarshal(into runtime.Object, data, originalData []byte) (strictErrs []error, err error) {
|
||||
// If the deserializer is non-strict, return here.
|
||||
if !s.options.Strict {
|
||||
if err := kjson.UnmarshalCaseSensitivePreserveInts(data, into); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if s.options.Yaml {
|
||||
// In strict mode pass the original data through the YAMLToJSONStrict converter.
|
||||
// This is done to catch duplicate fields in YAML that would have been dropped in the original YAMLToJSON conversion.
|
||||
// TODO: rework YAMLToJSONStrict to return warnings about duplicate fields without terminating so we don't have to do this twice.
|
||||
_, err := yaml.YAMLToJSONStrict(originalData)
|
||||
if err != nil {
|
||||
strictErrs = append(strictErrs, err)
|
||||
}
|
||||
}
|
||||
|
||||
var strictJSONErrs []error
|
||||
if u, isUnstructured := into.(runtime.Unstructured); isUnstructured {
|
||||
// Unstructured is a custom unmarshaler that gets delegated
|
||||
// to, so inorder to detect strict JSON errors we need
|
||||
// to unmarshal directly into the object.
|
||||
m := u.UnstructuredContent()
|
||||
strictJSONErrs, err = kjson.UnmarshalStrict(data, &m)
|
||||
u.SetUnstructuredContent(m)
|
||||
} else {
|
||||
strictJSONErrs, err = kjson.UnmarshalStrict(data, into)
|
||||
}
|
||||
if err != nil {
|
||||
// fatal decoding error, not due to strictness
|
||||
return nil, err
|
||||
}
|
||||
strictErrs = append(strictErrs, strictJSONErrs...)
|
||||
return strictErrs, nil
|
||||
}
|
||||
|
||||
// Identifier implements runtime.Encoder interface.
|
||||
func (s *Serializer) Identifier() runtime.Identifier {
|
||||
return s.identifier
|
||||
|
12
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
generated
vendored
12
vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer/recognizer.go
generated
vendored
@ -109,10 +109,16 @@ func (d *decoder) Decode(data []byte, gvk *schema.GroupVersionKind, into runtime
|
||||
for _, r := range skipped {
|
||||
out, actual, err := r.Decode(data, gvk, into)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
// if we got an object back from the decoder, and the
|
||||
// error was a strict decoding error (e.g. unknown or
|
||||
// duplicate fields), we still consider the recognizer
|
||||
// to have understood the object
|
||||
if out == nil || !runtime.IsStrictDecodingError(err) {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
}
|
||||
return out, actual, nil
|
||||
return out, actual, err
|
||||
}
|
||||
|
||||
if lastErr == nil {
|
||||
|
1
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
generated
vendored
1
vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming/streaming.go
generated
vendored
@ -90,7 +90,6 @@ func (d *decoder) Decode(defaults *schema.GroupVersionKind, into runtime.Object)
|
||||
}
|
||||
// must read the rest of the frame (until we stop getting ErrShortBuffer)
|
||||
d.resetRead = true
|
||||
base = 0
|
||||
return nil, nil, ErrObjectTooLarge
|
||||
}
|
||||
if err != nil {
|
||||
|
15
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
generated
vendored
15
vendor/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go
generated
vendored
@ -133,11 +133,18 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
|
||||
}
|
||||
}
|
||||
|
||||
var strictDecodingErr error
|
||||
obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto)
|
||||
if err != nil {
|
||||
return nil, gvk, err
|
||||
if obj != nil && runtime.IsStrictDecodingError(err) {
|
||||
// save the strictDecodingError and the caller decide what to do with it
|
||||
strictDecodingErr = err
|
||||
} else {
|
||||
return nil, gvk, err
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: look into strict handling of nested object decoding
|
||||
if d, ok := obj.(runtime.NestedObjectDecoder); ok {
|
||||
if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
|
||||
return nil, gvk, err
|
||||
@ -153,14 +160,14 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
|
||||
|
||||
// Short-circuit conversion if the into object is same object
|
||||
if into == obj {
|
||||
return into, gvk, nil
|
||||
return into, gvk, strictDecodingErr
|
||||
}
|
||||
|
||||
if err := c.convertor.Convert(obj, into, c.decodeVersion); err != nil {
|
||||
return nil, gvk, err
|
||||
}
|
||||
|
||||
return into, gvk, nil
|
||||
return into, gvk, strictDecodingErr
|
||||
}
|
||||
|
||||
// perform defaulting if requested
|
||||
@ -172,7 +179,7 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
|
||||
if err != nil {
|
||||
return nil, gvk, err
|
||||
}
|
||||
return out, gvk, nil
|
||||
return out, gvk, strictDecodingErr
|
||||
}
|
||||
|
||||
// Encode ensures the provided object is output in the appropriate group and version, invoking
|
||||
|
1
vendor/k8s.io/apimachinery/pkg/runtime/zz_generated.deepcopy.go
generated
vendored
1
vendor/k8s.io/apimachinery/pkg/runtime/zz_generated.deepcopy.go
generated
vendored
@ -1,3 +1,4 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user