Sfoglia il codice sorgente

fix: ensure that data is being deleted when using tpl

Moritz Johner 4 anni fa
parent
commit
e2701fa35a

+ 1 - 3
pkg/controllers/externalsecret/externalsecret_controller_template.go

@@ -64,9 +64,7 @@ func (r *Reconciler) applyTemplate(ctx context.Context, es *esv1alpha1.ExternalS
 	// if no data was provided by template fallback
 	// if no data was provided by template fallback
 	// to value from the provider
 	// to value from the provider
 	if len(es.Spec.Target.Template.Data) == 0 {
 	if len(es.Spec.Target.Template.Data) == 0 {
-		for k, v := range dataMap {
-			secret.Data[k] = v
-		}
+		secret.Data = dataMap
 	}
 	}
 	secret.Annotations[esv1alpha1.AnnotationDataHash] = utils.ObjectHash(secret.Data)
 	secret.Annotations[esv1alpha1.AnnotationDataHash] = utils.ObjectHash(secret.Data)
 
 

+ 81 - 0
pkg/controllers/externalsecret/externalsecret_controller_test.go

@@ -654,6 +654,85 @@ var _ = Describe("ExternalSecret controller", func() {
 		}
 		}
 	}
 	}
 
 
+	// when a provider secret was deleted it must be deleted from
+	// the secret aswell
+	refreshSecretValueMap := func(tc *testCase) {
+		fakeProvider.WithGetSecretMap(map[string][]byte{
+			"foo": []byte("1111"),
+			"bar": []byte("2222"),
+		}, nil)
+		tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
+		tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+			{
+				Key: remoteKey,
+			},
+		}
+		tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
+		tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
+			// check values
+			Expect(string(secret.Data["foo"])).To(Equal("1111"))
+			Expect(string(secret.Data["bar"])).To(Equal("2222"))
+
+			// update provider secret
+			sec := &v1.Secret{}
+			fakeProvider.WithGetSecretMap(map[string][]byte{
+				"foo": []byte("1111"),
+			}, nil)
+			secretLookupKey := types.NamespacedName{
+				Name:      ExternalSecretTargetSecretName,
+				Namespace: ExternalSecretNamespace,
+			}
+			Eventually(func() bool {
+				err := k8sClient.Get(context.Background(), secretLookupKey, sec)
+				if err != nil {
+					return false
+				}
+				return string(sec.Data["foo"]) == "1111" &&
+					sec.Data["bar"] == nil // must not be defined, it was deleted
+			}, timeout, interval).Should(BeTrue())
+		}
+	}
+
+	// when a provider secret was deleted it must be deleted from
+	// the secret aswell when using a template
+	refreshSecretValueMapTemplate := func(tc *testCase) {
+		fakeProvider.WithGetSecretMap(map[string][]byte{
+			"foo": []byte("1111"),
+			"bar": []byte("2222"),
+		}, nil)
+		tc.externalSecret.Spec.Target.Template = &esv1alpha1.ExternalSecretTemplate{}
+		tc.externalSecret.Spec.Data = []esv1alpha1.ExternalSecretData{}
+		tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
+			{
+				Key: remoteKey,
+			},
+		}
+		tc.externalSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Second}
+		tc.checkSecret = func(es *esv1alpha1.ExternalSecret, secret *v1.Secret) {
+			// check values
+			Expect(string(secret.Data["foo"])).To(Equal("1111"))
+			Expect(string(secret.Data["bar"])).To(Equal("2222"))
+
+			// update provider secret
+			sec := &v1.Secret{}
+			fakeProvider.WithGetSecretMap(map[string][]byte{
+				"foo": []byte("1111"),
+			}, nil)
+			secretLookupKey := types.NamespacedName{
+				Name:      ExternalSecretTargetSecretName,
+				Namespace: ExternalSecretNamespace,
+			}
+			Eventually(func() bool {
+				err := k8sClient.Get(context.Background(), secretLookupKey, sec)
+				if err != nil {
+					return false
+				}
+				return string(sec.Data["foo"]) == "1111" &&
+					sec.Data["bar"] == nil // must not be defined, it was deleted
+			}, timeout, interval).Should(BeTrue())
+		}
+	}
+
 	refreshintervalZero := func(tc *testCase) {
 	refreshintervalZero := func(tc *testCase) {
 		const targetProp = "targetProperty"
 		const targetProp = "targetProperty"
 		const secretVal = "someValue"
 		const secretVal = "someValue"
@@ -971,6 +1050,8 @@ var _ = Describe("ExternalSecret controller", func() {
 		Entry("should refresh secret from template", refreshWithTemplate),
 		Entry("should refresh secret from template", refreshWithTemplate),
 		Entry("should be able to use only metadata from template", onlyMetadataFromTemplate),
 		Entry("should be able to use only metadata from template", onlyMetadataFromTemplate),
 		Entry("should refresh secret value when provider secret changes", refreshSecretValue),
 		Entry("should refresh secret value when provider secret changes", refreshSecretValue),
+		Entry("should refresh secret map when provider secret changes", refreshSecretValueMap),
+		Entry("should refresh secret map when provider secret changes when using a template", refreshSecretValueMapTemplate),
 		Entry("should not refresh secret value when provider secret changes but refreshInterval is zero", refreshintervalZero),
 		Entry("should not refresh secret value when provider secret changes but refreshInterval is zero", refreshintervalZero),
 		Entry("should fetch secret using dataFrom", syncWithDataFrom),
 		Entry("should fetch secret using dataFrom", syncWithDataFrom),
 		Entry("should fetch secret using dataFrom and a template", syncWithDataFromTemplate),
 		Entry("should fetch secret using dataFrom and a template", syncWithDataFromTemplate),