mirror of
https://github.com/kubernetes/client-go.git
synced 2025-07-17 16:52:22 +00:00
add subresource support for the dynamic client
Kubernetes-commit: 82e32d2a3260807237a69bc40fb371db640d26fc
This commit is contained in:
parent
b4efb2d46b
commit
77541e5cb7
@ -58,12 +58,11 @@ func getObject(version, kind, name string) *unstructured.Unstructured {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getClientServer(gv *schema.GroupVersion, h func(http.ResponseWriter, *http.Request)) (Interface, *httptest.Server, error) {
|
func getClientServer(h func(http.ResponseWriter, *http.Request)) (DynamicInterface, *httptest.Server, error) {
|
||||||
srv := httptest.NewServer(http.HandlerFunc(h))
|
srv := httptest.NewServer(http.HandlerFunc(h))
|
||||||
cl, err := NewClient(&restclient.Config{
|
cl, err := NewForConfig(&restclient.Config{
|
||||||
Host: srv.URL,
|
Host: srv.URL,
|
||||||
ContentConfig: restclient.ContentConfig{GroupVersion: gv},
|
})
|
||||||
}, *gv)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srv.Close()
|
srv.Close()
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -116,9 +115,8 @@ func TestList(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
t.Errorf("List(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
t.Errorf("List(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -136,7 +134,7 @@ func TestList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
got, err := cl.Resource(resource, tc.namespace).List(metav1.ListOptions{})
|
got, err := cl.Resource(resource).Namespace(tc.namespace).List(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when listing %q: %v", tc.name, err)
|
t.Errorf("unexpected error when listing %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -151,6 +149,7 @@ func TestList(t *testing.T) {
|
|||||||
func TestGet(t *testing.T) {
|
func TestGet(t *testing.T) {
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
resource string
|
resource string
|
||||||
|
subresource []string
|
||||||
namespace string
|
namespace string
|
||||||
name string
|
name string
|
||||||
path string
|
path string
|
||||||
@ -173,14 +172,16 @@ func TestGet(t *testing.T) {
|
|||||||
want: getObject("vTest", "rTest", "namespaced_get"),
|
want: getObject("vTest", "rTest", "namespaced_get"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
name: "normal_subresource_get",
|
name: "normal_subresource_get",
|
||||||
path: "/apis/gtest/vtest/rtest/normal_subresource_get/srtest",
|
path: "/apis/gtest/vtest/rtest/normal_subresource_get/srtest",
|
||||||
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
resp: getJSON("vTest", "srTest", "normal_subresource_get"),
|
||||||
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
want: getObject("vTest", "srTest", "normal_subresource_get"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
namespace: "nstest",
|
namespace: "nstest",
|
||||||
name: "namespaced_subresource_get",
|
name: "namespaced_subresource_get",
|
||||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_get/srtest",
|
||||||
@ -189,9 +190,8 @@ func TestGet(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
t.Errorf("Get(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
t.Errorf("Get(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ func TestGet(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
got, err := cl.Resource(resource, tc.namespace).Get(tc.name, metav1.GetOptions{})
|
got, err := cl.Resource(resource).Namespace(tc.namespace).Get(tc.name, metav1.GetOptions{}, tc.subresource...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when getting %q: %v", tc.name, err)
|
t.Errorf("unexpected error when getting %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -230,6 +230,7 @@ func TestDelete(t *testing.T) {
|
|||||||
Status: metav1.StatusSuccess,
|
Status: metav1.StatusSuccess,
|
||||||
}
|
}
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
|
subresource []string
|
||||||
namespace string
|
namespace string
|
||||||
name string
|
name string
|
||||||
path string
|
path string
|
||||||
@ -244,6 +245,17 @@ func TestDelete(t *testing.T) {
|
|||||||
name: "namespaced_delete",
|
name: "namespaced_delete",
|
||||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
subresource: []string{"srtest"},
|
||||||
|
name: "normal_delete",
|
||||||
|
path: "/apis/gtest/vtest/rtest/normal_delete/srtest",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subresource: []string{"srtest"},
|
||||||
|
namespace: "nstest",
|
||||||
|
name: "namespaced_delete",
|
||||||
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_delete/srtest",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
namespace: "nstest",
|
namespace: "nstest",
|
||||||
name: "namespaced_delete_with_options",
|
name: "namespaced_delete_with_options",
|
||||||
@ -252,9 +264,8 @@ func TestDelete(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "DELETE" {
|
if r.Method != "DELETE" {
|
||||||
t.Errorf("Delete(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
t.Errorf("Delete(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -272,7 +283,7 @@ func TestDelete(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
err = cl.Resource(resource, tc.namespace).Delete(tc.name, tc.deleteOptions)
|
err = cl.Resource(resource).Namespace(tc.namespace).Delete(tc.name, tc.deleteOptions, tc.subresource...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when deleting %q: %v", tc.name, err)
|
t.Errorf("unexpected error when deleting %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -301,9 +312,8 @@ func TestDeleteCollection(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "DELETE" {
|
if r.Method != "DELETE" {
|
||||||
t.Errorf("DeleteCollection(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
t.Errorf("DeleteCollection(%q) got HTTP method %s. wanted DELETE", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -321,7 +331,7 @@ func TestDeleteCollection(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
err = cl.Resource(resource, tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
err = cl.Resource(resource).Namespace(tc.namespace).DeleteCollection(nil, metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when deleting collection %q: %v", tc.name, err)
|
t.Errorf("unexpected error when deleting collection %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -332,6 +342,7 @@ func TestDeleteCollection(t *testing.T) {
|
|||||||
func TestCreate(t *testing.T) {
|
func TestCreate(t *testing.T) {
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
resource string
|
resource string
|
||||||
|
subresource []string
|
||||||
name string
|
name string
|
||||||
namespace string
|
namespace string
|
||||||
obj *unstructured.Unstructured
|
obj *unstructured.Unstructured
|
||||||
@ -350,11 +361,25 @@ func TestCreate(t *testing.T) {
|
|||||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest",
|
||||||
obj: getObject("gtest/vTest", "rTest", "namespaced_create"),
|
obj: getObject("gtest/vTest", "rTest", "namespaced_create"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
|
name: "normal_subresource_create",
|
||||||
|
path: "/apis/gtest/vtest/rtest/normal_subresource_create/srtest",
|
||||||
|
obj: getObject("vTest", "srTest", "normal_subresource_create"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resource: "rtest/",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
|
name: "namespaced_subresource_create",
|
||||||
|
namespace: "nstest",
|
||||||
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_create/srtest",
|
||||||
|
obj: getObject("vTest", "srTest", "namespaced_subresource_create"),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "POST" {
|
if r.Method != "POST" {
|
||||||
t.Errorf("Create(%q) got HTTP method %s. wanted POST", tc.name, r.Method)
|
t.Errorf("Create(%q) got HTTP method %s. wanted POST", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -379,7 +404,7 @@ func TestCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
got, err := cl.Resource(resource, tc.namespace).Create(tc.obj)
|
got, err := cl.Resource(resource).Namespace(tc.namespace).Create(tc.obj, tc.subresource...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when creating %q: %v", tc.name, err)
|
t.Errorf("unexpected error when creating %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -394,6 +419,7 @@ func TestCreate(t *testing.T) {
|
|||||||
func TestUpdate(t *testing.T) {
|
func TestUpdate(t *testing.T) {
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
resource string
|
resource string
|
||||||
|
subresource []string
|
||||||
name string
|
name string
|
||||||
namespace string
|
namespace string
|
||||||
obj *unstructured.Unstructured
|
obj *unstructured.Unstructured
|
||||||
@ -413,13 +439,15 @@ func TestUpdate(t *testing.T) {
|
|||||||
obj: getObject("gtest/vTest", "rTest", "namespaced_update"),
|
obj: getObject("gtest/vTest", "rTest", "namespaced_update"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
name: "normal_subresource_update",
|
name: "normal_subresource_update",
|
||||||
path: "/apis/gtest/vtest/rtest/normal_update/srtest",
|
path: "/apis/gtest/vtest/rtest/normal_update/srtest",
|
||||||
obj: getObject("gtest/vTest", "srTest", "normal_update"),
|
obj: getObject("gtest/vTest", "srTest", "normal_update"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
name: "namespaced_subresource_update",
|
name: "namespaced_subresource_update",
|
||||||
namespace: "nstest",
|
namespace: "nstest",
|
||||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_update/srtest",
|
||||||
@ -427,9 +455,8 @@ func TestUpdate(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "PUT" {
|
if r.Method != "PUT" {
|
||||||
t.Errorf("Update(%q) got HTTP method %s. wanted PUT", tc.name, r.Method)
|
t.Errorf("Update(%q) got HTTP method %s. wanted PUT", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -454,7 +481,7 @@ func TestUpdate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
got, err := cl.Resource(resource, tc.namespace).Update(tc.obj)
|
got, err := cl.Resource(resource).Namespace(tc.namespace).Update(tc.obj, tc.subresource...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when updating %q: %v", tc.name, err)
|
t.Errorf("unexpected error when updating %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -497,9 +524,8 @@ func TestWatch(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: "rtest"}
|
||||||
resource := &metav1.APIResource{Name: "rtest", Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "GET" {
|
if r.Method != "GET" {
|
||||||
t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
t.Errorf("Watch(%q) got HTTP method %s. wanted GET", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -511,7 +537,7 @@ func TestWatch(t *testing.T) {
|
|||||||
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
t.Errorf("Watch(%q) got query %s. wanted %s", tc.name, r.URL.RawQuery, tc.query)
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, dynamicCodec{}), dynamicCodec{})
|
enc := restclientwatch.NewEncoder(streaming.NewEncoder(w, unstructured.UnstructuredJSONScheme), unstructured.UnstructuredJSONScheme)
|
||||||
for _, e := range tc.events {
|
for _, e := range tc.events {
|
||||||
enc.Encode(&e)
|
enc.Encode(&e)
|
||||||
}
|
}
|
||||||
@ -522,7 +548,7 @@ func TestWatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
watcher, err := cl.Resource(resource, tc.namespace).Watch(metav1.ListOptions{})
|
watcher, err := cl.Resource(resource).Namespace(tc.namespace).Watch(metav1.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when watching %q: %v", tc.name, err)
|
t.Errorf("unexpected error when watching %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
@ -540,6 +566,7 @@ func TestWatch(t *testing.T) {
|
|||||||
func TestPatch(t *testing.T) {
|
func TestPatch(t *testing.T) {
|
||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
resource string
|
resource string
|
||||||
|
subresource []string
|
||||||
name string
|
name string
|
||||||
namespace string
|
namespace string
|
||||||
patch []byte
|
patch []byte
|
||||||
@ -562,14 +589,16 @@ func TestPatch(t *testing.T) {
|
|||||||
want: getObject("gtest/vTest", "rTest", "namespaced_patch"),
|
want: getObject("gtest/vTest", "rTest", "namespaced_patch"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
name: "normal_subresource_patch",
|
name: "normal_subresource_patch",
|
||||||
path: "/apis/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
path: "/apis/gtest/vtest/rtest/normal_subresource_patch/srtest",
|
||||||
patch: getJSON("gtest/vTest", "srTest", "normal_subresource_patch"),
|
patch: getJSON("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||||
want: getObject("gtest/vTest", "srTest", "normal_subresource_patch"),
|
want: getObject("gtest/vTest", "srTest", "normal_subresource_patch"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
resource: "rtest/srtest",
|
resource: "rtest",
|
||||||
|
subresource: []string{"srtest"},
|
||||||
name: "namespaced_subresource_patch",
|
name: "namespaced_subresource_patch",
|
||||||
namespace: "nstest",
|
namespace: "nstest",
|
||||||
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
path: "/apis/gtest/vtest/namespaces/nstest/rtest/namespaced_subresource_patch/srtest",
|
||||||
@ -578,9 +607,8 @@ func TestPatch(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
gv := &schema.GroupVersion{Group: "gtest", Version: "vtest"}
|
resource := schema.GroupVersionResource{Group: "gtest", Version: "vtest", Resource: tc.resource}
|
||||||
resource := &metav1.APIResource{Name: tc.resource, Namespaced: len(tc.namespace) != 0}
|
cl, srv, err := getClientServer(func(w http.ResponseWriter, r *http.Request) {
|
||||||
cl, srv, err := getClientServer(gv, func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != "PATCH" {
|
if r.Method != "PATCH" {
|
||||||
t.Errorf("Patch(%q) got HTTP method %s. wanted PATCH", tc.name, r.Method)
|
t.Errorf("Patch(%q) got HTTP method %s. wanted PATCH", tc.name, r.Method)
|
||||||
}
|
}
|
||||||
@ -610,7 +638,7 @@ func TestPatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer srv.Close()
|
defer srv.Close()
|
||||||
|
|
||||||
got, err := cl.Resource(resource, tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch)
|
got, err := cl.Resource(resource).Namespace(tc.namespace).Patch(tc.name, types.StrategicMergePatchType, tc.patch, tc.subresource...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error when patching %q: %v", tc.name, err)
|
t.Errorf("unexpected error when patching %q: %v", tc.name, err)
|
||||||
continue
|
continue
|
||||||
|
@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
package fake
|
package fake
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"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/apis/meta/v1/unstructured"
|
||||||
@ -66,7 +68,6 @@ type dynamicResourceClient struct {
|
|||||||
client *FakeDynamicClient
|
client *FakeDynamicClient
|
||||||
namespace string
|
namespace string
|
||||||
resource schema.GroupVersionResource
|
resource schema.GroupVersionResource
|
||||||
subresource string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ dynamic.DynamicInterface = &FakeDynamicClient{}
|
var _ dynamic.DynamicInterface = &FakeDynamicClient{}
|
||||||
@ -75,26 +76,44 @@ func (c *FakeDynamicClient) Resource(resource schema.GroupVersionResource) dynam
|
|||||||
return &dynamicResourceClient{client: c, resource: resource}
|
return &dynamicResourceClient{client: c, resource: resource}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated, this isn't how we want to do it
|
|
||||||
func (c *FakeDynamicClient) ClusterSubresource(resource schema.GroupVersionResource, subresource string) dynamic.DynamicResourceInterface {
|
|
||||||
return &dynamicResourceClient{client: c, resource: resource, subresource: subresource}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated, this isn't how we want to do it
|
|
||||||
func (c *FakeDynamicClient) NamespacedSubresource(resource schema.GroupVersionResource, subresource, namespace string) dynamic.DynamicResourceInterface {
|
|
||||||
return &dynamicResourceClient{client: c, resource: resource, namespace: namespace, subresource: subresource}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Namespace(ns string) dynamic.DynamicResourceInterface {
|
func (c *dynamicResourceClient) Namespace(ns string) dynamic.DynamicResourceInterface {
|
||||||
ret := *c
|
ret := *c
|
||||||
ret.namespace = ns
|
ret.namespace = ns
|
||||||
return &ret
|
return &ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
uncastRet, err := c.client.Fake.
|
var uncastRet runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootCreateAction(c.resource, obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||||
|
accessor, err := meta.Accessor(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
name := accessor.GetName()
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
Invokes(testing.NewCreateAction(c.resource, c.namespace, obj), obj)
|
Invokes(testing.NewCreateAction(c.resource, c.namespace, obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||||
|
accessor, err := meta.Accessor(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
name := accessor.GetName()
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewCreateSubresourceAction(c.resource, name, strings.Join(subresources, "/"), c.namespace, obj), obj)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -109,10 +128,28 @@ func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured) (*unstruc
|
|||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
uncastRet, err := c.client.Fake.
|
var uncastRet runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootUpdateAction(c.resource, obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
Invokes(testing.NewUpdateAction(c.resource, c.namespace, obj), obj)
|
Invokes(testing.NewUpdateAction(c.resource, c.namespace, obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewUpdateSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, obj), obj)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -128,9 +165,19 @@ func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured) (*unstruc
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
||||||
uncastRet, err := c.client.Fake.
|
var uncastRet runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootUpdateSubresourceAction(c.resource, "status", obj), obj)
|
||||||
|
|
||||||
|
case len(c.namespace) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
Invokes(testing.NewUpdateSubresourceAction(c.resource, "status", c.namespace, obj), obj)
|
Invokes(testing.NewUpdateSubresourceAction(c.resource, "status", c.namespace, obj), obj)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -145,24 +192,66 @@ func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured) (*u
|
|||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions, subresources ...string) error {
|
||||||
_, err := c.client.Fake.
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||||
|
_, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootDeleteAction(c.resource, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||||
|
_, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic delete fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||||
|
_, err = c.client.Fake.
|
||||||
Invokes(testing.NewDeleteAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
|
Invokes(testing.NewDeleteAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||||
|
_, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewDeleteSubresourceAction(c.resource, strings.Join(subresources, "/"), c.namespace, name), &metav1.Status{Status: "dynamic delete fail"})
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||||
action := testing.NewDeleteCollectionAction(c.resource, c.namespace, listOptions)
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0:
|
||||||
|
action := testing.NewRootDeleteCollectionAction(c.resource, listOptions)
|
||||||
|
_, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0:
|
||||||
|
action := testing.NewDeleteCollectionAction(c.resource, c.namespace, listOptions)
|
||||||
|
_, err = c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
_, err := c.client.Fake.Invokes(action, &metav1.Status{Status: "dynamic deletecollection fail"})
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
uncastRet, err := c.client.Fake.
|
var uncastRet runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootGetAction(c.resource, name), &metav1.Status{Status: "dynamic get fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootGetSubresourceAction(c.resource, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
Invokes(testing.NewGetAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic get fail"})
|
Invokes(testing.NewGetAction(c.resource, c.namespace, name), &metav1.Status{Status: "dynamic get fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewGetSubresourceAction(c.resource, c.namespace, strings.Join(subresources, "/"), name), &metav1.Status{Status: "dynamic get fail"})
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -178,9 +267,19 @@ func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions) (*unstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||||
obj, err := c.client.Fake.
|
var obj runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0:
|
||||||
|
obj, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootListAction(c.resource, schema.GroupVersionKind{Version: "v1", Kind: "List"}, opts), &metav1.Status{Status: "dynamic list fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0:
|
||||||
|
obj, err = c.client.Fake.
|
||||||
Invokes(testing.NewListAction(c.resource, schema.GroupVersionKind{Version: "v1", Kind: "List"}, c.namespace, opts), &metav1.Status{Status: "dynamic list fail"})
|
Invokes(testing.NewListAction(c.resource, schema.GroupVersionKind{Version: "v1", Kind: "List"}, c.namespace, opts), &metav1.Status{Status: "dynamic list fail"})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -213,14 +312,42 @@ func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.Uns
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0:
|
||||||
|
return c.client.Fake.
|
||||||
|
InvokesWatch(testing.NewRootWatchAction(c.resource, opts))
|
||||||
|
|
||||||
|
case len(c.namespace) > 0:
|
||||||
return c.client.Fake.
|
return c.client.Fake.
|
||||||
InvokesWatch(testing.NewWatchAction(c.resource, c.namespace, opts))
|
InvokesWatch(testing.NewWatchAction(c.resource, c.namespace, opts))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("math broke")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
uncastRet, err := c.client.Fake.
|
var uncastRet runtime.Object
|
||||||
|
var err error
|
||||||
|
switch {
|
||||||
|
case len(c.namespace) == 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootPatchAction(c.resource, name, data), &metav1.Status{Status: "dynamic patch fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) == 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewRootPatchSubresourceAction(c.resource, name, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) == 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
|
Invokes(testing.NewPatchAction(c.resource, c.namespace, name, data), &metav1.Status{Status: "dynamic patch fail"})
|
||||||
|
|
||||||
|
case len(c.namespace) > 0 && len(subresources) > 0:
|
||||||
|
uncastRet, err = c.client.Fake.
|
||||||
Invokes(testing.NewPatchSubresourceAction(c.resource, c.namespace, name, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
Invokes(testing.NewPatchSubresourceAction(c.resource, c.namespace, name, data, subresources...), &metav1.Status{Status: "dynamic patch fail"})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package dynamic
|
package dynamic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
@ -33,20 +32,15 @@ import (
|
|||||||
|
|
||||||
type DynamicInterface interface {
|
type DynamicInterface interface {
|
||||||
Resource(resource schema.GroupVersionResource) NamespaceableDynamicResourceInterface
|
Resource(resource schema.GroupVersionResource) NamespaceableDynamicResourceInterface
|
||||||
|
|
||||||
// Deprecated, this isn't how we want to do it
|
|
||||||
ClusterSubresource(resource schema.GroupVersionResource, subresource string) DynamicResourceInterface
|
|
||||||
// Deprecated, this isn't how we want to do it
|
|
||||||
NamespacedSubresource(resource schema.GroupVersionResource, subresource, namespace string) DynamicResourceInterface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DynamicResourceInterface interface {
|
type DynamicResourceInterface interface {
|
||||||
Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
Create(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error)
|
||||||
Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
Update(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error)
|
||||||
UpdateStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
UpdateStatus(obj *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
||||||
Delete(name string, options *metav1.DeleteOptions) error
|
Delete(name string, options *metav1.DeleteOptions, subresources ...string) error
|
||||||
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
DeleteCollection(options *metav1.DeleteOptions, listOptions metav1.ListOptions) error
|
||||||
Get(name string, options metav1.GetOptions) (*unstructured.Unstructured, error)
|
Get(name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error)
|
||||||
List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
|
List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
|
||||||
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
Watch(opts metav1.ListOptions) (watch.Interface, error)
|
||||||
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*unstructured.Unstructured, error)
|
Patch(name string, pt types.PatchType, data []byte, subresources ...string) (*unstructured.Unstructured, error)
|
||||||
@ -87,37 +81,33 @@ type dynamicResourceClient struct {
|
|||||||
client *dynamicClient
|
client *dynamicClient
|
||||||
namespace string
|
namespace string
|
||||||
resource schema.GroupVersionResource
|
resource schema.GroupVersionResource
|
||||||
subresource string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableDynamicResourceInterface {
|
func (c *dynamicClient) Resource(resource schema.GroupVersionResource) NamespaceableDynamicResourceInterface {
|
||||||
return &dynamicResourceClient{client: c, resource: resource}
|
return &dynamicResourceClient{client: c, resource: resource}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicClient) ClusterSubresource(resource schema.GroupVersionResource, subresource string) DynamicResourceInterface {
|
|
||||||
return &dynamicResourceClient{client: c, resource: resource, subresource: subresource}
|
|
||||||
}
|
|
||||||
func (c *dynamicClient) NamespacedSubresource(resource schema.GroupVersionResource, subresource, namespace string) DynamicResourceInterface {
|
|
||||||
return &dynamicResourceClient{client: c, resource: resource, namespace: namespace, subresource: subresource}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Namespace(ns string) DynamicResourceInterface {
|
func (c *dynamicResourceClient) Namespace(ns string) DynamicResourceInterface {
|
||||||
ret := *c
|
ret := *c
|
||||||
ret.namespace = ns
|
ret.namespace = ns
|
||||||
return &ret
|
return &ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
return nil, fmt.Errorf("create not supported for subresources")
|
|
||||||
}
|
|
||||||
|
|
||||||
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
outBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
name := ""
|
||||||
|
if len(subresources) > 0 {
|
||||||
|
accessor, err := meta.Accessor(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
name = accessor.GetName()
|
||||||
|
}
|
||||||
|
|
||||||
result := c.client.client.Post().AbsPath(c.makeURLSegments("")...).Body(outBytes).Do()
|
result := c.client.client.Post().AbsPath(append(c.makeURLSegments(name), subresources...)...).Body(outBytes).Do()
|
||||||
if err := result.Error(); err != nil {
|
if err := result.Error(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -133,7 +123,7 @@ func (c *dynamicResourceClient) Create(obj *unstructured.Unstructured) (*unstruc
|
|||||||
return uncastObj.(*unstructured.Unstructured), nil
|
return uncastObj.(*unstructured.Unstructured), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
accessor, err := meta.Accessor(obj)
|
accessor, err := meta.Accessor(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -143,7 +133,7 @@ func (c *dynamicResourceClient) Update(obj *unstructured.Unstructured) (*unstruc
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := c.client.client.Put().AbsPath(c.makeURLSegments(accessor.GetName())...).Body(outBytes).Do()
|
result := c.client.client.Put().AbsPath(append(c.makeURLSegments(accessor.GetName()), subresources...)...).Body(outBytes).Do()
|
||||||
if err := result.Error(); err != nil {
|
if err := result.Error(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -182,7 +172,7 @@ func (c *dynamicResourceClient) UpdateStatus(obj *unstructured.Unstructured) (*u
|
|||||||
return uncastObj.(*unstructured.Unstructured), nil
|
return uncastObj.(*unstructured.Unstructured), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions) error {
|
func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions, subresources ...string) error {
|
||||||
if opts == nil {
|
if opts == nil {
|
||||||
opts = &metav1.DeleteOptions{}
|
opts = &metav1.DeleteOptions{}
|
||||||
}
|
}
|
||||||
@ -191,15 +181,11 @@ func (c *dynamicResourceClient) Delete(name string, opts *metav1.DeleteOptions)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
result := c.client.client.Delete().AbsPath(c.makeURLSegments(name)...).Body(deleteOptionsByte).Do()
|
result := c.client.client.Delete().AbsPath(append(c.makeURLSegments(name), subresources...)...).Body(deleteOptionsByte).Do()
|
||||||
return result.Error()
|
return result.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
return fmt.Errorf("deletecollection not supported for subresources")
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts == nil {
|
if opts == nil {
|
||||||
opts = &metav1.DeleteOptions{}
|
opts = &metav1.DeleteOptions{}
|
||||||
}
|
}
|
||||||
@ -212,8 +198,8 @@ func (c *dynamicResourceClient) DeleteCollection(opts *metav1.DeleteOptions, lis
|
|||||||
return result.Error()
|
return result.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions) (*unstructured.Unstructured, error) {
|
func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error) {
|
||||||
result := c.client.client.Get().AbsPath(c.makeURLSegments(name)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
result := c.client.client.Get().AbsPath(append(c.makeURLSegments(name), subresources...)...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
||||||
if err := result.Error(); err != nil {
|
if err := result.Error(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -229,10 +215,6 @@ func (c *dynamicResourceClient) Get(name string, opts metav1.GetOptions) (*unstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
return nil, fmt.Errorf("list not supported for subresources")
|
|
||||||
}
|
|
||||||
|
|
||||||
result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
result := c.client.client.Get().AbsPath(c.makeURLSegments("")...).SpecificallyVersionedParams(&opts, dynamicParameterCodec, versionV1).Do()
|
||||||
if err := result.Error(); err != nil {
|
if err := result.Error(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -257,10 +239,6 @@ func (c *dynamicResourceClient) List(opts metav1.ListOptions) (*unstructured.Uns
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
func (c *dynamicResourceClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
return nil, fmt.Errorf("watch not supported for subresources")
|
|
||||||
}
|
|
||||||
|
|
||||||
internalGV := schema.GroupVersions{
|
internalGV := schema.GroupVersions{
|
||||||
{Group: c.resource.Group, Version: runtime.APIVersionInternal},
|
{Group: c.resource.Group, Version: runtime.APIVersionInternal},
|
||||||
// always include the legacy group as a decoding target to handle non-error `Status` return types
|
// always include the legacy group as a decoding target to handle non-error `Status` return types
|
||||||
@ -320,15 +298,6 @@ func (c *dynamicResourceClient) makeURLSegments(name string) []string {
|
|||||||
|
|
||||||
if len(name) > 0 {
|
if len(name) > 0 {
|
||||||
url = append(url, name)
|
url = append(url, name)
|
||||||
|
|
||||||
// subresources only work on things with names
|
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
url = append(url, c.subresource)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if len(c.subresource) > 0 {
|
|
||||||
panic("somehow snuck a subresource and an empty name. programmer error")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
@ -225,6 +225,16 @@ func NewRootDeleteAction(resource schema.GroupVersionResource, name string) Dele
|
|||||||
return action
|
return action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewRootDeleteSubresourceAction(resource schema.GroupVersionResource, subresource string, name string) DeleteActionImpl {
|
||||||
|
action := DeleteActionImpl{}
|
||||||
|
action.Verb = "delete"
|
||||||
|
action.Resource = resource
|
||||||
|
action.Subresource = subresource
|
||||||
|
action.Name = name
|
||||||
|
|
||||||
|
return action
|
||||||
|
}
|
||||||
|
|
||||||
func NewDeleteAction(resource schema.GroupVersionResource, namespace, name string) DeleteActionImpl {
|
func NewDeleteAction(resource schema.GroupVersionResource, namespace, name string) DeleteActionImpl {
|
||||||
action := DeleteActionImpl{}
|
action := DeleteActionImpl{}
|
||||||
action.Verb = "delete"
|
action.Verb = "delete"
|
||||||
@ -235,6 +245,17 @@ func NewDeleteAction(resource schema.GroupVersionResource, namespace, name strin
|
|||||||
return action
|
return action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDeleteSubresourceAction(resource schema.GroupVersionResource, subresource, namespace, name string) DeleteActionImpl {
|
||||||
|
action := DeleteActionImpl{}
|
||||||
|
action.Verb = "delete"
|
||||||
|
action.Resource = resource
|
||||||
|
action.Subresource = subresource
|
||||||
|
action.Namespace = namespace
|
||||||
|
action.Name = name
|
||||||
|
|
||||||
|
return action
|
||||||
|
}
|
||||||
|
|
||||||
func NewRootDeleteCollectionAction(resource schema.GroupVersionResource, opts interface{}) DeleteCollectionActionImpl {
|
func NewRootDeleteCollectionAction(resource schema.GroupVersionResource, opts interface{}) DeleteCollectionActionImpl {
|
||||||
action := DeleteCollectionActionImpl{}
|
action := DeleteCollectionActionImpl{}
|
||||||
action.Verb = "delete-collection"
|
action.Verb = "delete-collection"
|
||||||
|
Loading…
Reference in New Issue
Block a user