Switch per-mount values to strings going in and seconds coming out, like other commands. Indicate deprecation of 'lease' in the token backend.
This commit is contained in:
parent
ae8192f990
commit
70ce824267
@ -5,7 +5,7 @@ DEPRECATIONS/BREAKING CHANGES:
|
||||
Note: deprecations and breaking changes in upcoming releases are announced ahead of time on the "vault-tool" mailing list.
|
||||
|
||||
* **Cookie Authentication Removed**: As of 0.3 the only way to authenticate is via the X-Vault-Token header. Cookie authentication was hard to properly test, could result in browsers/tools/applications saving tokens in plaintext on disk, and other issues. [GH-564]
|
||||
* **Terminology/Field Names**: Vault is transitioning from overloading the term "lease" to mean both "a set of metadata" and "the amount of time the metadata is valid". The latter is now being referred to as TTL (or "lease_duration" for backwards-compatibility); some parts of Vault have already switched to using "ttl" and others will follow in upcoming releases. In particular, both the "generic" and "pki" backend accept both "ttl" and "lease" but in 0.4 only "ttl" will be accepted. [GH-528]
|
||||
* **Terminology/Field Names**: Vault is transitioning from overloading the term "lease" to mean both "a set of metadata" and "the amount of time the metadata is valid". The latter is now being referred to as TTL (or "lease_duration" for backwards-compatibility); some parts of Vault have already switched to using "ttl" and others will follow in upcoming releases. In particular, the "token", "generic", and "pki" backends accept both "ttl" and "lease" but in 0.4 only "ttl" will be accepted. [GH-528]
|
||||
* **Downgrade Not Supported**: Due to enhancements in the storage subsytem, values written by Vault 0.3+ will not be able to be read by prior versions of Vault. There are no expected upgrade issues, however, as with all critical infrastructure it is recommended to back up Vault's physical storage before upgrading.
|
||||
|
||||
FEATURES:
|
||||
|
@ -2,12 +2,11 @@ package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
)
|
||||
|
||||
func (c *Sys) ListMounts() (map[string]*Mount, error) {
|
||||
func (c *Sys) ListMounts() (map[string]*MountOutput, error) {
|
||||
r := c.c.NewRequest("GET", "/v1/sys/mounts")
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
@ -15,12 +14,12 @@ func (c *Sys) ListMounts() (map[string]*Mount, error) {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var result map[string]*Mount
|
||||
var result map[string]*MountOutput
|
||||
err = resp.DecodeJSON(&result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (c *Sys) Mount(path string, mountInfo *Mount) error {
|
||||
func (c *Sys) Mount(path string, mountInfo *MountInput) error {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -79,7 +78,7 @@ func (c *Sys) Remount(from, to string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Sys) TuneMount(path string, config APIMountConfig) error {
|
||||
func (c *Sys) TuneMount(path string, config MountConfigInput) error {
|
||||
if err := c.checkMountPath(path); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -119,13 +118,24 @@ func (c *Sys) checkMountPath(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
Type string `json:"type" structs:"type"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
Config APIMountConfig `json:"config" structs:"config"`
|
||||
type MountInput struct {
|
||||
Type string `json:"type" structs:"type"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
Config MountConfigInput `json:"config" structs:"config"`
|
||||
}
|
||||
|
||||
type APIMountConfig struct {
|
||||
DefaultLeaseTTL *time.Duration `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL *time.Duration `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
type MountConfigInput struct {
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
}
|
||||
|
||||
type MountOutput struct {
|
||||
Type string `json:"type" structs:"type"`
|
||||
Description string `json:"description" structs:"description"`
|
||||
Config MountConfigOutput `json:"config" structs:"config"`
|
||||
}
|
||||
|
||||
type MountConfigOutput struct {
|
||||
DefaultLeaseTTL int `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
)
|
||||
@ -47,29 +46,13 @@ func (c *MountCommand) Run(args []string) int {
|
||||
return 2
|
||||
}
|
||||
|
||||
mountInfo := &api.Mount{
|
||||
mountInfo := &api.MountInput{
|
||||
Type: mountType,
|
||||
Description: description,
|
||||
Config: api.APIMountConfig{},
|
||||
}
|
||||
|
||||
if defaultLeaseTTL != "" {
|
||||
defTTL, err := time.ParseDuration(defaultLeaseTTL)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Error parsing default lease TTL duration: %s", err))
|
||||
return 2
|
||||
}
|
||||
mountInfo.Config.DefaultLeaseTTL = &defTTL
|
||||
}
|
||||
if maxLeaseTTL != "" {
|
||||
maxTTL, err := time.ParseDuration(maxLeaseTTL)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Error parsing max lease TTL duration: %s", err))
|
||||
return 2
|
||||
}
|
||||
mountInfo.Config.MaxLeaseTTL = &maxTTL
|
||||
Config: api.MountConfigInput{
|
||||
DefaultLeaseTTL: defaultLeaseTTL,
|
||||
MaxLeaseTTL: maxLeaseTTL,
|
||||
},
|
||||
}
|
||||
|
||||
if err := client.Sys().Mount(path, mountInfo); err != nil {
|
||||
|
@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ryanuber/columnize"
|
||||
@ -43,9 +44,26 @@ func (c *MountsCommand) Run(args []string) int {
|
||||
columns := []string{"Path | Type | Default TTL | Max TTL | Description"}
|
||||
for _, path := range paths {
|
||||
mount := mounts[path]
|
||||
|
||||
defTTL := "system"
|
||||
switch {
|
||||
case mount.Type == "system":
|
||||
defTTL = "n/a"
|
||||
case mount.Type == "cubbyhole":
|
||||
defTTL = "n/a"
|
||||
case mount.Config.DefaultLeaseTTL != 0:
|
||||
defTTL = strconv.Itoa(mount.Config.DefaultLeaseTTL)
|
||||
}
|
||||
maxTTL := "system"
|
||||
switch {
|
||||
case mount.Type == "system":
|
||||
maxTTL = "n/a"
|
||||
case mount.Type == "cubbyhole":
|
||||
maxTTL = "n/a"
|
||||
case mount.Config.MaxLeaseTTL != 0:
|
||||
maxTTL = strconv.Itoa(mount.Config.MaxLeaseTTL)
|
||||
}
|
||||
columns = append(columns, fmt.Sprintf(
|
||||
"%s | %s | %s | %s | %s", path, mount.Type, mount.Config.DefaultLeaseTTL, mount.Config.MaxLeaseTTL, mount.Description))
|
||||
"%s | %s | %s | %s | %s", path, mount.Type, defTTL, maxTTL, mount.Description))
|
||||
}
|
||||
|
||||
c.Ui.Output(columnize.SimpleFormat(columns))
|
||||
@ -64,7 +82,7 @@ Usage: vault mounts [options]
|
||||
|
||||
This command lists the mounted backends, their mount points, the
|
||||
configured TTLs, and a human-friendly description of the mount point.
|
||||
A TTL of '0' indicates that the system default is being used.
|
||||
A TTL of 'system' indicates that the system default is being used.
|
||||
|
||||
General Options:
|
||||
|
||||
|
@ -3,7 +3,6 @@ package command
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/api"
|
||||
)
|
||||
@ -34,24 +33,9 @@ func (c *MountTuneCommand) Run(args []string) int {
|
||||
|
||||
path := args[0]
|
||||
|
||||
mountConfig := api.APIMountConfig{}
|
||||
if defaultLeaseTTL != "" {
|
||||
defTTL, err := time.ParseDuration(defaultLeaseTTL)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Error parsing default lease TTL duration: %s", err))
|
||||
return 2
|
||||
}
|
||||
mountConfig.DefaultLeaseTTL = &defTTL
|
||||
}
|
||||
if maxLeaseTTL != "" {
|
||||
maxTTL, err := time.ParseDuration(maxLeaseTTL)
|
||||
if err != nil {
|
||||
c.Ui.Error(fmt.Sprintf(
|
||||
"Error parsing max lease TTL duration: %s", err))
|
||||
return 2
|
||||
}
|
||||
mountConfig.MaxLeaseTTL = &maxTTL
|
||||
mountConfig := api.MountConfigInput{
|
||||
DefaultLeaseTTL: defaultLeaseTTL,
|
||||
MaxLeaseTTL: maxLeaseTTL,
|
||||
}
|
||||
|
||||
client, err := c.Client()
|
||||
@ -83,7 +67,7 @@ func (c *MountTuneCommand) Help() string {
|
||||
|
||||
Tune configuration options for a mounted secret backend.
|
||||
|
||||
Example: vault tune-mount -default-lease-ttl="24h" secret/
|
||||
Example: vault tune-mount -default-lease-ttl="24h" secret
|
||||
|
||||
General Options:
|
||||
|
||||
@ -92,14 +76,14 @@ General Options:
|
||||
Mount Options:
|
||||
|
||||
-default-lease-ttl=<duration> Default lease time-to-live for this backend.
|
||||
If not specified, uses the global default, or
|
||||
the previously set value. Set to '0' to
|
||||
explicitly set it to use the global default.
|
||||
If not specified, uses the system default, or
|
||||
the previously set value. Set to 'system' to
|
||||
explicitly set it to use the system default.
|
||||
|
||||
-max-lease-ttl=<duration> Max lease time-to-live for this backend.
|
||||
If not specified, uses the global default, or
|
||||
the previously set value. Set to '0' to
|
||||
explicitly set it to use the global default.
|
||||
If not specified, uses the system default, or
|
||||
the previously set value. Set to 'system' to
|
||||
explicitly set it to use the system default.
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
|
@ -3,7 +3,6 @@ package http
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
@ -293,37 +292,37 @@ func TestSysTuneMount(t *testing.T) {
|
||||
|
||||
// Shorter than system default
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"default_lease_ttl": time.Duration(time.Hour * 72),
|
||||
"default_lease_ttl": "72h",
|
||||
})
|
||||
testResponseStatus(t, resp, 204)
|
||||
|
||||
// Longer than system max
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"default_lease_ttl": time.Duration(time.Hour * 72000),
|
||||
"default_lease_ttl": "72000h",
|
||||
})
|
||||
testResponseStatus(t, resp, 400)
|
||||
|
||||
// Longer than system default
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"max_lease_ttl": time.Duration(time.Hour * 72000),
|
||||
"max_lease_ttl": "72000h",
|
||||
})
|
||||
testResponseStatus(t, resp, 204)
|
||||
|
||||
// Longer than backend max
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"default_lease_ttl": time.Duration(time.Hour * 72001),
|
||||
"default_lease_ttl": "72001h",
|
||||
})
|
||||
testResponseStatus(t, resp, 400)
|
||||
|
||||
// Shorter than backend default
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"max_lease_ttl": time.Duration(time.Hour * 1),
|
||||
"max_lease_ttl": "1h",
|
||||
})
|
||||
testResponseStatus(t, resp, 400)
|
||||
|
||||
// Shorter than backend max, longer than system max
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"default_lease_ttl": time.Duration(time.Hour * 71999),
|
||||
"default_lease_ttl": "71999h",
|
||||
})
|
||||
testResponseStatus(t, resp, 204)
|
||||
|
||||
@ -333,8 +332,8 @@ func TestSysTuneMount(t *testing.T) {
|
||||
"description": "foo",
|
||||
"type": "generic",
|
||||
"config": map[string]interface{}{
|
||||
"default_lease_ttl": float64(time.Duration(time.Hour * 71999)),
|
||||
"max_lease_ttl": float64(time.Duration(time.Hour * 72000)),
|
||||
"default_lease_ttl": float64(259196400),
|
||||
"max_lease_ttl": float64(259200000),
|
||||
},
|
||||
},
|
||||
"secret/": map[string]interface{}{
|
||||
@ -374,8 +373,8 @@ func TestSysTuneMount(t *testing.T) {
|
||||
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/foo/tune")
|
||||
actual = map[string]interface{}{}
|
||||
expected = map[string]interface{}{
|
||||
"default_lease_ttl": float64(time.Duration(time.Hour * 71999)),
|
||||
"max_lease_ttl": float64(time.Duration(time.Hour * 72000)),
|
||||
"default_lease_ttl": float64(259196400),
|
||||
"max_lease_ttl": float64(259200000),
|
||||
}
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
@ -386,16 +385,16 @@ func TestSysTuneMount(t *testing.T) {
|
||||
|
||||
// Set a low max
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/secret/tune", map[string]interface{}{
|
||||
"default_lease_ttl": time.Duration(time.Second * 40),
|
||||
"max_lease_ttl": time.Duration(time.Second * 80),
|
||||
"default_lease_ttl": "40s",
|
||||
"max_lease_ttl": "80s",
|
||||
})
|
||||
testResponseStatus(t, resp, 204)
|
||||
|
||||
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/secret/tune")
|
||||
actual = map[string]interface{}{}
|
||||
expected = map[string]interface{}{
|
||||
"default_lease_ttl": float64(time.Duration(time.Second * 40)),
|
||||
"max_lease_ttl": float64(time.Duration(time.Second * 80)),
|
||||
"default_lease_ttl": float64(40),
|
||||
"max_lease_ttl": float64(80),
|
||||
}
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
@ -421,7 +420,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
testResponseBody(t, resp, &result)
|
||||
|
||||
expected = map[string]interface{}{
|
||||
"lease_duration": int(time.Duration(time.Second * 80).Seconds()),
|
||||
"lease_duration": int(80),
|
||||
"lease_id": result.LeaseID,
|
||||
}
|
||||
|
||||
@ -441,7 +440,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
testResponseBody(t, resp, &result)
|
||||
|
||||
expected = map[string]interface{}{
|
||||
"lease_duration": int(time.Duration(time.Second * 40).Seconds()),
|
||||
"lease_duration": int(40),
|
||||
"lease_id": result.LeaseID,
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ func Test(t TestT, c TestCase) {
|
||||
|
||||
// Mount the backend
|
||||
prefix := "mnt"
|
||||
mountInfo := &api.Mount{
|
||||
mountInfo := &api.MountInput{
|
||||
Type: "test",
|
||||
Description: "acceptance test",
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
@ -54,11 +53,11 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) logical.Backend
|
||||
Description: strings.TrimSpace(sysHelp["mount_path"][0]),
|
||||
},
|
||||
"default_lease_ttl": &framework.FieldSchema{
|
||||
Type: framework.TypeDurationSecond,
|
||||
Type: framework.TypeString,
|
||||
Description: strings.TrimSpace(sysHelp["tune_default_lease_ttl"][0]),
|
||||
},
|
||||
"max_lease_ttl": &framework.FieldSchema{
|
||||
Type: framework.TypeDurationSecond,
|
||||
Type: framework.TypeString,
|
||||
Description: strings.TrimSpace(sysHelp["tune_max_lease_ttl"][0]),
|
||||
},
|
||||
},
|
||||
@ -378,8 +377,12 @@ func (b *SystemBackend) handleMountTable(
|
||||
info := map[string]interface{}{
|
||||
"type": entry.Type,
|
||||
"description": entry.Description,
|
||||
"config": structs.Map(entry.Config),
|
||||
"config": map[string]interface{}{
|
||||
"default_lease_ttl": int(entry.Config.DefaultLeaseTTL.Seconds()),
|
||||
"max_lease_ttl": int(entry.Config.MaxLeaseTTL.Seconds()),
|
||||
},
|
||||
}
|
||||
|
||||
resp.Data[entry.Path] = info
|
||||
}
|
||||
|
||||
@ -395,9 +398,14 @@ func (b *SystemBackend) handleMount(
|
||||
description := data.Get("description").(string)
|
||||
|
||||
var config MountConfig
|
||||
|
||||
var apiConfig struct {
|
||||
DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
||||
MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
|
||||
}
|
||||
configMap := data.Get("config").(map[string]interface{})
|
||||
if configMap != nil && len(configMap) != 0 {
|
||||
err := mapstructure.Decode(configMap, &config)
|
||||
err := mapstructure.Decode(configMap, &apiConfig)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(
|
||||
"unable to convert given mount config information"),
|
||||
@ -405,6 +413,44 @@ func (b *SystemBackend) handleMount(
|
||||
}
|
||||
}
|
||||
|
||||
switch apiConfig.DefaultLeaseTTL {
|
||||
case "":
|
||||
case "system":
|
||||
default:
|
||||
tmpDef, err := time.ParseDuration(apiConfig.DefaultLeaseTTL)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"unable to parse default TTL of %s: %s", apiConfig.DefaultLeaseTTL, err)),
|
||||
logical.ErrInvalidRequest
|
||||
}
|
||||
config.DefaultLeaseTTL = tmpDef
|
||||
}
|
||||
|
||||
switch apiConfig.MaxLeaseTTL {
|
||||
case "":
|
||||
case "system":
|
||||
default:
|
||||
tmpMax, err := time.ParseDuration(apiConfig.MaxLeaseTTL)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"unable to parse max TTL of %s: %s", apiConfig.MaxLeaseTTL, err)),
|
||||
logical.ErrInvalidRequest
|
||||
}
|
||||
config.MaxLeaseTTL = tmpMax
|
||||
}
|
||||
|
||||
if config.MaxLeaseTTL != 0 && config.DefaultLeaseTTL > config.MaxLeaseTTL {
|
||||
return logical.ErrorResponse(
|
||||
"given default lease TTL greater than given max lease TTL"),
|
||||
logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
if config.DefaultLeaseTTL > b.Core.maxLeaseTTL {
|
||||
return logical.ErrorResponse(fmt.Sprintf(
|
||||
"given default lease TTL greater than system max lease TTL of %d", int(b.Core.maxLeaseTTL.Seconds()))),
|
||||
logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
if logicalType == "" {
|
||||
return logical.ErrorResponse(
|
||||
"backend type must be specified as a string"),
|
||||
@ -498,14 +544,10 @@ func (b *SystemBackend) handleMountConfig(
|
||||
return handleError(err)
|
||||
}
|
||||
|
||||
def := sysView.DefaultLeaseTTL()
|
||||
|
||||
max := sysView.MaxLeaseTTL()
|
||||
|
||||
resp := &logical.Response{
|
||||
Data: map[string]interface{}{
|
||||
"default_lease_ttl": def,
|
||||
"max_lease_ttl": max,
|
||||
"default_lease_ttl": int(sysView.DefaultLeaseTTL().Seconds()),
|
||||
"max_lease_ttl": int(sysView.MaxLeaseTTL().Seconds()),
|
||||
},
|
||||
}
|
||||
|
||||
@ -545,14 +587,34 @@ func (b *SystemBackend) handleMountTune(
|
||||
// Timing configuration parameters
|
||||
{
|
||||
var newDefault, newMax *time.Duration
|
||||
if defTTLInt, ok := data.GetOk("default_lease_ttl"); ok {
|
||||
def := time.Duration(defTTLInt.(int))
|
||||
newDefault = &def
|
||||
defTTL := data.Get("default_lease_ttl").(string)
|
||||
switch defTTL {
|
||||
case "":
|
||||
case "system":
|
||||
tmpDef := time.Duration(0)
|
||||
newDefault = &tmpDef
|
||||
default:
|
||||
tmpDef, err := time.ParseDuration(defTTL)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
}
|
||||
newDefault = &tmpDef
|
||||
}
|
||||
if maxTTLInt, ok := data.GetOk("max_lease_ttl"); ok {
|
||||
max := time.Duration(maxTTLInt.(int))
|
||||
newMax = &max
|
||||
|
||||
maxTTL := data.Get("max_lease_ttl").(string)
|
||||
switch maxTTL {
|
||||
case "":
|
||||
case "system":
|
||||
tmpMax := time.Duration(0)
|
||||
newMax = &tmpMax
|
||||
default:
|
||||
tmpMax, err := time.ParseDuration(maxTTL)
|
||||
if err != nil {
|
||||
return handleError(err)
|
||||
}
|
||||
newMax = &tmpMax
|
||||
}
|
||||
|
||||
if newDefault != nil || newMax != nil {
|
||||
if err := b.tuneMountTTLs(path, &mountEntry.Config, newDefault, newMax); err != nil {
|
||||
b.Backend.Logger().Printf("[ERR] sys: tune of path '%s' failed: %v", path, err)
|
||||
|
@ -26,27 +26,27 @@ func (b *SystemBackend) tuneMountTTLs(path string, meConfig *MountConfig, newDef
|
||||
}
|
||||
|
||||
if newMax != nil && newDefault != nil && *newMax < *newDefault {
|
||||
return fmt.Errorf("New backend max lease TTL of %d less than new backend default lease TTL of %d",
|
||||
*newMax, *newDefault)
|
||||
return fmt.Errorf("new backend max lease TTL of %d less than new backend default lease TTL of %d",
|
||||
int(newMax.Seconds()), int(newDefault.Seconds()))
|
||||
}
|
||||
|
||||
if newMax != nil && newDefault == nil {
|
||||
if meConfig.DefaultLeaseTTL != 0 && *newMax < meConfig.DefaultLeaseTTL {
|
||||
return fmt.Errorf("New backend max lease TTL of %d less than backend default lease TTL of %d",
|
||||
*newMax, meConfig.DefaultLeaseTTL)
|
||||
return fmt.Errorf("new backend max lease TTL of %d less than backend default lease TTL of %d",
|
||||
int(newMax.Seconds()), int(meConfig.DefaultLeaseTTL.Seconds()))
|
||||
}
|
||||
}
|
||||
|
||||
if newDefault != nil {
|
||||
if meConfig.MaxLeaseTTL == 0 {
|
||||
if *newDefault > b.Core.maxLeaseTTL {
|
||||
return fmt.Errorf("New backend default lease TTL of %d greater than system max lease TTL of %d",
|
||||
*newDefault, b.Core.maxLeaseTTL)
|
||||
return fmt.Errorf("new backend default lease TTL of %d greater than system max lease TTL of %d",
|
||||
int(newDefault.Seconds()), int(b.Core.maxLeaseTTL.Seconds()))
|
||||
}
|
||||
} else {
|
||||
if meConfig.MaxLeaseTTL < *newDefault {
|
||||
return fmt.Errorf("New backend default lease TTL of %d greater than backend max lease TTL of %d",
|
||||
*newDefault, meConfig.MaxLeaseTTL)
|
||||
return fmt.Errorf("new backend default lease TTL of %d greater than backend max lease TTL of %d",
|
||||
int(newDefault.Seconds()), int(meConfig.MaxLeaseTTL.Seconds()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,24 +47,24 @@ func TestSystemBackend_mounts(t *testing.T) {
|
||||
"type": "generic",
|
||||
"description": "generic secret storage",
|
||||
"config": map[string]interface{}{
|
||||
"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(time.Duration),
|
||||
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(time.Duration),
|
||||
"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int),
|
||||
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
|
||||
},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"type": "system",
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
"config": map[string]interface{}{
|
||||
"default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(time.Duration),
|
||||
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(time.Duration),
|
||||
"default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int),
|
||||
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
|
||||
},
|
||||
},
|
||||
"cubbyhole/": map[string]interface{}{
|
||||
"description": "per-token private secret storage",
|
||||
"type": "cubbyhole",
|
||||
"config": map[string]interface{}{
|
||||
"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(time.Duration),
|
||||
"max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(time.Duration),
|
||||
"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int),
|
||||
"max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -499,6 +499,7 @@ func (ts *TokenStore) handleCreate(
|
||||
Metadata map[string]string `mapstructure:"meta"`
|
||||
NoParent bool `mapstructure:"no_parent"`
|
||||
Lease string
|
||||
TTL string
|
||||
DisplayName string `mapstructure:"display_name"`
|
||||
NumUses int `mapstructure:"num_uses"`
|
||||
}
|
||||
@ -559,8 +560,17 @@ func (ts *TokenStore) handleCreate(
|
||||
te.Parent = ""
|
||||
}
|
||||
|
||||
// Parse the lease if any
|
||||
if data.Lease != "" {
|
||||
// Parse the TTL/lease if any
|
||||
if data.TTL != "" {
|
||||
dur, err := time.ParseDuration(data.TTL)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
if dur < 0 {
|
||||
return logical.ErrorResponse("ttl must be positive"), logical.ErrInvalidRequest
|
||||
}
|
||||
te.TTL = dur
|
||||
} else if data.Lease != "" {
|
||||
dur, err := time.ParseDuration(data.Lease)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
|
||||
|
@ -711,6 +711,29 @@ func TestTokenStore_HandleRequest_CreateToken_Lease(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenStore_HandleRequest_CreateToken_TTL(t *testing.T) {
|
||||
_, ts, root := mockTokenStore(t)
|
||||
|
||||
req := logical.TestRequest(t, logical.WriteOperation, "create")
|
||||
req.ClientToken = root
|
||||
req.Data["policies"] = []string{"foo"}
|
||||
req.Data["ttl"] = "1h"
|
||||
|
||||
resp, err := ts.HandleRequest(req)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v %v", err, resp)
|
||||
}
|
||||
if resp.Auth.ClientToken == "" {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
if resp.Auth.TTL != time.Hour {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
if !resp.Auth.Renewable {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenStore_HandleRequest_Revoke(t *testing.T) {
|
||||
_, ts, root := mockTokenStore(t)
|
||||
testMakeToken(t, ts, root, "child", []string{"root", "foo"})
|
||||
|
@ -87,9 +87,14 @@ of the header should be "X-Vault-Token" and the value should be the token.
|
||||
<li>
|
||||
<span class="param">lease</span>
|
||||
<span class="param-flags">optional</span>
|
||||
The lease period of the token, provided as "1h", where hour is
|
||||
DEPRECATED; use "ttl" instead.
|
||||
</li>
|
||||
<li>
|
||||
<span class="param">ttl</span>
|
||||
<span class="param-flags">optional</span>
|
||||
The TTL period of the token, provided as "1h", where hour is
|
||||
the largest suffix. If not provided, the token is valid for the
|
||||
[default lease duration](/docs/config/index.html), or
|
||||
[default lease TTL](/docs/config/index.html), or
|
||||
indefinitely if the root policy is used.
|
||||
</li>
|
||||
<li>
|
||||
|
@ -60,9 +60,9 @@ description: |-
|
||||
<dl>
|
||||
<dt>Description</dt>
|
||||
<dd>
|
||||
List the given secret backends configuration. `default_lease_ttl`
|
||||
or `max_lease_ttl` values of `0` mean that the system
|
||||
defaults are used by this backend.
|
||||
List the given mount's configuration. Unlike the `mounts`
|
||||
endpoint, this will return the current time in seconds for each
|
||||
TTL, which may be the system default or a mount-specific value.
|
||||
</dd>
|
||||
|
||||
<dt>Method</dt>
|
||||
@ -81,8 +81,8 @@ description: |-
|
||||
|
||||
```javascript
|
||||
{
|
||||
"default_lease_ttl": 0,
|
||||
"max_lease_ttl": 0
|
||||
"default_lease_ttl": 3600,
|
||||
"max_lease_ttl": 7200
|
||||
}
|
||||
```
|
||||
|
||||
@ -153,13 +153,15 @@ description: |-
|
||||
<span class="param">default_lease_ttl</span>
|
||||
<span class="param-flags">optional</span>
|
||||
The default time-to-live. If set on a specific mount,
|
||||
overrides the global default.
|
||||
overrides the global default. A value of "system" or "0"
|
||||
are equivalent and set to the system default TTL.
|
||||
</li>
|
||||
<li>
|
||||
<span class="param">max_lease_ttl</span>
|
||||
<span class="param-flags">optional</span>
|
||||
The maximum time-to-live. If set on a specific mount,
|
||||
overrides the global default.
|
||||
overrides the global default. A value of "system" or "0"
|
||||
are equivalent and set to the system max TTL.
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
|
Loading…
Reference in New Issue
Block a user