diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go index ed585ab7e9b..e770fb3f013 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning.go @@ -199,23 +199,22 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error { return err } + objectKind := obj.GetObjectKind() + old := objectKind.GroupVersionKind() + // restore the old GVK after encoding + defer objectKind.SetGroupVersionKind(old) + if c.encodeVersion == nil || isUnversioned { if e, ok := obj.(runtime.NestedObjectEncoder); ok { if err := e.EncodeNestedObjects(runtime.WithVersionEncoder{Encoder: c.encoder, ObjectTyper: c.typer}); err != nil { return err } } - objectKind := obj.GetObjectKind() - old := objectKind.GroupVersionKind() objectKind.SetGroupVersionKind(gvks[0]) - err = c.encoder.Encode(obj, w) - objectKind.SetGroupVersionKind(old) - return err + return c.encoder.Encode(obj, w) } // Perform a conversion if necessary - objectKind := obj.GetObjectKind() - old := objectKind.GroupVersionKind() out, err := c.convertor.ConvertToVersion(obj, c.encodeVersion) if err != nil { return err @@ -228,10 +227,7 @@ func (c *codec) Encode(obj runtime.Object, w io.Writer) error { } // Conversion is responsible for setting the proper group, version, and kind onto the outgoing object - err = c.encoder.Encode(out, w) - // restore the old GVK, in case conversion returned the same object - objectKind.SetGroupVersionKind(old) - return err + return c.encoder.Encode(out, w) } // DirectEncoder was moved and renamed to runtime.WithVersionEncoder in 1.15. diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go index d21b43def68..d4ef5827806 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/serializer/versioning/versioning_test.go @@ -102,6 +102,28 @@ func TestNestedEncode(t *testing.T) { } } +func TestNestedEncodeError(t *testing.T) { + n := &testNestedDecodable{nestedErr: fmt.Errorf("unable to encode")} + gvk1 := schema.GroupVersionKind{Kind: "test", Group: "other", Version: "v1"} + gvk2 := schema.GroupVersionKind{Kind: "test", Group: "other", Version: "v2"} + n.SetGroupVersionKind(gvk1) + codec := NewCodec( + nil, nil, + &mockConvertor{}, + nil, + &mockTyper{gvks: []schema.GroupVersionKind{gvk1, gvk2}}, + nil, + schema.GroupVersion{Group: "other", Version: "v2"}, nil, + "TestNestedEncodeError", + ) + if err := codec.Encode(n, ioutil.Discard); err != n.nestedErr { + t.Errorf("unexpected error: %v", err) + } + if n.GroupVersionKind() != gvk1 { + t.Errorf("unexpected gvk of input object: %v", n.GroupVersionKind()) + } +} + func TestDecode(t *testing.T) { gvk1 := &schema.GroupVersionKind{Kind: "Test", Group: "other", Version: "blah"} decodable1 := &testDecodable{} @@ -311,6 +333,28 @@ func (c *checkConvertor) ConvertFieldLabel(gvk schema.GroupVersionKind, label, v return "", "", fmt.Errorf("unexpected call to ConvertFieldLabel") } +type mockConvertor struct { +} + +func (c *mockConvertor) Convert(in, out, context interface{}) error { + return fmt.Errorf("unexpect call to Convert") +} + +func (c *mockConvertor) ConvertToVersion(in runtime.Object, outVersion runtime.GroupVersioner) (out runtime.Object, err error) { + objectKind := in.GetObjectKind() + inGVK := objectKind.GroupVersionKind() + if out, ok := outVersion.KindForGroupVersionKinds([]schema.GroupVersionKind{inGVK}); ok { + objectKind.SetGroupVersionKind(out) + } else { + return nil, fmt.Errorf("unexpected conversion") + } + return in, nil +} + +func (c *mockConvertor) ConvertFieldLabel(gvk schema.GroupVersionKind, label, value string) (string, string, error) { + return "", "", fmt.Errorf("unexpected call to ConvertFieldLabel") +} + type mockSerializer struct { err error obj runtime.Object