Browse Source

Fix: ESO template crash when Kubernetes secret data is nil (#3537)

* fix: check if secret.Data is nil before assigning a value

Signed-off-by: MathiasBleimhofer <mathias.bleimhofer@deutschebahn.com>
Mathias Bleimhofer 2 years ago
parent
commit
30e18870e2
2 changed files with 88 additions and 0 deletions
  1. 9 0
      pkg/template/v2/template.go
  2. 79 0
      pkg/template/v2/template_test.go

+ 9 - 0
pkg/template/v2/template.go

@@ -72,10 +72,19 @@ func init() {
 func applyToTarget(k, val string, target esapi.TemplateTarget, secret *corev1.Secret) {
 	switch target {
 	case esapi.TemplateTargetAnnotations:
+		if secret.Annotations == nil {
+			secret.Annotations = make(map[string]string)
+		}
 		secret.Annotations[k] = val
 	case esapi.TemplateTargetLabels:
+		if secret.Labels == nil {
+			secret.Labels = make(map[string]string)
+		}
 		secret.Labels[k] = val
 	case esapi.TemplateTargetData:
+		if secret.Data == nil {
+			secret.Data = make(map[string][]byte)
+		}
 		secret.Data[k] = []byte(val)
 	default:
 	}

+ 79 - 0
pkg/template/v2/template_test.go

@@ -523,6 +523,85 @@ func TestExecute(t *testing.T) {
 	}
 }
 
+func TestScopeValuesWithSecretFieldsNil(t *testing.T) {
+	tbl := []struct {
+		name               string
+		tpl                map[string][]byte
+		target             esapi.TemplateTarget
+		data               map[string][]byte
+		expectedData       map[string][]byte
+		expectedStringData map[string]string
+		expErr             string
+	}{
+		{
+			name:   "test empty",
+			tpl:    map[string][]byte{},
+			target: esapi.TemplateTargetData,
+			data:   nil,
+		},
+		{
+			name:   "test byte",
+			tpl:    map[string][]byte{"foo": []byte("bar")},
+			target: esapi.TemplateTargetData,
+			data: map[string][]byte{
+				"key":   []byte("foo"),
+				"value": []byte("bar"),
+			},
+			expectedData: map[string][]byte{
+				"foo": []byte("bar"),
+			},
+		},
+		{
+			name:   "test Annotations",
+			tpl:    map[string][]byte{"foo": []byte("bar")},
+			target: esapi.TemplateTargetAnnotations,
+			data: map[string][]byte{
+				"key":   []byte("foo"),
+				"value": []byte("bar"),
+			},
+			expectedStringData: map[string]string{
+				"foo": "bar",
+			},
+		},
+		{
+			name:   "test Labels",
+			tpl:    map[string][]byte{"foo": []byte("bar")},
+			target: esapi.TemplateTargetLabels,
+			data: map[string][]byte{
+				"key":   []byte("foo"),
+				"value": []byte("bar"),
+			},
+			expectedStringData: map[string]string{
+				"foo": "bar",
+			},
+		},
+	}
+	for i := range tbl {
+		row := tbl[i]
+		t.Run(row.name, func(t *testing.T) {
+			sec := &corev1.Secret{}
+			err := Execute(row.tpl, row.data, esapi.TemplateScopeValues, row.target, sec)
+			if !ErrorContains(err, row.expErr) {
+				t.Errorf("unexpected error: %s, expected: %s", err, row.expErr)
+			}
+			switch row.target {
+			case esapi.TemplateTargetData:
+				if row.expectedData != nil {
+					assert.EqualValues(t, row.expectedData, sec.Data)
+				}
+			case esapi.TemplateTargetLabels:
+				if row.expectedStringData != nil {
+					assert.EqualValues(t, row.expectedStringData, sec.Labels)
+				}
+			case esapi.TemplateTargetAnnotations:
+				if row.expectedStringData != nil {
+					assert.EqualValues(t, row.expectedStringData, sec.Annotations)
+				}
+			}
+		})
+	}
+}
+
 func TestExecuteInvalidTemplateScope(t *testing.T) {
 	sec := &corev1.Secret{}
 	err := Execute(map[string][]byte{"foo": []byte("bar")}, nil, "invalid", esapi.TemplateTargetData, sec)