From fae3dcdbf6c0c6b445a26a387066ef1f07d9e708 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Mon, 9 Sep 2024 09:40:38 +0300 Subject: [PATCH] avoid panic when subresource is a list Kubernetes-commit: 2e3b937dcdb02cab74213a5608cc4dac39c6423e --- dynamic/client_test.go | 15 +++++++++++++++ dynamic/simple.go | 5 +++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dynamic/client_test.go b/dynamic/client_test.go index c812b016..35f6e85a 100644 --- a/dynamic/client_test.go +++ b/dynamic/client_test.go @@ -64,6 +64,12 @@ func getObject(version, kind, name string) *unstructured.Unstructured { } } +func getObjectFromJSON(b []byte) *unstructured.Unstructured { + obj := &unstructured.Unstructured{} + _ = obj.UnmarshalJSON(b) // can ignore parse error because the comparison will fail + return obj +} + func getClientServer(h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) { srv := httptest.NewServer(http.HandlerFunc(h)) cl, err := NewForConfig(&restclient.Config{ @@ -359,6 +365,15 @@ func TestGet(t *testing.T) { resp: getJSON("vTest", "srTest", "namespaced_subresource_get"), want: getObject("vTest", "srTest", "namespaced_subresource_get"), }, + { + resource: "rtest", + subresource: []string{"srtest"}, + namespace: "nstest", + name: "namespaced_subresource_get_list", + path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get_list/srtest", + resp: getListJSON("vTest", "srTest", getJSON("vTest", "srTest", "a1")), + want: getObjectFromJSON(getListJSON("vTest", "srTest", getJSON("vTest", "srTest", "a1"))), + }, } for _, tc := range tcs { resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource} diff --git a/dynamic/simple.go b/dynamic/simple.go index 326da7cb..fa0ec68c 100644 --- a/dynamic/simple.go +++ b/dynamic/simple.go @@ -289,11 +289,12 @@ func (c *dynamicResourceClient) Get(ctx context.Context, name string, opts metav if err != nil { return nil, err } - uncastObj, err := runtime.Decode(unstructured.UnstructuredJSONScheme, retBytes) + obj := &unstructured.Unstructured{} + err = runtime.DecodeInto(unstructured.UnstructuredJSONScheme, retBytes, obj) if err != nil { return nil, err } - return uncastObj.(*unstructured.Unstructured), nil + return obj, nil } func (c *dynamicResourceClient) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {