Skip to content
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

feat(konnect): add indices for KongPluginBinding -> KonnectGatewayControlPlane and KongRoute -> KongService #685

Merged
merged 2 commits into from
Oct 3, 2024
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
51 changes: 41 additions & 10 deletions controller/konnect/index_kongpluginbinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ import (
)

const (
// IndexFieldKongPluginBindingKongPluginReference is the index field for KongPlugin -> KongPluginBinding.
IndexFieldKongPluginBindingKongPluginReference = "kongPluginRef"
// IndexFieldKongPluginBindingKongServiceReference is the index field for KongService -> KongPluginBinding.
IndexFieldKongPluginBindingKongServiceReference = "kongServiceRef"
// IndexFieldKongPluginBindingKongRouteReference is the index field for KongRoute -> KongPluginBinding.
IndexFieldKongPluginBindingKongRouteReference = "kongRouteRef"
// IndexFieldKongPluginBindingKongConsumerReference is the index field for KongConsumer -> KongPluginBinding.
IndexFieldKongPluginBindingKongConsumerReference = "kongConsumerRef"
// IndexFieldKongPluginBindingKongConsumerGroupReference is the index field for KongConsumerGroup -> KongPluginBinding.
IndexFieldKongPluginBindingKongConsumerGroupReference = "kongConsumerGroupRef"
// IndexFieldKongPluginBindingKongPluginReference is the index field for KongPluginBinding -> KongPlugin.
IndexFieldKongPluginBindingKongPluginReference = "kongPluginBindingPluginRef"
// IndexFieldKongPluginBindingKongServiceReference is the index field for KongPluginBinding -> KongService.
IndexFieldKongPluginBindingKongServiceReference = "kongPluginBindingServiceRef"
// IndexFieldKongPluginBindingKongRouteReference is the index field for KongPluginBinding -> KongRoute.
IndexFieldKongPluginBindingKongRouteReference = "kongPluginBindingRouteRef"
// IndexFieldKongPluginBindingKongConsumerReference is the index field for KongPluginBinding -> KongConsumer.
IndexFieldKongPluginBindingKongConsumerReference = "kongPluginBindingConsumerRef"
// IndexFieldKongPluginBindingKongConsumerGroupReference is the index field for KongPluginBinding -> KongConsumerGroup.
IndexFieldKongPluginBindingKongConsumerGroupReference = "kongPluginBindingConsumerGroupRef"
// IndexFieldKongPluginBindingKonnectGatewayControlPlane is the index field for KongPluginBinding -> KonnectGatewayControlPlane.
IndexFieldKongPluginBindingKonnectGatewayControlPlane = "kongPluginBindingKonnectGatewayControlPlaneRef"
)

// IndexOptionsForKongPluginBinding returns required Index options for KongPluginBinding reconclier.
Expand Down Expand Up @@ -47,6 +49,11 @@ func IndexOptionsForKongPluginBinding() []ReconciliationIndexOption {
IndexField: IndexFieldKongPluginBindingKongConsumerGroupReference,
ExtractValue: kongConsumerGroupReferencesFromKongPluginBinding,
},
{
IndexObject: &configurationv1alpha1.KongPluginBinding{},
IndexField: IndexFieldKongPluginBindingKonnectGatewayControlPlane,
ExtractValue: kongPluginBindingReferencesKonnectGatewayControlPlane,
},
}
}

Expand Down Expand Up @@ -113,3 +120,27 @@ func kongConsumerGroupReferencesFromKongPluginBinding(obj client.Object) []strin
}
return []string{binding.Spec.Targets.ConsumerGroupReference.Name}
}

// kongPluginBindingReferencesKonnectGatewayControlPlane returns name of referenced KonnectGatewayControlPlane in KongPluginBinding spec.
func kongPluginBindingReferencesKonnectGatewayControlPlane(obj client.Object) []string {
binding, ok := obj.(*configurationv1alpha1.KongPluginBinding)
if !ok {
return nil
}
cpRef := binding.Spec.ControlPlaneRef
if cpRef == nil ||
cpRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef ||
cpRef.KonnectNamespacedRef == nil {
return nil
}

// NOTE: This provides support for setting the namespace of the KonnectGatewayControlPlane ref
// but CRDs have validation rules in place which will disallow this until
// cross namespace refs are allowed.
namespace := binding.Namespace
if cpRef.KonnectNamespacedRef.Namespace != "" {
namespace = cpRef.KonnectNamespacedRef.Namespace
}

return []string{namespace + "/" + cpRef.KonnectNamespacedRef.Name}
}
25 changes: 25 additions & 0 deletions controller/konnect/index_kongroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
const (
// IndexFieldKongRouteOnReferencedPluginNames is the index field for KongRoute -> KongPlugin.
IndexFieldKongRouteOnReferencedPluginNames = "kongRouteKongPluginRef"
// IndexFieldKongRouteOnReferencedKongService is the index field for KongRoute -> KongService.
IndexFieldKongRouteOnReferencedKongService = "kongRouteKongServiceRef"
)

