Add command to look up a lease by ID (#11129)
* snapshot * basic test * update command and add documentation * update help text * typo * add changelog for lease lookup command * run go mod vendor * remove tabs from help output
This commit is contained in:
parent
eb36b68710
commit
5353279e75
|
@ -27,6 +27,27 @@ func (c *Sys) Renew(id string, increment int) (*Secret, error) {
|
||||||
return ParseSecret(resp.Body)
|
return ParseSecret(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Sys) Lookup(id string) (*Secret, error) {
|
||||||
|
r := c.c.NewRequest("PUT", "/v1/sys/leases/lookup")
|
||||||
|
|
||||||
|
body := map[string]interface{}{
|
||||||
|
"lease_id": id,
|
||||||
|
}
|
||||||
|
if err := r.SetJSONBody(body); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
defer cancelFunc()
|
||||||
|
resp, err := c.c.RawRequestWithContext(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
return ParseSecret(resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Sys) Revoke(id string) error {
|
func (c *Sys) Revoke(id string) error {
|
||||||
r := c.c.NewRequest("PUT", "/v1/sys/leases/revoke")
|
r := c.c.NewRequest("PUT", "/v1/sys/leases/revoke")
|
||||||
body := map[string]interface{}{
|
body := map[string]interface{}{
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:feature
|
||||||
|
cli/api: Add lease lookup command
|
||||||
|
```
|
|
@ -286,6 +286,11 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
|
||||||
BaseCommand: getBaseCommand(),
|
BaseCommand: getBaseCommand(),
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
|
"lease lookup": func() (cli.Command, error) {
|
||||||
|
return &LeaseLookupCommand{
|
||||||
|
BaseCommand: getBaseCommand(),
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
"lease revoke": func() (cli.Command, error) {
|
"lease revoke": func() (cli.Command, error) {
|
||||||
return &LeaseRevokeCommand{
|
return &LeaseRevokeCommand{
|
||||||
BaseCommand: getBaseCommand(),
|
BaseCommand: getBaseCommand(),
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
|
"github.com/posener/complete"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ cli.Command = (*LeaseLookupCommand)(nil)
|
||||||
|
var _ cli.CommandAutocomplete = (*LeaseLookupCommand)(nil)
|
||||||
|
|
||||||
|
type LeaseLookupCommand struct {
|
||||||
|
*BaseCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) Synopsis() string {
|
||||||
|
return "Lookup the lease of a secret"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) Help() string {
|
||||||
|
helpText := `
|
||||||
|
Usage: vault lease lookup ID
|
||||||
|
|
||||||
|
Lookup the lease information of a secret.
|
||||||
|
|
||||||
|
Every secret in Vault has a lease associated with it. Users can look up
|
||||||
|
information on the lease by referencing the lease ID.
|
||||||
|
|
||||||
|
Lookup lease of a secret:
|
||||||
|
|
||||||
|
$ vault lease lookup database/creds/readonly/2f6a614c...
|
||||||
|
|
||||||
|
` + c.Flags().Help()
|
||||||
|
|
||||||
|
return strings.TrimSpace(helpText)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) Flags() *FlagSets {
|
||||||
|
set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
|
||||||
|
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) AutocompleteArgs() complete.Predictor {
|
||||||
|
return complete.PredictAnything
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) AutocompleteFlags() complete.Flags {
|
||||||
|
return c.Flags().Completions()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *LeaseLookupCommand) Run(args []string) int {
|
||||||
|
f := c.Flags()
|
||||||
|
|
||||||
|
if err := f.Parse(args); err != nil {
|
||||||
|
c.UI.Error(err.Error())
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
leaseID := ""
|
||||||
|
|
||||||
|
args = f.Args()
|
||||||
|
switch len(args) {
|
||||||
|
case 0:
|
||||||
|
c.UI.Error("Missing ID!")
|
||||||
|
return 1
|
||||||
|
case 1:
|
||||||
|
leaseID = strings.TrimSpace(args[0])
|
||||||
|
default:
|
||||||
|
c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args)))
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := c.Client()
|
||||||
|
if err != nil {
|
||||||
|
c.UI.Error(err.Error())
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
secret, err := client.Sys().Lookup(leaseID)
|
||||||
|
if err != nil {
|
||||||
|
c.UI.Error(fmt.Sprintf("error looking up lease id %s: %s", leaseID, err))
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
return OutputSecret(c.UI, secret)
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/api"
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
func testLeaseLookupCommand(tb testing.TB) (*cli.MockUi, *LeaseLookupCommand) {
|
||||||
|
tb.Helper()
|
||||||
|
|
||||||
|
ui := cli.NewMockUi()
|
||||||
|
return ui, &LeaseLookupCommand{
|
||||||
|
BaseCommand: &BaseCommand{
|
||||||
|
UI: ui,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// testLeaseLookupCommandMountAndLease mounts a leased secret backend and returns
|
||||||
|
// the leaseID of an item.
|
||||||
|
func testLeaseLookupCommandMountAndLease(tb testing.TB, client *api.Client) string {
|
||||||
|
if err := client.Sys().Mount("testing", &api.MountInput{
|
||||||
|
Type: "generic-leased",
|
||||||
|
}); err != nil {
|
||||||
|
tb.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := client.Logical().Write("testing/foo", map[string]interface{}{
|
||||||
|
"key": "value",
|
||||||
|
"lease": "5m",
|
||||||
|
}); err != nil {
|
||||||
|
tb.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the secret back to get the leaseID
|
||||||
|
secret, err := client.Logical().Read("testing/foo")
|
||||||
|
if err != nil {
|
||||||
|
tb.Fatal(err)
|
||||||
|
}
|
||||||
|
if secret == nil || secret.LeaseID == "" {
|
||||||
|
tb.Fatalf("missing secret or lease: %#v", secret)
|
||||||
|
}
|
||||||
|
|
||||||
|
return secret.LeaseID
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLeaseLookupCommand_Run tests basic lookup
|
||||||
|
func TestLeaseLookupCommand_Run(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
t.Run("empty", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
client, closer := testVaultServer(t)
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
_ = testLeaseLookupCommandMountAndLease(t, client)
|
||||||
|
|
||||||
|
ui, cmd := testLeaseLookupCommand(t)
|
||||||
|
cmd.client = client
|
||||||
|
|
||||||
|
code := cmd.Run(nil)
|
||||||
|
if exp := 1; code != exp {
|
||||||
|
t.Errorf("expected %d to be %d", code, exp)
|
||||||
|
}
|
||||||
|
|
||||||
|
combined := ui.OutputWriter.String() + ui.ErrorWriter.String()
|
||||||
|
expectedMsg := "Missing ID!"
|
||||||
|
if !strings.Contains(combined, expectedMsg) {
|
||||||
|
t.Errorf("expected %q to contain %q", combined, expectedMsg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("integration", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
client, closer := testVaultServer(t)
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
leaseID := testLeaseLookupCommandMountAndLease(t, client)
|
||||||
|
|
||||||
|
_, cmd := testLeaseLookupCommand(t)
|
||||||
|
cmd.client = client
|
||||||
|
|
||||||
|
code := cmd.Run([]string{leaseID})
|
||||||
|
if exp := 0; code != exp {
|
||||||
|
t.Errorf("expected %d to be %d", code, exp)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("no_tabs", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
_, cmd := testLeaseLookupCommand(t)
|
||||||
|
assertNoTabs(t, cmd)
|
||||||
|
})
|
||||||
|
}
|
|
@ -27,6 +27,27 @@ func (c *Sys) Renew(id string, increment int) (*Secret, error) {
|
||||||
return ParseSecret(resp.Body)
|
return ParseSecret(resp.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Sys) Lookup(id string) (*Secret, error) {
|
||||||
|
r := c.c.NewRequest("PUT", "/v1/sys/leases/lookup")
|
||||||
|
|
||||||
|
body := map[string]interface{}{
|
||||||
|
"lease_id": id,
|
||||||
|
}
|
||||||
|
if err := r.SetJSONBody(body); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
defer cancelFunc()
|
||||||
|
resp, err := c.c.RawRequestWithContext(ctx, r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
return ParseSecret(resp.Body)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Sys) Revoke(id string) error {
|
func (c *Sys) Revoke(id string) error {
|
||||||
r := c.c.NewRequest("PUT", "/v1/sys/leases/revoke")
|
r := c.c.NewRequest("PUT", "/v1/sys/leases/revoke")
|
||||||
body := map[string]interface{}{
|
body := map[string]interface{}{
|
||||||
|
|
|
@ -14,6 +14,20 @@ secrets. For leases attached to tokens, use the [`vault token`](/docs/commands/t
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
Lookup a lease:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault lease lookup database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
Key Value
|
||||||
|
--- -----
|
||||||
|
expire_time 2021-03-17T11:55:50.755313-05:00
|
||||||
|
id database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
issue_time 2021-03-17T11:45:50.755312-05:00
|
||||||
|
last_renewal <nil>
|
||||||
|
renewable true
|
||||||
|
ttl 9m52s
|
||||||
|
```
|
||||||
|
|
||||||
Renew a lease:
|
Renew a lease:
|
||||||
|
|
||||||
```shell-session
|
```shell-session
|
||||||
|
@ -40,6 +54,7 @@ Usage: vault lease <subcommand> [options] [args]
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
Subcommands:
|
Subcommands:
|
||||||
|
lookup Lookup lease information by lease id
|
||||||
renew Renews the lease of a secret
|
renew Renews the lease of a secret
|
||||||
revoke Revokes leases and secrets
|
revoke Revokes leases and secrets
|
||||||
```
|
```
|
||||||
|
|
|
@ -14,6 +14,20 @@ secrets. For leases attached to tokens, use the [`vault token`](/docs/commands/t
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
Lookup a lease:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault lease lookup database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
Key Value
|
||||||
|
--- -----
|
||||||
|
expire_time 2021-03-17T11:55:50.755313-05:00
|
||||||
|
id database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
issue_time 2021-03-17T11:45:50.755312-05:00
|
||||||
|
last_renewal <nil>
|
||||||
|
renewable true
|
||||||
|
ttl 9m52s
|
||||||
|
```
|
||||||
|
|
||||||
Renew a lease:
|
Renew a lease:
|
||||||
|
|
||||||
```shell-session
|
```shell-session
|
||||||
|
@ -40,6 +54,7 @@ Usage: vault lease <subcommand> [options] [args]
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
Subcommands:
|
Subcommands:
|
||||||
|
lookup Lookup lease information by lease id
|
||||||
renew Renews the lease of a secret
|
renew Renews the lease of a secret
|
||||||
revoke Revokes leases and secrets
|
revoke Revokes leases and secrets
|
||||||
```
|
```
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
layout: docs
|
||||||
|
page_title: lease lookup - Command
|
||||||
|
sidebar_title: <code>lookup</code>
|
||||||
|
description: |-
|
||||||
|
The "lease lookup" command retrieves information about a lease.
|
||||||
|
---
|
||||||
|
|
||||||
|
# lease lookup
|
||||||
|
|
||||||
|
The `lease lookup` command retrieves information on the lease of a secret.
|
||||||
|
|
||||||
|
Every secret in Vault has a lease associated with it. Users can look up
|
||||||
|
information on the lease by referencing the lease ID.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Lookup a lease:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ vault lease lookup database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
Key Value
|
||||||
|
--- -----
|
||||||
|
expire_time 2021-03-17T11:55:50.755313-05:00
|
||||||
|
id database/creds/readonly/27e1b9a1-27b8-83d9-9fe0-d99d786bdc83
|
||||||
|
issue_time 2021-03-17T11:45:50.755312-05:00
|
||||||
|
last_renewal <nil>
|
||||||
|
renewable true
|
||||||
|
ttl 9m52s
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
There are no flags beyond the [standard set of flags](/docs/commands)
|
||||||
|
included on all commands.
|
Loading…
Reference in New Issue