Merge pull request #1531 from hashicorp/auth-mount-tune-params

Auth tune endpoints and config settings output from CLI
This commit is contained in:
Vishal Nayak
2016-06-20 20:24:47 -04:00
committed by GitHub
7 changed files with 271 additions and 81 deletions

View File

@@ -51,6 +51,12 @@ func (c *Sys) DisableAuth(path string) error {
// documentation. Please refer to that documentation for more details.
type AuthMount struct {
Type string
Description string
Type string `json:"type" structs:"type" mapstructure:"type"`
Description string `json:"description" structs:"description" mapstructure:"description"`
Config AuthConfigOutput `json:"config" structs:"config" mapstructure:"config"`
}
type AuthConfigOutput 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"`
}

View File

@@ -7,6 +7,7 @@ import (
"io"
"os"
"sort"
"strconv"
"strings"
"github.com/hashicorp/vault/api"
@@ -271,11 +272,19 @@ func (c *AuthCommand) listMethods() int {
}
sort.Strings(paths)
columns := []string{"Path | Type | Description"}
for _, k := range paths {
a := auth[k]
columns := []string{"Path | Type | Default TTL | Max TTL | Description"}
for _, path := range paths {
auth := auth[path]
defTTL := "system"
if auth.Config.DefaultLeaseTTL != 0 {
defTTL = strconv.Itoa(auth.Config.DefaultLeaseTTL)
}
maxTTL := "system"
if auth.Config.MaxLeaseTTL != 0 {
maxTTL = strconv.Itoa(auth.Config.MaxLeaseTTL)
}
columns = append(columns, fmt.Sprintf(
"%s | %s | %s", k, a.Type, a.Description))
"%s | %s | %s | %s | %s", path, auth.Type, defTTL, maxTTL, auth.Description))
}
c.Ui.Output(columnize.SimpleFormat(columns))

View File

