improve kv CLI to remove data or custom metadata using kv patch (#18067)
* improve kv CLI to remove data or custom metadata using kv patch * CL * adding a comment
This commit is contained in:
parent
1c0b2df8f1
commit
22f51dc6d6
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
cli/kv: improve kv CLI to remove data or custom metadata using kv patch
|
||||
```
|
|
@ -20,12 +20,13 @@ var (
|
|||
type KVMetadataPatchCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagMaxVersions int
|
||||
flagCASRequired BoolPtr
|
||||
flagDeleteVersionAfter time.Duration
|
||||
flagCustomMetadata map[string]string
|
||||
flagMount string
|
||||
testStdin io.Reader // for tests
|
||||
flagMaxVersions int
|
||||
flagCASRequired BoolPtr
|
||||
flagDeleteVersionAfter time.Duration
|
||||
flagCustomMetadata map[string]string
|
||||
flagRemoveCustomMetadata []string
|
||||
flagMount string
|
||||
testStdin io.Reader // for tests
|
||||
}
|
||||
|
||||
func (c *KVMetadataPatchCommand) Synopsis() string {
|
||||
|
@ -65,6 +66,10 @@ Usage: vault kv metadata patch [options] KEY
|
|||
|
||||
$ vault kv metadata patch -mount=secret -custom-metadata=foo=abc -custom-metadata=bar=123 foo
|
||||
|
||||
To remove custom meta data from the corresponding path in the key-value store, kv metadata patch can be used.
|
||||
|
||||
$ vault kv metadata patch -mount=secret -remove-custom-metadata=bar foo
|
||||
|
||||
Additional flags and more advanced use cases are detailed below.
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
@ -111,6 +116,13 @@ func (c *KVMetadataPatchCommand) Flags() *FlagSets {
|
|||
This can be specified multiple times to add multiple pieces of metadata.`,
|
||||
})
|
||||
|
||||
f.StringSliceVar(&StringSliceVar{
|
||||
Name: "remove-custom-metadata",
|
||||
Target: &c.flagRemoveCustomMetadata,
|
||||
Default: []string{},
|
||||
Usage: "Key to remove from custom metadata. To specify multiple values, specify this flag multiple times.",
|
||||
})
|
||||
|
||||
f.StringVar(&StringVar{
|
||||
Name: "mount",
|
||||
Target: &c.flagMount,
|
||||
|
@ -198,7 +210,7 @@ func (c *KVMetadataPatchCommand) Run(args []string) int {
|
|||
|
||||
fullPath := addPrefixToKVPath(partialPath, mountPath, "metadata")
|
||||
|
||||
data := map[string]interface{}{}
|
||||
data := make(map[string]interface{}, 0)
|
||||
|
||||
if c.flagMaxVersions >= 0 {
|
||||
data["max_versions"] = c.flagMaxVersions
|
||||
|
@ -212,10 +224,19 @@ func (c *KVMetadataPatchCommand) Run(args []string) int {
|
|||
data["delete_version_after"] = c.flagDeleteVersionAfter.String()
|
||||
}
|
||||
|
||||
if len(c.flagCustomMetadata) > 0 {
|
||||
data["custom_metadata"] = c.flagCustomMetadata
|
||||
customMetadata := make(map[string]interface{})
|
||||
|
||||
for key, value := range c.flagCustomMetadata {
|
||||
customMetadata[key] = value
|
||||
}
|
||||
|
||||
for _, key := range c.flagRemoveCustomMetadata {
|
||||
// A null in a JSON merge patch payload will remove the associated key
|
||||
customMetadata[key] = nil
|
||||
}
|
||||
|
||||
data["custom_metadata"] = customMetadata
|
||||
|
||||
secret, err := client.Logical().JSONMergePatch(context.Background(), fullPath, data)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", fullPath, err))
|
||||
|
|
|
@ -122,6 +122,29 @@ func TestKvMetadataPatchCommand_Flags(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"remove-custom_metadata",
|
||||
[]string{"-custom-metadata=baz=ghi", "-remove-custom-metadata=foo"},
|
||||
"Success!",
|
||||
0,
|
||||
map[string]interface{}{
|
||||
"custom_metadata": map[string]interface{}{
|
||||
"bar": "def",
|
||||
"baz": "ghi",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"remove-custom_metadata-multiple",
|
||||
[]string{"-custom-metadata=baz=ghi", "-remove-custom-metadata=foo", "-remove-custom-metadata=bar"},
|
||||
"Success!",
|
||||
0,
|
||||
map[string]interface{}{
|
||||
"custom_metadata": map[string]interface{}{
|
||||
"baz": "ghi",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"delete_version_after_success",
|
||||
[]string{"-delete-version-after=5s"},
|
||||
|
|
|
@ -21,10 +21,11 @@ var (
|
|||
type KVPatchCommand struct {
|
||||
*BaseCommand
|
||||
|
||||
flagCAS int
|
||||
flagMethod string
|
||||
flagMount string
|
||||
testStdin io.Reader // for tests
|
||||
flagCAS int
|
||||
flagMethod string
|
||||
flagMount string
|
||||
testStdin io.Reader // for tests
|
||||
flagRemoveData []string
|
||||
}
|
||||
|
||||
func (c *KVPatchCommand) Synopsis() string {
|
||||
|
@ -76,6 +77,10 @@ Usage: vault kv patch [options] KEY [DATA]
|
|||
|
||||
$ vault kv patch -mount=secret -method=rw foo bar=baz
|
||||
|
||||
To remove data from the corresponding path in the key-value store, kv patch can be used.
|
||||
|
||||
$ vault kv patch -mount=secret -remove-data=bar foo
|
||||
|
||||
Additional flags and more advanced use cases are detailed below.
|
||||
|
||||
` + c.Flags().Help()
|
||||
|
@ -117,6 +122,13 @@ func (c *KVPatchCommand) Flags() *FlagSets {
|
|||
v2 secrets.`,
|
||||
})
|
||||
|
||||
f.StringSliceVar(&StringSliceVar{
|
||||
Name: "remove-data",
|
||||
Target: &c.flagRemoveData,
|
||||
Default: []string{},
|
||||
Usage: "Key to remove from data. To specify multiple values, specify this flag multiple times.",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
|
@ -147,7 +159,7 @@ func (c *KVPatchCommand) Run(args []string) int {
|
|||
case len(args) < 1:
|
||||
c.UI.Error(fmt.Sprintf("Not enough arguments (expected >1, got %d)", len(args)))
|
||||
return 1
|
||||
case len(args) == 1:
|
||||
case len(c.flagRemoveData) == 0 && len(args) == 1:
|
||||
c.UI.Error("Must supply data")
|
||||
return 1
|
||||
}
|
||||
|
@ -211,6 +223,16 @@ func (c *KVPatchCommand) Run(args []string) int {
|
|||
return 2
|
||||
}
|
||||
|
||||
// collecting data to be removed
|
||||
if newData == nil {
|
||||
newData = make(map[string]interface{})
|
||||
}
|
||||
|
||||
for _, key := range c.flagRemoveData {
|
||||
// A null in a JSON merge patch payload will remove the associated key
|
||||
newData[key] = nil
|
||||
}
|
||||
|
||||
// Check the method and behave accordingly
|
||||
var secret *api.Secret
|
||||
var code int
|
||||
|
|
|
@ -249,6 +249,7 @@ func TestKV_Patch_RootToken(t *testing.T) {
|
|||
data := map[string]interface{}{
|
||||
"data": map[string]interface{}{
|
||||
"bar": "baz",
|
||||
"foo": "qux",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -263,6 +264,7 @@ func TestKV_Patch_RootToken(t *testing.T) {
|
|||
data := map[string]interface{}{
|
||||
"data": map[string]interface{}{
|
||||
"bar": "quux",
|
||||
"foo": nil,
|
||||
},
|
||||
}
|
||||
return client.Logical().JSONMergePatch(context.Background(), "kv/data/foo", data)
|
||||
|
@ -288,4 +290,8 @@ func TestKV_Patch_RootToken(t *testing.T) {
|
|||
if bar != "quux" {
|
||||
t.Fatalf("expected bar to be quux but it was %q", bar)
|
||||
}
|
||||
|
||||
if _, ok := secret.Data["data"].(map[string]interface{})["foo"]; ok {
|
||||
t.Fatalf("expected data not to include foo")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue