diff --git a/lib/resourceapply/apps.go b/lib/resourceapply/apps.go index 32fcd26eb..0a2ca3113 100644 --- a/lib/resourceapply/apps.go +++ b/lib/resourceapply/apps.go @@ -29,13 +29,19 @@ func ApplyDeploymentv1(ctx context.Context, client appsclientv1.DeploymentsGette return nil, false, nil } + var original appsv1.Deployment + existing.DeepCopyInto(&original) modified := pointer.BoolPtr(false) resourcemerge.EnsureDeployment(modified, existing, *required) if !*modified { return existing, false, nil } if reconciling { - klog.V(2).Infof("Updating Deployment %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required)) + if diff := cmp.Diff(&original, existing); diff != "" { + klog.V(2).Infof("Updating Deployment %s/%s due to diff: %v", required.Namespace, required.Name, diff) + } else { + klog.V(2).Infof("Updating Deployment %s/%s with empty diff: possible hotloop after wrong comparison", required.Namespace, required.Name) + } } actual, err := client.Deployments(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{}) diff --git a/lib/resourcemerge/core.go b/lib/resourcemerge/core.go index bd24ee462..b6f4df761 100644 --- a/lib/resourcemerge/core.go +++ b/lib/resourcemerge/core.go @@ -554,7 +554,7 @@ func ensureSeccompProfilePtr(modified *bool, existing **corev1.SeccompProfile, r } func ensureSeccompProfile(modified *bool, existing *corev1.SeccompProfile, required corev1.SeccompProfile) { - if equality.Semantic.DeepEqual(existing, required) { + if equality.Semantic.DeepEqual(*existing, required) { return } @@ -646,13 +646,13 @@ func ensureAffinity(modified *bool, existing *corev1.Affinity, required corev1.A } func ensurePodSecurityContextPtr(modified *bool, existing **corev1.PodSecurityContext, required *corev1.PodSecurityContext) { - if *existing == nil && required == nil { + if (*existing == nil || equality.Semantic.DeepEqual(*existing, &corev1.PodSecurityContext{})) && required == nil { return } // Check if we can simply set to required. This can be done if existing is not set or it is set // but required is not set. - if *existing == nil || (required == nil && *existing != nil) { + if *existing == nil || required == nil { *modified = true *existing = required return diff --git a/lib/resourcemerge/core_test.go b/lib/resourcemerge/core_test.go index 641ef144e..4ca897854 100644 --- a/lib/resourcemerge/core_test.go +++ b/lib/resourcemerge/core_test.go @@ -61,6 +61,37 @@ func TestEnsurePodSpec(t *testing.T) { expected: corev1.PodSpec{ SecurityContext: &corev1.PodSecurityContext{}}, }, + { + name: "Existing PodSecurityContext empty, desired nil => do not modify", + existing: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{}}, + input: corev1.PodSpec{SecurityContext: nil}, + expectedModified: false, + expected: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{}}, + }, + { + name: "PodSecurityContext no changes", + existing: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{RunAsNonRoot: boolPtr(true), + RunAsUser: int64Ptr(int64(1234)), + RunAsGroup: int64Ptr(int64(4321)), + SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}}, + }, + input: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{RunAsNonRoot: boolPtr(true), + RunAsUser: int64Ptr(int64(1234)), + RunAsGroup: int64Ptr(int64(4321)), + SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}}, + }, + expectedModified: false, + expected: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{RunAsNonRoot: boolPtr(true), + RunAsUser: int64Ptr(int64(1234)), + RunAsGroup: int64Ptr(int64(4321)), + SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault}}, + }, + }, { name: "PodSecurityContext changes", existing: corev1.PodSpec{