You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2021/01/22 17:15:27 UTC

[camel-k] branch release-1.3.x updated: Fix #1936: avoid patching if the target resource contains all expected fields

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

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


The following commit(s) were added to refs/heads/release-1.3.x by this push:
     new 0148fea  Fix #1936: avoid patching if the target resource contains all expected fields
0148fea is described below

commit 0148fea36b93d84125e5a7c3098036bb1dde79b4
Author: nicolaferraro <ni...@gmail.com>
AuthorDate: Fri Jan 22 13:28:23 2021 +0100

    Fix #1936: avoid patching if the target resource contains all expected fields
---
 pkg/trait/builder.go     |  2 ++
 pkg/trait/deployer.go    | 28 ++++++++++++++++------------
 pkg/trait/trait_types.go |  5 +++++
 pkg/util/patch/patch.go  | 20 ++++++++++++++++++++
 4 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go
index bdf9d42..3fa45d7 100644
--- a/pkg/trait/builder.go
+++ b/pkg/trait/builder.go
@@ -485,6 +485,7 @@ func mountRegistrySecret(name string, secret registrySecret, volumes *[]corev1.V
 	*volumeMounts = append(*volumeMounts, corev1.VolumeMount{
 		Name:      "registry-secret",
 		MountPath: secret.mountPath,
+		ReadOnly:  true,
 	})
 
 	if secret.refEnv != "" {
@@ -530,6 +531,7 @@ func mountRegistryConfigMap(name string, config registryConfigMap, volumes *[]co
 	*volumeMounts = append(*volumeMounts, corev1.VolumeMount{
 		Name:      "registry-config",
 		MountPath: config.mountPath,
+		ReadOnly:  true,
 	})
 }
 
diff --git a/pkg/trait/deployer.go b/pkg/trait/deployer.go
index b3cf394..81aaee8 100644
--- a/pkg/trait/deployer.go
+++ b/pkg/trait/deployer.go
@@ -19,7 +19,6 @@ package trait
 
 import (
 	"github.com/pkg/errors"
-
 	"k8s.io/apimachinery/pkg/types"
 
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -95,17 +94,22 @@ func (t *deployerTrait) Apply(e *Environment) error {
 					return err
 				}
 
-				p, err := patch.PositiveMergePatch(object, resource)
-				if err != nil {
-					return err
-				} else if len(p) == 0 {
-					// Avoid triggering a patch request for nothing
-					continue
-				}
-
-				err = env.Client.Patch(env.C, resource, client.RawPatch(types.MergePatchType, p))
-				if err != nil {
-					return errors.Wrap(err, "error during patch resource")
+				if !patch.SpecEqualDeepDerivative(object, resource) {
+					// If both objects have a "Spec" field and it contains all expected fields
+					// (plus optional others), then avoid patching
+
+					p, err := patch.PositiveMergePatch(object, resource)
+					if err != nil {
+						return err
+					} else if len(p) == 0 {
+						// Avoid triggering a patch request for nothing
+						continue
+					}
+
+					err = env.Client.Patch(env.C, resource, client.RawPatch(types.MergePatchType, p))
+					if err != nil {
+						return errors.Wrap(err, "error during patch resource")
+					}
 				}
 			}
 			return nil
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 8343fb9..f28fc8f 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -559,6 +559,7 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 		*mnts = append(*mnts, corev1.VolumeMount{
 			Name:      refName,
 			MountPath: resPath,
+			ReadOnly:  true,
 		})
 	}
 
@@ -603,6 +604,7 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 		*mnts = append(*mnts, corev1.VolumeMount{
 			Name:      refName,
 			MountPath: resPath,
+			ReadOnly:  true,
 		})
 	}
 
@@ -639,6 +641,7 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 				*mnts = append(*mnts, corev1.VolumeMount{
 					Name:      propertiesType + "-properties",
 					MountPath: mountPath,
+					ReadOnly:  true,
 				})
 			}
 		})
@@ -665,6 +668,7 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 		*mnts = append(*mnts, corev1.VolumeMount{
 			Name:      refName,
 			MountPath: path.Join(ConfigMapsMountPath, strings.ToLower(cmName)),
+			ReadOnly:  true,
 		})
 	}
 
@@ -687,6 +691,7 @@ func (e *Environment) ConfigureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c
 		*mnts = append(*mnts, corev1.VolumeMount{
 			Name:      refName,
 			MountPath: path.Join(SecretsMountPath, strings.ToLower(secretName)),
+			ReadOnly:  true,
 		})
 	}
 
diff --git a/pkg/util/patch/patch.go b/pkg/util/patch/patch.go
index e0ae632..67c2813 100644
--- a/pkg/util/patch/patch.go
+++ b/pkg/util/patch/patch.go
@@ -21,6 +21,7 @@ import (
 	"reflect"
 
 	jsonpatch "github.com/evanphx/json-patch"
+	"k8s.io/apimachinery/pkg/api/equality"
 
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/json"
@@ -89,3 +90,22 @@ func removeNilValues(v reflect.Value, parent reflect.Value) {
 		}
 	}
 }
+
+func SpecEqualDeepDerivative(object runtime.Object, expected runtime.Object) (res bool) {
+	defer func() {
+		if r := recover(); r != nil {
+			res = false
+		}
+	}()
+
+	if expected == nil {
+		return true
+	} else if object == nil {
+		return false
+	}
+
+	objectSpec := reflect.ValueOf(object).Elem().FieldByName("Spec").Interface()
+	expectedSpec := reflect.ValueOf(expected).Elem().FieldByName("Spec").Interface()
+
+	return equality.Semantic.DeepDerivative(expectedSpec, objectSpec)
+}