Skip to content

Commit

Permalink
refactor: KongPluginBinding watch functions (#806)
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalek authored Oct 28, 2024
1 parent 85f87b7 commit 7d67f04
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 137 deletions.
7 changes: 3 additions & 4 deletions controller/konnect/index_kongpluginbinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ func kongPluginBindingReferencesKonnectGatewayControlPlane(obj client.Object) []
if !ok {
return nil
}
cpRef := binding.Spec.ControlPlaneRef
if cpRef == nil ||
cpRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef ||
cpRef.KonnectNamespacedRef == nil {

cpRef, ok := controlPlaneRefIsKonnectNamespacedRef(binding)
if !ok {
return nil
}

Expand Down
9 changes: 8 additions & 1 deletion controller/konnect/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ func controlPlaneRefIsKonnectNamespacedRef[
if !ok {
return configurationv1alpha1.ControlPlaneRef{}, false
}
return cpRef, cpRef.Type == configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef
return cpRef, cpRef.KonnectNamespacedRef != nil &&
cpRef.Type == configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef
}

// objectListToReconcileRequests converts a list of objects to a list of reconcile requests.
Expand All @@ -124,10 +125,16 @@ func objectListToReconcileRequests[
},
](
items []T,
filters ...func(TPtr) bool,
) []ctrl.Request {
ret := make([]ctrl.Request, 0, len(items))
for _, item := range items {
var e TPtr = &item
for _, filter := range filters {
if filter != nil && !filter(e) {
continue
}
}
ret = append(ret, ctrl.Request{
NamespacedName: types.NamespacedName{
Namespace: e.GetNamespace(),
Expand Down
177 changes: 45 additions & 132 deletions controller/konnect/watch_kongpluginbinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"

"github.com/samber/lo"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand All @@ -14,6 +13,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

"github.com/kong/gateway-operator/controller/konnect/constraints"
"github.com/kong/gateway-operator/controller/pkg/log"
"github.com/kong/gateway-operator/modules/manager/logging"

configurationv1 "github.com/kong/kubernetes-configuration/api/configuration/v1"
Expand Down Expand Up @@ -75,31 +76,31 @@ func KongPluginBindingReconciliationWatchOptions(
return b.Watches(
&configurationv1alpha1.KongService{},
handler.EnqueueRequestsFromMapFunc(
enqueueKongPluginBindingForKongService(cl),
enqueueKongPluginBindingFor[configurationv1alpha1.KongService](cl),
),
)
},
func(b *ctrl.Builder) *ctrl.Builder {
return b.Watches(
&configurationv1alpha1.KongRoute{},
handler.EnqueueRequestsFromMapFunc(
enqueueKongPluginBindingForKongRoute(cl),
enqueueKongPluginBindingFor[configurationv1alpha1.KongRoute](cl),
),
)
},
func(b *ctrl.Builder) *ctrl.Builder {
return b.Watches(
&configurationv1.KongConsumer{},
handler.EnqueueRequestsFromMapFunc(
enqueueKongPluginBindingForKongConsumer(cl),
enqueueKongPluginBindingFor[configurationv1.KongConsumer](cl),
),
)
},
func(b *ctrl.Builder) *ctrl.Builder {
return b.Watches(
&configurationv1beta1.KongConsumerGroup{},
handler.EnqueueRequestsFromMapFunc(
enqueueKongPluginBindingForKongConsumerGroup(cl),
enqueueKongPluginBindingFor[configurationv1beta1.KongConsumerGroup](cl),
),
)
},
Expand Down Expand Up @@ -229,153 +230,65 @@ func enqueueKongPluginBindingForKongPlugin(cl client.Client) func(
return nil
}

return lo.FilterMap(pluginBindingList.Items, func(pb configurationv1alpha1.KongPluginBinding, _ int) (reconcile.Request, bool) {
// Only put KongPluginBindings referencing to a Konnect control plane,
if pb.Spec.ControlPlaneRef == nil || pb.Spec.ControlPlaneRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
return reconcile.Request{}, false
}
return reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
}, true
})
return objectListToReconcileRequests(pluginBindingList.Items, kongPluginBindingIsBoundToKonnectGatewayControlPlane)
}
}

func enqueueKongPluginBindingForKongService(cl client.Client) func(
ctx context.Context, obj client.Object) []reconcile.Request {
func enqueueKongPluginBindingFor[
T constraints.SupportedKonnectEntityPluginReferenceableType,
TEnt constraints.EntityType[T],
](
cl client.Client,
) func(ctx context.Context, obj client.Object) []reconcile.Request {
return func(ctx context.Context, obj client.Object) []reconcile.Request {
kongService, ok := obj.(*configurationv1alpha1.KongService)
ent, ok := obj.(TEnt)
if !ok {
return nil
}

pluginBindingList := configurationv1alpha1.KongPluginBindingList{}
err := cl.List(ctx, &pluginBindingList,
client.InNamespace(kongService.Namespace),
client.MatchingFields{
IndexFieldKongPluginBindingKongServiceReference: kongService.Name,
},
)
if err != nil {
ctrllog.FromContext(ctx).Error(err, "failed to list KongPluginBindings referencing KongServices")
}

return lo.FilterMap(pluginBindingList.Items, func(pb configurationv1alpha1.KongPluginBinding, _ int) (reconcile.Request, bool) {
// Only put KongPluginBindings referencing to a Konnect control plane,
if pb.Spec.ControlPlaneRef == nil || pb.Spec.ControlPlaneRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
return reconcile.Request{}, false
}
return reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
}, true
})
}
}

func enqueueKongPluginBindingForKongRoute(cl client.Client) func(
ctx context.Context, obj client.Object) []reconcile.Request {
return func(ctx context.Context, obj client.Object) []reconcile.Request {
kongRoute, ok := obj.(*configurationv1alpha1.KongRoute)
if !ok {
logger := ctrllog.FromContext(ctx)
var index string
switch any(ent).(type) {
case *configurationv1alpha1.KongService:
index = IndexFieldKongPluginBindingKongServiceReference
case *configurationv1alpha1.KongRoute:
index = IndexFieldKongPluginBindingKongRouteReference
case *configurationv1.KongConsumer:
index = IndexFieldKongPluginBindingKongConsumerReference
case *configurationv1beta1.KongConsumerGroup:
index = IndexFieldKongPluginBindingKongConsumerGroupReference
default:
log.Error(
logger,
fmt.Errorf("unsupported entity type %s in KongPluginBinding watch", constraints.EntityTypeName[T]()),
"unsupported entity type",
ent,
)
return nil
}

pluginBindingList := configurationv1alpha1.KongPluginBindingList{}
err := cl.List(ctx, &pluginBindingList,
client.InNamespace(kongRoute.Namespace),
client.MatchingFields{
IndexFieldKongPluginBindingKongRouteReference: kongRoute.Name,
},
)
if err != nil {
ctrllog.FromContext(ctx).Error(err, "failed to list KongPluginBindings referencing KongRoutes")
}

return lo.FilterMap(pluginBindingList.Items, func(pb configurationv1alpha1.KongPluginBinding, _ int) (reconcile.Request, bool) {
// Only put KongPluginBindings referencing to a Konnect control plane,
if pb.Spec.ControlPlaneRef == nil || pb.Spec.ControlPlaneRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
return reconcile.Request{}, false
}
return reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
}, true
})
}
}

