Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce minimum cache size for transit backend #12418

Merged
merged 13 commits into from Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions builtin/logical/transit/backend.go
Expand Up @@ -10,6 +10,9 @@ import (
"github.com/hashicorp/vault/sdk/logical"
)

// Minimum cache size for transit backend
const minCacheSize = 10

func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
b, err := Backend(ctx, conf)
if err != nil {
Expand Down Expand Up @@ -68,6 +71,11 @@ func Backend(ctx context.Context, conf *logical.BackendConfig) (*backend, error)
if err != nil {
return nil, fmt.Errorf("Error retrieving cache size from storage: %w", err)
}

if cacheSize != 0 && cacheSize < minCacheSize {
b.Logger().Warn("size %d is less than minimum %d. Cache size is set to %d", cacheSize, minCacheSize, minCacheSize)
cacheSize = minCacheSize
}
}

var err error
Expand Down
13 changes: 8 additions & 5 deletions builtin/logical/transit/path_cache_config.go
Expand Up @@ -3,8 +3,8 @@ package transit
import (
"context"
"errors"

"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/keysutil"
"github.com/hashicorp/vault/sdk/logical"
)

Expand Down Expand Up @@ -45,8 +45,8 @@ func (b *backend) pathCacheConfig() *framework.Path {
func (b *backend) pathCacheConfigWrite(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
// get target size
cacheSize := d.Get("size").(int)
if cacheSize < 0 {
return logical.ErrorResponse("size must be greater or equal to 0"), logical.ErrInvalidRequest
if cacheSize != 0 && cacheSize < minCacheSize {
return logical.ErrorResponse("size must be 0 or a value greater or equal to %d", minCacheSize), logical.ErrInvalidRequest
}

// store cache size
Expand All @@ -60,8 +60,11 @@ func (b *backend) pathCacheConfigWrite(ctx context.Context, req *logical.Request
return nil, err
}

resp := &logical.Response{
Warnings: []string{"cache configurations will be applied when this backend is restarted"},
resp := &logical.Response{}

b.lm, err = keysutil.NewLockManager(true, cacheSize)
divyapola5 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, err
}

return resp, nil
Expand Down
18 changes: 17 additions & 1 deletion builtin/logical/transit/path_cache_config_test.go
Expand Up @@ -8,6 +8,7 @@ import (
)

const targetCacheSize = 12345
const smallCacheSize = 3

func TestTransit_CacheConfig(t *testing.T) {
b1, storage := createBackendWithSysView(t)
Expand Down Expand Up @@ -58,6 +59,15 @@ func TestTransit_CacheConfig(t *testing.T) {
},
}

writeSmallCacheSizeReq := &logical.Request{
Storage: storage,
Operation: logical.UpdateOperation,
Path: "cache-config",
Data: map[string]interface{}{
"size": smallCacheSize,
},
}

readReq := &logical.Request{
Storage: storage,
Operation: logical.ReadOperation,
Expand All @@ -68,7 +78,7 @@ func TestTransit_CacheConfig(t *testing.T) {
// b1 should spin up with an unlimited cache
validateResponse(doReq(b1, readReq), 0, false)
doReq(b1, writeReq)
validateResponse(doReq(b1, readReq), targetCacheSize, true)
validateResponse(doReq(b1, readReq), targetCacheSize, false)

// b2 should spin up with a configured cache
b2 := createBackendWithSysViewWithStorage(t, storage)
Expand All @@ -77,4 +87,10 @@ func TestTransit_CacheConfig(t *testing.T) {
// b3 enables transit without a cache, trying to read it should error
b3 := createBackendWithForceNoCacheWithSysViewWithStorage(t, storage)
doErrReq(b3, readReq)

// b4 should spin up with a size less than minimum cache size (10)
b4, storage := createBackendWithSysView(t)
doErrReq(b4, writeSmallCacheSizeReq)


}
3 changes: 3 additions & 0 deletions changelog/12418.txt
@@ -0,0 +1,3 @@
```release-note:bug
Enforce minimum cache size for transit backend
```
2 changes: 1 addition & 1 deletion website/content/api-docs/secret/transit.mdx
Expand Up @@ -1307,7 +1307,7 @@ using the [`/sys/plugins/reload/backend`][sys-plugin-reload-backend] endpoint.

- `size` `(int: 0)` - Specifies the size in terms of number of entries. A size of
`0` means unlimited. A _Least Recently Used_ (LRU) caching strategy is used for a
non-zero cache size.
non-zero cache size. Must be 0 (default) or a value greater or equal to 10 (minimum cache size).
victorr marked this conversation as resolved.
Show resolved Hide resolved

### Sample Payload

Expand Down