From 72ff2d461bebdfa734c8f6621dd51c0e654d51b4 Mon Sep 17 00:00:00 2001 From: Pavel Busko Date: Thu, 5 Sep 2024 10:29:19 +0200 Subject: [PATCH] feat(vault): support complex data types in secrets (#5006) Co-authored-by: Ralf Pannemans --- pkg/vault/client.go | 16 +++++++++++++--- pkg/vault/client_test.go | 32 ++++++-------------------------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/pkg/vault/client.go b/pkg/vault/client.go index f9350958b0..ba1e14e929 100644 --- a/pkg/vault/client.go +++ b/pkg/vault/client.go @@ -169,9 +169,19 @@ func (v Client) GetKvSecret(path string) (map[string]string, error) { secretData := make(map[string]string, len(data)) for k, v := range data { - valueStr, ok := v.(string) - if ok { - secretData[k] = valueStr + switch t := v.(type) { + case string: + secretData[k] = t + case int: + secretData[k] = fmt.Sprintf("%d", t) + default: + jsonBytes, err := json.Marshal(t) + if err != nil { + log.Entry().Warnf("failed to parse Vault secret key %q, error: %s", k, err.Error()) + continue + } + + secretData[k] = string(jsonBytes) } } return secretData, nil diff --git a/pkg/vault/client_test.go b/pkg/vault/client_test.go index d95afd1f56..90a86b35bb 100644 --- a/pkg/vault/client_test.go +++ b/pkg/vault/client_test.go @@ -28,7 +28,6 @@ const ( ) func TestGetKV2Secret(t *testing.T) { - t.Run("Test missing secret", func(t *testing.T) { vaultMock := &mocks.VaultMock{} client := Client{vaultMock, &Config{}} @@ -47,21 +46,13 @@ func TestGetKV2Secret(t *testing.T) { vaultMock := &mocks.VaultMock{} setupMockKvV2(vaultMock) client := Client{vaultMock, &Config{}} - vaultMock.On("Read", secretAPIPath).Return(kv2Secret(SecretData{"key1": "value1"}), nil) + vaultMock.On("Read", secretAPIPath).Return(kv2Secret(SecretData{"key1": "value1", "key2": map[string]any{"subkey1": "subvalue2"}, "key3": 3, "key4": []string{"foo", "bar"}}), nil) secret, err := client.GetKvSecret(secretName) assert.NoError(t, err, "Expect GetKvSecret to succeed") assert.Equal(t, "value1", secret["key1"]) - - }) - - t.Run("field ignored when 'data' field can't be parsed", func(t *testing.T) { - vaultMock := &mocks.VaultMock{} - setupMockKvV2(vaultMock) - client := Client{vaultMock, &Config{}} - vaultMock.On("Read", secretAPIPath).Return(kv2Secret(SecretData{"key1": "value1", "key2": 5}), nil) - secret, err := client.GetKvSecret(secretName) - assert.NoError(t, err) - assert.Empty(t, secret["key2"]) + assert.Equal(t, `{"subkey1":"subvalue2"}`, secret["key2"]) + assert.Equal(t, "3", secret["key3"]) + assert.Equal(t, `["foo","bar"]`, secret["key4"]) }) t.Run("error is thrown when data field is missing", func(t *testing.T) { @@ -96,22 +87,11 @@ func TestGetKV1Secret(t *testing.T) { setupMockKvV1(vaultMock) client := Client{vaultMock, &Config{}} - vaultMock.On("Read", secretName).Return(kv1Secret(SecretData{"key1": "value1"}), nil) + vaultMock.On("Read", secretName).Return(kv1Secret(SecretData{"key1": "value1", "key2": 5}), nil) secret, err := client.GetKvSecret(secretName) assert.NoError(t, err) assert.Equal(t, "value1", secret["key1"]) - }) - - t.Run("Test parsing KV1 secrets", func(t *testing.T) { - vaultMock := &mocks.VaultMock{} - setupMockKvV1(vaultMock) - vaultMock.On("Read", secretName).Return(kv1Secret(SecretData{"key1": 5}), nil) - client := Client{vaultMock, &Config{}} - - secret, err := client.GetKvSecret(secretName) - assert.NoError(t, err) - assert.Empty(t, secret["key1"]) - + assert.Equal(t, "5", secret["key2"]) }) }