command/renew

This commit is contained in:
Mitchell Hashimoto
2015-04-13 17:37:39 -07:00
parent 4ee0222411
commit 4faf951f03
5 changed files with 168 additions and 3 deletions

View File

@@ -1,7 +1,13 @@
package api
func (c *Sys) Renew(id string) (*Secret, error) {
func (c *Sys) Renew(id string, increment int) (*Secret, error) {
r := c.c.NewRequest("PUT", "/v1/sys/renew/"+id)
body := map[string]interface{}{"increment": increment}
if err := r.SetJSONBody(body); err != nil {
return nil, err
}
resp, err := c.c.RawRequest(r)
if err != nil {
return nil, err

View File

@@ -132,6 +132,12 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
}, nil
},
"renew": func() (cli.Command, error) {
return &command.RenewCommand{
Meta: meta,
}, nil
},
"revoke": func() (cli.Command, error) {
return &command.RevokeCommand{
Meta: meta,

View File

@@ -46,6 +46,10 @@ func (c *ReadCommand) Run(args []string) int {
return 1
}
return c.output(format, secret)
}
func (c *ReadCommand) output(format string, secret *api.Secret) int {
switch format {
case "json":
return c.formatJSON(secret)
@@ -54,8 +58,6 @@ func (c *ReadCommand) Run(args []string) int {
default:
return c.formatTable(secret, true)
}
return 0
}
func (c *ReadCommand) formatJSON(s *api.Secret) int {

104
command/renew.go Normal file
View File

@@ -0,0 +1,104 @@
package command
import (
"fmt"
"strconv"
"strings"
)
// RenewCommand is a Command that mounts a new mount.
type RenewCommand struct {
Meta
}
func (c *RenewCommand) Run(args []string) int {
var format string
flags := c.Meta.FlagSet("renew", FlagSetDefault)
flags.StringVar(&format, "format", "table", "")
flags.Usage = func() { c.Ui.Error(c.Help()) }
if err := flags.Parse(args); err != nil {
return 1
}
args = flags.Args()
if len(args) < 1 || len(args) >= 3 {
flags.Usage()
c.Ui.Error(fmt.Sprintf(
"\nRenew expects at least one argument: the lease ID to renew"))
return 1
}
var increment int
leaseId := args[0]
if len(args) > 1 {
parsed, err := strconv.ParseInt(args[1], 10, 0)
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Invalid increment, must be an int: %s", err))
return 1
}
increment = int(parsed)
}
client, err := c.Client()
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Error initializing client: %s", err))
return 2
}
secret, err := client.Sys().Renew(leaseId, increment)
if err != nil {
c.Ui.Error(fmt.Sprintf(
"Renew error: %s", err))
return 1
}
// Use the ReadCommand in order to format our output
var read ReadCommand
read.Meta = c.Meta
return read.output(format, secret)
}
func (c *RenewCommand) Synopsis() string {
return "Renew the lease of a secret"
}
func (c *RenewCommand) Help() string {
helpText := `
Usage: vault renew [options] id [increment]
Renew the lease on a secret, extending the time that it can be used
before it is revoked by Vault.
Every secret in Vault has a lease associated with it. If the user of
the secret wants to use it longer than the lease, then it must be
renewed. Renewing the lease will not change the contents of the secret.
To renew a secret, run this command with the lease ID returned when it
was read. Optionally, request a specific increment in seconds. Vault may
is not required to honor this request.
General Options:
-address=TODO The address of the Vault server.
-ca-cert=path Path to a PEM encoded CA cert file to use to
verify the Vault server SSL certificate.
-ca-path=path Path to a directory of PEM encoded CA cert files
to verify the Vault server SSL certificate. If both
-ca-cert and -ca-path are specified, -ca-path is used.
-insecure Do not verify TLS certificate. This is highly
not recommended. This is especially not recommended
for unsealing a vault.
Renew Options:
-format=table The format for output. By default it is a whitespace-
delimited table. This can also be json.
`
return strings.TrimSpace(helpText)
}

47
command/renew_test.go Normal file
View File

@@ -0,0 +1,47 @@
package command
import (
"testing"
"github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/vault"
"github.com/mitchellh/cli"
)
func TestRenew(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := http.TestServer(t, core)
defer ln.Close()
ui := new(cli.MockUi)
c := &RenewCommand{
Meta: Meta{
ClientToken: token,
Ui: ui,
},
}
// write a secret with a lease
client := testClient(t, addr, token)
_, err := client.Logical().Write("secret/foo", map[string]interface{}{
"key": "value",
"lease": "1m",
})
if err != nil {
t.Fatalf("err: %s", err)
}
// read the secret to get its lease ID
secret, err := client.Logical().Read("secret/foo")
if err != nil {
t.Fatalf("err: %s", err)
}
args := []string{
"-address", addr,
secret.LeaseID,
}
if code := c.Run(args); code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
}
}