Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTTP PATCH support for key metadata #57

Merged
merged 22 commits into from
Jan 12, 2022
Merged

Conversation

ccapurso
Copy link
Contributor

@ccapurso ccapurso commented Nov 17, 2021

Overview

The custom_metadata map field was added to key metadata in #48. Updating the field currently results in a full overwrite. HTTP PATCH was introduced for the data endpoint in #49. Now that Vault generally supports HTTP PATCH, it seemed prudent to add a PatchOperation handler for the metadata endpoint so that custom_metadata can be patched rather than fully overwritten.

Design of Change

The custom_metadata type has been changed from framework.TypeKVPairs to framework.TypeMap. The framework.TypeKVPairs restricts values to strings but does not result in proper handling when users to submit null values within the JSON request body. A null will indicate to the JSON merge handler to remove the field. Using framework.TypeKVPairs will result in coercing a nil interface{} from the request data to an empty string which is not ideal. Changing the type of this field was a concern that was handled carefully. The parseCustomMetadata function was added to handle the parsing of the interface{} values into strings to create a map[string]string in the same way that the FieldData parsing would if it were otherwise typed as framework.TypeKVPairs . This function is then used for the CreateOperation/UpdateOperation and PatchOperation handlers to ensure consistent request data coercion.

A PatchOperation handler has been added to the metadata path. Similar to the CreateOperation/UpdateOperation handler, the cas_required field is treated as lower priority than the backend configuration. If the cas_required field on the backend configuration is set to true and an attempt made to set the metadata's cas_required to false will result in a warning.

The framework.PatchPreprocessorFunc for the metadata PatchOperation handler is responsible for the following:

  • Only include max_versions, cas_required, delete_version_after, custom_metadata as all other fields are handled internally by the backend
  • Ignore top-level nil values as they will result in the JSON merge patch removing them from the resource, they are allowed to exist within custom_metadata
  • Create a DurationProto value for delete_version_after

Related Issues/Pull Requests

  • Vault PR #13191 - handling type errors in HandlePatchOperation which have been included in the update of github.com/hashicorp/vault/sdk to version v0.3.1-0.20211124134129-09816c37b82e
  • Vault PR #13215 - kv metadata patch CLI support and doc updates

@ccapurso ccapurso requested review from calvn and a team and removed request for calvn December 9, 2021 19:33
Copy link

@HridoyRoy HridoyRoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lgtm! Thanks for including comments for each new function, and for the comprehensive testing!

Just a couple questions/comments to clarify my understanding.

go.mod Outdated
@@ -10,7 +10,7 @@ require (
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1
github.com/hashicorp/vault/api v1.3.0
github.com/hashicorp/vault/sdk v0.3.0
github.com/hashicorp/vault/sdk v0.3.1-0.20211124134129-09816c37b82e

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you link the relevant sdk update that is required for this PR? I noticed that this PR uses HandlePatchOperation , which is updated here: https://github.com/hashicorp/vault/pull/13191/files . Was this the change you wanted to include?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes. I did link the PR above but I will add a note in the description to specify why the sdk version has been updated. Thank you for calling that out!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! In that case, I think we'd want to merge the sdk PR first, then redo the go get so we don't depend on a branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's the plan.

// framework.PatchPreprocessorFunc handles filtering out Vault-managed fields,
// filtering out nulls, and ensuring appropriate handling of data types not
// supported directly by FieldType.
func metadataPatchPreprocessor() framework.PatchPreprocessorFunc {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we filter out nils here? Further down in PathMetadataPatch, the parsing logic should filter out nils already. Not a problem regardless as I think having the extra lair of defensive coding is a good thing, but I was just curious if I was missing something here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. We have discussed this further offline and come to the conclusion that nils provided for top-level fields will be treated as unsetting the field. The godoc for framework.HandlePatchOperation will account for this functionality.

@HridoyRoy HridoyRoy self-requested a review December 16, 2021 19:02
Copy link

@HridoyRoy HridoyRoy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing my review from Approve to Request changes because I think the question about the go.mod upgrade might be blocking, but otherwise lgtm!

@ccapurso ccapurso merged commit c2eb38b into master Jan 12, 2022
@ccapurso ccapurso deleted the vault-4290-patch-metadata branch January 12, 2022 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants