'Kubebuilder predicates to skip certain namespaces

I'm using the kubebuilder framework in my controller and I want to completely ignore events from a list of given system namespaces. I think predicates must be the best option for this, hence I have the following code

...

WithEventFilter(predicate.Funcs{
            GenericFunc: func(e event.GenericEvent) bool {
                namespace := e.Object.GetNamespace()
                if _, ok := systemNs[namespace]; ok {
                    // ignore events from system namespaces
                    return false
                }

                return true
            },
}).

However I still receive events from all namespaces instead of just the ones which I allow. Is this a correct and valid use case of predicates?



Solution 1:[1]

According to controller-runtime

Generic is called in response to an event of an unknown type or a synthetic event triggered as a cron or external trigger request - e.g. reconcile Autoscaling, or a Webhook.

Most of the time reconciliation gets triggered on Create, Update, or Delete so you need to filter on these events.

WithEventFilter(predicate.Funcs{
    CreateFunc: func(e event.CreateEvent) bool {
        namespace := e.Object.GetNamespace()
        if _, ok := systemNs[namespace]; ok {
            // ignore events from system namespaces
            return false
        }
        return true
    },
    UpdateFunc: func(e event.UpdateEvent) bool {
        namespace := e.ObjectNew.GetNamespace()
        if _, ok := systemNs[namespace]; ok {
            // ignore events from system namespaces
            return false
        }
        return true
    },
    DeleteFunc: func(e event.DeleteEvent) bool {
        namespace := e.Object.GetNamespace()
        if _, ok := systemNs[namespace]; ok {
            // ignore events from system namespaces
            return false
        }
        return true
    },
}).

Solution 2:[2]

NewPredicateFuncs apply the filter on all events:

WithEventFilter(predicate.NewPredicateFuncs(func(obj client.Object) bool {
    _, ok := systemNs[obj.GetNamespace()]
    return !ok
})).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Galletti_Lance
Solution 2 Viet Nguyen