diff --git a/controllers/policy_status_event_handler.go b/controllers/policy_status_event_handler.go deleted file mode 100644 index e7bbaf6bc..000000000 --- a/controllers/policy_status_event_handler.go +++ /dev/null @@ -1,96 +0,0 @@ -package controllers - -import ( - "context" - "reflect" - - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" -) - -// PolicyStatusEventHandlerFromMapFunc returns a PolicyStatusEventHandler that handles events from a mapping function. -func PolicyStatusEventHandlerFromMapFunc(mapFunc handler.MapFunc) handler.EventHandler { - return NewPolicyStatusEventHandler(WithHandler(handler.EnqueueRequestsFromMapFunc(mapFunc))) -} - -// NewPolicyStatusEventHandler returns a new PolicyStatusEventHandler. -func NewPolicyStatusEventHandler(opts ...PolicyStatusEventHandlerOption) handler.EventHandler { - h := &PolicyStatusEventHandler{} - for _, opt := range opts { - opt(h) - } - return h -} - -type PolicyStatusEventHandlerOption func(*PolicyStatusEventHandler) - -func WithHandler(h handler.EventHandler) PolicyStatusEventHandlerOption { - return func(p *PolicyStatusEventHandler) { - p.handler = h - } -} - -var _ handler.EventHandler = &PolicyStatusEventHandler{} - -// PolicyStatusEventHandler enqueues reconcile.Requests in response to events for Policy objects -// whose status blocks have changed. -// The handling of the events is delegated to the provided handler. -type PolicyStatusEventHandler struct { - handler handler.EventHandler -} - -// Create implements EventHandler. -func (h *PolicyStatusEventHandler) Create(ctx context.Context, evt event.CreateEvent, q workqueue.RateLimitingInterface) { - if h.handler == nil { - return - } - h.handler.Create(ctx, evt, q) -} - -// Update implements EventHandler. -func (h *PolicyStatusEventHandler) Update(ctx context.Context, evt event.UpdateEvent, q workqueue.RateLimitingInterface) { - if h.handler == nil { - return - } - oldPolicy, ok := evt.ObjectOld.(kuadrantgatewayapi.Policy) - if !ok { - return - } - newPolicy, ok := evt.ObjectNew.(kuadrantgatewayapi.Policy) - if !ok { - return - } - if statusChanged(oldPolicy, newPolicy) { - h.handler.Update(ctx, evt, q) - } -} - -// Delete implements EventHandler. -func (h *PolicyStatusEventHandler) Delete(ctx context.Context, evt event.DeleteEvent, q workqueue.RateLimitingInterface) { - if h.handler == nil { - return - } - h.handler.Delete(ctx, evt, q) -} - -// Generic implements EventHandler. -func (h *PolicyStatusEventHandler) Generic(ctx context.Context, evt event.GenericEvent, q workqueue.RateLimitingInterface) { - if h.handler == nil { - return - } - h.handler.Generic(ctx, evt, q) -} - -func statusChanged(old, new kuadrantgatewayapi.Policy) bool { - if old == nil || new == nil { - return false - } - - oldStatus := old.GetStatus() - newStatus := new.GetStatus() - - return !reflect.DeepEqual(oldStatus, newStatus) -} diff --git a/controllers/policy_status_event_handler_test.go b/controllers/policy_status_event_handler_test.go deleted file mode 100644 index 65a2838cd..000000000 --- a/controllers/policy_status_event_handler_test.go +++ /dev/null @@ -1,205 +0,0 @@ -//go:build unit - -package controllers - -import ( - "context" - "testing" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/util/workqueue" - "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" - gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - kuadrantgatewayapi "github.com/kuadrant/kuadrant-operator/pkg/library/gatewayapi" -) - -var _ handler.EventHandler = &testEventHandler{} - -type testEventHandler struct { - lastEventFunc string -} - -func (h *testEventHandler) Create(_ context.Context, _ event.CreateEvent, _ workqueue.RateLimitingInterface) { - h.lastEventFunc = "Create" -} -func (h *testEventHandler) Update(_ context.Context, _ event.UpdateEvent, _ workqueue.RateLimitingInterface) { - h.lastEventFunc = "Update" -} -func (h *testEventHandler) Delete(_ context.Context, _ event.DeleteEvent, _ workqueue.RateLimitingInterface) { - h.lastEventFunc = "Delete" -} -func (h *testEventHandler) Generic(_ context.Context, _ event.GenericEvent, _ workqueue.RateLimitingInterface) { - h.lastEventFunc = "Generic" -} - -// Test policy that implements kuadrantgatewayapi.Policy - -var ( - _ kuadrantgatewayapi.Policy = &TestPolicy{} - _ kuadrantgatewayapi.PolicyStatus = &FakePolicyStatus{} -) - -type TestPolicy struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - TargetRef gatewayapiv1alpha2.PolicyTargetReference `json:"targetRef"` - Status FakePolicyStatus `json:"status,omitempty"` -} - -func (p *TestPolicy) PolicyClass() kuadrantgatewayapi.PolicyClass { - return kuadrantgatewayapi.DirectPolicy -} - -func (p *TestPolicy) GetTargetRef() gatewayapiv1alpha2.PolicyTargetReference { - return p.TargetRef -} - -func (p *TestPolicy) GetStatus() kuadrantgatewayapi.PolicyStatus { - return &p.Status -} - -func (p *TestPolicy) DeepCopyObject() runtime.Object { - if c := p.DeepCopy(); c != nil { - return c - } - return nil -} - -func (p *TestPolicy) DeepCopy() *TestPolicy { - if p == nil { - return nil - } - out := new(TestPolicy) - p.DeepCopyInto(out) - return out -} - -func (p *TestPolicy) DeepCopyInto(out *TestPolicy) { - *out = *p - out.TypeMeta = p.TypeMeta - p.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - p.TargetRef.DeepCopyInto(&out.TargetRef) - out.Status = p.Status -} - -type FakePolicyStatus struct { - Conditions []metav1.Condition -} - -func (s *FakePolicyStatus) GetConditions() []metav1.Condition { - return s.Conditions -} - -func TestPolicyStatusEventHandler(t *testing.T) { - tests := []struct { - name string - lastEventFunc func() string - expected string - }{ - { - name: "Create event", - lastEventFunc: func() string { - testHandler := &testEventHandler{} - h := NewPolicyStatusEventHandler(WithHandler(testHandler)) - h.Create(context.Background(), event.CreateEvent{}, nil) - return testHandler.lastEventFunc - }, - expected: "Create", - }, - { - name: "Update event with different status", - lastEventFunc: func() string { - testHandler := &testEventHandler{} - h := NewPolicyStatusEventHandler(WithHandler(testHandler)) - ev := event.UpdateEvent{ - ObjectOld: &TestPolicy{ - Status: FakePolicyStatus{ - Conditions: []metav1.Condition{}, - }, - }, - ObjectNew: &TestPolicy{ - Status: FakePolicyStatus{ - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - Reason: "ValidPolicy", - }, - }, - }, - }, - } - h.Update(context.Background(), ev, nil) - return testHandler.lastEventFunc - }, - expected: "Update", - }, - { - name: "Update event without different status", - lastEventFunc: func() string { - testHandler := &testEventHandler{} - h := NewPolicyStatusEventHandler(WithHandler(testHandler)) - ev := event.UpdateEvent{ - ObjectOld: &TestPolicy{ - Status: FakePolicyStatus{ - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - Reason: "ValidPolicy", - }, - }, - }, - }, - ObjectNew: &TestPolicy{ - Status: FakePolicyStatus{ - Conditions: []metav1.Condition{ - { - Type: "Accepted", - Status: metav1.ConditionTrue, - Reason: "ValidPolicy", - }, - }, - }, - }, - } - h.Update(context.Background(), ev, nil) - return testHandler.lastEventFunc - }, - expected: "", - }, - { - name: "Delete event", - lastEventFunc: func() string { - testHandler := &testEventHandler{} - h := NewPolicyStatusEventHandler(WithHandler(testHandler)) - h.Delete(context.Background(), event.DeleteEvent{}, nil) - return testHandler.lastEventFunc - }, - expected: "Delete", - }, - { - name: "Generic event", - lastEventFunc: func() string { - testHandler := &testEventHandler{} - h := NewPolicyStatusEventHandler(WithHandler(testHandler)) - h.Generic(context.Background(), event.GenericEvent{}, nil) - return testHandler.lastEventFunc - }, - expected: "Generic", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := tt.lastEventFunc() - if got != tt.expected { - t.Errorf("%s failed. Expected %s, got %s", tt.name, tt.expected, got) - } - }) - } -} diff --git a/controllers/target_status_controller.go b/controllers/target_status_controller.go index f7a4a7965..d7cafd6b0 100644 --- a/controllers/target_status_controller.go +++ b/controllers/target_status_controller.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "reflect" "github.com/go-logr/logr" "github.com/google/uuid" @@ -28,8 +29,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "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/predicate" gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -319,6 +323,22 @@ func (r *TargetStatusReconciler) SetupWithManager(mgr ctrl.Manager) error { mappers.WithClient(r.Client()), ) + policyStatusChangedPredicate := predicate.Funcs{ + UpdateFunc: func(ev event.UpdateEvent) bool { + oldPolicy, ok := ev.ObjectOld.(kuadrantgatewayapi.Policy) + if !ok { + return false + } + newPolicy, ok := ev.ObjectNew.(kuadrantgatewayapi.Policy) + if !ok { + return false + } + oldStatus := oldPolicy.GetStatus() + newStatus := newPolicy.GetStatus() + return !reflect.DeepEqual(oldStatus, newStatus) + }, + } + return ctrl.NewControllerManagedBy(mgr). For(&gatewayapiv1.Gateway{}). Watches( @@ -327,19 +347,23 @@ func (r *TargetStatusReconciler) SetupWithManager(mgr ctrl.Manager) error { ). Watches( &kuadrantv1beta2.AuthPolicy{}, - PolicyStatusEventHandlerFromMapFunc(policyToParentGatewaysEventMapper.Map), + handler.EnqueueRequestsFromMapFunc(policyToParentGatewaysEventMapper.Map), + builder.WithPredicates(policyStatusChangedPredicate), ). Watches( &kuadrantv1alpha1.DNSPolicy{}, - PolicyStatusEventHandlerFromMapFunc(policyToParentGatewaysEventMapper.Map), + handler.EnqueueRequestsFromMapFunc(policyToParentGatewaysEventMapper.Map), + builder.WithPredicates(policyStatusChangedPredicate), ). Watches( &kuadrantv1beta2.RateLimitPolicy{}, - PolicyStatusEventHandlerFromMapFunc(policyToParentGatewaysEventMapper.Map), + handler.EnqueueRequestsFromMapFunc(policyToParentGatewaysEventMapper.Map), + builder.WithPredicates(policyStatusChangedPredicate), ). Watches( &kuadrantv1alpha1.TLSPolicy{}, - PolicyStatusEventHandlerFromMapFunc(policyToParentGatewaysEventMapper.Map), + handler.EnqueueRequestsFromMapFunc(policyToParentGatewaysEventMapper.Map), + builder.WithPredicates(policyStatusChangedPredicate), ). Complete(r) }