Browse Source

fix: allow pushing the whole secret to Vault (#3288)

Signed-off-by: Rodrigo Fior Kuntzer <rodrigo@miro.com>
Rodrigo Fior Kuntzer 2 years ago
parent
commit
ceb26a6d50
2 changed files with 42 additions and 5 deletions
  1. 19 1
      pkg/provider/vault/client_push.go
  2. 23 4
      pkg/provider/vault/client_push_test.go

+ 19 - 1
pkg/provider/vault/client_push.go

@@ -26,10 +26,28 @@ import (
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
 	"github.com/external-secrets/external-secrets/pkg/constants"
 	"github.com/external-secrets/external-secrets/pkg/metrics"
+	"github.com/external-secrets/external-secrets/pkg/utils"
 )
 
 func (c *client) PushSecret(ctx context.Context, secret *corev1.Secret, data esv1beta1.PushSecretData) error {
-	value := secret.Data[data.GetSecretKey()]
+	var (
+		value []byte
+		err   error
+	)
+	key := data.GetSecretKey()
+	if key == "" {
+		// Must convert secret values to string, otherwise data will be sent as base64 to Vault
+		secretStringVal := make(map[string]string)
+		for k, v := range secret.Data {
+			secretStringVal[k] = string(v)
+		}
+		value, err = utils.JSONMarshal(secretStringVal)
+		if err != nil {
+			return fmt.Errorf("failed to serialize secret content as JSON: %w", err)
+		}
+	} else {
+		value = secret.Data[key]
+	}
 	label := map[string]interface{}{
 		"custom_metadata": map[string]string{
 			"managed-by": "external-secrets",

+ 23 - 4
pkg/provider/vault/client_push_test.go

@@ -362,6 +362,7 @@ func TestPushSecret(t *testing.T) {
 		want   want
 		data   *testingfake.PushSecretData
 		value  []byte
+		secret *corev1.Secret
 	}{
 		"SetSecretKV1": {
 			reason: "secret is successfully set, with no existing vault secret",
@@ -648,6 +649,21 @@ func TestPushSecret(t *testing.T) {
 				err: errors.New("secret not managed by external-secrets"),
 			},
 		},
+		"WholeSecretKV2": {
+			reason: "secret is successfully set, with no existing vault secret",
+			args: args{
+				store: makeValidSecretStoreWithVersion(esv1beta1.VaultKVStoreV2).Spec.Provider.Vault,
+				vLogical: &fake.Logical{
+					ReadWithDataWithContextFn: fake.NewReadWithContextFn(nil, nil),
+					WriteWithContextFn:        fake.ExpectWriteWithContextValue(map[string]interface{}{"data": map[string]interface{}{"key1": "value1", "key2": "value2"}}),
+				},
+			},
+			data:   &testingfake.PushSecretData{SecretKey: "", RemoteKey: "secret", Property: ""},
+			secret: &corev1.Secret{Data: map[string][]byte{"key1": []byte(`value1`), "key2": []byte(`value2`)}},
+			want: want{
+				err: nil,
+			},
+		},
 	}
 
 	for name, tc := range tests {
@@ -660,11 +676,14 @@ func TestPushSecret(t *testing.T) {
 				logical: tc.args.vLogical,
 				store:   tc.args.store,
 			}
-			val := tc.value
-			if val == nil {
-				val = []byte(`{"fake-key":"fake-value"}`)
+			s := tc.secret
+			if s == nil {
+				val := tc.value
+				if val == nil {
+					val = []byte(`{"fake-key":"fake-value"}`)
+				}
+				s = &corev1.Secret{Data: map[string][]byte{secretKey: val}}
 			}
-			s := &corev1.Secret{Data: map[string][]byte{secretKey: val}}
 			err := client.PushSecret(context.Background(), s, data)
 
 			// Error nil XOR tc.want.err nil