Skip to content

[feat: gw api] Add eventhandlers for all the gateway resources #4148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,72 @@ rules:
verbs:
- patch
- update
- apiGroups:
- gateway.k8s.aws
resources:
- loadbalancerconfigurations
verbs:
- get
- list
- watch
- apiGroups:
- gateway.k8s.aws
resources:
- loadbalancerconfigurations/finalizers
verbs:
- update
- apiGroups:
- gateway.k8s.aws
resources:
- loadbalancerconfigurations/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.k8s.aws
resources:
- targetgroupconfigurations
verbs:
- get
- list
- watch
- apiGroups:
- gateway.k8s.aws
resources:
- targetgroupconfigurations/finalizers
verbs:
- update
- apiGroups:
- gateway.k8s.aws
resources:
- targetgroupconfigurations/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- gatewayclasses
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- gatewayclasses/finalizers
verbs:
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- gatewayclasses/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand All @@ -150,6 +216,50 @@ rules:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes/finalizers
verbs:
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- grpcroutes/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- httproutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- httproutes/finalizers
verbs:
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- httproutes/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand All @@ -172,6 +282,28 @@ rules:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- tlsroutes
verbs:
- get
- list
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
- tlsroutes/finalizers
verbs:
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- tlsroutes/status
verbs:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand Down
80 changes: 80 additions & 0 deletions controllers/gateway/eventhandlers/gateway_class_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package eventhandlers

import (
"context"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// NewEnqueueRequestsForGatewayClassEvent creates handler for GatewayClass resources
func NewEnqueueRequestsForGatewayClassEvent(
k8sClient client.Client, eventRecorder record.EventRecorder, gwController string, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.GatewayClass, reconcile.Request] {
return &enqueueRequestsForGatewayClassEvent{
k8sClient: k8sClient,
eventRecorder: eventRecorder,
gwController: gwController,
logger: logger,
}
}

var _ handler.TypedEventHandler[*gatewayv1.GatewayClass, reconcile.Request] = (*enqueueRequestsForGatewayClassEvent)(nil)

// enqueueRequestsForGatewayClassEvent handles GatewayClass events
type enqueueRequestsForGatewayClassEvent struct {
k8sClient client.Client
eventRecorder record.EventRecorder
gwController string
logger logr.Logger
}

func (h *enqueueRequestsForGatewayClassEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gwClassNew := e.Object
h.logger.V(1).Info("enqueue gatewayclass create event", "gatewayclass", gwClassNew.Name)
h.enqueueImpactedGateways(ctx, gwClassNew, queue)
}

func (h *enqueueRequestsForGatewayClassEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gwClassOld := e.ObjectOld
gwClassNew := e.ObjectNew

// we only care below update event:
// 1. GatewayClass spec updates
// 3. GatewayClass deletions
if equality.Semantic.DeepEqual(gwClassOld.Spec, gwClassNew.Spec) &&
equality.Semantic.DeepEqual(gwClassOld.DeletionTimestamp.IsZero(), gwClassNew.DeletionTimestamp.IsZero()) {
return
}

h.logger.V(1).Info("enqueue gatewayclass update event", "gatewayclass", gwClassNew.Name)
h.enqueueImpactedGateways(ctx, gwClassNew, queue)
}

// Delete is not implemented for this handler as GatewayClass deletion should be finalized and is prevented while referenced by Gateways
func (h *enqueueRequestsForGatewayClassEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
}

func (h *enqueueRequestsForGatewayClassEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.GatewayClass], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gwClass := e.Object
h.enqueueImpactedGateways(ctx, gwClass, queue)
}

func (h *enqueueRequestsForGatewayClassEvent) enqueueImpactedGateways(ctx context.Context, gwClass *gatewayv1.GatewayClass, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gwList := GetGatewaysManagedByLBController(ctx, h.k8sClient, h.gwController)

for _, gw := range gwList {
if string(gw.Spec.GatewayClassName) == gwClass.Name {
h.logger.V(1).Info("enqueue gateway for gatewayclass event",
"gatewayclass", gwClass.GetName(),
"gateway", k8s.NamespacedName(gw))
queue.Add(reconcile.Request{NamespacedName: k8s.NamespacedName(gw)})
}
}
}
71 changes: 71 additions & 0 deletions controllers/gateway/eventhandlers/grpc_route_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package eventhandlers

