You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2022/06/29 07:50:07 UTC

[camel-k] 05/06: fix: Use status change predicate to filter updates on owned resources

This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch release-1.9.x
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 22f4fed6a29ab14be84b59c5d1698aecef1dafd3
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Wed May 18 09:15:20 2022 +0200

    fix: Use status change predicate to filter updates on owned resources
    
    (cherry picked from commit 85483d4054457dad390b691c95a78cd2087a728b)
---
 .../integration/integration_controller.go          |  7 ++-
 pkg/controller/integration/predicate.go            | 57 ++++++++++++++++++++++
 2 files changed, 60 insertions(+), 4 deletions(-)

diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go
index acd9bfa55..964adb18f 100644
--- a/pkg/controller/integration/integration_controller.go
+++ b/pkg/controller/integration/integration_controller.go
@@ -31,7 +31,6 @@ import (
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/client-go/tools/record"
-
 	"sigs.k8s.io/controller-runtime/pkg/builder"
 	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/event"
@@ -203,9 +202,9 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error {
 				return requests
 			})).
 		// Watch for the owned Deployments
-		Owns(&appsv1.Deployment{}).
+		Owns(&appsv1.Deployment{}, builder.WithPredicates(StatusChangedPredicate{})).
 		// Watch for the owned CronJobs
-		Owns(&batchv1beta1.CronJob{}).
+		Owns(&batchv1beta1.CronJob{}, builder.WithPredicates(StatusChangedPredicate{})).
 		// Watch for the Integration Pods
 		Watches(&source.Kind{Type: &corev1.Pod{}},
 			handler.EnqueueRequestsFromMapFunc(func(a ctrl.Object) []reconcile.Request {
@@ -234,7 +233,7 @@ func add(mgr manager.Manager, c client.Client, r reconcile.Reconciler) error {
 		if ok, err = kubernetes.CheckPermission(ctx, c, serving.GroupName, "services", platform.GetOperatorWatchNamespace(), "", "watch"); err != nil {
 			return err
 		} else if ok {
-			b.Owns(&servingv1.Service{})
+			b.Owns(&servingv1.Service{}, builder.WithPredicates(StatusChangedPredicate{}))
 		}
 	}
 
diff --git a/pkg/controller/integration/predicate.go b/pkg/controller/integration/predicate.go
new file mode 100644
index 000000000..79d61556a
--- /dev/null
+++ b/pkg/controller/integration/predicate.go
@@ -0,0 +1,57 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package integration
+
+import (
+	"reflect"
+
+	"k8s.io/apimachinery/pkg/api/equality"
+	"sigs.k8s.io/controller-runtime/pkg/event"
+	"sigs.k8s.io/controller-runtime/pkg/predicate"
+)
+
+// StatusChangedPredicate implements a generic update predicate function on status change.
+type StatusChangedPredicate struct {
+	predicate.Funcs
+}
+
+// Update implements default UpdateEvent filter for validating status change.
+func (StatusChangedPredicate) Update(e event.UpdateEvent) bool {
+	if e.ObjectOld == nil {
+		Log.Error(nil, "Update event has no old object to update", "event", e)
+		return false
+	}
+	if e.ObjectNew == nil {
+		Log.Error(nil, "Update event has no new object to update", "event", e)
+		return false
+	}
+
+	s1 := reflect.ValueOf(e.ObjectOld).Elem().FieldByName("Status")
+	if !s1.IsValid() {
+		Log.Error(nil, "Update event old object has no Status field", "event", e)
+		return false
+	}
+
+	s2 := reflect.ValueOf(e.ObjectNew).Elem().FieldByName("Status")
+	if !s2.IsValid() {
+		Log.Error(nil, "Update event new object has no Status field", "event", e)
+		return false
+	}
+
+	return !equality.Semantic.DeepDerivative(s1.Interface(), s2.Interface())
+}