You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by as...@apache.org on 2019/11/28 07:41:11 UTC

[camel-k] 11/13: chore: Use reflection to compute positive JSON merge patch

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

astefanutti pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 6cf412a83e0c0cf525ea0a03229f5b7b884c37a1
Author: Antonin Stefanutti <an...@stefanutti.fr>
AuthorDate: Tue Nov 26 17:50:03 2019 +0100

    chore: Use reflection to compute positive JSON merge patch
---
 pkg/trait/deployer.go | 43 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index 1a9550f..56b0322 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -18,10 +18,12 @@ limitations under the License.
 package trait
 
 import (
-	jsonpatch "github.com/evanphx/json-patch"
+	"reflect"
 
 	"github.com/pkg/errors"
 
+	jsonpatch "github.com/evanphx/json-patch"
+
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/json"
@@ -119,24 +121,47 @@ func (s *mergeFromPositivePatch) Data(obj runtime.Object) ([]byte, error) {
 		return nil, err
 	}
 
-	patch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
+	mergePatch, err := jsonpatch.CreateMergePatch(originalJSON, modifiedJSON)
 	if err != nil {
 		return nil, err
 	}
 
-	// The following is a work-around to remove null fields from the JSON merge patch
-	// so that values defaulted by controllers server-side are not deleted.
-	// It's generally acceptable as these values are orthogonal to the values managed
-	// by the traits.
-	out := obj.DeepCopyObject()
-	err = json.Unmarshal(patch, out)
+	var positivePatch map[string]interface{}
+	err = json.Unmarshal(mergePatch, &positivePatch)
 	if err != nil {
 		return nil, err
 	}
 
-	return json.Marshal(out)
+	// The following is a work-around to remove null fields from the JSON merge patch,
+	// so that values defaulted by controllers server-side are not deleted.
+	// It's generally acceptable as these values are orthogonal to the values managed
+	// by the traits.
+	removeNilValues(reflect.ValueOf(positivePatch))
+
+	return json.Marshal(positivePatch)
 }
 
 func mergeFrom(obj runtime.Object) client.Patch {
 	return &mergeFromPositivePatch{obj}
 }
+
+func removeNilValues(v reflect.Value) {
+	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
+		v = v.Elem()
+	}
+	switch v.Kind() {
+	case reflect.Array, reflect.Slice:
+		for i := 0; i < v.Len(); i++ {
+			removeNilValues(v.Index(i))
+		}
+	case reflect.Map:
+		for _, k := range v.MapKeys() {
+			c := v.MapIndex(k)
+			if c.IsNil() {
+				v.SetMapIndex(k, reflect.Value{})
+			} else {
+				removeNilValues(c)
+			}
+		}
+	}
+}