From f5b27e9e8071476291d6e695467c5b9ae1d41032 Mon Sep 17 00:00:00 2001 From: Gavin Bunney <409207+gavinbunney@users.noreply.github.com> Date: Sat, 9 Oct 2021 23:11:15 -0700 Subject: [PATCH] Fix issues with empty planned attribute keys --- flatten/flatten.go | 4 ++++ kubernetes/resource_kubectl_manifest.go | 13 ++++++++----- kubernetes/resource_kubectl_manifest_test.go | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/flatten/flatten.go b/flatten/flatten.go index c15e3d95..d80cf069 100644 --- a/flatten/flatten.go +++ b/flatten/flatten.go @@ -36,6 +36,10 @@ func Flatten(thing map[string]interface{}) map[string]string { } func flatten(result map[string]string, prefix string, v reflect.Value) { + if v.Kind() == reflect.Invalid { + return + } + if v.Kind() == reflect.Interface { v = v.Elem() } diff --git a/kubernetes/resource_kubectl_manifest.go b/kubernetes/resource_kubectl_manifest.go index 7424c21b..ac90b8a8 100644 --- a/kubernetes/resource_kubectl_manifest.go +++ b/kubernetes/resource_kubectl_manifest.go @@ -945,17 +945,20 @@ func getLiveManifestFields_WithIgnoredFields(ignoredFields []string, userProvide // this implicitly excludes anything that the user didn't provide as it was added by kubernetes runtime (annotations/mutations etc) userKeys := []string{} for userKey, userValue := range flattenedUser { + normalizedUserValue := strings.TrimSpace(userValue) + // only include the value if it exists in the live version // that is, don't add to the userKeys array unless the key still exists in the live manifest if _, exists := flattenedLive[userKey]; exists { userKeys = append(userKeys, userKey) - flattenedUser[userKey] = strings.TrimSpace(flattenedLive[userKey]) - if strings.TrimSpace(userValue) != flattenedUser[userKey] { - log.Printf("[TRACE] yaml drift detected in %s for %s, was:\n%s now:\n%s", selfLink, userKey, userValue, flattenedLive[userKey]) + normalizedLiveValue := strings.TrimSpace(flattenedLive[userKey]) + flattenedUser[userKey] = normalizedLiveValue + if normalizedUserValue != normalizedLiveValue { + log.Printf("[TRACE] yaml drift detected in %s for %s, was: %s now: %s", selfLink, userKey, normalizedUserValue, normalizedLiveValue) } } else { - if strings.TrimSpace(userValue) != "" { - log.Printf("[TRACE] yaml drift detected in %s for %s, was %s now blank", selfLink, userKey, userValue) + if normalizedUserValue != "" { + log.Printf("[TRACE] yaml drift detected in %s for %s, was %s now blank", selfLink, userKey, normalizedUserValue) } } } diff --git a/kubernetes/resource_kubectl_manifest_test.go b/kubernetes/resource_kubectl_manifest_test.go index 195d0c2c..1a0fe27c 100644 --- a/kubernetes/resource_kubectl_manifest_test.go +++ b/kubernetes/resource_kubectl_manifest_test.go @@ -842,6 +842,26 @@ func TestGetLiveManifestFilteredForUserProvidedOnly(t *testing.T) { expectedFingerprint: "5d9a5cd23ce01763e52f171e6bf2d98ca3cfed982974579af4c011ff6010694f", expectedDrift: false, }, + { + description: "Map with empty annotations in user manifest", + userProvided: map[string]interface{}{ + "atest": "test", + "metadata": map[string]interface{}{ + "annotations": map[string]interface{}{}, + }, + }, + liveManifest: map[string]interface{}{ + "atest": "test", + "metadata": map[string]interface{}{ + "annotations": map[string]string{ + "kubectl.kubernetes.io/last-applied-configuration": "{\"should-be-ignored\"}", + }, + }, + }, + expectedFields: "atest=test", + expectedFingerprint: "df296364dd3346f0aa05c63f0b0df19b7aa850e44e9f4a80cf6ac06a889d9868", + expectedDrift: false, + }, { description: "Deployment manifest without changes", userProvided: loadRealDeploymentManifest().unstruct.Object,