mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	Allow token-renew to not be given a token; it will then use the
				
					
				
			renew-self endpoint. Otherwise it will use the renew endpoint, even if the token matches the client token. Adds an -increment flag to allow increments even with no token passed in. Fixes #1150
This commit is contained in:
		| @@ -2,8 +2,8 @@ package command | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" |  | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/hashicorp/vault/api" | 	"github.com/hashicorp/vault/api" | ||||||
| ) | ) | ||||||
| @@ -14,32 +14,45 @@ type TokenRenewCommand struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c *TokenRenewCommand) Run(args []string) int { | func (c *TokenRenewCommand) Run(args []string) int { | ||||||
| 	var format string | 	var format, increment string | ||||||
| 	flags := c.Meta.FlagSet("token-renew", FlagSetDefault) | 	flags := c.Meta.FlagSet("token-renew", FlagSetDefault) | ||||||
| 	flags.StringVar(&format, "format", "table", "") | 	flags.StringVar(&format, "format", "table", "") | ||||||
|  | 	flags.StringVar(&increment, "increment", "", "") | ||||||
| 	flags.Usage = func() { c.Ui.Error(c.Help()) } | 	flags.Usage = func() { c.Ui.Error(c.Help()) } | ||||||
| 	if err := flags.Parse(args); err != nil { | 	if err := flags.Parse(args); err != nil { | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	args = flags.Args() | 	args = flags.Args() | ||||||
| 	if len(args) < 1 { | 	if len(args) > 2 { | ||||||
| 		flags.Usage() | 		flags.Usage() | ||||||
| 		c.Ui.Error(fmt.Sprintf( | 		c.Ui.Error(fmt.Sprintf( | ||||||
| 			"\ntoken-renew expects at least one argument")) | 			"\ntoken-renew expects at most two arguments")) | ||||||
| 		return 1 | 		return 1 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var increment int | 	var token string | ||||||
| 	token := args[0] | 	if len(args) > 0 { | ||||||
| 	if len(args) > 1 { | 		token = args[0] | ||||||
| 		value, err := strconv.ParseInt(args[1], 10, 0) | 	} | ||||||
|  |  | ||||||
|  | 	var inc int | ||||||
|  | 	if len(args) == 2 { | ||||||
|  | 		dur, err := time.ParseDuration(args[1]) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			c.Ui.Error(fmt.Sprintf("Invalid increment: %s", err)) | 			c.Ui.Error(fmt.Sprintf("Invalid increment: %s", err)) | ||||||
| 			return 1 | 			return 1 | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		increment = int(value) | 		inc = int(dur / time.Second) | ||||||
|  | 	} else if increment != "" { | ||||||
|  | 		dur, err := time.ParseDuration(increment) | ||||||
|  | 		if err != nil { | ||||||
|  | 			c.Ui.Error(fmt.Sprintf("Invalid increment: %s", err)) | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		inc = int(dur / time.Second) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	client, err := c.Client() | 	client, err := c.Client() | ||||||
| @@ -52,10 +65,10 @@ func (c *TokenRenewCommand) Run(args []string) int { | |||||||
| 	// If the given token is the same as the client's, use renew-self instead | 	// If the given token is the same as the client's, use renew-self instead | ||||||
| 	// as this is far more likely to be allowed via policy | 	// as this is far more likely to be allowed via policy | ||||||
| 	var secret *api.Secret | 	var secret *api.Secret | ||||||
| 	if client.Token() == token { | 	if token == "" { | ||||||
| 		secret, err = client.Auth().Token().RenewSelf(increment) | 		secret, err = client.Auth().Token().RenewSelf(inc) | ||||||
| 	} else { | 	} else { | ||||||
| 		secret, err = client.Auth().Token().Renew(token, increment) | 		secret, err = client.Auth().Token().Renew(token, inc) | ||||||
| 	} | 	} | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		c.Ui.Error(fmt.Sprintf( | 		c.Ui.Error(fmt.Sprintf( | ||||||
| @@ -72,17 +85,20 @@ func (c *TokenRenewCommand) Synopsis() string { | |||||||
|  |  | ||||||
| func (c *TokenRenewCommand) Help() string { | func (c *TokenRenewCommand) Help() string { | ||||||
| 	helpText := ` | 	helpText := ` | ||||||
| Usage: vault token-renew [options] token [increment] | Usage: vault token-renew [options] [token] [increment] | ||||||
|  |  | ||||||
|   Renew an auth token, extending the amount of time it can be used. |   Renew an auth token, extending the amount of time it can be used. If a token | ||||||
|   Token is renewable only if there is a lease associated with it. |   is given to the command, '/auth/token/renew' will be called with the given | ||||||
|  |   token; otherwise, '/auth/token/renew-self' will be called with the client | ||||||
|  |   token. | ||||||
|  |  | ||||||
|   This command is similar to "renew", but "renew" is only for lease IDs. |   This command is similar to "renew", but "renew" is only for leases; this | ||||||
|   This command is only for tokens. |   command is only for tokens. | ||||||
|  |  | ||||||
|   An optional increment can be given to request a certain number of |   An optional increment can be given to request a certain number of seconds to | ||||||
|   seconds to increment the lease. This request is advisory; Vault may not |   increment the lease. This request is advisory; Vault may not adhere to it at | ||||||
|   adhere to it at all. |   all. If a token is being passed in on the command line, the increment can as | ||||||
|  |   well; otherwise it must be passed in via the '-increment' flag. | ||||||
|  |  | ||||||
| General Options: | General Options: | ||||||
|  |  | ||||||
| @@ -90,6 +106,11 @@ General Options: | |||||||
|  |  | ||||||
| Token Renew Options: | Token Renew Options: | ||||||
|  |  | ||||||
|  |   -increment=3600         The desired increment. If not supplied, Vault will | ||||||
|  |                           use the default TTL. If supplied, it may still be | ||||||
|  |                           ignored. This can be submitted as an integer number | ||||||
|  |                           of seconds or a string duration (e.g. "72h"). | ||||||
|  |  | ||||||
|   -format=table           The format for output. By default it is a whitespace- |   -format=table           The format for output. By default it is a whitespace- | ||||||
|                           delimited table. This can also be json or yaml. |                           delimited table. This can also be json or yaml. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -41,9 +41,136 @@ func TestTokenRenew(t *testing.T) { | |||||||
| 		t.Fatalf("err: %s", err) | 		t.Fatalf("err: %s", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Verify it worked | 	// Renew, passing in the token | ||||||
| 	args = append(args, resp.Auth.ClientToken) | 	args = append(args, resp.Auth.ClientToken) | ||||||
| 	if code := c.Run(args); code != 0 { | 	if code := c.Run(args); code != 0 { | ||||||
| 		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | 		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestTokenRenewWithIncrement(t *testing.T) { | ||||||
|  | 	core, _, token := vault.TestCoreUnsealed(t) | ||||||
|  | 	ln, addr := http.TestServer(t, core) | ||||||
|  | 	defer ln.Close() | ||||||
|  |  | ||||||
|  | 	ui := new(cli.MockUi) | ||||||
|  | 	c := &TokenRenewCommand{ | ||||||
|  | 		Meta: Meta{ | ||||||
|  | 			ClientToken: token, | ||||||
|  | 			Ui:          ui, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	args := []string{ | ||||||
|  | 		"-address", addr, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Run it once for client | ||||||
|  | 	c.Run(args) | ||||||
|  |  | ||||||
|  | 	// Create a token | ||||||
|  | 	client, err := c.Client() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  | 	resp, err := client.Auth().Token().Create(&api.TokenCreateRequest{ | ||||||
|  | 		Lease: "1h", | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Renew, passing in the token | ||||||
|  | 	args = append(args, resp.Auth.ClientToken) | ||||||
|  | 	args = append(args, "72h") | ||||||
|  | 	if code := c.Run(args); code != 0 { | ||||||
|  | 		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestTokenRenewSelf(t *testing.T) { | ||||||
|  | 	core, _, token := vault.TestCoreUnsealed(t) | ||||||
|  | 	ln, addr := http.TestServer(t, core) | ||||||
|  | 	defer ln.Close() | ||||||
|  |  | ||||||
|  | 	ui := new(cli.MockUi) | ||||||
|  | 	c := &TokenRenewCommand{ | ||||||
|  | 		Meta: Meta{ | ||||||
|  | 			ClientToken: token, | ||||||
|  | 			Ui:          ui, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	args := []string{ | ||||||
|  | 		"-address", addr, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Run it once for client | ||||||
|  | 	c.Run(args) | ||||||
|  |  | ||||||
|  | 	// Create a token | ||||||
|  | 	client, err := c.Client() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  | 	resp, err := client.Auth().Token().Create(&api.TokenCreateRequest{ | ||||||
|  | 		Lease: "1h", | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  | 	if resp.Auth.ClientToken == "" { | ||||||
|  | 		t.Fatal("returned client token is empty") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	c.Meta.ClientToken = resp.Auth.ClientToken | ||||||
|  |  | ||||||
|  | 	// Renew using the self endpoint | ||||||
|  | 	if code := c.Run(args); code != 0 { | ||||||
|  | 		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestTokenRenewSelfWithIncrement(t *testing.T) { | ||||||
|  | 	core, _, token := vault.TestCoreUnsealed(t) | ||||||
|  | 	ln, addr := http.TestServer(t, core) | ||||||
|  | 	defer ln.Close() | ||||||
|  |  | ||||||
|  | 	ui := new(cli.MockUi) | ||||||
|  | 	c := &TokenRenewCommand{ | ||||||
|  | 		Meta: Meta{ | ||||||
|  | 			ClientToken: token, | ||||||
|  | 			Ui:          ui, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	args := []string{ | ||||||
|  | 		"-address", addr, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Run it once for client | ||||||
|  | 	c.Run(args) | ||||||
|  |  | ||||||
|  | 	// Create a token | ||||||
|  | 	client, err := c.Client() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  | 	resp, err := client.Auth().Token().Create(&api.TokenCreateRequest{ | ||||||
|  | 		Lease: "1h", | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("err: %s", err) | ||||||
|  | 	} | ||||||
|  | 	if resp.Auth.ClientToken == "" { | ||||||
|  | 		t.Fatal("returned client token is empty") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	c.Meta.ClientToken = resp.Auth.ClientToken | ||||||
|  |  | ||||||
|  | 	args = append(args, "-increment=72h") | ||||||
|  | 	// Renew using the self endpoint | ||||||
|  | 	if code := c.Run(args); code != 0 { | ||||||
|  | 		t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jeff Mitchell
					Jeff Mitchell