diff --git a/pkg/client/request.go b/pkg/client/request.go index d0016aedaf2..e0d0081cf7c 100644 --- a/pkg/client/request.go +++ b/pkg/client/request.go @@ -99,6 +99,7 @@ type Request struct { namespaceSet bool resource string resourceName string + subresource string selector labels.Selector timeout time.Duration @@ -160,6 +161,21 @@ func (r *Request) Resource(resource string) *Request { return r } +// SubResource sets a sub-resource path which can be multiple segments segment after the resource +// name but before the suffix. +func (r *Request) SubResource(subresources ...string) *Request { + if r.err != nil { + return r + } + subresource := path.Join(subresources...) + if len(r.subresource) != 0 { + r.err = fmt.Errorf("subresource already set to %q, cannot change to %q", r.resource, subresource) + return r + } + r.subresource = subresource + return r +} + // Name sets the name of a resource to access (/[ns//]) func (r *Request) Name(resourceName string) *Request { if r.err != nil { @@ -354,8 +370,8 @@ func (r *Request) finalURL() string { p = path.Join(p, resource) } // Join trims trailing slashes, so preserve r.path's trailing slash for backwards compat if nothing was changed - if len(r.resourceName) != 0 || len(r.subpath) != 0 { - p = path.Join(p, r.resourceName, r.subpath) + if len(r.resourceName) != 0 || len(r.subpath) != 0 || len(r.subresource) != 0 { + p = path.Join(p, r.resourceName, r.subresource, r.subpath) } finalURL := *r.baseURL diff --git a/pkg/client/request_test.go b/pkg/client/request_test.go index 4c1bfe642a8..ed38611da85 100644 --- a/pkg/client/request_test.go +++ b/pkg/client/request_test.go @@ -129,6 +129,16 @@ func TestRequestOrdersNamespaceInPath(t *testing.T) { } } +func TestRequestOrdersSubResource(t *testing.T) { + r := (&Request{ + baseURL: &url.URL{}, + path: "/test/", + }).Name("bar").Resource("baz").Namespace("foo").Suffix("test").SubResource("a", "b") + if s := r.finalURL(); s != "/test/namespaces/foo/baz/bar/a/b/test" { + t.Errorf("namespace should be in order in path: %s", s) + } +} + func TestRequestSetTwiceError(t *testing.T) { if (&Request{}).Name("bar").Name("baz").err == nil { t.Errorf("setting name twice should result in error") @@ -139,6 +149,9 @@ func TestRequestSetTwiceError(t *testing.T) { if (&Request{}).Resource("bar").Resource("baz").err == nil { t.Errorf("setting resource twice should result in error") } + if (&Request{}).SubResource("bar").SubResource("baz").err == nil { + t.Errorf("setting subresource twice should result in error") + } } func TestRequestParseSelectorParam(t *testing.T) {