Skip to content
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
9 changes: 9 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ rules:
- get
- patch
- update
- apiGroups:
- gateway.networking.k8s.io
resources:
- referencegrants
verbs:
- get
- list
- patch
- watch
- apiGroups:
- gateway.networking.k8s.io
resources:
Expand Down
174 changes: 174 additions & 0 deletions controllers/gateway/eventhandlers/reference_grant_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package eventhandlers

import (
"context"
"fmt"
"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/routeutils"
"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"
gwalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwbeta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
)

// NewEnqueueRequestsForReferenceGrantEvent creates handler for ReferenceGrant resources
func NewEnqueueRequestsForReferenceGrantEvent(httpRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.HTTPRoute],
grpcRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.GRPCRoute],
tcpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TCPRoute],
udpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.UDPRoute],
tlsRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TLSRoute],
k8sClient client.Client, eventRecorder record.EventRecorder, logger logr.Logger) handler.TypedEventHandler[*gwbeta1.ReferenceGrant, reconcile.Request] {
return &enqueueRequestsForReferenceGrantEvent{
httpRouteEventChan: httpRouteEventChan,
grpcRouteEventChan: grpcRouteEventChan,
tcpRouteEventChan: tcpRouteEventChan,
udpRouteEventChan: udpRouteEventChan,
tlsRouteEventChan: tlsRouteEventChan,
k8sClient: k8sClient,
eventRecorder: eventRecorder,
logger: logger,
}
}

var _ handler.TypedEventHandler[*gwbeta1.ReferenceGrant, reconcile.Request] = (*enqueueRequestsForReferenceGrantEvent)(nil)

// enqueueRequestsForReferenceGrantEvent handles ReferenceGrant events
type enqueueRequestsForReferenceGrantEvent struct {
httpRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.HTTPRoute]
grpcRouteEventChan chan<- event.TypedGenericEvent[*gatewayv1.GRPCRoute]
tcpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TCPRoute]
udpRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.UDPRoute]
tlsRouteEventChan chan<- event.TypedGenericEvent[*gwalpha2.TLSRoute]
k8sClient client.Client
eventRecorder record.EventRecorder
logger logr.Logger
}

func (h *enqueueRequestsForReferenceGrantEvent) Create(ctx context.Context, e event.TypedCreateEvent[*gwbeta1.ReferenceGrant], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) {
referenceGrantNew := e.Object
h.logger.V(1).Info("enqueue reference grant create event", "reference grant", referenceGrantNew.Name)
h.enqueueImpactedRoutes(ctx, referenceGrantNew, nil)
}

func (h *enqueueRequestsForReferenceGrantEvent) Update(ctx context.Context, e event.TypedUpdateEvent[*gwbeta1.ReferenceGrant], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) {
referenceGrantNew := e.ObjectNew
referenceGrantOld := e.ObjectOld
h.logger.V(1).Info("enqueue reference grant update event", "reference grant", referenceGrantNew.Name)
h.enqueueImpactedRoutes(ctx, referenceGrantNew, referenceGrantOld)
}

func (h *enqueueRequestsForReferenceGrantEvent) Delete(ctx context.Context, e event.TypedDeleteEvent[*gwbeta1.ReferenceGrant], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) {
refgrant := e.Object
h.logger.V(1).Info("enqueue reference grant delete event", "reference grant", refgrant.Name)
h.enqueueImpactedRoutes(ctx, refgrant, nil)
}

func (h *enqueueRequestsForReferenceGrantEvent) Generic(ctx context.Context, e event.TypedGenericEvent[*gwbeta1.ReferenceGrant], _ workqueue.TypedRateLimitingInterface[reconcile.Request]) {
refgrant := e.Object
h.logger.V(1).Info("enqueue reference grant generic event", "reference grant", refgrant.Name)
h.enqueueImpactedRoutes(ctx, refgrant, nil)
}

