Skip to content

Commit ee75e63

Browse files
authored
Merge pull request #4274 from shraddhabang/gwrulescrdevent
[feat: gw api] Add event handling for Rules CRD
2 parents 2f5aed0 + 96072f3 commit ee75e63

File tree

19 files changed

+814
-14
lines changed

19 files changed

+814
-14
lines changed

config/rbac/role.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,30 @@ rules:
128128
verbs:
129129
- patch
130130
- update
131+
- apiGroups:
132+
- gateway.k8s.aws
133+
resources:
134+
- listenerruleconfigurations
135+
verbs:
136+
- get
137+
- list
138+
- patch
139+
- watch
140+
- apiGroups:
141+
- gateway.k8s.aws
142+
resources:
143+
- listenerruleconfigurations/finalizers
144+
verbs:
145+
- patch
146+
- update
147+
- apiGroups:
148+
- gateway.k8s.aws
149+
resources:
150+
- listenerruleconfigurations/status
151+
verbs:
152+
- get
153+
- patch
154+
- update
131155
- apiGroups:
132156
- gateway.k8s.aws
133157
resources:

controllers/gateway/eventhandlers/http_route_events.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (h *enqueueRequestsForHTTPRouteEvent) Delete(ctx context.Context, e event.T
5454

5555
func (h *enqueueRequestsForHTTPRouteEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
5656
route := e.Object
57-
h.logger.V(1).Info("enqueue grpcroute generic event", "grpcroute", route.Name)
57+
h.logger.V(1).Info("enqueue httproute generic event", "httproute", route.Name)
5858
h.enqueueImpactedGateways(ctx, route, queue)
5959
}
6060

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
"k8s.io/client-go/util/workqueue"
7+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
8+
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/routeutils"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
"sigs.k8s.io/controller-runtime/pkg/event"
11+
"sigs.k8s.io/controller-runtime/pkg/handler"
12+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
13+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
14+
)
15+
16+
// NewEnqueueRequestsForListenerRuleConfigurationEvent creates handler for ListenerRuleConfiguration resources
17+
func NewEnqueueRequestsForListenerRuleConfigurationEvent(httpRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.HTTPRoute],
18+
grpcRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.GRPCRoute], k8sClient client.Client, logger logr.Logger) handler.TypedEventHandler[*elbv2gw.ListenerRuleConfiguration, reconcile.Request] {
19+
return &enqueueRequestsForListenerRuleConfigurationEvent{
20+
httpRouteEventChan: httpRouteEventChan,
21+
grpcRouteEventChan: grpcRouteEventChan,
22+
k8sClient: k8sClient,
23+
logger: logger,
24+
}
25+
}
26+
27+
var _ handler.TypedEventHandler[*elbv2gw.ListenerRuleConfiguration, reconcile.Request] = (*enqueueRequestsForListenerRuleConfigurationEvent)(nil)
28+
29+
// enqueueRequestsForListenerRuleConfigurationEvent handles ListenerRuleConfiguration events
30+
type enqueueRequestsForListenerRuleConfigurationEvent struct {
31+
httpRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.HTTPRoute]
32+
grpcRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.GRPCRoute]
33+
k8sClient client.Client
34+
logger logr.Logger
35+
}
36+
37+
func (h *enqueueRequestsForListenerRuleConfigurationEvent) Create(ctx context.Context, e event.TypedCreateEvent[*elbv2gw.ListenerRuleConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
38+
ruleConfig := e.Object
39+
h.logger.V(1).Info("enqueue listenerruleconfiguration create event", "listenerruleconfiguration", ruleConfig.Name)
40+
h.enqueueImpactedRoutes(ctx, ruleConfig, queue)
41+
}
42+
43+
func (h *enqueueRequestsForListenerRuleConfigurationEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*elbv2gw.ListenerRuleConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
44+
ruleConfig := e.ObjectNew
45+
h.logger.V(1).Info("enqueue listenerruleconfiguration update event", "listenerruleconfiguration", ruleConfig.Name)
46+
h.enqueueImpactedRoutes(ctx, ruleConfig, queue)
47+
}
48+
49+
func (h *enqueueRequestsForListenerRuleConfigurationEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*elbv2gw.ListenerRuleConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
50+
ruleConfig := e.Object
51+
h.logger.V(1).Info("enqueue listenerruleconfiguration delete event", "listenerruleconfiguration", ruleConfig.Name)
52+
h.enqueueImpactedRoutes(ctx, ruleConfig, queue)
53+
}
54+
55+
func (h *enqueueRequestsForListenerRuleConfigurationEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*elbv2gw.ListenerRuleConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
56+
ruleConfig := e.Object
57+
h.logger.V(1).Info("enqueue listenerruleconfiguration generic event", "listenerruleconfiguration", ruleConfig.Name)
58+
h.enqueueImpactedRoutes(ctx, ruleConfig, queue)
59+
}
60+
61+
func (h *enqueueRequestsForListenerRuleConfigurationEvent) enqueueImpactedRoutes(ctx context.Context, ruleConfig *elbv2gw.ListenerRuleConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
62+
// Find all L7 Routes that reference this ListenerRuleConfiguration via ExtensionRef
63+
64+
l7Routes, err := routeutils.ListL7Routes(ctx, h.k8sClient)
65+
if err != nil {
66+
h.logger.V(1).Info("ignoring to enqueue impacted L7 routes ", "error: ", err)
67+
}
68+
filteredRoutesByListenerRuleCfg := routeutils.FilterRoutesByListenerRuleCfg(l7Routes, ruleConfig)
69+
for _, route := range filteredRoutesByListenerRuleCfg {
70+
routeType := route.GetRouteKind()
71+
switch routeType {
72+
case routeutils.HTTPRouteKind:
73+
h.logger.V(1).Info("enqueue httproute for listenerruleconfiguration event",
74+
"listenerruleconfiguration", ruleConfig.Name,
75+
"httproute", route.GetRouteNamespacedName())
76+
h.httpRouteEventChan <- event.TypedGenericEvent[*gatewayv1.HTTPRoute]{
77+
Object: route.GetRawRoute().(*gatewayv1.HTTPRoute),
78+
}
79+
case routeutils.GRPCRouteKind:
80+
h.logger.V(1).Info("enqueue grpcroute for listenerruleconfiguration event",
81+
"listenerruleconfiguration", ruleConfig.Name,
82+
"grpcroute", route.GetRouteNamespacedName())
83+
h.grpcRouteEventChan <- event.TypedGenericEvent[*gatewayv1.GRPCRoute]{
84+
Object: route.GetRawRoute().(*gatewayv1.GRPCRoute),
85+
}
86+
}
87+
}
88+
89+
}

controllers/gateway/eventhandlers/load_balancer_configuration_events.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,28 @@ type enqueueRequestsForLoadBalancerConfigurationEvent struct {
4444
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Create(ctx context.Context, e event.TypedCreateEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
4545
lbconfigNew := e.Object
4646
h.logger.V(1).Info("enqueue loadbalancerconfiguration create event", "loadbalancerconfiguration", lbconfigNew.Name)
47-
h.enqueueImpactedService(ctx, lbconfigNew, queue)
47+
h.enqueueImpactedGateways(ctx, lbconfigNew, queue)
4848
}
4949

5050
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
5151
lbconfigNew := e.ObjectNew
5252
h.logger.V(1).Info("enqueue loadbalancerconfiguration update event", "loadbalancerconfiguration", lbconfigNew.Name)
53-
h.enqueueImpactedService(ctx, lbconfigNew, queue)
53+
h.enqueueImpactedGateways(ctx, lbconfigNew, queue)
5454
}
5555

5656
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
5757
lbconfig := e.Object
5858
h.logger.V(1).Info("enqueue loadbalancerconfiguration delete event", "loadbalancerconfiguration", lbconfig.Name)
59-
h.enqueueImpactedService(ctx, lbconfig, queue)
59+
h.enqueueImpactedGateways(ctx, lbconfig, queue)
6060
}
6161

