Skip to content

Commit fae9196

Browse files
committed
add event handler for ingressClass&ingressClassParams events
1 parent 4cb7510 commit fae9196

File tree

5 files changed

+380
-3
lines changed

5 files changed

+380
-3
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
networking "k8s.io/api/networking/v1beta1"
7+
"k8s.io/apimachinery/pkg/api/equality"
8+
"k8s.io/apimachinery/pkg/api/meta"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/client-go/tools/record"
11+
"k8s.io/client-go/util/workqueue"
12+
"sigs.k8s.io/aws-load-balancer-controller/pkg/ingress"
13+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
14+
"sigs.k8s.io/controller-runtime/pkg/client"
15+
"sigs.k8s.io/controller-runtime/pkg/event"
16+
"sigs.k8s.io/controller-runtime/pkg/handler"
17+
)
18+
19+
// NewEnqueueRequestsForIngressClassEvent constructs new enqueueRequestsForIngressClassEvent.
20+
func NewEnqueueRequestsForIngressClassEvent(ingEventChan chan<- event.GenericEvent,
21+
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) *enqueueRequestsForIngressClassEvent {
22+
return &enqueueRequestsForIngressClassEvent{
23+
ingEventChan: ingEventChan,
24+
k8sClient: k8sClient,
25+
eventRecorder: eventRecorder,
26+
logger: logger,
27+
}
28+
}
29+
30+
var _ handler.EventHandler = (*enqueueRequestsForIngressClassEvent)(nil)
31+
32+
type enqueueRequestsForIngressClassEvent struct {
33+
ingEventChan chan<- event.GenericEvent
34+
k8sClient client.Client
35+
eventRecorder record.EventRecorder
36+
logger logr.Logger
37+
}
38+
39+
func (h *enqueueRequestsForIngressClassEvent) Create(e event.CreateEvent, _ workqueue.RateLimitingInterface) {
40+
h.enqueueImpactedIngresses(e.Meta)
41+
}
42+
43+
func (h *enqueueRequestsForIngressClassEvent) Update(e event.UpdateEvent, _ workqueue.RateLimitingInterface) {
44+
ingClassOld := e.ObjectOld.(*networking.IngressClass)
45+
ingClassNew := e.ObjectNew.(*networking.IngressClass)
46+
47+
// we only care below update event:
48+
// 2. IngressClass spec updates
49+
// 3. IngressClass deletions
50+
if equality.Semantic.DeepEqual(ingClassOld.Spec, ingClassNew.Spec) &&
51+
equality.Semantic.DeepEqual(ingClassOld.DeletionTimestamp.IsZero(), ingClassNew.DeletionTimestamp.IsZero()) {
52+
return
53+
}
54+
55+
h.enqueueImpactedIngresses(e.MetaNew)
56+
}
57+
58+
func (h *enqueueRequestsForIngressClassEvent) Delete(e event.DeleteEvent, _ workqueue.RateLimitingInterface) {
59+
h.enqueueImpactedIngresses(e.Meta)
60+
}
61+
62+
func (h *enqueueRequestsForIngressClassEvent) Generic(e event.GenericEvent, _ workqueue.RateLimitingInterface) {
63+
h.enqueueImpactedIngresses(e.Meta)
64+
}
65+
66+
func (h *enqueueRequestsForIngressClassEvent) enqueueImpactedIngresses(ingClass metav1.Object) {
67+
ingList := &networking.IngressList{}
68+
if err := h.k8sClient.List(context.Background(), ingList,
69+
client.MatchingFields{ingress.IndexKeyIngressClassRefName: ingClass.GetName()}); err != nil {
70+
h.logger.Error(err, "failed to fetch ingresses")
71+
return
72+
}
73+
74+
for index := range ingList.Items {
75+
ing := &ingList.Items[index]
76+
meta, _ := meta.Accessor(ing)
77+
78+
h.logger.V(1).Info("enqueue ingress for ingressClass event",
79+
"ingressClass", ingClass.GetName(),
80+
"ingress", k8s.NamespacedName(ing))
81+
h.ingEventChan <- event.GenericEvent{
82+
Meta: meta,
83+
Object: ing,
84+
}
85+
}
86+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
networking "k8s.io/api/networking/v1beta1"
7+
"k8s.io/apimachinery/pkg/api/equality"
8+
"k8s.io/apimachinery/pkg/api/meta"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/client-go/tools/record"
11+
"k8s.io/client-go/util/workqueue"
12+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
13+
"sigs.k8s.io/aws-load-balancer-controller/pkg/ingress"
14+
"sigs.k8s.io/controller-runtime/pkg/client"
15+
"sigs.k8s.io/controller-runtime/pkg/event"
16+
"sigs.k8s.io/controller-runtime/pkg/handler"
17+
)
18+
19+
// NewEnqueueRequestsForIngressClassParamsEvent constructs new enqueueRequestsForIngressClassParamsEvent.
20+
func NewEnqueueRequestsForIngressClassParamsEvent(ingClassEventChan chan<- event.GenericEvent,
21+
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) *enqueueRequestsForIngressClassParamsEvent {
22+
return &enqueueRequestsForIngressClassParamsEvent{
23+
ingClassEventChan: ingClassEventChan,
24+
k8sClient: k8sClient,
25+
eventRecorder: eventRecorder,
26+
logger: logger,
27+
}
28+
}
29+
30+
var _ handler.EventHandler = (*enqueueRequestsForIngressClassParamsEvent)(nil)
31+
32+
type enqueueRequestsForIngressClassParamsEvent struct {
33+
ingClassEventChan chan<- event.GenericEvent
34+
k8sClient client.Client
35+
eventRecorder record.EventRecorder
36+
logger logr.Logger
37+
}
38+
39+
func (h *enqueueRequestsForIngressClassParamsEvent) Create(e event.CreateEvent, _ workqueue.RateLimitingInterface) {
40+
h.enqueueImpactedIngressClasses(e.Meta)
41+
}
42+
43+
func (h *enqueueRequestsForIngressClassParamsEvent) Update(e event.UpdateEvent, _ workqueue.RateLimitingInterface) {
44+
ingClassParamsOld := e.ObjectOld.(*elbv2api.IngressClassParams)
45+
ingClassParamsNew := e.ObjectNew.(*elbv2api.IngressClassParams)
46+
47+
// we only care below update event:
48+
// 2. IngressClassParams spec updates
49+
// 3. IngressClassParams deletion
50+
if equality.Semantic.DeepEqual(ingClassParamsOld.Spec, ingClassParamsNew.Spec) &&
51+
equality.Semantic.DeepEqual(ingClassParamsOld.DeletionTimestamp.IsZero(), ingClassParamsNew.DeletionTimestamp.IsZero()) {
52+
return
53+
}
54+
55+
h.enqueueImpactedIngressClasses(e.MetaNew)
56+
}
57+
58+
func (h *enqueueRequestsForIngressClassParamsEvent) Delete(e event.DeleteEvent, _ workqueue.RateLimitingInterface) {
59+
h.enqueueImpactedIngressClasses(e.Meta)
60+
}
61+
62+
func (h *enqueueRequestsForIngressClassParamsEvent) Generic(e event.GenericEvent, _ workqueue.RateLimitingInterface) {
63+
// we don't have any generic event for secrets.
64+
}
65+
66+
//
67+
func (h *enqueueRequestsForIngressClassParamsEvent) enqueueImpactedIngressClasses(ingClassParams metav1.Object) {
68+
ingClassList := &networking.IngressClassList{}
69+
if err := h.k8sClient.List(context.Background(), ingClassList,
70+
client.MatchingFields{ingress.IndexKeyIngressClassParamsRefName: ingClassParams.GetName()}); err != nil {
71+
h.logger.Error(err, "failed to fetch ingressClasses")
72+
return
73+
}
74+
for index := range ingClassList.Items {
75+
ingClass := &ingClassList.Items[index]
76+
meta, _ := meta.Accessor(ingClass)
77+
78+
h.logger.V(1).Info("enqueue ingressClass for ingressClassParams event",
79+
"ingressClassParams", ingClassParams.GetName(),
80+
"ingressClass", ingClass.GetName())
81+
h.ingClassEventChan <- event.GenericEvent{
82+
Meta: meta,
83+
Object: ingClass,
84+
}
85+
}
86+
}

