mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-03 12:07:54 +00:00
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:
@@ -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.
|
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]
|
* **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.
|
* **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:
|
FEATURES:
|
||||||
|
|||||||
@@ -2,12 +2,11 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"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")
|
r := c.c.NewRequest("GET", "/v1/sys/mounts")
|
||||||
resp, err := c.c.RawRequest(r)
|
resp, err := c.c.RawRequest(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -15,12 +14,12 @@ func (c *Sys) ListMounts() (map[string]*Mount, error) {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
var result map[string]*Mount
|
var result map[string]*MountOutput
|
||||||
err = resp.DecodeJSON(&result)
|
err = resp.DecodeJSON(&result)
|
||||||
return result, err
|
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 {
|
if err := c.checkMountPath(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -79,7 +78,7 @@ func (c *Sys) Remount(from, to string) error {
|
|||||||
return err
|
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 {
|
if err := c.checkMountPath(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -119,13 +118,24 @@ func (c *Sys) checkMountPath(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mount struct {
|
type MountInput struct {
|
||||||
Type string `json:"type" structs:"type"`
|
Type string `json:"type" structs:"type"`
|
||||||
Description string `json:"description" structs:"description"`
|
Description string `json:"description" structs:"description"`
|
||||||
Config APIMountConfig `json:"config" structs:"config"`
|
Config MountConfigInput `json:"config" structs:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type APIMountConfig struct {
|
type MountConfigInput struct {
|
||||||
DefaultLeaseTTL *time.Duration `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
|
DefaultLeaseTTL string `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"`
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
)
|
)
|
||||||
@@ -47,29 +46,13 @@ func (c *MountCommand) Run(args []string) int {
|
|||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
mountInfo := &api.Mount{
|
mountInfo := &api.MountInput{
|
||||||
Type: mountType,
|
Type: mountType,
|
||||||
Description: description,
|
Description: description,
|
||||||
Config: api.APIMountConfig{},
|
Config: api.MountConfigInput{
|
||||||
}
|
DefaultLeaseTTL: defaultLeaseTTL,
|
||||||
|
MaxLeaseTTL: maxLeaseTTL,
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := client.Sys().Mount(path, mountInfo); err != nil {
|
if err := client.Sys().Mount(path, mountInfo); err != nil {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package command
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ryanuber/columnize"
|
"github.com/ryanuber/columnize"
|
||||||
@@ -43,9 +44,26 @@ func (c *MountsCommand) Run(args []string) int {
|
|||||||
columns := []string{"Path | Type | Default TTL | Max TTL | Description"}
|
columns := []string{"Path | Type | Default TTL | Max TTL | Description"}
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
mount := mounts[path]
|
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(
|
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))
|
c.Ui.Output(columnize.SimpleFormat(columns))
|
||||||
@@ -64,7 +82,7 @@ Usage: vault mounts [options]
|
|||||||
|
|
||||||
This command lists the mounted backends, their mount points, the
|
This command lists the mounted backends, their mount points, the
|
||||||
configured TTLs, and a human-friendly description of the mount point.
|
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:
|
General Options:
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package command
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
)
|
)
|
||||||
@@ -34,24 +33,9 @@ func (c *MountTuneCommand) Run(args []string) int {
|
|||||||
|
|
||||||
path := args[0]
|
path := args[0]
|
||||||
|
|
||||||
mountConfig := api.APIMountConfig{}
|
mountConfig := api.MountConfigInput{
|
||||||
if defaultLeaseTTL != "" {
|
DefaultLeaseTTL: defaultLeaseTTL,
|
||||||
defTTL, err := time.ParseDuration(defaultLeaseTTL)
|
MaxLeaseTTL: maxLeaseTTL,
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := c.Client()
|
client, err := c.Client()
|
||||||
@@ -83,7 +67,7 @@ func (c *MountTuneCommand) Help() string {
|
|||||||
|
|
||||||
Tune configuration options for a mounted secret backend.
|
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:
|
General Options:
|
||||||
|
|
||||||
@@ -92,14 +76,14 @@ General Options:
|
|||||||
Mount Options:
|
Mount Options:
|
||||||
|
|
||||||
-default-lease-ttl=<duration> Default lease time-to-live for this backend.
|
-default-lease-ttl=<duration> Default lease time-to-live for this backend.
|
||||||
If not specified, uses the global default, or
|
If not specified, uses the system default, or
|
||||||
the previously set value. Set to '0' to
|
the previously set value. Set to 'system' to
|
||||||
explicitly set it to use the global default.
|
explicitly set it to use the system default.
|
||||||
|
|
||||||
-max-lease-ttl=<duration> Max lease time-to-live for this backend.
|
-max-lease-ttl=<duration> Max lease time-to-live for this backend.
|
||||||
If not specified, uses the global default, or
|
If not specified, uses the system default, or
|
||||||
the previously set value. Set to '0' to
|
the previously set value. Set to 'system' to
|
||||||
explicitly set it to use the global default.
|
explicitly set it to use the system default.
|
||||||
|
|
||||||
`
|
`
|
||||||
return strings.TrimSpace(helpText)
|
return strings.TrimSpace(helpText)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package http
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
"github.com/hashicorp/vault/vault"
|
"github.com/hashicorp/vault/vault"
|
||||||
@@ -293,37 +292,37 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
|
|
||||||
// Shorter than system default
|
// Shorter than system default
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 204)
|
||||||
|
|
||||||
// Longer than system max
|
// Longer than system max
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 400)
|
||||||
|
|
||||||
// Longer than system default
|
// Longer than system default
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 204)
|
||||||
|
|
||||||
// Longer than backend max
|
// Longer than backend max
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 400)
|
||||||
|
|
||||||
// Shorter than backend default
|
// Shorter than backend default
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 400)
|
||||||
|
|
||||||
// Shorter than backend max, longer than system max
|
// Shorter than backend max, longer than system max
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
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)
|
testResponseStatus(t, resp, 204)
|
||||||
|
|
||||||
@@ -333,8 +332,8 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
"description": "foo",
|
"description": "foo",
|
||||||
"type": "generic",
|
"type": "generic",
|
||||||
"config": map[string]interface{}{
|
"config": map[string]interface{}{
|
||||||
"default_lease_ttl": float64(time.Duration(time.Hour * 71999)),
|
"default_lease_ttl": float64(259196400),
|
||||||
"max_lease_ttl": float64(time.Duration(time.Hour * 72000)),
|
"max_lease_ttl": float64(259200000),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"secret/": map[string]interface{}{
|
"secret/": map[string]interface{}{
|
||||||
@@ -374,8 +373,8 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/foo/tune")
|
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/foo/tune")
|
||||||
actual = map[string]interface{}{}
|
actual = map[string]interface{}{}
|
||||||
expected = map[string]interface{}{
|
expected = map[string]interface{}{
|
||||||
"default_lease_ttl": float64(time.Duration(time.Hour * 71999)),
|
"default_lease_ttl": float64(259196400),
|
||||||
"max_lease_ttl": float64(time.Duration(time.Hour * 72000)),
|
"max_lease_ttl": float64(259200000),
|
||||||
}
|
}
|
||||||
|
|
||||||
testResponseStatus(t, resp, 200)
|
testResponseStatus(t, resp, 200)
|
||||||
@@ -386,16 +385,16 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
|
|
||||||
// Set a low max
|
// Set a low max
|
||||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/secret/tune", map[string]interface{}{
|
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/secret/tune", map[string]interface{}{
|
||||||
"default_lease_ttl": time.Duration(time.Second * 40),
|
"default_lease_ttl": "40s",
|
||||||
"max_lease_ttl": time.Duration(time.Second * 80),
|
"max_lease_ttl": "80s",
|
||||||
})
|
})
|
||||||
testResponseStatus(t, resp, 204)
|
testResponseStatus(t, resp, 204)
|
||||||
|
|
||||||
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/secret/tune")
|
resp = testHttpGet(t, token, addr+"/v1/sys/mounts/secret/tune")
|
||||||
actual = map[string]interface{}{}
|
actual = map[string]interface{}{}
|
||||||
expected = map[string]interface{}{
|
expected = map[string]interface{}{
|
||||||
"default_lease_ttl": float64(time.Duration(time.Second * 40)),
|
"default_lease_ttl": float64(40),
|
||||||
"max_lease_ttl": float64(time.Duration(time.Second * 80)),
|
"max_lease_ttl": float64(80),
|
||||||
}
|
}
|
||||||
|
|
||||||
testResponseStatus(t, resp, 200)
|
testResponseStatus(t, resp, 200)
|
||||||
@@ -421,7 +420,7 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
testResponseBody(t, resp, &result)
|
testResponseBody(t, resp, &result)
|
||||||
|
|
||||||
expected = map[string]interface{}{
|
expected = map[string]interface{}{
|
||||||
"lease_duration": int(time.Duration(time.Second * 80).Seconds()),
|
"lease_duration": int(80),
|
||||||
"lease_id": result.LeaseID,
|
"lease_id": result.LeaseID,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +440,7 @@ func TestSysTuneMount(t *testing.T) {
|
|||||||
testResponseBody(t, resp, &result)
|
testResponseBody(t, resp, &result)
|
||||||
|
|
||||||
expected = map[string]interface{}{
|
expected = map[string]interface{}{
|
||||||
"lease_duration": int(time.Duration(time.Second * 40).Seconds()),
|
"lease_duration": int(40),
|
||||||
"lease_id": result.LeaseID,
|
"lease_id": result.LeaseID,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ func Test(t TestT, c TestCase) {
|
|||||||
|
|
||||||
// Mount the backend
|
// Mount the backend
|
||||||
prefix := "mnt"
|
prefix := "mnt"
|
||||||
mountInfo := &api.Mount{
|
mountInfo := &api.MountInput{
|
||||||
Type: "test",
|
Type: "test",
|
||||||
Description: "acceptance test",
|
Description: "acceptance test",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
|
||||||
"github.com/hashicorp/vault/logical"
|
"github.com/hashicorp/vault/logical"
|
||||||
"github.com/hashicorp/vault/logical/framework"
|
"github.com/hashicorp/vault/logical/framework"
|
||||||
"github.com/mitchellh/mapstructure"
|
"github.com/mitchellh/mapstructure"
|
||||||
@@ -54,11 +53,11 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) logical.Backend
|
|||||||
Description: strings.TrimSpace(sysHelp["mount_path"][0]),
|
Description: strings.TrimSpace(sysHelp["mount_path"][0]),
|
||||||
},
|
},
|
||||||
"default_lease_ttl": &framework.FieldSchema{
|
"default_lease_ttl": &framework.FieldSchema{
|
||||||
Type: framework.TypeDurationSecond,
|
Type: framework.TypeString,
|
||||||
Description: strings.TrimSpace(sysHelp["tune_default_lease_ttl"][0]),
|
Description: strings.TrimSpace(sysHelp["tune_default_lease_ttl"][0]),
|
||||||
},
|
},
|
||||||
"max_lease_ttl": &framework.FieldSchema{
|
"max_lease_ttl": &framework.FieldSchema{
|
||||||
Type: framework.TypeDurationSecond,
|
Type: framework.TypeString,
|
||||||
Description: strings.TrimSpace(sysHelp["tune_max_lease_ttl"][0]),
|
Description: strings.TrimSpace(sysHelp["tune_max_lease_ttl"][0]),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -378,8 +377,12 @@ func (b *SystemBackend) handleMountTable(
|
|||||||
info := map[string]interface{}{
|
info := map[string]interface{}{
|
||||||
"type": entry.Type,
|
"type": entry.Type,
|
||||||
"description": entry.Description,
|
"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
|
resp.Data[entry.Path] = info
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,9 +398,14 @@ func (b *SystemBackend) handleMount(
|
|||||||
description := data.Get("description").(string)
|
description := data.Get("description").(string)
|
||||||
|
|
||||||
var config MountConfig
|
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{})
|
configMap := data.Get("config").(map[string]interface{})
|
||||||
if configMap != nil && len(configMap) != 0 {
|
if configMap != nil && len(configMap) != 0 {
|
||||||
err := mapstructure.Decode(configMap, &config)
|
err := mapstructure.Decode(configMap, &apiConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return logical.ErrorResponse(
|
return logical.ErrorResponse(
|
||||||
"unable to convert given mount config information"),
|
"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 == "" {
|
if logicalType == "" {
|
||||||
return logical.ErrorResponse(
|
return logical.ErrorResponse(
|
||||||
"backend type must be specified as a string"),
|
"backend type must be specified as a string"),
|
||||||
@@ -498,14 +544,10 @@ func (b *SystemBackend) handleMountConfig(
|
|||||||
return handleError(err)
|
return handleError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
def := sysView.DefaultLeaseTTL()
|
|
||||||
|
|
||||||
max := sysView.MaxLeaseTTL()
|
|
||||||
|
|
||||||
resp := &logical.Response{
|
resp := &logical.Response{
|
||||||
Data: map[string]interface{}{
|
Data: map[string]interface{}{
|
||||||
"default_lease_ttl": def,
|
"default_lease_ttl": int(sysView.DefaultLeaseTTL().Seconds()),
|
||||||
"max_lease_ttl": max,
|
"max_lease_ttl": int(sysView.MaxLeaseTTL().Seconds()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,14 +587,34 @@ func (b *SystemBackend) handleMountTune(
|
|||||||
// Timing configuration parameters
|
// Timing configuration parameters
|
||||||
{
|
{
|
||||||
var newDefault, newMax *time.Duration
|
var newDefault, newMax *time.Duration
|
||||||
if defTTLInt, ok := data.GetOk("default_lease_ttl"); ok {
|
defTTL := data.Get("default_lease_ttl").(string)
|
||||||
def := time.Duration(defTTLInt.(int))
|
switch defTTL {
|
||||||
newDefault = &def
|
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))
|
maxTTL := data.Get("max_lease_ttl").(string)
|
||||||
newMax = &max
|
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 newDefault != nil || newMax != nil {
|
||||||
if err := b.tuneMountTTLs(path, &mountEntry.Config, newDefault, newMax); err != 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)
|
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 {
|
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",
|
return fmt.Errorf("new backend max lease TTL of %d less than new backend default lease TTL of %d",
|
||||||
*newMax, *newDefault)
|
int(newMax.Seconds()), int(newDefault.Seconds()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if newMax != nil && newDefault == nil {
|
if newMax != nil && newDefault == nil {
|
||||||
if meConfig.DefaultLeaseTTL != 0 && *newMax < meConfig.DefaultLeaseTTL {
|
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",
|
return fmt.Errorf("new backend max lease TTL of %d less than backend default lease TTL of %d",
|
||||||
*newMax, meConfig.DefaultLeaseTTL)
|
int(newMax.Seconds()), int(meConfig.DefaultLeaseTTL.Seconds()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if newDefault != nil {
|
if newDefault != nil {
|
||||||
if meConfig.MaxLeaseTTL == 0 {
|
if meConfig.MaxLeaseTTL == 0 {
|
||||||
if *newDefault > b.Core.maxLeaseTTL {
|
if *newDefault > b.Core.maxLeaseTTL {
|
||||||
return fmt.Errorf("New backend default lease TTL of %d greater than system max lease TTL of %d",
|
return fmt.Errorf("new backend default lease TTL of %d greater than system max lease TTL of %d",
|
||||||
*newDefault, b.Core.maxLeaseTTL)
|
int(newDefault.Seconds()), int(b.Core.maxLeaseTTL.Seconds()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if meConfig.MaxLeaseTTL < *newDefault {
|
if meConfig.MaxLeaseTTL < *newDefault {
|
||||||
return fmt.Errorf("New backend default lease TTL of %d greater than backend max lease TTL of %d",
|
return fmt.Errorf("new backend default lease TTL of %d greater than backend max lease TTL of %d",
|
||||||
*newDefault, meConfig.MaxLeaseTTL)
|
int(newDefault.Seconds()), int(meConfig.MaxLeaseTTL.Seconds()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,24 +47,24 @@ func TestSystemBackend_mounts(t *testing.T) {
|
|||||||
"type": "generic",
|
"type": "generic",
|
||||||
"description": "generic secret storage",
|
"description": "generic secret storage",
|
||||||
"config": map[string]interface{}{
|
"config": map[string]interface{}{
|
||||||
"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_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"].(time.Duration),
|
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sys/": map[string]interface{}{
|
"sys/": map[string]interface{}{
|
||||||
"type": "system",
|
"type": "system",
|
||||||
"description": "system endpoints used for control, policy and debugging",
|
"description": "system endpoints used for control, policy and debugging",
|
||||||
"config": map[string]interface{}{
|
"config": map[string]interface{}{
|
||||||
"default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_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"].(time.Duration),
|
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"cubbyhole/": map[string]interface{}{
|
"cubbyhole/": map[string]interface{}{
|
||||||
"description": "per-token private secret storage",
|
"description": "per-token private secret storage",
|
||||||
"type": "cubbyhole",
|
"type": "cubbyhole",
|
||||||
"config": map[string]interface{}{
|
"config": map[string]interface{}{
|
||||||
"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_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"].(time.Duration),
|
"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"`
|
Metadata map[string]string `mapstructure:"meta"`
|
||||||
NoParent bool `mapstructure:"no_parent"`
|
NoParent bool `mapstructure:"no_parent"`
|
||||||
Lease string
|
Lease string
|
||||||
|
TTL string
|
||||||
DisplayName string `mapstructure:"display_name"`
|
DisplayName string `mapstructure:"display_name"`
|
||||||
NumUses int `mapstructure:"num_uses"`
|
NumUses int `mapstructure:"num_uses"`
|
||||||
}
|
}
|
||||||
@@ -559,8 +560,17 @@ func (ts *TokenStore) handleCreate(
|
|||||||
te.Parent = ""
|
te.Parent = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the lease if any
|
// Parse the TTL/lease if any
|
||||||
if data.Lease != "" {
|
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)
|
dur, err := time.ParseDuration(data.Lease)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
|
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) {
|
func TestTokenStore_HandleRequest_Revoke(t *testing.T) {
|
||||||
_, ts, root := mockTokenStore(t)
|
_, ts, root := mockTokenStore(t)
|
||||||
testMakeToken(t, ts, root, "child", []string{"root", "foo"})
|
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>
|
<li>
|
||||||
<span class="param">lease</span>
|
<span class="param">lease</span>
|
||||||
<span class="param-flags">optional</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
|
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.
|
indefinitely if the root policy is used.
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ description: |-
|
|||||||
<dl>
|
<dl>
|
||||||
<dt>Description</dt>
|
<dt>Description</dt>
|
||||||
<dd>
|
<dd>
|
||||||
List the given secret backends configuration. `default_lease_ttl`
|
List the given mount's configuration. Unlike the `mounts`
|
||||||
or `max_lease_ttl` values of `0` mean that the system
|
endpoint, this will return the current time in seconds for each
|
||||||
defaults are used by this backend.
|
TTL, which may be the system default or a mount-specific value.
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
<dt>Method</dt>
|
<dt>Method</dt>
|
||||||
@@ -81,8 +81,8 @@ description: |-
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
"default_lease_ttl": 0,
|
"default_lease_ttl": 3600,
|
||||||
"max_lease_ttl": 0
|
"max_lease_ttl": 7200
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -153,13 +153,15 @@ description: |-
|
|||||||
<span class="param">default_lease_ttl</span>
|
<span class="param">default_lease_ttl</span>
|
||||||
<span class="param-flags">optional</span>
|
<span class="param-flags">optional</span>
|
||||||
The default time-to-live. If set on a specific mount,
|
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>
|
||||||
<li>
|
<li>
|
||||||
<span class="param">max_lease_ttl</span>
|
<span class="param">max_lease_ttl</span>
|
||||||
<span class="param-flags">optional</span>
|
<span class="param-flags">optional</span>
|
||||||
The maximum time-to-live. If set on a specific mount,
|
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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</dd>
|
</dd>
|
||||||
|
|||||||
Reference in New Issue
Block a user