Add option to disable caching per-backend. (#2455)

This commit is contained in:
Jeff Mitchell 2017-03-08 09:20:09 -05:00 committed by GitHub
parent b11f92ba5a
commit f03d500808
11 changed files with 128 additions and 14 deletions

View File

@ -129,6 +129,7 @@ type MountInput struct {
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"`
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
}
type MountOutput struct {
@ -139,6 +140,7 @@ type MountOutput struct {
}
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"`
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"`
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
}

View File

@ -15,12 +15,13 @@ type MountCommand struct {
func (c *MountCommand) Run(args []string) int {
var description, path, defaultLeaseTTL, maxLeaseTTL string
var local bool
var local, forceNoCache bool
flags := c.Meta.FlagSet("mount", meta.FlagSetDefault)
flags.StringVar(&description, "description", "", "")
flags.StringVar(&path, "path", "", "")
flags.StringVar(&defaultLeaseTTL, "default-lease-ttl", "", "")
flags.StringVar(&maxLeaseTTL, "max-lease-ttl", "", "")
flags.BoolVar(&forceNoCache, "force-no-cache", false, "")
flags.BoolVar(&local, "local", false, "")
flags.Usage = func() { c.Ui.Error(c.Help()) }
if err := flags.Parse(args); err != nil {
@ -55,6 +56,7 @@ func (c *MountCommand) Run(args []string) int {
Config: api.MountConfigInput{
DefaultLeaseTTL: defaultLeaseTTL,
MaxLeaseTTL: maxLeaseTTL,
ForceNoCache: forceNoCache,
},
Local: local,
}
@ -105,6 +107,11 @@ Mount Options:
the previously set value. Set to '0' to
explicitly set it to use the global default.
-force-no-cache Forces the backend to disable caching. If not
specified, uses the global default. This does
not affect caching of the underlying encrypted
data storage.
-local Mark the mount as a local mount. Local mounts
are not replicated nor (if a secondary)
removed by replication.

View File

@ -42,7 +42,7 @@ func (c *MountsCommand) Run(args []string) int {
}
sort.Strings(paths)
columns := []string{"Path | Type | Default TTL | Max TTL | Replication Behavior | Description"}
columns := []string{"Path | Type | Default TTL | Max TTL | Force No Cache | Replication Behavior | Description"}
for _, path := range paths {
mount := mounts[path]
defTTL := "system"
@ -68,7 +68,8 @@ func (c *MountsCommand) Run(args []string) int {
replicatedBehavior = "local"
}
columns = append(columns, fmt.Sprintf(
"%s | %s | %s | %s | %s | %s", path, mount.Type, defTTL, maxTTL, replicatedBehavior, mount.Description))
"%s | %s | %s | %s | %v | %s | %s", path, mount.Type, defTTL, maxTTL,
mount.Config.ForceNoCache, replicatedBehavior, mount.Description))
}
c.Ui.Output(columnize.SimpleFormat(columns))

View File

@ -80,6 +80,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -89,6 +90,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -98,6 +100,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -108,6 +111,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -117,6 +121,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -126,6 +131,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},

View File

@ -32,6 +32,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -41,6 +42,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -50,6 +52,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -60,6 +63,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -69,6 +73,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -78,6 +83,7 @@ func TestSysMounts(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -119,6 +125,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -128,6 +135,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -137,6 +145,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -146,6 +155,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -156,6 +166,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -165,6 +176,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -174,6 +186,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -183,6 +196,7 @@ func TestSysMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -246,6 +260,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -255,6 +270,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -264,6 +280,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -273,6 +290,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -283,6 +301,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -292,6 +311,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -301,6 +321,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -310,6 +331,7 @@ func TestSysRemount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -354,6 +376,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -363,6 +386,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -372,6 +396,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -382,6 +407,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -391,6 +417,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -400,6 +427,7 @@ func TestSysUnmount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -441,6 +469,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -450,6 +479,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -459,6 +489,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -468,6 +499,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -478,6 +510,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -487,6 +520,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -496,6 +530,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -505,6 +540,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -567,6 +603,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
},
"local": false,
},
@ -576,6 +613,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -585,6 +623,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -594,6 +633,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -604,6 +644,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
},
"local": false,
},
@ -613,6 +654,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -622,6 +664,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": false,
},
@ -631,6 +674,7 @@ func TestSysTuneMount(t *testing.T) {
"config": map[string]interface{}{
"default_lease_ttl": json.Number("0"),
"max_lease_ttl": json.Number("0"),
"force_no_cache": false,
},
"local": true,
},
@ -656,9 +700,11 @@ func TestSysTuneMount(t *testing.T) {
"data": map[string]interface{}{
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
},
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
}
testResponseStatus(t, resp, 200)
@ -687,9 +733,11 @@ func TestSysTuneMount(t *testing.T) {
"data": map[string]interface{}{
"default_lease_ttl": json.Number("40"),
"max_lease_ttl": json.Number("80"),
"force_no_cache": false,
},
"default_lease_ttl": json.Number("40"),
"max_lease_ttl": json.Number("80"),
"force_no_cache": false,
}
testResponseStatus(t, resp, 200)

View File

