From d869496969d2ee274ffc727b87966cacac9ffc56 Mon Sep 17 00:00:00 2001 From: AnPucel Date: Wed, 5 Oct 2022 16:43:54 -0700 Subject: [PATCH] Fix for KV_V2 Custom Metadata Bug (#17395) --- api/kv_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++--- api/kv_v2.go | 44 ++++++++------------------------ changelog/17395.txt | 3 +++ 3 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 changelog/17395.txt diff --git a/api/kv_test.go b/api/kv_test.go index 2c16b2d43..f8b3d3917 100644 --- a/api/kv_test.go +++ b/api/kv_test.go @@ -319,13 +319,66 @@ func TestExtractCustomMetadata(t *testing.T) { }, 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 { - cm, err := extractCustomMetadata(tc.inputAPIResp) - if err != nil { - t.Fatalf("err: %s", err) - } + cm := extractCustomMetadata(tc.inputAPIResp) if !reflect.DeepEqual(cm, tc.expected) { t.Fatalf("%s: got\n%#v\nexpected\n%#v\n", tc.name, cm, tc.expected) diff --git a/api/kv_v2.go b/api/kv_v2.go index 7a98cfeef..335c21001 100644 --- a/api/kv_v2.go +++ b/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) } - cm, err := extractCustomMetadata(secret) - if err != nil { - return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToRead, err) - } - kvSecret.CustomMetadata = cm + kvSecret.CustomMetadata = extractCustomMetadata(secret) 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) } - cm, err := extractCustomMetadata(secret) - if err != nil { - return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToRead, err) - } - kvSecret.CustomMetadata = cm + kvSecret.CustomMetadata = extractCustomMetadata(secret) return kvSecret, nil } @@ -260,11 +252,7 @@ func (kv *KVv2) Put(ctx context.Context, secretPath string, data map[string]inte Raw: secret, } - cm, err := extractCustomMetadata(secret) - if err != nil { - return nil, fmt.Errorf("error reading custom metadata for secret at %s: %w", pathToWriteTo, err) - } - kvSecret.CustomMetadata = cm + kvSecret.CustomMetadata = extractCustomMetadata(secret) return kvSecret, nil } @@ -497,30 +485,24 @@ func (kv *KVv2) Rollback(ctx context.Context, secretPath string, toVersion int) 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 customMetadataInterface, ok := secret.Data["custom_metadata"] if !ok { - metadataInterface, ok := 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") - } + metadataInterface := secret.Data["metadata"] metadataMap, ok := metadataInterface.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", metadataInterface, metadataInterface) - } - customMetadataInterface, ok = metadataMap["custom_metadata"] - if !ok { - return nil, fmt.Errorf("metadata missing expected field \"custom_metadata\": %v", metadataMap) + return nil } + customMetadataInterface = metadataMap["custom_metadata"] } cm, ok := customMetadataInterface.(map[string]interface{}) - if !ok && customMetadataInterface != nil { - return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", customMetadataInterface, customMetadataInterface) + if !ok { + return nil } - return cm, nil + return cm } func extractDataAndVersionMetadata(secret *Secret) (*KVSecret, error) { @@ -724,11 +706,7 @@ func mergePatch(ctx context.Context, client *Client, mountPath string, secretPat Raw: secret, } - cm, err := extractCustomMetadata(secret) - if err != nil { - return nil, fmt.Errorf("error reading custom metadata for secret %s: %w", secretPath, err) - } - kvSecret.CustomMetadata = cm + kvSecret.CustomMetadata = extractCustomMetadata(secret) return kvSecret, nil } diff --git a/changelog/17395.txt b/changelog/17395.txt new file mode 100644 index 000000000..f7ce60294 --- /dev/null +++ b/changelog/17395.txt @@ -0,0 +1,3 @@ +```release-note:bug: +api: Fix to account for older versions of Vault with no `custom_metadata` support +```