Skip to content

Commit

Permalink
Kv preflight (#4430)
Browse files Browse the repository at this point in the history
* Update kv command to use a preflight check

* Make the existing ui endpoint return the allowed mounts

* Add kv subcommand tests

* Enable `-field` in `vault kv get/put` (#4426)

* Enable `-field` in `vault kv get/put`

Fixes #4424

* Unify nil value handling

* Use preflight helper

* Update vkv plugin

* Add all the mount info when authenticated

* Add fix the error message on put

* add metadata test

* No need to sort the capabilities

* Remove the kv client header

* kv patch command (#4432)

* Fix test

* Fix tests

* Use permission denied instead of entity disabled
  • Loading branch information
briankassouf authored Apr 23, 2018
1 parent b82bd74 commit a136c79
Show file tree
Hide file tree
Showing 30 changed files with 1,343 additions and 450 deletions.
2 changes: 2 additions & 0 deletions command/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

log "github.com/hashicorp/go-hclog"
kv "github.com/hashicorp/vault-plugin-secrets-kv"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/builtin/logical/pki"
Expand Down Expand Up @@ -41,6 +42,7 @@ var (
"pki": pki.Factory,
"ssh": ssh.Factory,
"transit": transit.Factory,
"kv": kv.Factory,
}
)

Expand Down
7 changes: 7 additions & 0 deletions command/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,13 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
},
}, nil
},
"kv patch": func() (cli.Command, error) {
return &KVPatchCommand{
BaseCommand: &BaseCommand{
UI: ui,
},
}, nil
},
"kv get": func() (cli.Command, error) {
return &KVGetCommand{
BaseCommand: &BaseCommand{
Expand Down
65 changes: 34 additions & 31 deletions command/kv_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"strings"

"github.com/hashicorp/vault/api"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
Expand Down Expand Up @@ -87,13 +88,25 @@ func (c *KVDeleteCommand) Run(args []string) int {
return 1
}

client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 2
}

path := sanitizePath(args[0])
var err error
if len(c.flagVersions) > 0 {
err = c.deleteVersions(path, kvParseVersionsFlags(c.flagVersions))
mountPath, v2, err := isKVv2(path, client)
if err != nil {
c.UI.Error(err.Error())
return 2
}

if v2 {
err = c.deleteV2(path, mountPath, client)
} else {
err = c.deleteLatest(path)
_, err = client.Logical().Delete(path)
}

if err != nil {
c.UI.Error(fmt.Sprintf("Error deleting %s: %s", path, err))
return 2
Expand All @@ -103,39 +116,29 @@ func (c *KVDeleteCommand) Run(args []string) int {
return 0
}

func (c *KVDeleteCommand) deleteLatest(path string) error {
func (c *KVDeleteCommand) deleteV2(path, mountPath string, client *api.Client) error {
var err error
path, err = addPrefixToVKVPath(path, "data")
if err != nil {
return err
}

client, err := c.Client()
if err != nil {
return err
}

_, err = kvDeleteRequest(client, path)
switch {
case len(c.flagVersions) > 0:
path = addPrefixToVKVPath(path, mountPath, "delete")
if err != nil {
return err
}

return err
}
data := map[string]interface{}{
"versions": kvParseVersionsFlags(c.flagVersions),
}

func (c *KVDeleteCommand) deleteVersions(path string, versions []string) error {
var err error
path, err = addPrefixToVKVPath(path, "delete")
if err != nil {
return err
}
_, err = client.Logical().Write(path, data)
default:

data := map[string]interface{}{
"versions": versions,
}
path = addPrefixToVKVPath(path, mountPath, "data")
if err != nil {
return err
}

client, err := c.Client()
if err != nil {
return err
_, err = client.Logical().Delete(path)
}

_, err = kvWriteRequest(client, path, data)
return err
}
22 changes: 16 additions & 6 deletions command/kv_destroy.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,33 @@ func (c *KVDestroyCommand) Run(args []string) int {
}
var err error
path := sanitizePath(args[0])
path, err = addPrefixToVKVPath(path, "destroy")

client, err := c.Client()
if err != nil {
c.UI.Error(err.Error())
return 2
}

data := map[string]interface{}{
"versions": kvParseVersionsFlags(c.flagVersions),
mountPath, v2, err := isKVv2(path, client)
if err != nil {
c.UI.Error(err.Error())
return 2
}

client, err := c.Client()
if !v2 {
c.UI.Error("Destroy not supported on KV Version 1")
return 1
}
path = addPrefixToVKVPath(path, mountPath, "destroy")
if err != nil {
c.UI.Error(err.Error())
return 2
}

secret, err := kvWriteRequest(client, path, data)
data := map[string]interface{}{
"versions": kvParseVersionsFlags(c.flagVersions),
}

secret, err := client.Logical().Write(path, data)
if err != nil {
c.UI.Error(fmt.Sprintf("Error writing data to %s: %s", path, err))
return 2
Expand Down
45 changes: 37 additions & 8 deletions command/kv_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Usage: vault kv get [options] KEY
}

func (c *KVGetCommand) Flags() *FlagSets {
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
set := c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat)

// Common Options
f := set.NewFlagSet("Common Options")
Expand Down Expand Up @@ -91,16 +91,25 @@ func (c *KVGetCommand) Run(args []string) int {
}

path := sanitizePath(args[0])
path, err = addPrefixToVKVPath(path, "data")
mountPath, v2, err := isKVv2(path, client)
if err != nil {
c.UI.Error(err.Error())
return 2
}

var versionParam map[string]string
if c.flagVersion > 0 {
versionParam = map[string]string{
"version": fmt.Sprintf("%d", c.flagVersion),

if v2 {
path = addPrefixToVKVPath(path, mountPath, "data")
if err != nil {
c.UI.Error(err.Error())
return 2
}

if c.flagVersion > 0 {
versionParam = map[string]string{
"version": fmt.Sprintf("%d", c.flagVersion),
}
}
}

Expand All @@ -115,7 +124,17 @@ func (c *KVGetCommand) Run(args []string) int {
}

if c.flagField != "" {
return PrintRawField(c.UI, secret, c.flagField)
if v2 {
// This is a v2, pass in the data field
if data, ok := secret.Data["data"]; ok && data != nil {
return PrintRawField(c.UI, data, c.flagField)
} else {
c.UI.Error(fmt.Sprintf("No data found at %s", path))
return 2
}
} else {
return PrintRawField(c.UI, secret, c.flagField)
}
}

// If we have wrap info print the secret normally.
Expand All @@ -128,8 +147,18 @@ func (c *KVGetCommand) Run(args []string) int {
OutputData(c.UI, metadata)
c.UI.Info("")
}
if data, ok := secret.Data["data"]; ok && data != nil {
c.UI.Info(getHeaderForMap("Data", data.(map[string]interface{})))

data := secret.Data
if v2 && data != nil {
data = nil
dataRaw := secret.Data["data"]
if dataRaw != nil {
data = dataRaw.(map[string]interface{})
}
}

if data != nil {
c.UI.Info(getHeaderForMap("Data", data))
OutputData(c.UI, data)
}

Expand Down
Loading

0 comments on commit a136c79

Please sign in to comment.