6262
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
6363
lbconfig := e.Object
6464
h.logger.V(1).Info("enqueue loadbalancerconfiguration generic event", "loadbalancerconfiguration", lbconfig.Name)
65-
h.enqueueImpactedService(ctx, lbconfig, queue)
65+
h.enqueueImpactedGateways(ctx, lbconfig, queue)
6666
}
6767

68-
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) enqueueImpactedService(ctx context.Context, lbconfig *elbv2gw.LoadBalancerConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
68+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) enqueueImpactedGateways(ctx context.Context, lbconfig *elbv2gw.LoadBalancerConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
6969
// NOTE: That LB Config changes for GatewayClass are done a little differently.
7070
// LB config change -> gateway class reconciler -> patch status for new version of LB config on Gateway Class -> Trigger the Gateway Class event handler.
7171
gateways, err := gatewayutils.GetImpactedGatewaysFromLbConfig(ctx, h.k8sClient, lbconfig, h.gwController)

controllers/gateway/gateway_controller.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,10 @@ type gatewayReconciler struct {
144144
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=targetgroupconfigurations/status,verbs=get;update;patch
145145
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=targetgroupconfigurations/finalizers,verbs=update;patch
146146

147+
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=listenerruleconfigurations,verbs=get;list;watch;patch
148+
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=listenerruleconfigurations/status,verbs=get;update;patch
149+
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=listenerruleconfigurations/finalizers,verbs=update;patch
150+
147151
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=udproutes,verbs=get;list;watch
148152
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=udproutes/status,verbs=get;update;patch
149153
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=udproutes/finalizers,verbs=update
@@ -164,9 +168,6 @@ type gatewayReconciler struct {
164168
// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=grpcroutes/status,verbs=get;update;patch
165169
// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=grpcroutes/finalizers,verbs=update
166170

167-
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=loadbalancerconfigurations,verbs=get;list;watch
168-
//+kubebuilder:rbac:groups=gateway.k8s.aws,resources=targetgroupconfigurations,verbs=get;list;watch
169-
170171
func (r *gatewayReconciler) Reconcile(ctx context.Context, req reconcile.Request) (ctrl.Result, error) {
171172
r.reconcileTracker(req.NamespacedName)
172173
err := r.reconcileHelper(ctx, req)
@@ -449,11 +450,13 @@ func (r *gatewayReconciler) setupCommonGatewayControllerWatches(ctrl controller.
449450
func (r *gatewayReconciler) setupALBGatewayControllerWatches(ctrl controller.Controller, mgr ctrl.Manager) error {
450451
loggerPrefix := r.logger.WithName("eventHandlers")
451452
tbConfigEventChan := make(chan event.TypedGenericEvent[*elbv2gw.TargetGroupConfiguration])
453+
listenerRuleConfigEventChan := make(chan event.TypedGenericEvent[*elbv2gw.ListenerRuleConfiguration])
452454
httpRouteEventChan := make(chan event.TypedGenericEvent[*gwv1.HTTPRoute])
453455
grpcRouteEventChan := make(chan event.TypedGenericEvent[*gwv1.GRPCRoute])
454456
svcEventChan := make(chan event.TypedGenericEvent[*corev1.Service])
455457
tgConfigEventHandler := eventhandlers.NewEnqueueRequestsForTargetGroupConfigurationEvent(svcEventChan, r.k8sClient, r.eventRecorder,
456458
loggerPrefix.WithName("TargetGroupConfiguration"))
459+
listenerRuleConfigEventHandler := eventhandlers.NewEnqueueRequestsForListenerRuleConfigurationEvent(httpRouteEventChan, grpcRouteEventChan, r.k8sClient, loggerPrefix.WithName("ListenerRuleConfiguration"))
457460
grpcRouteEventHandler := eventhandlers.NewEnqueueRequestsForGRPCRouteEvent(r.k8sClient, r.eventRecorder,
458461
loggerPrefix.WithName("GRPCRoute"))
459462
httpRouteEventHandler := eventhandlers.NewEnqueueRequestsForHTTPRouteEvent(r.k8sClient, r.eventRecorder,
@@ -465,6 +468,9 @@ func (r *gatewayReconciler) setupALBGatewayControllerWatches(ctrl controller.Con
465468
if err := ctrl.Watch(source.Channel(tbConfigEventChan, tgConfigEventHandler)); err != nil {
466469
return err
467470
}
471+
if err := ctrl.Watch(source.Channel(listenerRuleConfigEventChan, listenerRuleConfigEventHandler)); err != nil {
472+
return err
473+
}
468474
if err := ctrl.Watch(source.Channel(httpRouteEventChan, httpRouteEventHandler)); err != nil {
469475
return err
470476
}
@@ -477,6 +483,9 @@ func (r *gatewayReconciler) setupALBGatewayControllerWatches(ctrl controller.Con
477483
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &elbv2gw.TargetGroupConfiguration{}, tgConfigEventHandler)); err != nil {
478484
return err
479485
}
486+
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &elbv2gw.ListenerRuleConfiguration{}, listenerRuleConfigEventHandler)); err != nil {
487+
return err
488+
}
480489
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &corev1.Service{}, svcEventHandler)); err != nil {
481490
return err
482491
}

helm/aws-load-balancer-controller/templates/rbac.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ rules:
9090
resources: [endpointslices]
9191
verbs: [get, list, watch]
9292
- apiGroups: ["gateway.k8s.aws"]
93-
resources: [loadbalancerconfigurations, targetgroupconfigurations]
93+
resources: [loadbalancerconfigurations, targetgroupconfigurations, listenerruleconfigurations]
9494
verbs: [get, list, watch, patch]
9595
- apiGroups: ["gateway.k8s.aws"]
96-
resources: [loadbalancerconfigurations/finalizers, targetgroupconfigurations/finalizers]
96+
resources: [loadbalancerconfigurations/finalizers, targetgroupconfigurations/finalizers, listenerruleconfigurations/finalizers]
9797
verbs: [update, patch]
9898
- apiGroups: ["gateway.k8s.aws"]
99-
resources: [loadbalancerconfigurations/status, targetgroupconfigurations/status]
99+
resources: [loadbalancerconfigurations/status, targetgroupconfigurations/status, listenerruleconfigurations/status]
100100
verbs: [get, patch, watch]
101101
- apiGroups: ["gateway.networking.k8s.io"]
102102
resources: [gatewayclasses, gateways]

pkg/gateway/constants/controller_constants.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ const (
1414
// GatewayResourceGroupVersion the groupVersion used by Gateway & GatewayClass resources.
1515
GatewayResourceGroupVersion = "gateway.networking.k8s.io/v1"
1616

17+
//ControllerCRDGroupVersion the groupVersion used by customization CRDs
18+
ControllerCRDGroupVersion = "gateway.k8s.aws"
19+
1720
// LoadBalancerConfiguration the CRD name of LoadBalancerConfiguration
1821
LoadBalancerConfiguration = "LoadBalancerConfiguration"
22+
23+
// ListenerRuleConfiguration the CRD name of ListenerRuleConfiguration
24+
ListenerRuleConfiguration = "ListenerRuleConfiguration"
1925
)
2026

2127
/*

pkg/gateway/routeutils/descriptor.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type routeMetadataDescriptor interface {
1818
GetParentRefs() []gwv1.ParentReference
1919
GetRawRoute() interface{}
2020
GetBackendRefs() []gwv1.BackendRef
21+
GetListenerRuleConfigs() []gwv1.LocalObjectReference
2122
GetRouteGeneration() int64
2223
GetRouteCreateTimestamp() time.Time
2324
}

pkg/gateway/routeutils/grpc.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package routeutils
33
import (
44
"context"
55
"k8s.io/apimachinery/pkg/types"
6+
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
67
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
78
"sigs.k8s.io/controller-runtime/pkg/client"
89
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
@@ -107,6 +108,32 @@ func (grpcRoute *grpcRouteDescription) GetBackendRefs() []gwv1.BackendRef {
107108
return backendRefs
108109
}
109110

111+
// GetListenerRuleConfigs returns all ListenerRuleConfiguration references from
112+
// ExtensionRef filters in the GRPCRoute
113+
func (grpcRoute *grpcRouteDescription) GetListenerRuleConfigs() []gwv1.LocalObjectReference {
114+
listenerRuleConfigs := make([]gwv1.LocalObjectReference, 0)
115+
if grpcRoute.route.Spec.Rules != nil {
116+
for _, rule := range grpcRoute.route.Spec.Rules {
117+
if rule.Filters != nil {
118+
for _, filter := range rule.Filters {
119+
if filter.Type != gwv1.GRPCRouteFilterExtensionRef {
120+
continue
121+
}
122+
if string(filter.ExtensionRef.Group) == constants.ControllerCRDGroupVersion && string(filter.ExtensionRef.Kind) == constants.ListenerRuleConfiguration {
123+
listenerRuleConfigs = append(listenerRuleConfigs, gwv1.LocalObjectReference{
124+
Group: constants.ControllerCRDGroupVersion,
125+
Kind: constants.ListenerRuleConfiguration,
126+
Name: filter.ExtensionRef.Name,
127+
})
128+
}
129+
}
130+
131+
}
132+
}
133+
}
134+
return listenerRuleConfigs
135+
}
136+
110137
func (grpcRoute *grpcRouteDescription) GetRouteGeneration() int64 {
111138
return grpcRoute.route.Generation
112139
}

0 commit comments

Comments
 (0)