@@ -20,12 +20,16 @@ func TestSysAuth(t *testing.T) {
"token/": map[string]interface{}{
"description": "token based credentials",
"type": "token",
"config": map[string]interface{}{
"default_lease_ttl": float64(0),
"max_lease_ttl": float64(0),
},
},
}
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
}
}
@@ -48,16 +52,24 @@ func TestSysEnableAuth(t *testing.T) {
"foo/": map[string]interface{}{
"description": "foo",
"type": "noop",
"config": map[string]interface{}{
"default_lease_ttl": float64(0),
"max_lease_ttl": float64(0),
},
},
"token/": map[string]interface{}{
"description": "token based credentials",
"type": "token",
"config": map[string]interface{}{
"default_lease_ttl": float64(0),
"max_lease_ttl": float64(0),
},
},
}
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
}
}
@@ -81,6 +93,10 @@ func TestSysDisableAuth(t *testing.T) {
var actual map[string]interface{}
expected := map[string]interface{}{
"token/": map[string]interface{}{
"config": map[string]interface{}{
"default_lease_ttl": float64(0),
"max_lease_ttl": float64(0),
},
"description": "token based credentials",
"type": "token",
},
@@ -88,6 +104,6 @@ func TestSysDisableAuth(t *testing.T) {
testResponseStatus(t, resp, 200)
testResponseBody(t, resp, &actual)
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
t.Fatalf("bad: expected:%#v\nactual:%#v", expected, actual)
}
}

View File

@@ -146,6 +146,30 @@ func NewSystemBackend(core *Core, config *logical.BackendConfig) logical.Backend
HelpDescription: strings.TrimSpace(sysHelp["rekey_backup"][0]),
},
&framework.Path{
Pattern: "auth/(?P<path>.+?)/tune$",
Fields: map[string]*framework.FieldSchema{
"path": &framework.FieldSchema{
Type: framework.TypeString,
Description: strings.TrimSpace(sysHelp["auth_tune"][0]),
},
"default_lease_ttl": &framework.FieldSchema{
Type: framework.TypeString,
Description: strings.TrimSpace(sysHelp["tune_default_lease_ttl"][0]),
},
"max_lease_ttl": &framework.FieldSchema{
Type: framework.TypeString,
Description: strings.TrimSpace(sysHelp["tune_max_lease_ttl"][0]),
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.handleAuthTuneRead,
logical.UpdateOperation: b.handleAuthTuneWrite,
},
HelpSynopsis: strings.TrimSpace(sysHelp["auth_tune"][0]),
HelpDescription: strings.TrimSpace(sysHelp["auth_tune"][1]),
},
&framework.Path{
Pattern: "mounts/(?P<path>.+?)/tune$",
@@ -637,8 +661,8 @@ func (b *SystemBackend) handleMountTable(
"type": entry.Type,
"description": entry.Description,
"config": map[string]interface{}{
"default_lease_ttl": int(entry.Config.DefaultLeaseTTL.Seconds()),
"max_lease_ttl": int(entry.Config.MaxLeaseTTL.Seconds()),
"default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()),
"max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()),
},
}
@@ -790,6 +814,18 @@ func (b *SystemBackend) handleRemount(
return nil, nil
}
// handleAuthTuneRead is used to get config settings on a auth path
func (b *SystemBackend) handleAuthTuneRead(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
path := data.Get("path").(string)
if path == "" {
return logical.ErrorResponse(
"path must be specified as a string"),
logical.ErrInvalidRequest
}
return b.handleTuneReadCommon("auth/" + path)
}
// handleMountTuneRead is used to get config settings on a backend
func (b *SystemBackend) handleMountTuneRead(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
@@ -800,6 +836,14 @@ func (b *SystemBackend) handleMountTuneRead(
logical.ErrInvalidRequest
}
// This call will read both logical backend's configuration as well as auth backends'.
// Retaining this behavior for backward compatibility. If this behavior is not desired,
// an error can be returned if path has a prefix of "auth/".
return b.handleTuneReadCommon(path)
}
// handleTuneReadCommon returns the config settings of a path
func (b *SystemBackend) handleTuneReadCommon(path string) (*logical.Response, error) {
path = sanitizeMountPath(path)
sysView := b.Core.router.MatchingSystemView(path)
@@ -819,16 +863,34 @@ func (b *SystemBackend) handleMountTuneRead(
return resp, nil
}
// handleAuthTuneWrite is used to set config settings on an auth path
func (b *SystemBackend) handleAuthTuneWrite(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
path := data.Get("path").(string)
if path == "" {
return logical.ErrorResponse("path must be specified as a string"),
logical.ErrInvalidRequest
}
return b.handleTuneWriteCommon("auth/"+path, data)
}
// handleMountTuneWrite is used to set config settings on a backend
func (b *SystemBackend) handleMountTuneWrite(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
path := data.Get("path").(string)
if path == "" {
return logical.ErrorResponse(
"path must be specified as a string"),
return logical.ErrorResponse("path must be specified as a string"),
logical.ErrInvalidRequest
}
// This call will write both logical backend's configuration as well as auth backends'.
// Retaining this behavior for backward compatibility. If this behavior is not desired,
// an error can be returned if path has a prefix of "auth/".
return b.handleTuneWriteCommon(path, data)
}
// handleTuneWriteCommon is used to set config settings on a path
func (b *SystemBackend) handleTuneWriteCommon(
path string, data *framework.FieldData) (*logical.Response, error) {
path = sanitizeMountPath(path)
// Prevent protected paths from being changed
@@ -975,9 +1037,13 @@ func (b *SystemBackend) handleAuthTable(
Data: make(map[string]interface{}),
}
for _, entry := range b.Core.auth.Entries {
info := map[string]string{
info := map[string]interface{}{
"type": entry.Type,
"description": entry.Description,
"config": map[string]interface{}{
"default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()),
"max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()),
},
}
resp.Data[entry.Path] = info
}
@@ -1467,8 +1533,16 @@ This path responds to the following HTTP methods.
`,
},
"auth_tune": {
"Tune the configuration parameters for an auth path.",
`Read and write the 'default-lease-ttl' and 'max-lease-ttl' values of
the auth path.`,
},
"mount_tune": {
"Tune backend configuration parameters for this mount.",
`Read and write the 'default-lease-ttl' and 'max-lease-ttl' values of
the mount.`,
},
"renew": {

View File

@@ -46,24 +46,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"].(int),
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
"max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
},
},
"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"].(int),
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
"default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
"max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
},
},
"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"].(int),
"max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int),
"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
"max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
},
},
}
@@ -525,9 +525,13 @@ func TestSystemBackend_authTable(t *testing.T) {
}
exp := map[string]interface{}{
"token/": map[string]string{
"token/": map[string]interface{}{
"type": "token",
"description": "token based credentials",
"config": map[string]interface{}{
"default_lease_ttl": int64(0),
"max_lease_ttl": int64(0),
},
},
}
if !reflect.DeepEqual(resp.Data, exp) {

View File

@@ -45,8 +45,8 @@ description: |-
<dt>Description</dt>
<dd>
Enable a new auth backend. The auth backend can be accessed
and configured via the mount point specified in the URL. This
mount point will be exposed under the `auth` prefix. For example,
and configured via the auth path specified in the URL. This
auth path will be exposed under the `auth` prefix. For example,
enabling with the `/sys/auth/foo` URL will make the backend
available at `/auth/foo`.
</dd>
@@ -55,7 +55,7 @@ description: |-
<dd>POST</dd>
<dt>URL</dt>
<dd>`/sys/auth/<mount point>`</dd>
<dd>`/sys/auth/<auth_path>`</dd>
<dt>Parameters</dt>
<dd>
@@ -83,14 +83,14 @@ description: |-
<dl>
<dt>Description</dt>
<dd>
Disable the auth backend at the given mount point.
Disable the auth backend at the given auth path.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/sys/auth/<mount point>`</dd>
<dd>`/sys/auth/<auth_path>`</dd>
<dt>Parameters</dt>
<dd>None
@@ -100,3 +100,78 @@ description: |-
<dd>`204` response code.
</dd>
</dl>
# /sys/auth/<auth_path>/tune
## GET
<dl>
<dt>Description</dt>
<dd>
Read the given auth path's configuration. Returns the current time
in seconds for each TTL, which may be the system default or a
auth path specific value.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/sys/auth/<auth_path>/tune`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"default_lease_ttl": 3600,
"max_lease_ttl": 7200
}
```
</dd>
</dl>
## POST
<dl>
<dt>Description</dt>
<dd>
Tune configuration parameters for a given auth path.
</dd>
<dt>Method</dt>
<dd>POST</dd>
<dt>URL</dt>
<dd>`/sys/auth/<auth_path>/tune`</dd>
<dt>Parameters</dt>
<dd>
<ul>
<li>
<span class="param">default_lease_ttl</span>
<span class="param-flags">optional</span>
The default time-to-live. If set on a specific auth path,
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 auth path,
overrides the global default. A value of "system" or "0"
are equivalent and set to the system max TTL.
</li>
</ul>
</dd>
<dt>Returns</dt>
<dd>`204` response code.
</dd>
</dl>

View File

@@ -57,38 +57,6 @@ description: |-
</dd>
</dl>
<dl>
<dt>Description</dt>
<dd>
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>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/sys/mounts/<mount point>/tune`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"default_lease_ttl": 3600,
"max_lease_ttl": 7200
}
```
</dd>
</dl>
## POST
<dl>
@@ -134,6 +102,67 @@ description: |-
</dd>
</dl>
## DELETE
<dl>
<dt>Description</dt>
<dd>
Unmount the mount point specified in the URL.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/sys/mounts/<mount point>`</dd>
<dt>Parameters</dt>
<dd>None
</dd>
<dt>Returns</dt>
<dd>`204` response code.
</dd>
</dl>
# /sys/mounts/<mount point>/tune
## GET
<dl>
<dt>Description</dt>
<dd>
Read 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>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/sys/mounts/<mount point>/tune`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```javascript
{
"default_lease_ttl": 3600,
"max_lease_ttl": 7200
}
```
</dd>
</dl>
## POST
<dl>
<dt>Description</dt>
<dd>
@@ -170,26 +199,3 @@ description: |-
<dd>`204` response code.
</dd>
</dl>
## DELETE
<dl>
<dt>Description</dt>
<dd>
Unmount the mount point specified in the URL.
</dd>
<dt>Method</dt>
<dd>DELETE</dd>
<dt>URL</dt>
<dd>`/sys/mounts/<mount point>`</dd>
<dt>Parameters</dt>
<dd>None
</dd>
<dt>Returns</dt>
<dd>`204` response code.
</dd>
</dl>