mirror of https://github.com/k3s-io/k3s
Merge pull request #60201 from sttts/sttts-unstructured-convert-to-version
Automatic merge from submit-queue (batch tested with PRs 60201, 62744). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. apimachinery: normal conversion code path for Unstructured in ConvertToVersion Preparation for https://github.com/kubernetes/kubernetes/pull/60113pull/8/head
commit
4bccf6a7aa
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -707,5 +708,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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ go_library(
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||||
|
|
|
@ -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...)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,6 +436,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
|
||||||
|
|
|
@ -41,10 +41,18 @@ func NewNotRegisteredErrForTarget(t reflect.Type, target GroupVersioner) error {
|
||||||
return ¬RegisteredErr{t: t, target: target}
|
return ¬RegisteredErr{t: t, target: target}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewNotRegisteredGVKErrForTarget(gvk schema.GroupVersionKind, target GroupVersioner) error {
|
||||||
|
return ¬RegisteredErr{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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,9 +166,22 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
|
||||||
// Encode ensures the provided object is output in the appropriate group and version, invoking
|
// 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.
|
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
|
||||||
func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||||
switch obj.(type) {
|
switch obj := obj.(type) {
|
||||||
case *runtime.Unknown, runtime.Unstructured:
|
case *runtime.Unknown:
|
||||||
return c.encoder.Encode(obj, w)
|
return c.encoder.Encode(obj, w)
|
||||||
|
case runtime.Unstructured:
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
targetGVK, ok := c.encodeVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{objGVK})
|
||||||
|
if !ok {
|
||||||
|
return runtime.NewNotRegisteredGVKErrForTarget(objGVK, c.encodeVersion)
|
||||||
|
}
|
||||||
|
if targetGVK == objGVK {
|
||||||
|
return c.encoder.Encode(obj, w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gvks, isUnversioned, err := c.typer.ObjectKinds(obj)
|
gvks, isUnversioned, err := c.typer.ObjectKinds(obj)
|
||||||
|
|
Loading…
Reference in New Issue