@ -48,6 +48,10 @@ func TestSysMountConfig(t *testing.T) {
t.Fatalf("Expected default lease TTL: %d, got %d",
expectedMaxTTL, mountConfig.MaxLeaseTTL)
}
if mountConfig.ForceNoCache == true {
t.Fatalf("did not expect force cache")
}
}
// testMount sets up a test mount of a generic backend w/ a random path; caller

View File

@ -76,7 +76,7 @@ func (d dynamicSystemView) Tainted() bool {
// CachingDisabled indicates whether to use caching behavior
func (d dynamicSystemView) CachingDisabled() bool {
return d.core.cachingDisabled
return d.core.cachingDisabled || (d.mountEntry != nil && d.mountEntry.Config.ForceNoCache)
}
// Checks if this is a primary Vault instance.

View File

@ -924,6 +924,7 @@ func (b *SystemBackend) handleMountTable(
"config": map[string]interface{}{
"default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()),
"max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()),
"force_no_cache": entry.Config.ForceNoCache,
},
"local": entry.Local,
}
@ -958,6 +959,7 @@ func (b *SystemBackend) handleMount(
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"`
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"`
}
configMap := data.Get("config").(map[string]interface{})
if configMap != nil && len(configMap) != 0 {
@ -1007,6 +1009,11 @@ func (b *SystemBackend) handleMount(
logical.ErrInvalidRequest
}
// Copy over the force no cache if set
if apiConfig.ForceNoCache {
config.ForceNoCache = true
}
if logicalType == "" {
return logical.ErrorResponse(
"backend type must be specified as a string"),
@ -1142,10 +1149,17 @@ func (b *SystemBackend) handleTuneReadCommon(path string) (*logical.Response, er
return handleError(fmt.Errorf("sys: cannot fetch sysview for path %s", path))
}
mountEntry := b.Core.router.MatchingMountEntry(path)
if mountEntry == nil {
b.Backend.Logger().Error("sys: cannot fetch mount entry", "path", path)
return handleError(fmt.Errorf("sys: cannot fetch mount entry for path %s", path))
}
resp := &logical.Response{
Data: map[string]interface{}{
"default_lease_ttl": int(sysView.DefaultLeaseTTL().Seconds()),
"max_lease_ttl": int(sysView.MaxLeaseTTL().Seconds()),
"force_no_cache": mountEntry.Config.ForceNoCache,
},
}

View File

@ -51,6 +51,7 @@ func TestSystemBackend_mounts(t *testing.T) {
"config": map[string]interface{}{
"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),
"force_no_cache": false,
},
"local": false,
},
@ -60,6 +61,7 @@ func TestSystemBackend_mounts(t *testing.T) {
"config": map[string]interface{}{
"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),
"force_no_cache": false,
},
"local": false,
},
@ -69,6 +71,7 @@ func TestSystemBackend_mounts(t *testing.T) {
"config": map[string]interface{}{
"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),
"force_no_cache": false,
},
"local": true,
},
@ -93,6 +96,32 @@ func TestSystemBackend_mount(t *testing.T) {
}
}
func TestSystemBackend_mount_force_no_cache(t *testing.T) {
core, b, _ := testCoreSystemBackend(t)
req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
req.Data["type"] = "generic"
req.Data["config"] = map[string]interface{}{
"force_no_cache": true,
}
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
mountEntry := core.router.MatchingMountEntry("prod/secret/")
if mountEntry == nil {
t.Fatalf("missing mount entry")
}
if !mountEntry.Config.ForceNoCache {
t.Fatalf("bad config %#v", mountEntry)
}
}
func TestSystemBackend_mount_invalid(t *testing.T) {
b := testSystemBackend(t)

View File

@ -146,6 +146,7 @@ type MountEntry struct {
type MountConfig struct {
DefaultLeaseTTL time.Duration `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"` // Override for global default
MaxLeaseTTL time.Duration `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` // Override for global default
ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"` // Override for global default
}
// Returns a deep copy of the mount entry

View File

@ -39,7 +39,8 @@ description: |-
"description": "AWS keys",
"config": {
"default_lease_ttl": 0,
"max_lease_ttl": 0
"max_lease_ttl": 0,
"force_no_cache": false
}
},
@ -48,7 +49,8 @@ description: |-
"description": "system endpoint",
"config": {
"default_lease_ttl": 0,
"max_lease_ttl": 0
"max_lease_ttl": 0,
"force_no_cache": false
}
}
}
@ -88,11 +90,10 @@ description: |-
<span class="param">config</span>
<span class="param-flags">optional</span>
Config options for this mount. This is an object with
two possible values: `default_lease_ttl` and
`max_lease_ttl`. These control the default and
maximum lease time-to-live, respectively. If set
on a specific mount, this overrides the global
defaults.
three possible values: `default_lease_ttl`,
`max_lease_ttl`, and`force_no_cache`. These control the default and
maximum lease time-to-live, and force disabling backend caching respectively.
If set on a specific mount, this overrides the global defaults.
</li>
</ul>
</dd>
@ -154,7 +155,8 @@ description: |-
```javascript
{
"default_lease_ttl": 3600,
"max_lease_ttl": 7200
"max_lease_ttl": 7200,
"force_no_cache": false
}
```