func (h *enqueueRequestsForReferenceGrantEvent) enqueueImpactedRoutes(ctx context.Context, newRefGrant *gwbeta1.ReferenceGrant, oldRefGrant *gwbeta1.ReferenceGrant) {

impactedRoutes := make(map[string]gwbeta1.ReferenceGrantFrom)

for i, from := range newRefGrant.Spec.From {
impactedRoutes[generateGrantFromKey(from)] = newRefGrant.Spec.From[i]
}

if oldRefGrant != nil {
for i, from := range oldRefGrant.Spec.From {
impactedRoutes[generateGrantFromKey(from)] = oldRefGrant.Spec.From[i]
}
}

for _, impactedFrom := range impactedRoutes {
switch string(impactedFrom.Kind) {
case string(routeutils.HTTPRouteKind):
if h.httpRouteEventChan == nil {
continue
}
routes, err := routeutils.ListHTTPRoutes(ctx, h.k8sClient, &client.ListOptions{Namespace: string(impactedFrom.Namespace)})
if err == nil {
for _, route := range routes {
h.httpRouteEventChan <- event.TypedGenericEvent[*gatewayv1.HTTPRoute]{
Object: route.GetRawRoute().(*gatewayv1.HTTPRoute),
}
}

} else {
h.logger.Error(err, "Unable to list impacted http routes for reference grant event handler")
}
case string(routeutils.GRPCRouteKind):
if h.grpcRouteEventChan == nil {
continue
}
routes, err := routeutils.ListGRPCRoutes(ctx, h.k8sClient, &client.ListOptions{Namespace: string(impactedFrom.Namespace)})
if err == nil {
for _, route := range routes {
h.grpcRouteEventChan <- event.TypedGenericEvent[*gatewayv1.GRPCRoute]{
Object: route.GetRawRoute().(*gatewayv1.GRPCRoute),
}
}

} else {
h.logger.Error(err, "Unable to list impacted grpc routes for reference grant event handler")
}
case string(routeutils.TCPRouteKind):
if h.tcpRouteEventChan == nil {
continue
}
routes, err := routeutils.ListTCPRoutes(ctx, h.k8sClient, &client.ListOptions{Namespace: string(impactedFrom.Namespace)})
if err == nil {
for _, route := range routes {
h.tcpRouteEventChan <- event.TypedGenericEvent[*gwalpha2.TCPRoute]{
Object: route.GetRawRoute().(*gwalpha2.TCPRoute),
}
}

} else {
h.logger.Error(err, "Unable to list impacted tcp routes for reference grant event handler")
}
case string(routeutils.UDPRouteKind):
if h.udpRouteEventChan == nil {
continue
}
routes, err := routeutils.ListUDPRoutes(ctx, h.k8sClient, &client.ListOptions{Namespace: string(impactedFrom.Namespace)})
if err == nil {
for _, route := range routes {
h.udpRouteEventChan <- event.TypedGenericEvent[*gwalpha2.UDPRoute]{
Object: route.GetRawRoute().(*gwalpha2.UDPRoute),
}
}

} else {
h.logger.Error(err, "Unable to list impacted udp routes for reference grant event handler")
}
case string(routeutils.TLSRouteKind):
if h.tlsRouteEventChan == nil {
continue
}
routes, err := routeutils.ListTLSRoutes(ctx, h.k8sClient, &client.ListOptions{Namespace: string(impactedFrom.Namespace)})
if err == nil {
for _, route := range routes {
h.tlsRouteEventChan <- event.TypedGenericEvent[*gwalpha2.TLSRoute]{
Object: route.GetRawRoute().(*gwalpha2.TLSRoute),
}
}

} else {
h.logger.Error(err, "Unable to list impacted tls routes for reference grant event handler")
}
}
}
}

func generateGrantFromKey(from gwbeta1.ReferenceGrantFrom) string {
return fmt.Sprintf("%s-%s", from.Kind, from.Namespace)
}
13 changes: 13 additions & 0 deletions controllers/gateway/gateway_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/source"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
gwalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwbeta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
"time"
)