func enqueueKongPluginBindingForKongConsumer(cl client.Client) func(
ctx context.Context, obj client.Object) []reconcile.Request {
return func(ctx context.Context, obj client.Object) []reconcile.Request {
kongConsumer, ok := obj.(*configurationv1.KongConsumer)
if !ok {
return nil
}

pluginBindingList := configurationv1alpha1.KongPluginBindingList{}
var pluginBindingList configurationv1alpha1.KongPluginBindingList
err := cl.List(ctx, &pluginBindingList,
client.InNamespace(kongConsumer.Namespace),
client.InNamespace(ent.GetNamespace()),
client.MatchingFields{
IndexFieldKongPluginBindingKongConsumerReference: kongConsumer.Name,
index: ent.GetName(),
},
)
if err != nil {
ctrllog.FromContext(ctx).Error(err, "failed to list KongPluginBindings referencing KongConsumers")
log.Error(
logger,
err,
"failed to list KongPluginBindings referencing %ss", constraints.EntityTypeName[T](),
ent,
)
return nil
}

return lo.FilterMap(pluginBindingList.Items, func(pb configurationv1alpha1.KongPluginBinding, _ int) (reconcile.Request, bool) {
// Only put KongPluginBindings referencing to a Konnect control plane,
if pb.Spec.ControlPlaneRef == nil || pb.Spec.ControlPlaneRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
return reconcile.Request{}, false
}
return reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
}, true
})
return objectListToReconcileRequests(pluginBindingList.Items, kongPluginBindingIsBoundToKonnectGatewayControlPlane)
}
}

func enqueueKongPluginBindingForKongConsumerGroup(cl client.Client) func(
ctx context.Context, obj client.Object) []reconcile.Request {
return func(ctx context.Context, obj client.Object) []reconcile.Request {
kongConsumerGroup, ok := obj.(*configurationv1beta1.KongConsumerGroup)
if !ok {
return nil
}

pluginBindingList := configurationv1alpha1.KongPluginBindingList{}
err := cl.List(ctx, &pluginBindingList,
client.InNamespace(kongConsumerGroup.Namespace),
client.MatchingFields{
IndexFieldKongPluginBindingKongConsumerGroupReference: kongConsumerGroup.Name,
},
)
if err != nil {
ctrllog.FromContext(ctx).Error(err, "failed to list KongPluginBindings referencing KongConsumerGroups")
}

return lo.FilterMap(pluginBindingList.Items, func(pb configurationv1alpha1.KongPluginBinding, _ int) (reconcile.Request, bool) {
// Only put KongPluginBindings referencing to a Konnect control plane,
if pb.Spec.ControlPlaneRef == nil || pb.Spec.ControlPlaneRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
return reconcile.Request{}, false
}
return reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
}, true
})
}
func kongPluginBindingIsBoundToKonnectGatewayControlPlane(kpb *configurationv1alpha1.KongPluginBinding) bool {
return objHasControlPlaneRefKonnectNamespacedRef(kpb)
}

0 comments on commit 7d67f04

Please sign in to comment.