diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/BUILD b/staging/src/k8s.io/cli-runtime/pkg/resource/BUILD index e8e3f6c6d9f..da0fea8d658 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/BUILD +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/BUILD @@ -51,6 +51,7 @@ go_test( srcs = [ "builder_test.go", "helper_test.go", + "scheme_test.go", "visitor_test.go", ], data = [ @@ -64,6 +65,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go index 5459fdded96..cce86edf412 100644 --- a/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme.go @@ -41,11 +41,13 @@ func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtim return nil, nil, err } - if _, ok := obj.(*metav1.Status); !ok && strings.ToLower(gvk.Kind) == "status" { - obj = &metav1.Status{} - err := json.Unmarshal(data, obj) - if err != nil { - return nil, nil, err + if strings.ToLower(gvk.Kind) == "status" && gvk.Version == "v1" && (gvk.Group == "" || gvk.Group == "meta.k8s.io") { + if _, ok := obj.(*metav1.Status); !ok { + obj = &metav1.Status{} + err := json.Unmarshal(data, obj) + if err != nil { + return nil, nil, err + } } } diff --git a/staging/src/k8s.io/cli-runtime/pkg/resource/scheme_test.go b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme_test.go new file mode 100644 index 00000000000..14274432bc3 --- /dev/null +++ b/staging/src/k8s.io/cli-runtime/pkg/resource/scheme_test.go @@ -0,0 +1,88 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "reflect" + "strings" + "testing" + + 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/schema" +) + +func TestDynamicCodecDecode(t *testing.T) { + testcases := []struct { + name string + data []byte + gvk *schema.GroupVersionKind + obj runtime.Object + + expectErr string + expectGVK *schema.GroupVersionKind + expectObj runtime.Object + }{ + { + name: "v1 Status", + data: []byte(`{"apiVersion":"v1","kind":"Status"}`), + expectGVK: &schema.GroupVersionKind{"", "v1", "Status"}, + expectObj: &metav1.Status{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Status"}}, + }, + { + name: "meta.k8s.io/v1 Status", + data: []byte(`{"apiVersion":"meta.k8s.io/v1","kind":"Status"}`), + expectGVK: &schema.GroupVersionKind{"meta.k8s.io", "v1", "Status"}, + expectObj: &metav1.Status{TypeMeta: metav1.TypeMeta{APIVersion: "meta.k8s.io/v1", Kind: "Status"}}, + }, + { + name: "example.com/v1 Status", + data: []byte(`{"apiVersion":"example.com/v1","kind":"Status"}`), + expectGVK: &schema.GroupVersionKind{"example.com", "v1", "Status"}, + expectObj: &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": "example.com/v1", "kind": "Status"}}, + }, + { + name: "example.com/v1 Foo", + data: []byte(`{"apiVersion":"example.com/v1","kind":"Foo"}`), + expectGVK: &schema.GroupVersionKind{"example.com", "v1", "Foo"}, + expectObj: &unstructured.Unstructured{Object: map[string]interface{}{"apiVersion": "example.com/v1", "kind": "Foo"}}, + }, + } + + for _, test := range testcases { + t.Run(test.name, func(t *testing.T) { + obj, gvk, err := dynamicCodec{}.Decode(test.data, test.gvk, test.obj) + if (err == nil) != (test.expectErr == "") { + t.Fatalf("expected err=%v, got %v", test.expectErr, err) + } + if err != nil && !strings.Contains(err.Error(), test.expectErr) { + t.Fatalf("expected err=%v, got %v", test.expectErr, err) + } + if err != nil { + return + } + + if !reflect.DeepEqual(test.expectGVK, gvk) { + t.Errorf("expected\n\tgvk=%#v\ngot\n\t%#v", test.expectGVK, gvk) + } + if !reflect.DeepEqual(test.expectObj, obj) { + t.Errorf("expected\n\t%#v\n\t%#v", test.expectObj, obj) + } + }) + } +}