Expand Down Expand Up @@ -125,6 +126,8 @@ type gatewayReconciler struct {
routeReconciler routeutils.RouteReconciler
}

//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=referencegrants,verbs=get;list;watch;patch

//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways,verbs=get;list;watch;patch
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=gateways/finalizers,verbs=update;patch
Expand Down Expand Up @@ -457,6 +460,8 @@ func (r *gatewayReconciler) setupALBGatewayControllerWatches(ctrl controller.Con
loggerPrefix.WithName("HTTPRoute"))
svcEventHandler := eventhandlers.NewEnqueueRequestsForServiceEvent(httpRouteEventChan, grpcRouteEventChan, nil, nil, nil, r.k8sClient, r.eventRecorder,
loggerPrefix.WithName("Service"), constants.ALBGatewayController)
refGrantHandler := eventhandlers.NewEnqueueRequestsForReferenceGrantEvent(httpRouteEventChan, grpcRouteEventChan, nil, nil, nil, r.k8sClient, r.eventRecorder,
loggerPrefix.WithName("ReferenceGrant"))
if err := ctrl.Watch(source.Channel(tbConfigEventChan, tgConfigEventHandler)); err != nil {
return err
}
Expand All @@ -475,6 +480,9 @@ func (r *gatewayReconciler) setupALBGatewayControllerWatches(ctrl controller.Con
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &corev1.Service{}, svcEventHandler)); err != nil {
return err
}
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &gwbeta1.ReferenceGrant{}, refGrantHandler)); err != nil {
return err
}
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &gwv1.HTTPRoute{}, httpRouteEventHandler)); err != nil {
return err
}
Expand All @@ -501,6 +509,8 @@ func (r *gatewayReconciler) setupNLBGatewayControllerWatches(ctrl controller.Con
loggerPrefix.WithName("TLSRoute"))
svcEventHandler := eventhandlers.NewEnqueueRequestsForServiceEvent(nil, nil, tcpRouteEventChan, udpRouteEventChan, tlsRouteEventChan, r.k8sClient, r.eventRecorder,
loggerPrefix.WithName("Service"), constants.NLBGatewayController)
refGrantHandler := eventhandlers.NewEnqueueRequestsForReferenceGrantEvent(nil, nil, tcpRouteEventChan, udpRouteEventChan, tlsRouteEventChan, r.k8sClient, r.eventRecorder,
loggerPrefix.WithName("ReferenceGrant"))
if err := ctrl.Watch(source.Channel(tbConfigEventChan, tgConfigEventHandler)); err != nil {
return err
}
Expand All @@ -522,6 +532,9 @@ func (r *gatewayReconciler) setupNLBGatewayControllerWatches(ctrl controller.Con
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &corev1.Service{}, svcEventHandler)); err != nil {
return err
}
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &gwbeta1.ReferenceGrant{}, refGrantHandler)); err != nil {
return err
}
if err := ctrl.Watch(source.Kind(mgr.GetCache(), &gwalpha2.TCPRoute{}, tcpRouteEventHandler)); err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions helm/aws-load-balancer-controller/templates/rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ rules:
- apiGroups: ["gateway.networking.k8s.io"]
resources: [gatewayclasses, gateways]
verbs: [get, list, watch, patch]
- apiGroups: ["gateway.networking.k8s.io"]
resources: [referencegrants]
verbs: [get, list, watch]
- apiGroups: ["gateway.networking.k8s.io"]
resources: [gatewayclasses/finalizers, gateways/finalizers]
verbs: [update, patch]
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
gwv1 "sigs.k8s.io/gateway-api/apis/v1"
gwalpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwbeta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
"sync"

"k8s.io/client-go/util/workqueue"
Expand Down Expand Up @@ -82,6 +83,7 @@ func init() {
_ = elbv2gw.AddToScheme(scheme)
_ = gwv1.AddToScheme(scheme)
_ = gwalpha2.AddToScheme(scheme)
_ = gwbeta1.AddToScheme(scheme)
// +kubebuilder:scaffold:scheme
}

Expand Down
Loading
Loading