From 3f533d83e51e975e723c06a14489e5dded11f2e3 Mon Sep 17 00:00:00 2001
From: Vlad Fratila <vlad.fratila@gmail.com>
Date: Thu, 24 Aug 2023 20:06:53 +0300
Subject: [PATCH] fix(app): use jsonpatch to check for changes in status field
 (#15126)

Signed-off-by: Vlad Fratila <vlad.fratila@gmail.com>
---
 controller/appcontroller.go |  5 +++--
 util/argo/diff/diff.go      | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/controller/appcontroller.go b/controller/appcontroller.go
index 9f3e32ba0b6e6..54f7deaf546ff 100644
--- a/controller/appcontroller.go
+++ b/controller/appcontroller.go
@@ -1620,9 +1620,10 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new
 		}
 		delete(newAnnotations, appv1.AnnotationKeyRefresh)
 	}
-	patch, modified, err := diff.CreateTwoWayMergePatch(
+
+	patch, modified, err := argodiff.jsonMergePatch(
 		&appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: orig.GetAnnotations()}, Status: orig.Status},
-		&appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus}, appv1.Application{})
+		&appv1.Application{ObjectMeta: metav1.ObjectMeta{Annotations: newAnnotations}, Status: *newStatus})
 	if err != nil {
 		logCtx.Errorf("Error constructing app status patch: %v", err)
 		return
diff --git a/util/argo/diff/diff.go b/util/argo/diff/diff.go
index 9b104719c5616..f480ec6082f1e 100644
--- a/util/argo/diff/diff.go
+++ b/util/argo/diff/diff.go
@@ -1,8 +1,10 @@
 package diff
 
 import (
+	"encoding/json"
 	"fmt"
 
+	jsonpatch "github.com/evanphx/json-patch"
 	"github.com/go-logr/logr"
 
 	k8smanagedfields "k8s.io/apimachinery/pkg/util/managedfields"
@@ -386,3 +388,18 @@ func safeDeepCopy(obj *unstructured.Unstructured) *unstructured.Unstructured {
 	}
 	return obj.DeepCopy()
 }
+
+// jsonMergePatch is a wrapper func to calculate the diff between two objects
+// instead of bytes.
+func jsonMergePatch(orig, new interface{}) ([]byte, bool, error) {
+	origBytes, err := json.Marshal(orig)
+	if err != nil {
+		return nil, false, err
+	}
+	newBytes, err := json.Marshal(new)
+	if err != nil {
+		return nil, false, err
+	}
+	patch, err := jsonpatch.CreateMergePatch(origBytes, newBytes)
+	return patch, string(patch) != "{}", err
+}