Fix for KV_V2 Custom Metadata Bug (#17395)
This commit is contained in:
parent
6bba760da0
commit
d869496969
|
@ -319,13 +319,66 @@ func TestExtractCustomMetadata(t *testing.T) {
|
||||||
},
|
},
|
||||||
expected: map[string]interface{}{"org": "eng"},
|
expected: map[string]interface{}{"org": "eng"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "a read response with no custom metadata from a pre-1.9 Vault server",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a write response with no custom metadata from a pre-1.9 Vault server",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a read response with no custom metadata from a post-1.9 Vault server",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"custom_metadata": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a write response with no custom metadata from a post-1.9 Vault server",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"custom_metadata": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a read response where custom metadata was deleted",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"metadata": map[string]interface{}{
|
||||||
|
"custom_metadata": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "a write response where custom metadata was deleted",
|
||||||
|
inputAPIResp: &Secret{
|
||||||
|
Data: map[string]interface{}{
|
||||||
|
"custom_metadata": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expected: map[string]interface{}{},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
cm, err := extractCustomMetadata(tc.inputAPIResp)
|
cm := extractCustomMetadata(tc.inputAPIResp)
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(cm, tc.expected) {
|
if !reflect.DeepEqual(cm, tc.expected) {
|
||||||
t.Fatalf("%s: got\n%#v\nexpected\n%#v\n", tc.name, cm, tc.expected)
|
t.Fatalf("%s: got\n%#v\nexpected\n%#v\n", tc.name, cm, tc.expected)
|
||||||
|
|
44
api/kv_v2.go
44
api/kv_v2.go
|
@ -125,11 +125,7 @@ func (kv *KVv2) Get(ctx context.Context, secretPath string) (*KVSecret, error) {
|
||||||
return nil, fmt.Errorf("error parsing secret at %s: %w", pathToRead, err)
|
return nil, fmt.Errorf("error parsing secret at %s: %w", pathToRead, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := extractCustomMetadata(secret)
|
kvSecret.CustomMetadata = extractCustomMetadata(secret)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToRead, err)
|
|
||||||
}
|
|
||||||
kvSecret.CustomMetadata = cm
|
|
||||||
|
|
||||||
return kvSecret, nil
|
return kvSecret, nil
|
||||||
}
|
}
|
||||||
|
@ -159,11 +155,7 @@ func (kv *KVv2) GetVersion(ctx context.Context, secretPath string, version int)
|
||||||
return nil, fmt.Errorf("error parsing secret at %s: %w", pathToRead, err)
|
return nil, fmt.Errorf("error parsing secret at %s: %w", pathToRead, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := extractCustomMetadata(secret)
|
kvSecret.CustomMetadata = extractCustomMetadata(secret)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToRead, err)
|
|
||||||
}
|
|
||||||
kvSecret.CustomMetadata = cm
|
|
||||||
|
|
||||||
return kvSecret, nil
|
return kvSecret, nil
|
||||||
}
|
}
|
||||||
|
@ -260,11 +252,7 @@ func (kv *KVv2) Put(ctx context.Context, secretPath string, data map[string]inte
|
||||||
Raw: secret,
|
Raw: secret,
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := extractCustomMetadata(secret)
|
kvSecret.CustomMetadata = extractCustomMetadata(secret)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToWriteTo, err)
|
|
||||||
}
|
|
||||||
kvSecret.CustomMetadata = cm
|
|
||||||
|
|
||||||
return kvSecret, nil
|
return kvSecret, nil
|
||||||
}
|
}
|
||||||
|
@ -497,30 +485,24 @@ func (kv *KVv2) Rollback(ctx context.Context, secretPath string, toVersion int)
|
||||||
return kvs, nil
|
return kvs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractCustomMetadata(secret *Secret) (map[string]interface{}, error) {
|
func extractCustomMetadata(secret *Secret) map[string]interface{} {
|
||||||
// Logical Writes return the metadata directly, Reads return it nested inside the "metadata" key
|
// Logical Writes return the metadata directly, Reads return it nested inside the "metadata" key
|
||||||
customMetadataInterface, ok := secret.Data["custom_metadata"]
|
customMetadataInterface, ok := secret.Data["custom_metadata"]
|
||||||
if !ok {
|
if !ok {
|
||||||
metadataInterface, ok := secret.Data["metadata"]
|
metadataInterface := secret.Data["metadata"]
|
||||||
if !ok { // if that's not found, bail since it should have had one or the other
|
|
||||||
return nil, fmt.Errorf("secret is missing expected fields")
|
|
||||||
}
|
|
||||||
metadataMap, ok := metadataInterface.(map[string]interface{})
|
metadataMap, ok := metadataInterface.(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", metadataInterface, metadataInterface)
|
return nil
|
||||||
}
|
|
||||||
customMetadataInterface, ok = metadataMap["custom_metadata"]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("metadata missing expected field \"custom_metadata\": %v", metadataMap)
|
|
||||||
}
|
}
|
||||||
|
customMetadataInterface = metadataMap["custom_metadata"]
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, ok := customMetadataInterface.(map[string]interface{})
|
cm, ok := customMetadataInterface.(map[string]interface{})
|
||||||
if !ok && customMetadataInterface != nil {
|
if !ok {
|
||||||
return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", customMetadataInterface, customMetadataInterface)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return cm, nil
|
return cm
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractDataAndVersionMetadata(secret *Secret) (*KVSecret, error) {
|
func extractDataAndVersionMetadata(secret *Secret) (*KVSecret, error) {
|
||||||
|
@ -724,11 +706,7 @@ func mergePatch(ctx context.Context, client *Client, mountPath string, secretPat
|
||||||
Raw: secret,
|
Raw: secret,
|
||||||
}
|
}
|
||||||
|
|
||||||
cm, err := extractCustomMetadata(secret)
|
kvSecret.CustomMetadata = extractCustomMetadata(secret)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error reading custom metadata for secret %s: %w", secretPath, err)
|
|
||||||
}
|
|
||||||
kvSecret.CustomMetadata = cm
|
|
||||||
|
|
||||||
return kvSecret, nil
|
return kvSecret, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug:
|
||||||
|
api: Fix to account for older versions of Vault with no `custom_metadata` support
|
||||||
|
```
|
Loading…
Reference in New Issue