Skip to content

Commit

Permalink
Merge pull request #235 from souleb/fix-stringdata-diff
Browse files Browse the repository at this point in the history
ssa: Fix Secrets diff by converting StringData to Data
  • Loading branch information
stefanprodan authored Feb 18, 2022
2 parents af165a9 + 94fc3ea commit 5f45ff6
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
52 changes: 52 additions & 0 deletions ssa/manager_diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,49 @@ func TestDiff(t *testing.T) {
}
})

t.Run("generates diff for replaced key in stringData secret", func(t *testing.T) {
// create a new stringData secret
sec := secret.DeepCopy()
if err := unstructured.SetNestedField(sec.Object, generateName("diff"), "metadata", "name"); err != nil {
t.Fatal(err)
}

// copy the secret to simulate a replace of key
diffSecret := sec.DeepCopy()

// apply stringData conversion
SetNativeKindsDefaults([]*unstructured.Unstructured{sec})

if _, err = manager.Apply(ctx, sec, DefaultApplyOptions()); err != nil {
t.Fatal(err)
}

newVal := "diff-test"
unstructured.RemoveNestedField(diffSecret.Object, "stringData", "key")

newKey := "key.new"
err = unstructured.SetNestedField(diffSecret.Object, newVal, "stringData", newKey)
if err != nil {
t.Fatal(err)
}

// apply stringData conversion
SetNativeKindsDefaults([]*unstructured.Unstructured{diffSecret})

_, liveObj, mergedObj, err := manager.Diff(ctx, diffSecret, DefaultDiffOptions())
if err != nil {
t.Fatal(err)
}

liveKeys := getKeys(liveObj.Object["data"].(map[string]interface{}))
mergedKeys := getKeys(mergedObj.Object["data"].(map[string]interface{}))

if diff := cmp.Diff(liveKeys, mergedKeys); diff != "" && len(liveKeys) != len(mergedKeys) {
t.Errorf("Mismatch from expected value (-want +got):\n%s", diff)
}

})

t.Run("masks secret values", func(t *testing.T) {
newVal := "diff-test"
err = unstructured.SetNestedField(secret.Object, newVal, "stringData", "key")
Expand Down Expand Up @@ -340,3 +383,12 @@ func TestHasDrifted_Metadata(t *testing.T) {
})
}
}

func getKeys(m map[string]interface{}) []string {
var keys []string
for k := range m {
keys = append(keys, k)
}

return keys
}
27 changes: 27 additions & 0 deletions ssa/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ func AnyInMetadata(object *unstructured.Unstructured, metadata map[string]string
// ContainerPort missing default TCP proto: https://github.com/kubernetes-sigs/structured-merge-diff/issues/130
// ServicePort missing default TCP proto: https://github.com/kubernetes/kubernetes/pull/98576
// PodSpec resources missing int to string conversion for e.g. 'cpu: 2'
// secret.stringData key replacement add an extra key in the resulting data map: https://github.com/kubernetes/kubernetes/issues/108008
func SetNativeKindsDefaults(objects []*unstructured.Unstructured) error {

var setProtoDefault = func(spec *corev1.PodSpec) {
Expand Down Expand Up @@ -326,6 +327,18 @@ func SetNativeKindsDefaults(objects []*unstructured.Unstructured) error {
return fmt.Errorf("%s validation error: %w", FmtUnstructured(u), err)
}
u.Object = out
case "Secret":
var s corev1.Secret
err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, &s)
if err != nil {
return fmt.Errorf("%s validation error: %w", FmtUnstructured(u), err)
}
convertStringDataToData(&s)
out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&s)
if err != nil {
return fmt.Errorf("%s validation error: %w", FmtUnstructured(u), err)
}
u.Object = out
}

case "apps/v1":
Expand Down Expand Up @@ -475,3 +488,17 @@ func containsItemString(s []string, e string) bool {
}
return false
}

func convertStringDataToData(secret *corev1.Secret) {
// StringData overwrites Data
if len(secret.StringData) > 0 {
if secret.Data == nil {
secret.Data = map[string][]byte{}
}
for k, v := range secret.StringData {
secret.Data[k] = []byte(v)
}

secret.StringData = nil
}
}

0 comments on commit 5f45ff6

Please sign in to comment.