|
|
@@ -58,6 +58,7 @@ const (
|
|
|
annotationValue = "annotation-value"
|
|
|
existingLabelKey = "existing-label-key"
|
|
|
existingLabelValue = "existing-label-value"
|
|
|
+ nullByteSecretVal = "A\x00B"
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
@@ -2125,6 +2126,91 @@ var _ = Describe("ExternalSecret controller", Serial, func() {
|
|
|
Expect(string(secret.Data[targetProp])).To(Equal(secretVal))
|
|
|
}
|
|
|
}
|
|
|
+ failWhenFetchedSecretContainsNullBytes := func(tc *testCase) {
|
|
|
+ tc.externalSecret.Spec.Data[0].RemoteRef.NullBytePolicy = esv1.ExternalSecretNullBytePolicyFail
|
|
|
+ fakeProvider.WithGetSecret([]byte(nullByteSecretVal), nil)
|
|
|
+ tc.checkCondition = func(es *esv1.ExternalSecret) bool {
|
|
|
+ cond := GetExternalSecretCondition(es.Status, esv1.ExternalSecretReady)
|
|
|
+ if cond == nil || cond.Status != v1.ConditionFalse || cond.Reason != esv1.ConditionReasonSecretSyncedError {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ tc.checkExternalSecret = func(_ *esv1.ExternalSecret) {
|
|
|
+ secretLookupKey := types.NamespacedName{
|
|
|
+ Name: tc.targetSecretName,
|
|
|
+ Namespace: ExternalSecretNamespace,
|
|
|
+ }
|
|
|
+ Consistently(func() bool {
|
|
|
+ err := k8sClient.Get(context.Background(), secretLookupKey, &v1.Secret{})
|
|
|
+ return apierrors.IsNotFound(err)
|
|
|
+ }, time.Second, interval).Should(BeTrue())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ failWhenExtractedSecretContainsNullBytes := func(tc *testCase) {
|
|
|
+ tc.externalSecret.Spec.Data = nil
|
|
|
+ tc.externalSecret.Spec.DataFrom = []esv1.ExternalSecretDataFromRemoteRef{
|
|
|
+ {
|
|
|
+ Extract: &esv1.ExternalSecretDataRemoteRef{
|
|
|
+ Key: remoteKey,
|
|
|
+ NullBytePolicy: esv1.ExternalSecretNullBytePolicyFail,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ fakeProvider.WithGetSecretMap(map[string][]byte{
|
|
|
+ "payload": []byte(nullByteSecretVal),
|
|
|
+ }, nil)
|
|
|
+ tc.checkCondition = func(es *esv1.ExternalSecret) bool {
|
|
|
+ cond := GetExternalSecretCondition(es.Status, esv1.ExternalSecretReady)
|
|
|
+ if cond == nil || cond.Status != v1.ConditionFalse || cond.Reason != esv1.ConditionReasonSecretSyncedError {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ tc.checkExternalSecret = func(_ *esv1.ExternalSecret) {
|
|
|
+ secretLookupKey := types.NamespacedName{
|
|
|
+ Name: tc.targetSecretName,
|
|
|
+ Namespace: ExternalSecretNamespace,
|
|
|
+ }
|
|
|
+ Consistently(func() bool {
|
|
|
+ err := k8sClient.Get(context.Background(), secretLookupKey, &v1.Secret{})
|
|
|
+ return apierrors.IsNotFound(err)
|
|
|
+ }, time.Second, interval).Should(BeTrue())
|
|
|
+ }
|
|
|
+ }
|
|
|
+ failWhenFoundSecretContainsNullBytes := func(tc *testCase) {
|
|
|
+ tc.externalSecret.Spec.Data = nil
|
|
|
+ tc.externalSecret.Spec.DataFrom = []esv1.ExternalSecretDataFromRemoteRef{
|
|
|
+ {
|
|
|
+ Find: &esv1.ExternalSecretFind{
|
|
|
+ Name: &esv1.FindName{
|
|
|
+ RegExp: "foobar",
|
|
|
+ },
|
|
|
+ NullBytePolicy: esv1.ExternalSecretNullBytePolicyFail,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ fakeProvider.WithGetAllSecrets(map[string][]byte{
|
|
|
+ "payload": []byte(nullByteSecretVal),
|
|
|
+ }, nil)
|
|
|
+ tc.checkCondition = func(es *esv1.ExternalSecret) bool {
|
|
|
+ cond := GetExternalSecretCondition(es.Status, esv1.ExternalSecretReady)
|
|
|
+ if cond == nil || cond.Status != v1.ConditionFalse || cond.Reason != esv1.ConditionReasonSecretSyncedError {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ tc.checkExternalSecret = func(_ *esv1.ExternalSecret) {
|
|
|
+ secretLookupKey := types.NamespacedName{
|
|
|
+ Name: tc.targetSecretName,
|
|
|
+ Namespace: ExternalSecretNamespace,
|
|
|
+ }
|
|
|
+ Consistently(func() bool {
|
|
|
+ err := k8sClient.Get(context.Background(), secretLookupKey, &v1.Secret{})
|
|
|
+ return apierrors.IsNotFound(err)
|
|
|
+ }, time.Second, interval).Should(BeTrue())
|
|
|
+ }
|
|
|
+ }
|
|
|
useClusterSecretStore := func(tc *testCase) {
|
|
|
tc.secretStore = &esv1.ClusterSecretStore{
|
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
|
@@ -2398,6 +2484,9 @@ var _ = Describe("ExternalSecret controller", Serial, func() {
|
|
|
Entry("should sync template with correct value precedence", syncWithTemplatePrecedence),
|
|
|
Entry("should sync template from keys and values", syncTemplateFromKeysAndValues),
|
|
|
Entry("should sync template from literal", syncTemplateFromLiteral),
|
|
|
+ Entry("should fail when fetched secret data contains null bytes and remoteRef.nullBytePolicy=Fail", failWhenFetchedSecretContainsNullBytes),
|
|
|
+ Entry("should fail when extracted secret data contains null bytes and extract.nullBytePolicy=Fail", failWhenExtractedSecretContainsNullBytes),
|
|
|
+ Entry("should fail when found secret data contains null bytes and find.nullBytePolicy=Fail", failWhenFoundSecretContainsNullBytes),
|
|
|
Entry("should update template if ExternalSecret is updated", templateShouldRewrite),
|
|
|
Entry("should keep data with templates if MergePolicy=Merge", templateShouldMerge),
|
|
|
Entry("should refresh secret from template", refreshWithTemplate),
|