controllers/ingress/group_controller.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
networking "k8s.io/api/networking/v1beta1"
1010
k8sruntime "k8s.io/apimachinery/pkg/runtime"
1111
"k8s.io/client-go/tools/record"
12+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
1213
"sigs.k8s.io/aws-load-balancer-controller/controllers/ingress/eventhandlers"
1314
"sigs.k8s.io/aws-load-balancer-controller/pkg/annotations"
1415
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws"
@@ -215,6 +216,20 @@ func (r *groupReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager
215216
}
216217

217218
func (r *groupReconciler) setupIndexes(ctx context.Context, fieldIndexer client.FieldIndexer) error {
219+
if err := fieldIndexer.IndexField(ctx, &networking.IngressClass{}, ingress.IndexKeyIngressClassParamsRefName,
220+
func(obj k8sruntime.Object) []string {
221+
return r.referenceIndexer.BuildIngressClassParamsRefIndexes(ctx, obj.(*networking.IngressClass))
222+
},
223+
); err != nil {
224+
return err
225+
}
226+
if err := fieldIndexer.IndexField(ctx, &networking.Ingress{}, ingress.IndexKeyIngressClassRefName,
227+
func(obj k8sruntime.Object) []string {
228+
return r.referenceIndexer.BuildIngressClassRefIndexes(ctx, obj.(*networking.Ingress))
229+
},
230+
); err != nil {
231+
return err
232+
}
218233
if err := fieldIndexer.IndexField(ctx, &networking.Ingress{}, ingress.IndexKeyServiceRefName,
219234
func(obj k8sruntime.Object) []string {
220235
return r.referenceIndexer.BuildServiceRefIndexes(context.Background(), obj.(*networking.Ingress))
@@ -240,21 +255,34 @@ func (r *groupReconciler) setupIndexes(ctx context.Context, fieldIndexer client.
240255
}
241256

242257
func (r *groupReconciler) setupWatches(_ context.Context, c controller.Controller) error {
258+
ingClassEventChan := make(chan event.GenericEvent)
243259
ingEventChan := make(chan event.GenericEvent)
244260
svcEventChan := make(chan event.GenericEvent)
261+
ingClassParamsEventHandler := eventhandlers.NewEnqueueRequestsForIngressClassParamsEvent(ingClassEventChan, r.k8sClient, r.eventRecorder,
262+
r.logger.WithName("eventHandlers").WithName("ingressClassParams"))
263+
ingClassEventHandler := eventhandlers.NewEnqueueRequestsForIngressClassEvent(ingEventChan, r.k8sClient, r.eventRecorder,
264+
r.logger.WithName("eventHandlers").WithName("ingressClass"))
245265
ingEventHandler := eventhandlers.NewEnqueueRequestsForIngressEvent(r.groupLoader, r.eventRecorder,
246266
r.logger.WithName("eventHandlers").WithName("ingress"))
247267
svcEventHandler := eventhandlers.NewEnqueueRequestsForServiceEvent(ingEventChan, r.k8sClient, r.eventRecorder,
248268
r.logger.WithName("eventHandlers").WithName("service"))
249269
secretEventHandler := eventhandlers.NewEnqueueRequestsForSecretEvent(ingEventChan, svcEventChan, r.k8sClient, r.eventRecorder,
250270
r.logger.WithName("eventHandlers").WithName("secret"))
251-
271+
if err := c.Watch(&source.Channel{Source: ingClassEventChan}, ingClassEventHandler); err != nil {
272+
return err
273+
}
252274
if err := c.Watch(&source.Channel{Source: ingEventChan}, ingEventHandler); err != nil {
253275
return err
254276
}
255277
if err := c.Watch(&source.Channel{Source: svcEventChan}, svcEventHandler); err != nil {
256278
return err
257279
}
280+
if err := c.Watch(&source.Kind{Type: &elbv2api.IngressClassParams{}}, ingClassParamsEventHandler); err != nil {
281+
return err
282+
}
283+
if err := c.Watch(&source.Kind{Type: &networking.IngressClass{}}, ingClassEventHandler); err != nil {
284+
return err
285+
}
258286
if err := c.Watch(&source.Kind{Type: &networking.Ingress{}}, ingEventHandler); err != nil {
259287
return err
260288
}

pkg/ingress/reference_indexer.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,35 @@ package ingress
22

33
import (
44
"context"
5+
awssdk "github.com/aws/aws-sdk-go/aws"
56
"github.com/go-logr/logr"
67
networking "k8s.io/api/networking/v1beta1"
78
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
89
"k8s.io/apimachinery/pkg/util/sets"
10+
elbv2api "sigs.k8s.io/aws-load-balancer-controller/apis/elbv2/v1beta1"
911
)
1012

1113
const (
12-
// IndexKey for services referenced by Ingress.
14+
// IndexKeyServiceRefName is index key for services referenced by Ingress.
1315
IndexKeyServiceRefName = "ingress.serviceRef.name"
14-
// IndexKey for secrets referenced by Ingress or Service.
16+
// IndexKeySecretRefName is index key for secrets referenced by Ingress or Service.
1517
IndexKeySecretRefName = "ingress.secretRef.name"
18+
// IndexKeyIngressClassRefName is index key for ingressClass referenced by Ingress.
19+
IndexKeyIngressClassRefName = "ingress.ingressClassRef.name"
20+
// IndexKeyIngressClassParamsRefName is index key for ingressClassParams referenced by IngressClass.
21+
IndexKeyIngressClassParamsRefName = "ingressClass.ingressClassParamsRef.name"
1622
)
1723

1824
// ReferenceIndexer has the ability to index Ingresses with referenced objects.
1925
type ReferenceIndexer interface {
26+
// BuildServiceRefIndexes returns the name of related Service objects.
2027
BuildServiceRefIndexes(ctx context.Context, ing *networking.Ingress) []string
28+
// BuildSecretRefIndexes returns the name of related Secret objects.
2129
BuildSecretRefIndexes(ctx context.Context, ingOrSvc metav1.Object) []string
30+
// BuildIngressClassRefIndexes returns the name of related IngressClass objects.
31+
BuildIngressClassRefIndexes(ctx context.Context, ing *networking.Ingress) []string
32+
// BuildIngressClassParamsRefIndexes returns the name of related IngressClassParams objects.
33+
BuildIngressClassParamsRefIndexes(ctx context.Context, ingClass *networking.IngressClass) []string
2234
}
2335

2436
// NewDefaultReferenceIndexer constructs new defaultReferenceIndexer.
@@ -80,6 +92,28 @@ func (i *defaultReferenceIndexer) BuildSecretRefIndexes(ctx context.Context, ing
8092
return extractSecretNamesFromAuthConfig(authCfg)
8193
}
8294

95+
func (i *defaultReferenceIndexer) BuildIngressClassRefIndexes(_ context.Context, ing *networking.Ingress) []string {
96+
if ing.Spec.IngressClassName == nil {
97+
return nil
98+
}
99+
100+
ingClassName := awssdk.StringValue(ing.Spec.IngressClassName)
101+
return []string{ingClassName}
102+
}
103+
104+
func (i *defaultReferenceIndexer) BuildIngressClassParamsRefIndexes(_ context.Context, ingClass *networking.IngressClass) []string {
105+
if ingClass.Spec.Controller != ingressClassControllerALB || ingClass.Spec.Parameters == nil {
106+
return nil
107+
}
108+
if ingClass.Spec.Parameters.APIGroup == nil ||
109+
(*ingClass.Spec.Parameters.APIGroup) != elbv2api.GroupVersion.Group ||
110+
ingClass.Spec.Parameters.Kind != ingressClassParamsKind {
111+
return nil
112+
}
113+
ingClassParamsName := ingClass.Spec.Parameters.Name
114+
return []string{ingClassParamsName}
115+
}
116+
83117
func extractServiceNamesFromAction(action Action) []string {
84118
if action.Type != ActionTypeForward || action.ForwardConfig == nil {
85119
return nil

0 commit comments

Comments
 (0)