Fix for KV_V2 Custom Metadata Bug (#17395)

This commit is contained in:
AnPucel 2022-10-05 16:43:54 -07:00 committed by GitHub
parent 6bba760da0
commit d869496969
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 37 deletions

View File

@ -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)

View File

@ -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
} }

3
changelog/17395.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug:
api: Fix to account for older versions of Vault with no `custom_metadata` support
```