Skip to content

Commit 955306a

Browse files
authored
Merge pull request #2306 from alvaroaleman/interceptor-flatten
⚠️ Inteceptor: Unify Client and Subresource Client
2 parents eb0ebc9 + 6ca0111 commit 955306a

File tree

3 files changed

+113
-119
lines changed

3 files changed

+113
-119
lines changed

pkg/client/interceptor/intercept.go

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,29 @@ import (
1010
"sigs.k8s.io/controller-runtime/pkg/client"
1111
)
1212

13-
type (
14-
15-
// Funcs contains functions that are called instead of the underlying client's methods.
16-
Funcs struct {
17-
Get func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error
18-
List func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error
19-
Create func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error
20-
Delete func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error
21-
DeleteAllOf func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error
22-
Update func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error
23-
Patch func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error
24-
Watch func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error)
25-
SubResource func(client client.WithWatch, subResource string) client.SubResourceClient
26-
}
27-
28-
// SubResourceFuncs is a set of functions that can be used to intercept calls to a SubResourceClient.
29-
SubResourceFuncs struct {
30-
Get func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error
31-
Create func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error
32-
Update func(ctx context.Context, client client.SubResourceClient, obj client.Object, opts ...client.SubResourceUpdateOption) error
33-
Patch func(ctx context.Context, client client.SubResourceClient, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error
34-
}
35-
)
13+
// Funcs contains functions that are called instead of the underlying client's methods.
14+
type Funcs struct {
15+
Get func(ctx context.Context, client client.WithWatch, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error
16+
List func(ctx context.Context, client client.WithWatch, list client.ObjectList, opts ...client.ListOption) error
17+
Create func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.CreateOption) error
18+
Delete func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteOption) error
19+
DeleteAllOf func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.DeleteAllOfOption) error
20+
Update func(ctx context.Context, client client.WithWatch, obj client.Object, opts ...client.UpdateOption) error
21+
Patch func(ctx context.Context, client client.WithWatch, obj client.Object, patch client.Patch, opts ...client.PatchOption) error
22+
Watch func(ctx context.Context, client client.WithWatch, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error)
23+
SubResource func(client client.WithWatch, subResource string) client.SubResourceClient
24+
SubResourceGet func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error
25+
SubResourceCreate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error
26+
SubResourceUpdate func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error
27+
SubResourcePatch func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error
28+
}
3629

3730
// NewClient returns a new interceptor client that calls the functions in funcs instead of the underlying client's methods, if they are not nil.
3831
func NewClient(interceptedClient client.WithWatch, funcs Funcs) client.WithWatch {
39-
return interceptor{client: interceptedClient, funcs: funcs}
40-
}
41-
42-
// NewSubResourceClient returns a SubResourceClient that intercepts calls to the provided client with the provided functions.
43-
func NewSubResourceClient(interceptedClient client.SubResourceClient, funcs SubResourceFuncs) client.SubResourceClient {
44-
return subResourceInterceptor{client: interceptedClient, funcs: funcs}
32+
return interceptor{
33+
client: interceptedClient,
34+
funcs: funcs,
35+
}
4536
}
4637

