kubectl: add JSON fallback codec to cope with more strict stock versioning codec

This commit is contained in:
Dr. Stefan Schimanski 2018-02-22 18:01:48 +01:00
parent ca9d1f728b
commit 0fc2c48444
6 changed files with 32 additions and 7 deletions

View File

@ -178,7 +178,7 @@ func annotateRuntimeObject(t *testing.T, originalObj, currentObj runtime.Object,
originalLabels := originalAccessor.GetLabels() originalLabels := originalAccessor.GetLabels()
originalLabels["DELETE_ME"] = "DELETE_ME" originalLabels["DELETE_ME"] = "DELETE_ME"
originalAccessor.SetLabels(originalLabels) originalAccessor.SetLabels(originalLabels)
original, err := runtime.Encode(testapi.Default.Codec(), originalObj) original, err := runtime.Encode(unstructured.JSONFallbackEncoder{Encoder: testapi.Default.Codec()}, originalObj)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -194,7 +194,7 @@ func annotateRuntimeObject(t *testing.T, originalObj, currentObj runtime.Object,
} }
currentAnnotations[api.LastAppliedConfigAnnotation] = string(original) currentAnnotations[api.LastAppliedConfigAnnotation] = string(original)
currentAccessor.SetAnnotations(currentAnnotations) currentAccessor.SetAnnotations(currentAnnotations)
current, err := runtime.Encode(testapi.Default.Codec(), currentObj) current, err := runtime.Encode(unstructured.JSONFallbackEncoder{Encoder: testapi.Default.Codec()}, currentObj)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -971,7 +971,7 @@ func TestUnstructuredIdempotentApply(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)
serversideObject := readUnstructuredFromFile(t, filenameWidgetServerside) serversideObject := readUnstructuredFromFile(t, filenameWidgetServerside)
serversideData, err := runtime.Encode(testapi.Default.Codec(), serversideObject) serversideData, err := runtime.Encode(unstructured.JSONFallbackEncoder{Encoder: testapi.Default.Codec()}, serversideObject)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -45,6 +45,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
utilflag "k8s.io/apiserver/pkg/util/flag" utilflag "k8s.io/apiserver/pkg/util/flag"
@ -662,5 +663,6 @@ func InternalVersionDecoder() runtime.Decoder {
} }
func InternalVersionJSONEncoder() runtime.Encoder { func InternalVersionJSONEncoder() runtime.Encoder {
return legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.EnabledVersions()...) encoder := legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.EnabledVersions()...)
return unstructured.JSONFallbackEncoder{Encoder: encoder}
} }

View File

@ -21,6 +21,7 @@ import (
"k8s.io/apimachinery/pkg/apimachinery/announced" "k8s.io/apimachinery/pkg/apimachinery/announced"
"k8s.io/apimachinery/pkg/apimachinery/registered" "k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
@ -50,5 +51,5 @@ var Versions = []schema.GroupVersion{}
// DefaultJSONEncoder returns a default encoder for our scheme // DefaultJSONEncoder returns a default encoder for our scheme
func DefaultJSONEncoder() runtime.Encoder { func DefaultJSONEncoder() runtime.Encoder {
return Codecs.LegacyCodec(Versions...) return unstructured.JSONFallbackEncoder{Encoder: Codecs.LegacyCodec(Versions...)}
} }

View File

@ -433,6 +433,21 @@ func (s unstructuredJSONScheme) decodeToList(data []byte, list *UnstructuredList
return nil return nil
} }
type JSONFallbackEncoder struct {
runtime.Encoder
}
func (c JSONFallbackEncoder) Encode(obj runtime.Object, w io.Writer) error {
err := c.Encoder.Encode(obj, w)
if runtime.IsNotRegisteredError(err) {
switch obj.(type) {
case *Unstructured, *UnstructuredList:
return UnstructuredJSONScheme.Encode(obj, w)
}
}
return err
}
// UnstructuredObjectConverter is an ObjectConverter for use with // UnstructuredObjectConverter is an ObjectConverter for use with
// Unstructured objects. Since it has no schema or type information, // Unstructured objects. Since it has no schema or type information,
// it will only succeed for no-op conversions. This is provided as a // it will only succeed for no-op conversions. This is provided as a

View File

@ -41,10 +41,18 @@ func NewNotRegisteredErrForTarget(t reflect.Type, target GroupVersioner) error {
return &notRegisteredErr{t: t, target: target} return &notRegisteredErr{t: t, target: target}
} }
func NewNotRegisteredGVKErrForTarget(gvk schema.GroupVersionKind, target GroupVersioner) error {
return &notRegisteredErr{gvk: gvk, target: target}
}
func (k *notRegisteredErr) Error() string { func (k *notRegisteredErr) Error() string {
if k.t != nil && k.target != nil { if k.t != nil && k.target != nil {
return fmt.Sprintf("%v is not suitable for converting to %q", k.t, k.target) return fmt.Sprintf("%v is not suitable for converting to %q", k.t, k.target)
} }
nullGVK := schema.GroupVersionKind{}
if k.gvk != nullGVK && k.target != nil {
return fmt.Sprintf("%q is not suitable for converting to %q", k.gvk.GroupVersion(), k.target)
}
if k.t != nil { if k.t != nil {
return fmt.Sprintf("no kind is registered for the type %v", k.t) return fmt.Sprintf("no kind is registered for the type %v", k.t)
} }

View File

@ -18,7 +18,6 @@ package versioning
import ( import (
"io" "io"
"reflect"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
@ -178,7 +177,7 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
} }
targetGVK, ok := c.encodeVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{objGVK}) targetGVK, ok := c.encodeVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{objGVK})
if !ok { if !ok {
return runtime.NewNotRegisteredErrForTarget(reflect.TypeOf(obj).Elem(), c.encodeVersion) return runtime.NewNotRegisteredGVKErrForTarget(objGVK, c.encodeVersion)
} }
if targetGVK == objGVK { if targetGVK == objGVK {
return c.encoder.Encode(obj, w) return c.encoder.Encode(obj, w)