mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Merge pull request #63525 from enj/enj/i/flatten_transform_requests
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Correctly apply request transforms with flattened resource builder This change moves the NewClientWithOptions call into Builder.getClient. Since getClient is the only way for Builder and its visitors to create a RESTClient, we can reasonably guarantee that the request transforms will be honored. Previously, it was possible for a call to NewFlattenListVisitor to return resource Info objects whose Client field did not honor the request transforms. Signed-off-by: Monis Khan <mkhan@redhat.com> /kind bug @kubernetes/sig-cli-maintainers /assign @smarterclayton @deads2k Builds on #63318 ```release-note NONE ```
This commit is contained in:
commit
7cc1103011
@ -49,9 +49,7 @@ type Builder struct {
|
|||||||
categoryExpander restmapper.CategoryExpander
|
categoryExpander restmapper.CategoryExpander
|
||||||
|
|
||||||
// mapper is set explicitly by resource builders
|
// mapper is set explicitly by resource builders
|
||||||
mapper *mapper
|
mapper *mapper
|
||||||
internal *mapper
|
|
||||||
unstructured *mapper
|
|
||||||
|
|
||||||
// clientConfigFn is a function to produce a client, *if* you need one
|
// clientConfigFn is a function to produce a client, *if* you need one
|
||||||
clientConfigFn ClientConfigFunc
|
clientConfigFn ClientConfigFunc
|
||||||
@ -829,7 +827,6 @@ func (b *Builder) visitBySelector() *Result {
|
|||||||
result.err = err
|
result.err = err
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
client = NewClientWithOptions(client, b.requestTransforms...)
|
|
||||||
selectorNamespace := b.namespace
|
selectorNamespace := b.namespace
|
||||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||||
selectorNamespace = ""
|
selectorNamespace = ""
|
||||||
@ -846,15 +843,25 @@ func (b *Builder) visitBySelector() *Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) getClient(gv schema.GroupVersion) (RESTClient, error) {
|
func (b *Builder) getClient(gv schema.GroupVersion) (RESTClient, error) {
|
||||||
if b.fakeClientFn != nil {
|
var (
|
||||||
return b.fakeClientFn(gv)
|
client RESTClient
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case b.fakeClientFn != nil:
|
||||||
|
client, err = b.fakeClientFn(gv)
|
||||||
|
case b.negotiatedSerializer != nil:
|
||||||
|
client, err = b.clientConfigFn.clientForGroupVersion(gv, b.negotiatedSerializer)
|
||||||
|
default:
|
||||||
|
client, err = b.clientConfigFn.unstructuredClientForGroupVersion(gv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.negotiatedSerializer != nil {
|
if err != nil {
|
||||||
return b.clientConfigFn.clientForGroupVersion(gv, b.negotiatedSerializer)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.clientConfigFn.unstructuredClientForGroupVersion(gv)
|
return NewClientWithOptions(client, b.requestTransforms...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) visitByResource() *Result {
|
func (b *Builder) visitByResource() *Result {
|
||||||
@ -891,7 +898,6 @@ func (b *Builder) visitByResource() *Result {
|
|||||||
result.err = err
|
result.err = err
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
client = NewClientWithOptions(client, b.requestTransforms...)
|
|
||||||
clients[s] = client
|
clients[s] = client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,22 +655,50 @@ func TestMultipleResourceByTheSameName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestRequestModifier(t *testing.T) {
|
func TestRequestModifier(t *testing.T) {
|
||||||
var got *rest.Request
|
for _, tc := range []struct {
|
||||||
b := newDefaultBuilderWith(fakeClientWith("test", t, nil)).
|
name string
|
||||||
NamespaceParam("foo").
|
f func(t *testing.T, got **rest.Request) *Builder
|
||||||
TransformRequests(func(req *rest.Request) {
|
}{
|
||||||
got = req
|
{
|
||||||
}).
|
name: "simple",
|
||||||
ResourceNames("", "services/baz").
|
f: func(t *testing.T, got **rest.Request) *Builder {
|
||||||
RequireObject(false)
|
return newDefaultBuilderWith(fakeClientWith(t.Name(), t, nil)).
|
||||||
|
NamespaceParam("foo").
|
||||||
i, err := b.Do().Infos()
|
TransformRequests(func(req *rest.Request) {
|
||||||
if err != nil {
|
*got = req
|
||||||
t.Fatal(err)
|
}).
|
||||||
}
|
ResourceNames("", "services/baz").
|
||||||
req := i[0].Client.Get()
|
RequireObject(false)
|
||||||
if got != req {
|
},
|
||||||
t.Fatalf("request was not received by modifier: %#v", req)
|
},
|
||||||
|
{
|
||||||
|
name: "flatten",
|
||||||
|
f: func(t *testing.T, got **rest.Request) *Builder {
|
||||||
|
pods, _ := testData()
|
||||||
|
return newDefaultBuilderWith(fakeClientWith(t.Name(), t, map[string]string{
|
||||||
|
"/namespaces/foo/pods": runtime.EncodeOrDie(corev1Codec, pods),
|
||||||
|
})).
|
||||||
|
NamespaceParam("foo").
|
||||||
|
TransformRequests(func(req *rest.Request) {
|
||||||
|
*got = req
|
||||||
|
}).
|
||||||
|
ResourceTypeOrNameArgs(true, "pods").
|
||||||
|
Flatten()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
var got *rest.Request
|
||||||
|
b := tc.f(t, &got)
|
||||||
|
i, err := b.Do().Infos()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
req := i[0].Client.Get()
|
||||||
|
if got != req {
|
||||||
|
t.Fatalf("request was not received by modifier: %#v", req)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,9 @@ type RequestTransform func(*rest.Request)
|
|||||||
// NewClientWithOptions wraps the provided RESTClient and invokes each transform on each
|
// NewClientWithOptions wraps the provided RESTClient and invokes each transform on each
|
||||||
// newly created request.
|
// newly created request.
|
||||||
func NewClientWithOptions(c RESTClient, transforms ...RequestTransform) RESTClient {
|
func NewClientWithOptions(c RESTClient, transforms ...RequestTransform) RESTClient {
|
||||||
|
if len(transforms) == 0 {
|
||||||
|
return c
|
||||||
|
}
|
||||||
return &clientOptions{c: c, transforms: transforms}
|
return &clientOptions{c: c, transforms: transforms}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user