4738
type interceptor struct {
@@ -116,7 +107,11 @@ func (c interceptor) SubResource(subResource string) client.SubResourceClient {
116107
if c.funcs.SubResource != nil {
117108
return c.funcs.SubResource(c.client, subResource)
118109
}
119-
return c.client.SubResource(subResource)
110+
return subResourceInterceptor{
111+
subResourceName: subResource,
112+
client: c.client,
113+
funcs: c.funcs,
114+
}
120115
}
121116

122117
func (c interceptor) Scheme() *runtime.Scheme {
@@ -135,36 +130,37 @@ func (c interceptor) Watch(ctx context.Context, obj client.ObjectList, opts ...c
135130
}
136131

137132
type subResourceInterceptor struct {
138-
client client.SubResourceClient
139-
funcs SubResourceFuncs
133+
subResourceName string
134+
client client.Client
135+
funcs Funcs
140136
}
141137

142138
var _ client.SubResourceClient = &subResourceInterceptor{}
143139

144140
func (s subResourceInterceptor) Get(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error {
145-
if s.funcs.Get != nil {
146-
return s.funcs.Get(ctx, s.client, obj, subResource, opts...)
141+
if s.funcs.SubResourceGet != nil {
142+
return s.funcs.SubResourceGet(ctx, s.client, s.subResourceName, obj, subResource, opts...)
147143
}
148-
return s.client.Get(ctx, obj, subResource, opts...)
144+
return s.client.SubResource(s.subResourceName).Get(ctx, obj, subResource, opts...)
149145
}
150146

151147
func (s subResourceInterceptor) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
152-
if s.funcs.Create != nil {
153-
return s.funcs.Create(ctx, s.client, obj, subResource, opts...)
148+
if s.funcs.SubResourceCreate != nil {
149+
return s.funcs.SubResourceCreate(ctx, s.client, s.subResourceName, obj, subResource, opts...)
154150
}
155-
return s.client.Create(ctx, obj, subResource, opts...)
151+
return s.client.SubResource(s.subResourceName).Create(ctx, obj, subResource, opts...)
156152
}
157153

158154
func (s subResourceInterceptor) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error {
159-
if s.funcs.Update != nil {
160-
return s.funcs.Update(ctx, s.client, obj, opts...)
155+
if s.funcs.SubResourceUpdate != nil {
156+
return s.funcs.SubResourceUpdate(ctx, s.client, s.subResourceName, obj, opts...)
161157
}
162-
return s.client.Update(ctx, obj, opts...)
158+
return s.client.SubResource(s.subResourceName).Update(ctx, obj, opts...)
163159
}
164160

165161
func (s subResourceInterceptor) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
166-
if s.funcs.Patch != nil {
167-
return s.funcs.Patch(ctx, s.client, obj, patch, opts...)
162+
if s.funcs.SubResourcePatch != nil {
163+
return s.funcs.SubResourcePatch(ctx, s.client, s.subResourceName, obj, patch, opts...)
168164
}
169-
return s.client.Patch(ctx, obj, patch, opts...)
165+
return s.client.SubResource(s.subResourceName).Patch(ctx, obj, patch, opts...)
170166
}

pkg/client/interceptor/intercept_test.go

Lines changed: 37 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,6 @@ var _ = Describe("NewClient", func() {
212212
_ = client.SubResource("")
213213
Expect(called).To(BeTrue())
214214
})
215-
It("should call the underlying client if the provided SubResource function is nil", func() {
216-
var called bool
217-
client1 := NewClient(wrappedClient, Funcs{
218-
SubResource: func(client client.WithWatch, subResource string) client.SubResourceClient {
219-
called = true
220-
return nil
221-
},
222-
})
223-
client2 := NewClient(client1, Funcs{})
224-
_ = client2.SubResource("")
225-
Expect(called).To(BeTrue())
226-
})
227215
It("should call the provided SubResource function with 'status' when calling Status()", func() {
228216
var called bool
229217
client := NewClient(wrappedClient, Funcs{
@@ -237,115 +225,109 @@ var _ = Describe("NewClient", func() {
237225
_ = client.Status()
238226
Expect(called).To(BeTrue())
239227
})
240-
It("should call the underlying client if the provided SubResource function is nil when calling Status", func() {
241-
var called bool
242-
client1 := NewClient(wrappedClient, Funcs{
243-
SubResource: func(client client.WithWatch, subResource string) client.SubResourceClient {
244-
if subResource == "status" {
245-
called = true
246-
}
247-
return nil
248-
},
249-
})
250-
client2 := NewClient(client1, Funcs{})
251-
_ = client2.Status()
252-
Expect(called).To(BeTrue())
253-
})
254228
})
255229

256230
var _ = Describe("NewSubResourceClient", func() {
257-
srClient := dummySubResourceClient{}
231+
c := dummyClient{}
258232
ctx := context.Background()
259233
It("should call the provided Get function", func() {
260234
var called bool
261-
client := NewSubResourceClient(srClient, SubResourceFuncs{
262-
Get: func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error {
235+
c := NewClient(c, Funcs{
236+
SubResourceGet: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceGetOption) error {
263237
called = true
238+
Expect(subResourceName).To(BeEquivalentTo("foo"))
264239
return nil
265240
},
266241
})
267-
_ = client.Get(ctx, nil, nil)
242+
_ = c.SubResource("foo").Get(ctx, nil, nil)
268243
Expect(called).To(BeTrue())
269244
})
270245
It("should call the underlying client if the provided Get function is nil", func() {
271246
var called bool
272-
client1 := NewSubResourceClient(srClient, SubResourceFuncs{
273-
Get: func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error {
247+
client1 := NewClient(c, Funcs{
248+
SubResourceGet: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceGetOption) error {
274249
called = true
250+
Expect(subResourceName).To(BeEquivalentTo("foo"))
275251
return nil
276252
},
277253
})
278-
client2 := NewSubResourceClient(client1, SubResourceFuncs{})
279-
_ = client2.Get(ctx, nil, nil)
254+
client2 := NewClient(client1, Funcs{})
255+
_ = client2.SubResource("foo").Get(ctx, nil, nil)
280256
Expect(called).To(BeTrue())
281257
})
282258
It("should call the provided Update function", func() {
283259
var called bool
284-
client := NewSubResourceClient(srClient, SubResourceFuncs{
285-
Update: func(ctx context.Context, client client.SubResourceClient, obj client.Object, opts ...client.SubResourceUpdateOption) error {
260+
client := NewClient(c, Funcs{
261+
SubResourceUpdate: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error {
286262
called = true
263+
Expect(subResourceName).To(BeEquivalentTo("foo"))
287264
return nil
288265
},
289266
})
290-
_ = client.Update(ctx, nil, nil)
267+
_ = client.SubResource("foo").Update(ctx, nil, nil)
291268
Expect(called).To(BeTrue())
292269
})
293270
It("should call the underlying client if the provided Update function is nil", func() {
294271
var called bool
295-
client1 := NewSubResourceClient(srClient, SubResourceFuncs{
296-
Update: func(ctx context.Context, client client.SubResourceClient, obj client.Object, opts ...client.SubResourceUpdateOption) error {
272+
client1 := NewClient(c, Funcs{
273+
SubResourceUpdate: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, opts ...client.SubResourceUpdateOption) error {
297274
called = true
275+
Expect(subResourceName).To(BeEquivalentTo("foo"))
298276
return nil
299277
},
300278
})
301-
client2 := NewSubResourceClient(client1, SubResourceFuncs{})
302-
_ = client2.Update(ctx, nil, nil)
279+
client2 := NewClient(client1, Funcs{})
280+
_ = client2.SubResource("foo").Update(ctx, nil, nil)
303281
Expect(called).To(BeTrue())
304282
})
305283
It("should call the provided Patch function", func() {
306284
var called bool
307-
client := NewSubResourceClient(srClient, SubResourceFuncs{
308-
Patch: func(ctx context.Context, client client.SubResourceClient, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
285+
client := NewClient(c, Funcs{
286+
SubResourcePatch: func(_ context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
309287
called = true
288+
Expect(subResourceName).To(BeEquivalentTo("foo"))
310289
return nil
311290
},
312291
})
313-
_ = client.Patch(ctx, nil, nil)
292+
_ = client.SubResource("foo").Patch(ctx, nil, nil)
314293
Expect(called).To(BeTrue())
315294
})
316295
It("should call the underlying client if the provided Patch function is nil", func() {
317296
var called bool
318-
client1 := NewSubResourceClient(srClient, SubResourceFuncs{
319-
Patch: func(ctx context.Context, client client.SubResourceClient, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
297+
client1 := NewClient(c, Funcs{
298+
SubResourcePatch: func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
320299
called = true
300+
Expect(subResourceName).To(BeEquivalentTo("foo"))
321301
return nil
322302
},
323303
})
324-
client2 := NewSubResourceClient(client1, SubResourceFuncs{})
325-
_ = client2.Patch(ctx, nil, nil)
304+
client2 := NewClient(client1, Funcs{})
305+
_ = client2.SubResource("foo").Patch(ctx, nil, nil)
326306
Expect(called).To(BeTrue())
327307
})
328308
It("should call the provided Create function", func() {
329309
var called bool
330-
client := NewSubResourceClient(srClient, SubResourceFuncs{
331-
Create: func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
310+
client := NewClient(c, Funcs{
311+
SubResourceCreate: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceCreateOption) error {
332312
called = true
313+
Expect(subResourceName).To(BeEquivalentTo("foo"))
333314
return nil
334315
},
335316
})
336-
_ = client.Create(ctx, nil, nil)
317+
_ = client.SubResource("foo").Create(ctx, nil, nil)
337318
Expect(called).To(BeTrue())
338319
})
339320
It("should call the underlying client if the provided Create function is nil", func() {
340321
var called bool
341-
client1 := NewSubResourceClient(srClient, SubResourceFuncs{
342-
Create: func(ctx context.Context, client client.SubResourceClient, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
322+
client1 := NewClient(c, Funcs{
323+
SubResourceCreate: func(_ context.Context, client client.Client, subResourceName string, obj, subResource client.Object, opts ...client.SubResourceCreateOption) error {
343324
called = true
325+
Expect(subResourceName).To(BeEquivalentTo("foo"))
344326
return nil
345327
},
346328
})
347-
client2 := NewSubResourceClient(client1, SubResourceFuncs{})
348-
_ = client2.Create(ctx, nil, nil)
329+
client2 := NewClient(client1, Funcs{})
330+
_ = client2.SubResource("foo").Create(ctx, nil, nil)
349331
Expect(called).To(BeTrue())
350332
})
351333
})
@@ -409,23 +391,3 @@ func (d dummyClient) IsObjectNamespaced(obj runtime.Object) (bool, error) {
409391
func (d dummyClient) Watch(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) (watch.Interface, error) {
410392
return nil, nil
411393
}
412-
413-
type dummySubResourceClient struct{}
414-
415-
var _ client.SubResourceClient = &dummySubResourceClient{}
416-
417-
func (d dummySubResourceClient) Get(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceGetOption) error {
418-
return nil
419-
}
420-
421-
func (d dummySubResourceClient) Create(ctx context.Context, obj client.Object, subResource client.Object, opts ...client.SubResourceCreateOption) error {
422-
return nil
423-
}
424-
425-
func (d dummySubResourceClient) Update(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error {
426-
return nil
427-
}
428-
429-
func (d dummySubResourceClient) Patch(ctx context.Context, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
430-
return nil
431-
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package interceptor
18+
19+
import (
20+
"testing"
21+
22+
. "github.com/onsi/ginkgo/v2"
23+
. "github.com/onsi/gomega"
24+
25+
logf "sigs.k8s.io/controller-runtime/pkg/log"
26+
"sigs.k8s.io/controller-runtime/pkg/log/zap"
27+
)
28+
29+
func TestInterceptor(t *testing.T) {
30+
RegisterFailHandler(Fail)
31+
RunSpecs(t, "Fake client Suite")
32+
}
33+
34+
var _ = BeforeSuite(func() {
35+
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
36+
})

0 commit comments

Comments
 (0)