Merge pull request #1470 from hashicorp/unwrap-in-api

Make Unwrap a first-party API command and refactor UnwrapCommand to u…
This commit is contained in:
Jeff Mitchell 2016-06-03 13:25:10 -04:00
commit 6f5fa23386
2 changed files with 42 additions and 36 deletions

View File

@ -1,5 +1,15 @@
package api
import (
"bytes"
"encoding/json"
"fmt"
)
const (
wrappedResponseLocation = "cubbyhole/response"
)
// Logical is used to perform logical backend operations on Vault.
type Logical struct {
c *Client
@ -80,3 +90,34 @@ func (c *Logical) Delete(path string) (*Secret, error) {
return nil, nil
}
func (c *Logical) Unwrap(wrappingToken string) (*Secret, error) {
origToken := c.c.Token()
defer c.c.SetToken(origToken)
c.c.SetToken(wrappingToken)
secret, err := c.Read(wrappedResponseLocation)
if err != nil {
return nil, fmt.Errorf("error reading %s: %s", wrappedResponseLocation, err)
}
if secret == nil {
return nil, fmt.Errorf("no value found at %s", wrappedResponseLocation)
}
if secret.Data == nil {
return nil, fmt.Errorf("\"data\" not found in wrapping response")
}
if _, ok := secret.Data["response"]; !ok {
return nil, fmt.Errorf("\"response\" not found in wrapping response \"data\" map")
}
wrappedSecret := new(Secret)
buf := bytes.NewBufferString(secret.Data["response"].(string))
dec := json.NewDecoder(buf)
dec.UseNumber()
if err := dec.Decode(wrappedSecret); err != nil {
return nil, fmt.Errorf("error unmarshaling wrapped secret: %s", err)
}
return wrappedSecret, nil
}

View File

@ -1,8 +1,6 @@
package command
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"strings"
@ -12,10 +10,6 @@ import (
"github.com/hashicorp/vault/meta"
)
const (
wrappedResponseLocation = "cubbyhole/response"
)
// UnwrapCommand is a Command that behaves like ReadCommand but specifically
// for unwrapping cubbyhole-wrapped secrets
type UnwrapCommand struct {
@ -58,9 +52,7 @@ func (c *UnwrapCommand) Run(args []string) int {
return 2
}
client.SetToken(tokenID)
secret, err = c.getUnwrappedResponse(client)
secret, err = client.Logical().Unwrap(tokenID)
if err != nil {
c.Ui.Error(err.Error())
return 1
@ -78,33 +70,6 @@ func (c *UnwrapCommand) Run(args []string) int {
return OutputSecret(c.Ui, format, secret)
}
// getUnwrappedResponse is a helper to do the actual reading and unwrapping
func (c *UnwrapCommand) getUnwrappedResponse(client *api.Client) (*api.Secret, error) {
secret, err := client.Logical().Read(wrappedResponseLocation)
if err != nil {
return nil, fmt.Errorf("Error reading %s: %s", wrappedResponseLocation, err)
}
if secret == nil {
return nil, fmt.Errorf("No value found at %s", wrappedResponseLocation)
}
if secret.Data == nil {
return nil, fmt.Errorf("\"data\" not found in wrapping response")
}
if _, ok := secret.Data["response"]; !ok {
return nil, fmt.Errorf("\"response\" not found in wrapping response \"data\" map")
}
wrappedSecret := new(api.Secret)
buf := bytes.NewBufferString(secret.Data["response"].(string))
dec := json.NewDecoder(buf)
dec.UseNumber()
if err := dec.Decode(wrappedSecret); err != nil {
return nil, fmt.Errorf("Error unmarshaling wrapped secret: %s", err)
}
return wrappedSecret, nil
}
func (c *UnwrapCommand) Synopsis() string {
return "Unwrap a wrapped secret"
}