// IndexOptionsForKongRoute returns required Index options for KongRoute reconciler.
Expand All @@ -21,6 +23,11 @@ func IndexOptionsForKongRoute() []ReconciliationIndexOption {
IndexField: IndexFieldKongRouteOnReferencedPluginNames,
ExtractValue: kongRouteUsesPlugins,
},
{
IndexObject: &configurationv1alpha1.KongRoute{},
IndexField: IndexFieldKongRouteOnReferencedKongService,
ExtractValue: kongRouteRefersToKongService,
},
}
}

Expand All @@ -31,3 +38,21 @@ func kongRouteUsesPlugins(object client.Object) []string {
}
return annotations.ExtractPluginsWithNamespaces(route)
}

func kongRouteRefersToKongService(object client.Object) []string {
route, ok := object.(*configurationv1alpha1.KongRoute)
if !ok {
return nil
}
svcRef := route.Spec.ServiceRef
if svcRef == nil ||
svcRef.Type != configurationv1alpha1.ServiceRefNamespacedRef ||
svcRef.NamespacedRef == nil {
return nil
}

// NOTE: We currently do not allow cross namespace references between KongRoute and KongService.
// https://github.com/Kong/kubernetes-configuration/issues/106 tracks the implementation.

return []string{route.Namespace + "/" + svcRef.NamespacedRef.Name}
}
46 changes: 7 additions & 39 deletions controller/konnect/watch_kongpluginbinding.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,49 +194,17 @@ func enqueueKongPluginBindingForKonnectGatewayControlPlane(
return nil
}
var l configurationv1alpha1.KongPluginBindingList
if err := cl.List(ctx, &l, &client.ListOptions{
if err := cl.List(ctx, &l,
// TODO: change this when cross namespace refs are allowed.
Namespace: cp.GetNamespace(),
}); err != nil {
client.InNamespace(cp.GetNamespace()),
client.MatchingFields{
IndexFieldKongPluginBindingKonnectGatewayControlPlane: cp.Namespace + "/" + cp.Name,
},
); err != nil {
return nil
}

var ret []reconcile.Request
for _, pb := range l.Items {
if pb.Spec.ControlPlaneRef == nil {
continue
}
switch pb.Spec.ControlPlaneRef.Type {
case configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef:
// TODO: change this when cross namespace refs are allowed.
if pb.Spec.ControlPlaneRef.KonnectNamespacedRef.Name != cp.Name {
continue
}

ret = append(ret, reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: pb.Namespace,
Name: pb.Name,
},
})

case configurationv1alpha1.ControlPlaneRefKonnectID:
ctrllog.FromContext(ctx).Error(
fmt.Errorf("unimplemented ControlPlaneRef type %q", pb.Spec.ControlPlaneRef.Type),
"unimplemented ControlPlaneRef for KongPluginBinding",
"KongPluginBinding", pb, "refType", pb.Spec.ControlPlaneRef.Type,
)
continue

default:
ctrllog.FromContext(ctx).V(logging.DebugLevel.Value()).Info(
"unsupported ControlPlaneRef for KongPluginBinding",
"KongPluginBinding", pb, "refType", pb.Spec.ControlPlaneRef.Type,
)
continue
}
}
return ret
return objectListToReconcileRequests(l.Items)
}
}

Expand Down
48 changes: 8 additions & 40 deletions controller/konnect/watch_kongroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"

operatorerrors "github.com/kong/gateway-operator/internal/errors"
"github.com/kong/gateway-operator/modules/manager/logging"

configurationv1alpha1 "github.com/kong/kubernetes-configuration/api/configuration/v1alpha1"
)
Expand Down Expand Up @@ -98,52 +97,21 @@ func enqueueKongRouteForKongService(

// If the KongService does not refer to a KonnectGatewayControlPlane,
// we do not need to enqueue any KongRoutes bound to this KongService.
cpRef := kongSvc.Spec.ControlPlaneRef
if cpRef == nil || cpRef.Type != configurationv1alpha1.ControlPlaneRefKonnectNamespacedRef {
if !objHasControlPlaneRefKonnectNamespacedRef(kongSvc) {
return nil
}

var l configurationv1alpha1.KongRouteList
if err := cl.List(ctx, &l, &client.ListOptions{
if err := cl.List(ctx, &l,
// TODO: change this when cross namespace refs are allowed.
Namespace: kongSvc.GetNamespace(),
}); err != nil {
client.InNamespace(kongSvc.GetNamespace()),
client.MatchingFields{
IndexFieldKongRouteOnReferencedKongService: kongSvc.Namespace + "/" + kongSvc.Name,
},
); err != nil {
return nil
}

var ret []reconcile.Request
for _, route := range l.Items {
svcRef, ok := getServiceRef(&route).Get()
if !ok {
continue
}

switch svcRef.Type {
case configurationv1alpha1.ServiceRefNamespacedRef:
if svcRef.NamespacedRef == nil {
continue
}

// TODO: change this when cross namespace refs are allowed.
if svcRef.NamespacedRef.Name != kongSvc.GetName() {
continue
}

ret = append(ret, reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: route.Namespace,
Name: route.Name,
},
})

default:
ctrllog.FromContext(ctx).V(logging.DebugLevel.Value()).Info(
"unsupported ServiceRef for KongRoute",
"KongRoute", route, "refType", svcRef.Type,
)
continue
}
}
return ret
return objectListToReconcileRequests(l.Items)
}
}
Loading