Fix writing to KVv2 root via `kv put` (#4726)

* Fix writing to KVv2 root via `kv put`

The check that adds the API path wasn't taking into account the root,
e.g. if it's mounted at `kv`, `kv` and `kv/` would end up creating an
extra copy of the mount path in front, leading to paths like
`kv/data/kv`.

* Output warnings if they come back and fix a panic in metadata_get

* Also add to metadata put/delete
This commit is contained in:
Jeff Mitchell 2018-06-08 13:45:47 -04:00 committed by GitHub
parent 9c6a5a807f
commit c1267ab16c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 12 deletions

View File

@ -101,14 +101,18 @@ func (c *KVDeleteCommand) Run(args []string) int {
return 2
}
var secret *api.Secret
if v2 {
err = c.deleteV2(path, mountPath, client)
secret, err = c.deleteV2(path, mountPath, client)
} else {
_, err = client.Logical().Delete(path)
secret, err = client.Logical().Delete(path)
}
if err != nil {
c.UI.Error(fmt.Sprintf("Error deleting %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}
@ -116,29 +120,30 @@ func (c *KVDeleteCommand) Run(args []string) int {
return 0
}
func (c *KVDeleteCommand) deleteV2(path, mountPath string, client *api.Client) error {
func (c *KVDeleteCommand) deleteV2(path, mountPath string, client *api.Client) (*api.Secret, error) {
var err error
var secret *api.Secret
switch {
case len(c.flagVersions) > 0:
path = addPrefixToVKVPath(path, mountPath, "delete")
if err != nil {
return err
return nil, err
}
data := map[string]interface{}{
"versions": kvParseVersionsFlags(c.flagVersions),
}
_, err = client.Logical().Write(path, data)
secret, err = client.Logical().Write(path, data)
default:
path = addPrefixToVKVPath(path, mountPath, "data")
if err != nil {
return err
return nil, err
}
_, err = client.Logical().Delete(path)
secret, err = client.Logical().Delete(path)
}
return err
return secret, err
}

View File

@ -115,6 +115,9 @@ func (c *KVDestroyCommand) Run(args []string) int {
secret, err := client.Logical().Write(path, data)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}
if secret == nil {

View File

@ -99,8 +99,13 @@ func isKVv2(path string, client *api.Client) (string, bool, error) {
}
func addPrefixToVKVPath(p, mountPath, apiPrefix string) string {
p = strings.TrimPrefix(p, mountPath)
return path.Join(mountPath, apiPrefix, p)
switch {
case p == mountPath, p == strings.TrimSuffix(mountPath, "/"):
return path.Join(mountPath, apiPrefix)
default:
p = strings.TrimPrefix(p, mountPath)
return path.Join(mountPath, apiPrefix, p)
}
}
func getHeaderForMap(header string, data map[string]interface{}) string {

View File

@ -82,8 +82,11 @@ func (c *KVMetadataDeleteCommand) Run(args []string) int {
}
path = addPrefixToVKVPath(path, mountPath, "metadata")
if _, err := client.Logical().Delete(path); err != nil {
if secret, err := client.Logical().Delete(path); err != nil {
c.UI.Error(fmt.Sprintf("Error deleting %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}

View File

@ -105,7 +105,13 @@ func (c *KVMetadataGetCommand) Run(args []string) int {
return OutputSecret(c.UI, secret)
}
versions := secret.Data["versions"].(map[string]interface{})
versionsRaw, ok := secret.Data["versions"]
if !ok || versionsRaw == nil {
c.UI.Error(fmt.Sprintf("No value found at %s", path))
OutputSecret(c.UI, secret)
return 2
}
versions := versionsRaw.(map[string]interface{})
delete(secret.Data, "versions")

View File

@ -125,6 +125,9 @@ func (c *KVMetadataPutCommand) Run(args []string) int {
secret, err := client.Logical().Write(path, data)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}
if secret == nil {

View File

@ -110,6 +110,9 @@ func (c *KVUndeleteCommand) Run(args []string) int {
secret, err := client.Logical().Write(path, data)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", path, err))
if secret != nil {
OutputSecret(c.UI, secret)
}
return 2
}
if secret == nil {