vendor: bump k8s to v0.25.4

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
This commit is contained in:
CrazyMax
2023-03-14 18:20:37 +01:00
parent 4a73abfd64
commit cfa6b4f7c8
889 changed files with 96934 additions and 11708 deletions

View File

@ -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)
@ -243,7 +259,8 @@ func (f CodecFactory) SupportedMediaTypes() []runtime.SerializerInfo {
// invoke CodecForVersions. Callers that need only to read data should use UniversalDecoder().
//
// TODO: make this call exist only in pkg/api, and initialize it with the set of default versions.
// All other callers will be forced to request a Codec directly.
//
// All other callers will be forced to request a Codec directly.
func (f CodecFactory) LegacyCodec(version ...schema.GroupVersion) runtime.Codec {
return versioning.NewDefaultingCodecForScheme(f.scheme, f.legacySerializer, f.universal, schema.GroupVersions(version), runtime.InternalGroupVersioner)
}

View File

@ -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,9 +163,25 @@ 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
}
// when decoding directly into a provided unstructured object,
// extract the actual gvk decoded from the provided data,
// and ensure it is non-empty.
if isUnstructured {
*actual = into.GetObjectKind().GroupVersionKind()
if len(actual.Kind) == 0 {
return nil, actual, runtime.NewMissingKindErr(string(originalData))
}
// TODO(109023): require apiVersion here as well once unstructuredJSONScheme#Decode does
}
if len(strictErrs) > 0 {
return into, actual, runtime.NewStrictDecodingError(strictErrs)
}
return into, actual, nil
case err != nil:
return nil, actual, err
@ -261,35 +203,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 +222,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 +235,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 +246,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 in order to detect strict JSON errors we need
// to unmarshal directly into the object.
m := map[string]interface{}{}
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

View File

@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
"k8s.io/apimachinery/pkg/util/framer"
"k8s.io/klog/v2"
)
var (
@ -86,6 +87,7 @@ type Serializer struct {
}
var _ runtime.Serializer = &Serializer{}
var _ runtime.EncoderWithAllocator = &Serializer{}
var _ recognizer.RecognizingDecoder = &Serializer{}
const serializerIdentifier runtime.Identifier = "protobuf"
@ -161,22 +163,36 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
return unmarshalToObject(s.typer, s.creater, &actual, into, unk.Raw)
}
// Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(s.Identifier(), s.doEncode, w)
}
return s.doEncode(obj, w)
// EncodeWithAllocator writes an object to the provided writer.
// In addition, it allows for providing a memory allocator for efficient memory usage during object serialization.
func (s *Serializer) EncodeWithAllocator(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
return s.encode(obj, w, memAlloc)
}
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
// Encode serializes the provided object to the given writer.
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
return s.encode(obj, w, &runtime.SimpleAllocator{})
}
func (s *Serializer) encode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(s.Identifier(), func(obj runtime.Object, w io.Writer) error { return s.doEncode(obj, w, memAlloc) }, w)
}
return s.doEncode(obj, w, memAlloc)
}
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
if memAlloc == nil {
klog.Error("a mandatory memory allocator wasn't provided, this might have a negative impact on performance, check invocations of EncodeWithAllocator method, falling back on runtime.SimpleAllocator")
memAlloc = &runtime.SimpleAllocator{}
}
prefixSize := uint64(len(s.prefix))
var unk runtime.Unknown
switch t := obj.(type) {
case *runtime.Unknown:
estimatedSize := prefixSize + uint64(t.Size())
data := make([]byte, estimatedSize)
data := memAlloc.Allocate(estimatedSize)
i, err := t.MarshalTo(data[prefixSize:])
if err != nil {
return err
@ -196,11 +212,11 @@ func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
switch t := obj.(type) {
case bufferedMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalToSizedBuffer methods
// this path performs a single allocation during write only when the Allocator wasn't provided
// it also requires the caller to implement the more efficient Size and MarshalToSizedBuffer methods
encodedSize := uint64(t.Size())
estimatedSize := prefixSize + estimateUnknownSize(&unk, encodedSize)
data := make([]byte, estimatedSize)
data := memAlloc.Allocate(estimatedSize)
i, err := unk.NestedMarshalTo(data[prefixSize:], t, encodedSize)
if err != nil {
@ -221,7 +237,7 @@ func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
unk.Raw = data
estimatedSize := prefixSize + uint64(unk.Size())
data = make([]byte, estimatedSize)
data = memAlloc.Allocate(estimatedSize)
i, err := unk.MarshalTo(data[prefixSize:])
if err != nil {
@ -395,19 +411,33 @@ func unmarshalToObject(typer runtime.ObjectTyper, creater runtime.ObjectCreater,
// Encode serializes the provided object to the given writer. Overrides is ignored.
func (s *RawSerializer) Encode(obj runtime.Object, w io.Writer) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(s.Identifier(), s.doEncode, w)
}
return s.doEncode(obj, w)
return s.encode(obj, w, &runtime.SimpleAllocator{})
}
func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer) error {
// EncodeWithAllocator writes an object to the provided writer.
// In addition, it allows for providing a memory allocator for efficient memory usage during object serialization.
func (s *RawSerializer) EncodeWithAllocator(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
return s.encode(obj, w, memAlloc)
}
func (s *RawSerializer) encode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(s.Identifier(), func(obj runtime.Object, w io.Writer) error { return s.doEncode(obj, w, memAlloc) }, w)
}
return s.doEncode(obj, w, memAlloc)
}
func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
if memAlloc == nil {
klog.Error("a mandatory memory allocator wasn't provided, this might have a negative impact on performance, check invocations of EncodeWithAllocator method, falling back on runtime.SimpleAllocator")
memAlloc = &runtime.SimpleAllocator{}
}
switch t := obj.(type) {
case bufferedReverseMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalToSizedBuffer methods
// this path performs a single allocation during write only when the Allocator wasn't provided
// it also requires the caller to implement the more efficient Size and MarshalToSizedBuffer methods
encodedSize := uint64(t.Size())
data := make([]byte, encodedSize)
data := memAlloc.Allocate(encodedSize)
n, err := t.MarshalToSizedBuffer(data)
if err != nil {
@ -417,10 +447,10 @@ func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer) error {
return err
case bufferedMarshaller:
// this path performs a single allocation during write but requires the caller to implement
// the more efficient Size and MarshalTo methods
// this path performs a single allocation during write only when the Allocator wasn't provided
// it also requires the caller to implement the more efficient Size and MarshalTo methods
encodedSize := uint64(t.Size())
data := make([]byte, encodedSize)
data := memAlloc.Allocate(encodedSize)
n, err := t.MarshalTo(data)
if err != nil {

View File

@ -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 {

View File

@ -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 {
@ -135,3 +134,23 @@ func (e *encoder) Encode(obj runtime.Object) error {
e.buf.Reset()
return err
}
type encoderWithAllocator struct {
writer io.Writer
encoder runtime.EncoderWithAllocator
memAllocator runtime.MemoryAllocator
}
// NewEncoderWithAllocator returns a new streaming encoder
func NewEncoderWithAllocator(w io.Writer, e runtime.EncoderWithAllocator, a runtime.MemoryAllocator) Encoder {
return &encoderWithAllocator{
writer: w,
encoder: e,
memAllocator: a,
}
}
// Encode writes the provided object to the nested writer
func (e *encoderWithAllocator) Encode(obj runtime.Object) error {
return e.encoder.EncodeWithAllocator(obj, e.writer, e.memAllocator)
}

View File

@ -89,6 +89,8 @@ type codec struct {
originalSchemeName string
}
var _ runtime.EncoderWithAllocator = &codec{}
var identifiersMap sync.Map
type codecIdentifier struct {
@ -133,17 +135,34 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
}
}
var strictDecodingErrs []error
obj, gvk, err := c.decoder.Decode(data, defaultGVK, decodeInto)
if err != nil {
return nil, gvk, err
}
if d, ok := obj.(runtime.NestedObjectDecoder); ok {
if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
if strictErr, ok := runtime.AsStrictDecodingError(err); obj != nil && ok {
// save the strictDecodingError and let the caller decide what to do with it
strictDecodingErrs = append(strictDecodingErrs, strictErr.Errors()...)
} else {
return nil, gvk, err
}
}
if d, ok := obj.(runtime.NestedObjectDecoder); ok {
if err := d.DecodeNestedObjects(runtime.WithoutVersionDecoder{c.decoder}); err != nil {
if strictErr, ok := runtime.AsStrictDecodingError(err); ok {
// save the strictDecodingError let and the caller decide what to do with it
strictDecodingErrs = append(strictDecodingErrs, strictErr.Errors()...)
} else {
return nil, gvk, err
}
}
}
// aggregate the strict decoding errors into one
var strictDecodingErr error
if len(strictDecodingErrs) > 0 {
strictDecodingErr = runtime.NewStrictDecodingError(strictDecodingErrs)
}
// if we specify a target, use generic conversion.
if into != nil {
// perform defaulting if requested
@ -153,14 +172,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,22 +191,43 @@ 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
}
// EncodeWithAllocator ensures the provided object is output in the appropriate group and version, invoking
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
// In addition, it allows for providing a memory allocator for efficient memory usage during object serialization.
func (c *codec) EncodeWithAllocator(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
return c.encode(obj, w, memAlloc)
}
// Encode ensures the provided object is output in the appropriate group and version, invoking
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(c.Identifier(), c.doEncode, w)
}
return c.doEncode(obj, w)
return c.encode(obj, w, nil)
}
func (c *codec) doEncode(obj runtime.Object, w io.Writer) error {
func (c *codec) encode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
if co, ok := obj.(runtime.CacheableObject); ok {
return co.CacheEncode(c.Identifier(), func(obj runtime.Object, w io.Writer) error { return c.doEncode(obj, w, memAlloc) }, w)
}
return c.doEncode(obj, w, memAlloc)
}
func (c *codec) doEncode(obj runtime.Object, w io.Writer, memAlloc runtime.MemoryAllocator) error {
encodeFn := c.encoder.Encode
if memAlloc != nil {
if encoder, supportsAllocator := c.encoder.(runtime.EncoderWithAllocator); supportsAllocator {
encodeFn = func(obj runtime.Object, w io.Writer) error {
return encoder.EncodeWithAllocator(obj, w, memAlloc)
}
} else {
klog.V(6).Infof("a memory allocator was provided but the encoder %s doesn't implement the runtime.EncoderWithAllocator, using regular encoder.Encode method", c.encoder.Identifier())
}
}
switch obj := obj.(type) {
case *runtime.Unknown:
return c.encoder.Encode(obj, w)
return encodeFn(obj, w)
case runtime.Unstructured:
// An unstructured list can contain objects of multiple group version kinds. don't short-circuit just
// because the top-level type matches our desired destination type. actually send the object to the converter
@ -196,14 +236,14 @@ func (c *codec) doEncode(obj runtime.Object, w io.Writer) error {
// avoid conversion roundtrip if GVK is the right one already or is empty (yes, this is a hack, but the old behaviour we rely on in kubectl)
objGVK := obj.GetObjectKind().GroupVersionKind()
if len(objGVK.Version) == 0 {
return c.encoder.Encode(obj, w)
return encodeFn(obj, w)
}
targetGVK, ok := c.encodeVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{objGVK})
if !ok {
return runtime.NewNotRegisteredGVKErrForTarget(c.originalSchemeName, objGVK, c.encodeVersion)
}
if targetGVK == objGVK {
return c.encoder.Encode(obj, w)
return encodeFn(obj, w)
}
}
}
@ -225,7 +265,7 @@ func (c *codec) doEncode(obj runtime.Object, w io.Writer) error {
}
}
objectKind.SetGroupVersionKind(gvks[0])
return c.encoder.Encode(obj, w)
return encodeFn(obj, w)
}
// Perform a conversion if necessary
@ -241,7 +281,7 @@ func (c *codec) doEncode(obj runtime.Object, w io.Writer) error {
}
// Conversion is responsible for setting the proper group, version, and kind onto the outgoing object
return c.encoder.Encode(out, w)
return encodeFn(out, w)
}
// Identifier implements runtime.Encoder interface.