import (
"context"
"github.com/go-logr/logr"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// NewEnqueueRequestsForGRPCRouteEvent creates handler for GRPCRoute resources
func NewEnqueueRequestsForGRPCRouteEvent(
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.GRPCRoute, reconcile.Request] {
return &enqueueRequestsForGRPCRouteEvent{
k8sClient: k8sClient,
eventRecorder: eventRecorder,
logger: logger,
}
}

var _ handler.TypedEventHandler[*gatewayv1.GRPCRoute, reconcile.Request] = (*enqueueRequestsForGRPCRouteEvent)(nil)

// enqueueRequestsForGRPCRouteEvent handles GRPCRoute events
type enqueueRequestsForGRPCRouteEvent struct {
k8sClient client.Client
eventRecorder record.EventRecorder
logger logr.Logger
}

func (h *enqueueRequestsForGRPCRouteEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
routeNew := e.Object
h.logger.V(1).Info("enqueue grpcroute create event", "grpcroute", routeNew.Name)
h.enqueueImpactedGateways(ctx, routeNew, queue)
}

func (h *enqueueRequestsForGRPCRouteEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
routeNew := e.ObjectNew
h.logger.V(1).Info("enqueue grpcroute update event", "grpcroute", routeNew.Name)
h.enqueueImpactedGateways(ctx, routeNew, queue)
}

func (h *enqueueRequestsForGRPCRouteEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
route := e.Object
h.logger.V(1).Info("enqueue grpcroute delete event", "grpcroute", route.Name)
h.enqueueImpactedGateways(ctx, route, queue)
}

func (h *enqueueRequestsForGRPCRouteEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gatewayv1.GRPCRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
route := e.Object
h.logger.V(1).Info("enqueue grpcroute generic event", "grpcroute", route.Name)
h.enqueueImpactedGateways(ctx, route, queue)
}

func (h *enqueueRequestsForGRPCRouteEvent) enqueueImpactedGateways(ctx context.Context, route *gatewayv1.GRPCRoute, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gateways, err := GetImpactedGatewaysFromParentRefs(ctx, h.k8sClient, route.Spec.ParentRefs, route.Namespace, constants.ALBGatewayController)
if err != nil {
h.logger.V(1).Info("ignoring unknown gateways referred by", "grpcroute", route.Name, "error", err)
}
for _, gw := range gateways {
h.logger.V(1).Info("enqueue gateway for grpcroute event",
"grpcroute", k8s.NamespacedName(route),
"gateway", gw)
queue.Add(reconcile.Request{NamespacedName: gw})
}
}
71 changes: 71 additions & 0 deletions controllers/gateway/eventhandlers/http_route_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package eventhandlers

import (
"context"
"github.com/go-logr/logr"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/aws-load-balancer-controller/pkg/gateway/constants"
"sigs.k8s.io/aws-load-balancer-controller/pkg/k8s"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// NewEnqueueRequestsForHTTPRouteEvent creates handler for HTTPRoute resources
func NewEnqueueRequestsForHTTPRouteEvent(
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*gatewayv1.HTTPRoute, reconcile.Request] {
return &enqueueRequestsForHTTPRouteEvent{
k8sClient: k8sClient,
eventRecorder: eventRecorder,
logger: logger,
}
}

var _ handler.TypedEventHandler[*gatewayv1.HTTPRoute, reconcile.Request] = (*enqueueRequestsForHTTPRouteEvent)(nil)

// enqueueRequestsForHTTPRouteEvent handles HTTPRoute events
type enqueueRequestsForHTTPRouteEvent struct {
k8sClient client.Client
eventRecorder record.EventRecorder
logger logr.Logger
}

func (h *enqueueRequestsForHTTPRouteEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
routeNew := e.Object
h.logger.V(1).Info("enqueue httproute create event", "httproute", routeNew.Name)
h.enqueueImpactedGateways(ctx, routeNew, queue)
}

func (h *enqueueRequestsForHTTPRouteEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
routeNew := e.ObjectNew
h.logger.V(1).Info("enqueue httproute update event", "httproute", routeNew.Name)
h.enqueueImpactedGateways(ctx, routeNew, queue)
}

func (h *enqueueRequestsForHTTPRouteEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gatewayv1.HTTPRoute], queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
route := e.Object
h.logger.V(1).Info("enqueue httproute delete event", "httproute", route.Name)
h.enqueueImpactedGateways(ctx, route, queue)
}

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

func (h *enqueueRequestsForHTTPRouteEvent) enqueueImpactedGateways(ctx context.Context, route *gatewayv1.HTTPRoute, queue workqueue.TypedRateLimitingInterface[reconcile.Request]) {
gateways, err := GetImpactedGatewaysFromParentRefs(ctx, h.k8sClient, route.Spec.ParentRefs, route.Namespace, constants.ALBGatewayController)
if err != nil {
h.logger.V(1).Info("ignoring unknown gateways referred by", "httproute", route.Name, "error", err)
}
for _, gw := range gateways {
h.logger.V(1).Info("enqueue gateway for httproute event",
"httproute", k8s.NamespacedName(route),
"gateway", gw)
queue.Add(reconcile.Request{NamespacedName: gw})
}
}
Loading
Loading