Skip to content

Commit dd03af9

Browse files
committed
[feat: gw api] Add eventhandlers for all the gateway resources (kubernetes-sigs#4148)
1 parent 3b5a953 commit dd03af9

34 files changed

+2704
-100
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
"k8s.io/apimachinery/pkg/api/equality"
7+
"k8s.io/client-go/tools/record"
8+
"k8s.io/client-go/util/workqueue"
9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
10+
"sigs.k8s.io/controller-runtime/pkg/client"
11+
"sigs.k8s.io/controller-runtime/pkg/event"
12+
"sigs.k8s.io/controller-runtime/pkg/handler"
13+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
14+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
)
16+
17+
// NewEnqueueRequestsForGatewayClassEvent creates handler for GatewayClass resources
18+
func NewEnqueueRequestsForGatewayClassEvent(
19+
k8sClient client.Client, eventRecorder record.EventRecorder, gwController string, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.GatewayClass, reconcile.Request] {
20+
return &enqueueRequestsForGatewayClassEvent{
21+
k8sClient: k8sClient,
22+
eventRecorder: eventRecorder,
23+
gwController: gwController,
24+
logger: logger,
25+
}
26+
}
27+
28+
var _ handler.TypedEventHandler[*gatewayv1.GatewayClass, reconcile.Request] = (*enqueueRequestsForGatewayClassEvent)(nil)
29+
30+
// enqueueRequestsForGatewayClassEvent handles GatewayClass events
31+
type enqueueRequestsForGatewayClassEvent struct {
32+
k8sClient client.Client
33+
eventRecorder record.EventRecorder
34+
gwController string
35+
logger logr.Logger
36+
}
37+
38+
func (h *enqueueRequestsForGatewayClassEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
39+
gwClassNew := e.Object
40+
h.logger.V(1).Info("enqueue gatewayclass create event", "gatewayclass", gwClassNew.Name)
41+
h.enqueueImpactedGateways(ctx, gwClassNew, queue)
42+
}
43+
44+
func (h *enqueueRequestsForGatewayClassEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
45+
gwClassOld := e.ObjectOld
46+
gwClassNew := e.ObjectNew
47+
48+
// we only care below update event:
49+
// 1. GatewayClass spec updates
50+
// 3. GatewayClass deletions
51+
if equality.Semantic.DeepEqual(gwClassOld.Spec, gwClassNew.Spec) &&
52+
equality.Semantic.DeepEqual(gwClassOld.DeletionTimestamp.IsZero(), gwClassNew.DeletionTimestamp.IsZero()) {
53+
return
54+
}
55+
56+
h.logger.V(1).Info("enqueue gatewayclass update event", "gatewayclass", gwClassNew.Name)
57+
h.enqueueImpactedGateways(ctx, gwClassNew, queue)
58+
}
59+
60+
// Delete is not implemented for this handler as GatewayClass deletion should be finalized and is prevented while referenced by Gateways
61+
func (h *enqueueRequestsForGatewayClassEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
62+
}
63+
64+
func (h *enqueueRequestsForGatewayClassEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
65+
gwClass := e.Object
66+
h.enqueueImpactedGateways(ctx, gwClass, queue)
67+
}
68+
69+
func (h *enqueueRequestsForGatewayClassEvent) enqueueImpactedGateways(ctx context.Context, gwClass *gatewayv1.GatewayClass, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
70+
gwList := GetGatewaysManagedByLBController(ctx, h.k8sClient, h.gwController)
71+
72+
for _, gw := range gwList {
73+
if string(gw.Spec.GatewayClassName) == gwClass.Name {
74+
h.logger.V(1).Info("enqueue gateway for gatewayclass event",
75+
"gatewayclass", gwClass.GetName(),
76+
"gateway", k8s.NamespacedName(gw))
77+
queue.Add(reconcile.Request{NamespacedName: k8s.NamespacedName(gw)})
78+
}
79+
}
80+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
"k8s.io/client-go/tools/record"
7+
"k8s.io/client-go/util/workqueue"
8+
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
10+
"sigs.k8s.io/controller-runtime/pkg/client"
11+
"sigs.k8s.io/controller-runtime/pkg/event"
12+
"sigs.k8s.io/controller-runtime/pkg/handler"
13+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
14+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
)
16+
17+
// NewEnqueueRequestsForGRPCRouteEvent creates handler for GRPCRoute resources
18+
func NewEnqueueRequestsForGRPCRouteEvent(
19+
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.GRPCRoute, reconcile.Request] {
20+
return &enqueueRequestsForGRPCRouteEvent{
21+
k8sClient: k8sClient,
22+
eventRecorder: eventRecorder,
23+
logger: logger,
24+
}
25+
}
26+
27+
var _ handler.TypedEventHandler[*gatewayv1.GRPCRoute, reconcile.Request] = (*enqueueRequestsForGRPCRouteEvent)(nil)
28+
29+
// enqueueRequestsForGRPCRouteEvent handles GRPCRoute events
30+
type enqueueRequestsForGRPCRouteEvent struct {
31+
k8sClient client.Client
32+
eventRecorder record.EventRecorder
33+
logger logr.Logger
34+
}
35+
36+
func (h *enqueueRequestsForGRPCRouteEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
37+
routeNew := e.Object
38+
h.logger.V(1).Info("enqueue grpcroute create event", "grpcroute", routeNew.Name)
39+
h.enqueueImpactedGateways(ctx, routeNew, queue)
40+
}
41+
42+
func (h *enqueueRequestsForGRPCRouteEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
43+
routeNew := e.ObjectNew
44+
h.logger.V(1).Info("enqueue grpcroute update event", "grpcroute", routeNew.Name)
45+
h.enqueueImpactedGateways(ctx, routeNew, queue)
46+
}
47+
48+
func (h *enqueueRequestsForGRPCRouteEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
49+
route := e.Object
50+
h.logger.V(1).Info("enqueue grpcroute delete event", "grpcroute", route.Name)
51+
h.enqueueImpactedGateways(ctx, route, queue)
52+
}
53+
54+
func (h *enqueueRequestsForGRPCRouteEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
55+
route := e.Object
56+
h.logger.V(1).Info("enqueue grpcroute generic event", "grpcroute", route.Name)
57+
h.enqueueImpactedGateways(ctx, route, queue)
58+
}
59+
60+
func (h *enqueueRequestsForGRPCRouteEvent) enqueueImpactedGateways(ctx context.Context, route *gatewayv1.GRPCRoute, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
61+
gateways, err := GetImpactedGatewaysFromParentRefs(ctx, h.k8sClient, route.Spec.ParentRefs, route.Namespace, constants.ALBGatewayController)
62+
if err != nil {
63+
h.logger.V(1).Info("ignoring unknown gateways referred by", "grpcroute", route.Name, "error", err)
64+
}
65+
for _, gw := range gateways {
66+
h.logger.V(1).Info("enqueue gateway for grpcroute event",
67+
"grpcroute", k8s.NamespacedName(route),
68+
"gateway", gw)
69+
queue.Add(reconcile.Request{NamespacedName: gw})
70+
}
71+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
"k8s.io/client-go/tools/record"
7+
"k8s.io/client-go/util/workqueue"
8+
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
10+
"sigs.k8s.io/controller-runtime/pkg/client"
11+
"sigs.k8s.io/controller-runtime/pkg/event"
12+
"sigs.k8s.io/controller-runtime/pkg/handler"
13+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
14+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
)
16+
17+
// NewEnqueueRequestsForHTTPRouteEvent creates handler for HTTPRoute resources
18+
func NewEnqueueRequestsForHTTPRouteEvent(
19+
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.HTTPRoute, reconcile.Request] {
20+
return &enqueueRequestsForHTTPRouteEvent{
21+
k8sClient: k8sClient,
22+
eventRecorder: eventRecorder,
23+
logger: logger,
24+
}
25+
}
26+
27+
var _ handler.TypedEventHandler[*gatewayv1.HTTPRoute, reconcile.Request] = (*enqueueRequestsForHTTPRouteEvent)(nil)
28+
29+
// enqueueRequestsForHTTPRouteEvent handles HTTPRoute events
30+
type enqueueRequestsForHTTPRouteEvent struct {
31+
k8sClient client.Client
32+
eventRecorder record.EventRecorder
33+
logger logr.Logger
34+
}
35+
36+
func (h *enqueueRequestsForHTTPRouteEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
37+
routeNew := e.Object
38+
h.logger.V(1).Info("enqueue httproute create event", "httproute", routeNew.Name)
39+
h.enqueueImpactedGateways(ctx, routeNew, queue)
40+
}
41+
42+
func (h *enqueueRequestsForHTTPRouteEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
43+
routeNew := e.ObjectNew
44+
h.logger.V(1).Info("enqueue httproute update event", "httproute", routeNew.Name)
45+
h.enqueueImpactedGateways(ctx, routeNew, queue)
46+
}
47+
48+
func (h *enqueueRequestsForHTTPRouteEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
49+
route := e.Object
50+
h.logger.V(1).Info("enqueue httproute delete event", "httproute", route.Name)
51+
h.enqueueImpactedGateways(ctx, route, queue)
52+
}
53+
54+
func (h *enqueueRequestsForHTTPRouteEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
55+
route := e.Object
56+
h.logger.V(1).Info("enqueue grpcroute generic event", "grpcroute", route.Name)
57+
h.enqueueImpactedGateways(ctx, route, queue)
58+
}
59+
60+
func (h *enqueueRequestsForHTTPRouteEvent) enqueueImpactedGateways(ctx context.Context, route *gatewayv1.HTTPRoute, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
61+
gateways, err := GetImpactedGatewaysFromParentRefs(ctx, h.k8sClient, route.Spec.ParentRefs, route.Namespace, constants.ALBGatewayController)
62+
if err != nil {
63+
h.logger.V(1).Info("ignoring unknown gateways referred by", "httproute", route.Name, "error", err)
64+
}
65+
for _, gw := range gateways {
66+
h.logger.V(1).Info("enqueue gateway for httproute event",
67+
"httproute", k8s.NamespacedName(route),
68+
"gateway", gw)
69+
queue.Add(reconcile.Request{NamespacedName: gw})
70+
}
71+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package eventhandlers
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
"k8s.io/client-go/tools/record"
7+
"k8s.io/client-go/util/workqueue"
8+
elbv2gw "sigs.k8s.io/aws-load-balancer-controller/apis/gateway/v1beta1"
9+
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
10+
"sigs.k8s.io/controller-runtime/pkg/client"
11+
"sigs.k8s.io/controller-runtime/pkg/event"
12+
"sigs.k8s.io/controller-runtime/pkg/handler"
13+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
14+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
)
16+
17+
// NewEnqueueRequestsForLoadBalancerConfigurationEvent creates handler for LoadBalancerConfiguration resources
18+
func NewEnqueueRequestsForLoadBalancerConfigurationEvent(gwClassEventChan chan<- event.TypedGenericEvent[*gatewayv1.GatewayClass],
19+
k8sClient client.Client, eventRecorder record.EventRecorder, gwController string, logger logr.Logger) handler.TypedEventHandler[*elbv2gw.LoadBalancerConfiguration, reconcile.Request] {
20+
return &enqueueRequestsForLoadBalancerConfigurationEvent{
21+
gwClassEventChan: gwClassEventChan,
22+
k8sClient: k8sClient,
23+
eventRecorder: eventRecorder,
24+
gwController: gwController,
25+
logger: logger,
26+
}
27+
}
28+
29+
var _ handler.TypedEventHandler[*elbv2gw.LoadBalancerConfiguration, reconcile.Request] = (*enqueueRequestsForLoadBalancerConfigurationEvent)(nil)
30+
31+
// enqueueRequestsForLoadBalancerConfigurationEvent handles LoadBalancerConfiguration events
32+
type enqueueRequestsForLoadBalancerConfigurationEvent struct {
33+
gwClassEventChan chan<- event.TypedGenericEvent[*gatewayv1.GatewayClass]
34+
k8sClient client.Client
35+
eventRecorder record.EventRecorder
36+
gwController string
37+
logger logr.Logger
38+
}
39+
40+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Create(ctx context.Context, e event.TypedCreateEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
41+
lbconfigNew := e.Object
42+
h.logger.V(1).Info("enqueue loadbalancerconfiguration create event", "loadbalancerconfiguration", lbconfigNew.Name)
43+
h.enqueueImpactedService(ctx, lbconfigNew, queue)
44+
}
45+
46+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
47+
lbconfigNew := e.ObjectNew
48+
h.logger.V(1).Info("enqueue loadbalancerconfiguration update event", "loadbalancerconfiguration", lbconfigNew.Name)
49+
h.enqueueImpactedService(ctx, lbconfigNew, queue)
50+
}
51+
52+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
53+
lbconfig := e.Object
54+
h.logger.V(1).Info("enqueue loadbalancerconfiguration delete event", "loadbalancerconfiguration", lbconfig.Name)
55+
h.enqueueImpactedService(ctx, lbconfig, queue)
56+
}
57+
58+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*elbv2gw.LoadBalancerConfiguration], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
59+
lbconfig := e.Object
60+
h.logger.V(1).Info("enqueue loadbalancerconfiguration generic event", "loadbalancerconfiguration", lbconfig.Name)
61+
h.enqueueImpactedService(ctx, lbconfig, queue)
62+
}
63+
64+
func (h *enqueueRequestsForLoadBalancerConfigurationEvent) enqueueImpactedService(ctx context.Context, lbconfig *elbv2gw.LoadBalancerConfiguration, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
65+
gwClasses := GetImpactedGatewayClassesFromLbConfig(ctx, h.k8sClient, lbconfig, h.gwController)
66+
for _, gwClass := range gwClasses {
67+
h.logger.V(1).Info("enqueue gatewayClass for loadbalancerconfiguration event",
68+
"loadbalancerconfiguration", k8s.NamespacedName(lbconfig),
69+
"gatewayclass", k8s.NamespacedName(gwClass))
70+
h.gwClassEventChan <- event.TypedGenericEvent[*gatewayv1.GatewayClass]{
71+
Object: gwClass,
72+
}
73+
}
74+
gateways := GetImpactedGatewaysFromLbConfig(ctx, h.k8sClient, lbconfig, h.gwController)
75+
for _, gw := range gateways {
76+
if _, isAlreadyEnqueued := gwClasses[string(gw.Spec.GatewayClassName)]; !isAlreadyEnqueued {
77+
h.logger.V(1).Info("enqueue gateway for loadbalancerconfiguration event",
78+
"loadbalancerconfiguration", k8s.NamespacedName(lbconfig),
79+
"gateway", k8s.NamespacedName(gw))
80+
queue.Add(reconcile.Request{NamespacedName: k8s.NamespacedName(gw)})
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)