Skip to content

Commit cc225cf

Browse files
committed
debug: chain predicates to filter service updates
1 parent 451fd56 commit cc225cf

File tree

2 files changed

+104
-38
lines changed

2 files changed

+104
-38
lines changed

internal/provider/kubernetes/controller.go

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package kubernetes
88
import (
99
"context"
1010
"fmt"
11+
"strings"
1112
"time"
1213

1314
appsv1 "k8s.io/api/apps/v1"
@@ -24,7 +25,8 @@ import (
2425
"k8s.io/utils/ptr"
2526
"sigs.k8s.io/controller-runtime/pkg/client"
2627
"sigs.k8s.io/controller-runtime/pkg/controller"
27-
// "sigs.k8s.io/controller-runtime/pkg/event"
28+
29+
"sigs.k8s.io/controller-runtime/pkg/event"
2830
"sigs.k8s.io/controller-runtime/pkg/handler"
2931
"sigs.k8s.io/controller-runtime/pkg/manager"
3032
"sigs.k8s.io/controller-runtime/pkg/predicate"
@@ -1354,32 +1356,49 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
13541356
}
13551357

13561358
// // create service predicate with additonal logic for update events
1357-
// servicePredicateFuncs := func (filter func(*corev1.Service) bool) predicate.TypedFuncs[*corev1.Service] {
1358-
// return TypedFuncs[*corev1.Service]{
1359-
// CreateFunc: func(e event.TypedCreateEvent[*corev1.Service]) bool {
1360-
// return filter(e.Object)
1361-
// },
1362-
// UpdateFunc: func(e event.TypedUpdateEvent[*corev1.Service]) bool {
1363-
// return filter(e.ObjectNew)
1364-
// },
1365-
// DeleteFunc: func(e event.TypedDeleteEvent[*corev1.Service]) bool {
1366-
// return filter(e.Object)
1367-
// },
1368-
// GenericFunc: func(e event.TypedGenericEvent[*corev1.Service]) bool {
1369-
// return filter(e.Object)
1370-
// },
1371-
// }
1372-
// }
1373-
1359+
servicePredicateFuncs := predicate.TypedFuncs[*corev1.Service]{
1360+
CreateFunc: func(e event.TypedCreateEvent[*corev1.Service]) bool {
1361+
return true
1362+
},
1363+
UpdateFunc: func(e event.TypedUpdateEvent[*corev1.Service]) bool {
1364+
retVal := r.validateServiceUpdateForReconcile(e.ObjectOld, e.ObjectNew)
1365+
if strings.HasPrefix(e.ObjectOld.Name, "brendan") {
1366+
r.log.Info(fmt.Sprintf("predicate -- validateServiceUpdateForReconcile=%v",retVal), "name", e.ObjectOld.Name)
1367+
}
1368+
return retVal
1369+
1370+
},
1371+
DeleteFunc: func(e event.TypedDeleteEvent[*corev1.Service]) bool {
1372+
return true
1373+
},
1374+
GenericFunc: func(e event.TypedGenericEvent[*corev1.Service]) bool {
1375+
return true
1376+
},
1377+
}
1378+
13741379

13751380
// Watch Service CRUDs and process affected *Route objects.
1376-
servicePredicates := []predicate.TypedPredicate[*corev1.Service]{
1381+
servicePredicates := []predicate.TypedPredicate[*corev1.Service]{predicate.And[*corev1.Service](
1382+
servicePredicateFuncs,
13771383
predicate.NewTypedPredicateFuncs[*corev1.Service](func(svc *corev1.Service) bool {
1378-
retVal := r.validateServiceForReconcile(svc)
1379-
r.log.Info(fmt.Sprintf("predicate -- validateServiceForReconcile=%v",retVal), "namespace", svc.Namespace, "name", svc.Name)
1380-
return retVal
1384+
validateService := r.validateServiceForReconcile(svc)
1385+
if strings.HasPrefix(svc.Namespace, "dev-blue-cloud-teleportinfra-dev") {
1386+
r.log.Info(fmt.Sprintf("predicate -- validateServiceForReconcile=%v",validateService), "namespace", svc.Namespace, "name", svc.Name)
1387+
}
1388+
return validateService
13811389
}),
1382-
}
1390+
),}
1391+
1392+
1393+
// servicePredicates := []predicate.TypedPredicate[*corev1.Service]{
1394+
// predicate.NewTypedPredicateFuncs[*corev1.Service](func(svc *corev1.Service) bool {
1395+
// retVal := r.validateServiceForReconcile(svc)
1396+
// if strings.HasPrefix(svc.Namespace, "dev-blue-cloud-teleportinfra-dev") {
1397+
// r.log.Info(fmt.Sprintf("predicate -- validateServiceForReconcile=%v",retVal), "namespace", svc.Namespace, "name", svc.Name)
1398+
// }
1399+
// return retVal
1400+
// }),
1401+
// }
13831402

13841403
if r.namespaceLabel != nil {
13851404
servicePredicates = append(servicePredicates, predicate.NewTypedPredicateFuncs[*corev1.Service](func(svc *corev1.Service) bool {

internal/provider/kubernetes/predicates.go

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -280,32 +280,78 @@ func (r *gatewayAPIReconciler) isOIDCHMACSecret(nsName *types.NamespacedName) bo
280280
return *nsName == oidcHMACSecret
281281
}
282282

283-
// validateServiceForReconcile tries finding the owning Gateway of the Service
284-
// if it exists, finds the Gateway's Deployment, and further updates the Gateway
285-
// status Ready condition. All Services are pushed for reconciliation.
286-
func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bool {
283+
// isServiceOwnedByGateway returns true if the Service belongs to a Gateway.
284+
func (r *gatewayAPIReconciler) isServiceOwnedByGateway(svc *corev1.Service, updateStatus bool) bool {
287285
ctx := context.Background()
288-
svc, ok := obj.(*corev1.Service)
289-
if !ok {
290-
r.log.Info("unexpected object type, bypassing reconciliation", "object", obj)
291-
return false
292-
}
293286
labels := svc.GetLabels()
294287

295288
// Check if the Service belongs to a Gateway, if so, update the Gateway status.
296-
gtw := r.findOwningGateway(ctx, labels)
289+
gtw := r.findOwningGateway(context.Background(), labels)
297290
if gtw != nil {
298-
r.updateGatewayStatus(gtw)
299-
return false
291+
if updateStatus {
292+
r.updateGatewayStatus(gtw)
293+
}
294+
return true
300295
}
301296

302297
// Merged gateways will have only this label, update status of all Gateways under found GatewayClass.
303298
gcName, ok := labels[gatewayapi.OwningGatewayClassLabel]
304299
if ok && r.mergeGateways.Has(gcName) {
305-
if err := r.updateStatusForGatewaysUnderGatewayClass(ctx, gcName); err != nil {
306-
r.log.Info("no Gateways found under GatewayClass", "name", gcName)
307-
return false
300+
if updateStatus {
301+
if err := r.updateStatusForGatewaysUnderGatewayClass(ctx, gcName); err != nil {
302+
r.log.Info("no Gateways found under GatewayClass", "name", gcName)
303+
return true
304+
}
308305
}
306+
return true
307+
}
308+
309+
return false
310+
}
311+
312+
// validateServiceUpdateForReconcile checks whether a Service update should trigger a reconcile.
313+
// Returns false when the backend does not have endpoint routing and the service of type clusterIP
314+
// does not have a new IP address.
315+
func (r *gatewayAPIReconciler) validateServiceUpdateForReconcile(oldObj client.Object, newObj client.Object) bool {
316+
oldSvc, ok := oldObj.(*corev1.Service)
317+
if !ok {
318+
r.log.Info("unexpected object type, bypassing reconciliation", "object", oldObj)
319+
return true
320+
}
321+
newSvc, ok := newObj.(*corev1.Service)
322+
if !ok {
323+
r.log.Info("unexpected object type, bypassing reconciliation", "object", newObj)
324+
return true
325+
}
326+
327+
if r.isServiceOwnedByGateway(newSvc, false) {
328+
return true
329+
}
330+
331+
if (newSvc.Spec.Type != corev1.ServiceTypeClusterIP) || (oldSvc.Spec.Type != corev1.ServiceTypeClusterIP) || (newSvc.Spec.ClusterIP != oldSvc.Spec.ClusterIP) {
332+
return true
333+
}
334+
335+
nsName := utils.NamespacedName(newSvc)
336+
if !r.hasRouteWithEndpointRouting(&nsName) {
337+
r.log.Info("validateServiceUpdateForReconcile -- Service is not referenced by backend with endpoint routing", "service", nsName)
338+
return false
339+
}
340+
341+
return true
342+
}
343+
344+
// validateServiceForReconcile tries finding the owning Gateway of the Service
345+
// if it exists, finds the Gateway's Deployment, and further updates the Gateway
346+
// status Ready condition. All Services are pushed for reconciliation.
347+
func (r *gatewayAPIReconciler) validateServiceForReconcile(obj client.Object) bool {
348+
svc, ok := obj.(*corev1.Service)
349+
if !ok {
350+
r.log.Info("unexpected object type, bypassing reconciliation", "object", obj)
351+
return false
352+
}
353+
354+
if r.isServiceOwnedByGateway(svc, true) {
309355
return false
310356
}
311357

@@ -437,6 +483,7 @@ func (r *gatewayAPIReconciler) isRouteReferencingBackend(nsName *types.Namespace
437483
if len(tlsRouteList.Items) > 0 {
438484
// we don't know the old value of the service clusterIP here, so we can't avoid reconciling on service change.
439485
return true
486+
440487
}
441488
}
442489

0 commit comments

Comments
 (0)