mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	Fix for KV_V2 Custom Metadata Bug (#17395)
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
							
								
								
									
										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) | ||||
| 	} | ||||
|  | ||||
| 	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 | ||||
| } | ||||
|   | ||||
							
								
								
									
										3
									
								
								changelog/17395.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/17395.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| ```release-note:bug: | ||||
| api: Fix to account for older versions of Vault with no `custom_metadata` support | ||||
| ``` | ||||
		Reference in New Issue
	
	Block a user
	 AnPucel
					AnPucel