Skip to content

Commit

Permalink
feat(vault): support complex data types in secrets (#5006)
Browse files Browse the repository at this point in the history
Co-authored-by: Ralf Pannemans <[email protected]>
  • Loading branch information
pbusko and c0d1ngm0nk3y authored Sep 5, 2024
1 parent 91ae39c commit 72ff2d4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 29 deletions.
16 changes: 13 additions & 3 deletions pkg/vault/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
32 changes: 6 additions & 26 deletions pkg/vault/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}}
Expand All @@ -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) {
Expand Down Expand Up @@ -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"])
})
}

Expand Down

0 comments on commit 72ff2d4

Please sign in to comment.