Skip to content

Commit 4ead43d

Browse files
committed
✨ Add handler.FromMapFunc to simplify creation of custom mappers
1 parent 4195d2d commit 4ead43d

File tree

4 files changed

+88
-90
lines changed

4 files changed

+88
-90
lines changed

pkg/handler/enqueue_mapped.go

+22-16
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ import (
2424
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
2525
)
2626

27-
var _ EventHandler = &EnqueueRequestsFromMapFunc{}
28-
2927
// EnqueueRequestsFromMapFunc enqueues Requests by running a transformation function that outputs a collection
3028
// of reconcile.Requests on each Event. The reconcile.Requests may be for an arbitrary set of objects
3129
// defined by some user specified transformation of the source Event. (e.g. trigger Reconciler for a set of objects
@@ -36,33 +34,41 @@ var _ EventHandler = &EnqueueRequestsFromMapFunc{}
3634
//
3735
// For UpdateEvents which contain both a new and old object, the transformation function is run on both
3836
// objects and both sets of Requests are enqueue.
39-
type EnqueueRequestsFromMapFunc struct {
37+
func EnqueueRequestsFromMapFunc(mapFN func(MapObject) []reconcile.Request) EventHandler {
38+
return &enqueueRequestsFromMapFunc{
39+
ToRequests: toRequestsFunc(mapFN),
40+
}
41+
}
42+
43+
var _ EventHandler = &enqueueRequestsFromMapFunc{}
44+
45+
type enqueueRequestsFromMapFunc struct {
4046
// Mapper transforms the argument into a slice of keys to be reconciled
41-
ToRequests Mapper
47+
ToRequests mapper
4248
}
4349

4450
// Create implements EventHandler
45-
func (e *EnqueueRequestsFromMapFunc) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) {
51+
func (e *enqueueRequestsFromMapFunc) Create(evt event.CreateEvent, q workqueue.RateLimitingInterface) {
4652
e.mapAndEnqueue(q, MapObject{Object: evt.Object})
4753
}
4854

4955
// Update implements EventHandler
50-
func (e *EnqueueRequestsFromMapFunc) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) {
56+
func (e *enqueueRequestsFromMapFunc) Update(evt event.UpdateEvent, q workqueue.RateLimitingInterface) {
5157
e.mapAndEnqueue(q, MapObject{Object: evt.ObjectOld})
5258
e.mapAndEnqueue(q, MapObject{Object: evt.ObjectNew})
5359
}
5460

5561
// Delete implements EventHandler
56-
func (e *EnqueueRequestsFromMapFunc) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) {
62+
func (e *enqueueRequestsFromMapFunc) Delete(evt event.DeleteEvent, q workqueue.RateLimitingInterface) {
5763
e.mapAndEnqueue(q, MapObject{Object: evt.Object})
5864
}
5965

6066
// Generic implements EventHandler
61-
func (e *EnqueueRequestsFromMapFunc) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) {
67+
func (e *enqueueRequestsFromMapFunc) Generic(evt event.GenericEvent, q workqueue.RateLimitingInterface) {
6268
e.mapAndEnqueue(q, MapObject{Object: evt.Object})
6369
}
6470

65-
func (e *EnqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInterface, object MapObject) {
71+
func (e *enqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInterface, object MapObject) {
6672
for _, req := range e.ToRequests.Map(object) {
6773
q.Add(req)
6874
}
@@ -71,15 +77,15 @@ func (e *EnqueueRequestsFromMapFunc) mapAndEnqueue(q workqueue.RateLimitingInter
7177
// EnqueueRequestsFromMapFunc can inject fields into the mapper.
7278

7379
// InjectFunc implements inject.Injector.
74-
func (e *EnqueueRequestsFromMapFunc) InjectFunc(f inject.Func) error {
80+
func (e *enqueueRequestsFromMapFunc) InjectFunc(f inject.Func) error {
7581
if f == nil {
7682
return nil
7783
}
7884
return f(e.ToRequests)
7985
}
8086

81-
// Mapper maps an object to a collection of keys to be enqueued
82-
type Mapper interface {
87+
// mapper maps an object to a collection of keys to be enqueued
88+
type mapper interface {
8389
// Map maps an object
8490
Map(MapObject) []reconcile.Request
8591
}
@@ -89,12 +95,12 @@ type MapObject struct {
8995
Object controllerutil.Object
9096
}
9197

92-
var _ Mapper = ToRequestsFunc(nil)
98+
var _ mapper = toRequestsFunc(nil)
9399

94-
// ToRequestsFunc implements Mapper using a function.
95-
type ToRequestsFunc func(MapObject) []reconcile.Request
100+
// toRequestsFunc implements Mapper using a function.
101+
type toRequestsFunc func(MapObject) []reconcile.Request
96102

97103
// Map implements Mapper
98-
func (m ToRequestsFunc) Map(i MapObject) []reconcile.Request {
104+
func (m toRequestsFunc) Map(i MapObject) []reconcile.Request {
99105
return m(i)
100106
}

pkg/handler/eventhandler.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import (
3333
// * Use EnqueueRequestForOwner to reconcile the owner of the object the event is for
3434
// - do this for events for the types the Controller creates. (e.g. ReplicaSets created by a Deployment Controller)
3535
//
36-
// * Use EnqueueRequestsFromMapFunc to transform an event for an object to a reconcile of an object
36+
// * Use EnqueueRequestsFromMapFunc or FromMapFunc to transform an event for an object to a reconcile of an object
3737
// of a different type - do this for events for types the Controller may be interested in, but doesn't create.
3838
// (e.g. If Foo responds to cluster size events, map Node events to Foo objects.)
3939
//

pkg/handler/eventhandler_test.go

+52-59
Original file line numberDiff line numberDiff line change
@@ -191,21 +191,19 @@ var _ = Describe("Eventhandler", func() {
191191
Describe("EnqueueRequestsFromMapFunc", func() {
192192
It("should enqueue a Request with the function applied to the CreateEvent.", func() {
193193
req := []reconcile.Request{}
194-
instance := handler.EnqueueRequestsFromMapFunc{
195-
ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
196-
defer GinkgoRecover()
197-
Expect(a.Object).To(Equal(pod))
198-
req = []reconcile.Request{
199-
{
200-
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
201-
},
202-
{
203-
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
204-
},
205-
}
206-
return req
207-
}),
208-
}
194+
instance := handler.EnqueueRequestsFromMapFunc(func(a handler.MapObject) []reconcile.Request {
195+
defer GinkgoRecover()
196+
Expect(a.Object).To(Equal(pod))
197+
req = []reconcile.Request{
198+
{
199+
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
200+
},
201+
{
202+
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
203+
},
204+
}
205+
return req
206+
})
209207

210208
evt := event.CreateEvent{
211209
Object: pod,
@@ -224,21 +222,19 @@ var _ = Describe("Eventhandler", func() {
224222

225223
It("should enqueue a Request with the function applied to the DeleteEvent.", func() {
226224
req := []reconcile.Request{}
227-
instance := handler.EnqueueRequestsFromMapFunc{
228-
ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
229-
defer GinkgoRecover()
230-
Expect(a.Object).To(Equal(pod))
231-
req = []reconcile.Request{
232-
{
233-
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
234-
},
235-
{
236-
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
237-
},
238-
}
239-
return req
240-
}),
241-
}
225+
instance := handler.EnqueueRequestsFromMapFunc(func(a handler.MapObject) []reconcile.Request {
226+
defer GinkgoRecover()
227+
Expect(a.Object).To(Equal(pod))
228+
req = []reconcile.Request{
229+
{
230+
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
231+
},
232+
{
233+
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
234+
},
235+
}
236+
return req
237+
})
242238

243239
evt := event.DeleteEvent{
244240
Object: pod,
@@ -262,20 +258,19 @@ var _ = Describe("Eventhandler", func() {
262258
newPod.Namespace = pod.Namespace + "2"
263259

264260
req := []reconcile.Request{}
265-
instance := handler.EnqueueRequestsFromMapFunc{
266-
ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
267-
defer GinkgoRecover()
268-
req = []reconcile.Request{
269-
{
270-
NamespacedName: types.NamespacedName{Namespace: "foo", Name: a.Object.GetName() + "-bar"},
271-
},
272-
{
273-
NamespacedName: types.NamespacedName{Namespace: "biz", Name: a.Object.GetName() + "-baz"},
274-
},
275-
}
276-
return req
277-
}),
278-
}
261+
262+
instance := handler.EnqueueRequestsFromMapFunc(func(a handler.MapObject) []reconcile.Request {
263+
defer GinkgoRecover()
264+
req = []reconcile.Request{
265+
{
266+
NamespacedName: types.NamespacedName{Namespace: "foo", Name: a.Object.GetName() + "-bar"},
267+
},
268+
{
269+
NamespacedName: types.NamespacedName{Namespace: "biz", Name: a.Object.GetName() + "-baz"},
270+
},
271+
}
272+
return req
273+
})
279274

280275
evt := event.UpdateEvent{
281276
ObjectOld: pod,
@@ -303,21 +298,19 @@ var _ = Describe("Eventhandler", func() {
303298

304299
It("should enqueue a Request with the function applied to the GenericEvent.", func() {
305300
req := []reconcile.Request{}
306-
instance := handler.EnqueueRequestsFromMapFunc{
307-
ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
308-
defer GinkgoRecover()
309-
Expect(a.Object).To(Equal(pod))
310-
req = []reconcile.Request{
311-
{
312-
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
313-
},
314-
{
315-
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
316-
},
317-
}
318-
return req
319-
}),
320-
}
301+
instance := handler.EnqueueRequestsFromMapFunc(func(a handler.MapObject) []reconcile.Request {
302+
defer GinkgoRecover()
303+
Expect(a.Object).To(Equal(pod))
304+
req = []reconcile.Request{
305+
{
306+
NamespacedName: types.NamespacedName{Namespace: "foo", Name: "bar"},
307+
},
308+
{
309+
NamespacedName: types.NamespacedName{Namespace: "biz", Name: "baz"},
310+
},
311+
}
312+
return req
313+
})
321314

322315
evt := event.GenericEvent{
323316
Object: pod,

pkg/handler/example_test.go

+13-14
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,19 @@ func ExampleEnqueueRequestsFromMapFunc() {
6565
// controller is a controller.controller
6666
err := c.Watch(
6767
&source.Kind{Type: &appsv1.Deployment{}},
68-
&handler.EnqueueRequestsFromMapFunc{
69-
ToRequests: handler.ToRequestsFunc(func(a handler.MapObject) []reconcile.Request {
70-
return []reconcile.Request{
71-
{NamespacedName: types.NamespacedName{
72-
Name: a.Object.GetName() + "-1",
73-
Namespace: a.Object.GetNamespace(),
74-
}},
75-
{NamespacedName: types.NamespacedName{
76-
Name: a.Object.GetName() + "-2",
77-
Namespace: a.Object.GetNamespace(),
78-
}},
79-
}
80-
}),
81-
})
68+
handler.EnqueueRequestsFromMapFunc(func(a handler.MapObject) []reconcile.Request {
69+
return []reconcile.Request{
70+
{NamespacedName: types.NamespacedName{
71+
Name: a.Object.GetName() + "-1",
72+
Namespace: a.Object.GetNamespace(),
73+
}},
74+
{NamespacedName: types.NamespacedName{
75+
Name: a.Object.GetName() + "-2",
76+
Namespace: a.Object.GetNamespace(),
77+
}},
78+
}
79+
}),
80+
)
8281
if err != nil {
8382
// handle it
8483
}

0 commit comments

Comments
 (0)