transit cache is an Interface implemented by wrapped versions of sync… (#6225)

* transit cache is an Interface implemented by wrapped versions of syncmap and golang-lru

* transit cache is an Interface implemented by wrapped versions of syncmap and golang-lru

* changed some import paths to point to sdk

* Apply suggestions from code review

Co-Authored-By: Lexman42 <Lexman42@users.noreply.github.com>

* updates docs with information on transit/cache-config endpoint

* updates vendored files

* fixes policy tests to actually use a cache where expected and renames the struct and storage path used for cache configurations to be more generic

* updates document links

* fixed a typo in a documentation link

* changes cache_size to just size for the cache-config endpoint
This commit is contained in:
Lexman
2019-06-04 15:40:56 -07:00
committed by Brian Kassouf
parent 4d0d70551d
commit 4ed616dacb
15 changed files with 547 additions and 36 deletions

View File

@@ -0,0 +1,8 @@
package keysutil
type Cache interface {
Delete(key interface{})
Load(key interface{}) (value interface{}, ok bool)
Store(key, value interface{})
Size() int
}

View File

@@ -55,21 +55,44 @@ type PolicyRequest struct {
type LockManager struct {
useCache bool
// If caching is enabled, the map of name to in-memory policy cache
cache sync.Map
cache Cache
keyLocks []*locksutil.LockEntry
}
func NewLockManager(cacheDisabled bool) *LockManager {
func NewLockManager(useCache bool, cacheSize int) (*LockManager, error) {
// determine the type of cache to create
var cache Cache
switch {
case !useCache:
case cacheSize < 0:
return nil, errors.New("cache size must be greater or equal to zero")
case cacheSize == 0:
cache = NewTransitSyncMap()
case cacheSize > 0:
newLRUCache, err := NewTransitLRU(cacheSize)
if err != nil {
return nil, errwrap.Wrapf("failed to create cache: {{err}}", err)
}
cache = newLRUCache
}
lm := &LockManager{
useCache: !cacheDisabled,
useCache: useCache,
cache: cache,
keyLocks: locksutil.CreateLocks(),
}
return lm
return lm, nil
}
func (lm *LockManager) CacheActive() bool {
func (lm *LockManager) GetCacheSize() int {
if !lm.useCache {
return 0
}
return lm.cache.Size()
}
func (lm *LockManager) GetUseCache() bool {
return lm.useCache
}
@@ -178,7 +201,6 @@ func (lm *LockManager) RestorePolicy(ctx context.Context, storage logical.Storag
if lm.useCache {
lm.cache.Store(name, keyData.Policy)
}
return nil
}
@@ -186,7 +208,7 @@ func (lm *LockManager) BackupPolicy(ctx context.Context, storage logical.Storage
var p *Policy
var err error
// Backup writes information about when the bacup took place, so we get an
// Backup writes information about when the backup took place, so we get an
// exclusive lock here
lock := locksutil.LockForKey(lm.keyLocks, name)
lock.Lock()

View File

@@ -52,8 +52,10 @@ func TestPolicy_KeyEntryMapUpgrade(t *testing.T) {
}
func Test_KeyUpgrade(t *testing.T) {
testKeyUpgradeCommon(t, NewLockManager(false))
testKeyUpgradeCommon(t, NewLockManager(true))
lockManagerWithCache, _ := NewLockManager(true, 0)
lockManagerWithoutCache, _ := NewLockManager(false, 0)
testKeyUpgradeCommon(t, lockManagerWithCache)
testKeyUpgradeCommon(t, lockManagerWithoutCache)
}
func testKeyUpgradeCommon(t *testing.T, lm *LockManager) {
@@ -97,8 +99,10 @@ func testKeyUpgradeCommon(t *testing.T, lm *LockManager) {
}
func Test_ArchivingUpgrade(t *testing.T) {
testArchivingUpgradeCommon(t, NewLockManager(false))
testArchivingUpgradeCommon(t, NewLockManager(true))
lockManagerWithCache, _ := NewLockManager(true, 0)
lockManagerWithoutCache, _ := NewLockManager(false, 0)
testArchivingUpgradeCommon(t, lockManagerWithCache)
testArchivingUpgradeCommon(t, lockManagerWithoutCache)
}
func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) {
@@ -255,8 +259,10 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) {
}
func Test_Archiving(t *testing.T) {
testArchivingCommon(t, NewLockManager(false))
testArchivingCommon(t, NewLockManager(true))
lockManagerWithCache, _ := NewLockManager(true, 0)
lockManagerWithoutCache, _ := NewLockManager(false, 0)
testArchivingUpgradeCommon(t, lockManagerWithCache)
testArchivingUpgradeCommon(t, lockManagerWithoutCache)
}
func testArchivingCommon(t *testing.T, lm *LockManager) {
@@ -420,7 +426,7 @@ func checkKeys(t *testing.T,
func Test_StorageErrorSafety(t *testing.T) {
ctx := context.Background()
lm := NewLockManager(false)
lm, _ := NewLockManager(true, 0)
storage := &logical.InmemStorage{}
p, _, err := lm.GetPolicy(ctx, PolicyRequest{
@@ -468,7 +474,7 @@ func Test_StorageErrorSafety(t *testing.T) {
func Test_BadUpgrade(t *testing.T) {
ctx := context.Background()
lm := NewLockManager(false)
lm, _ := NewLockManager(true, 0)
storage := &logical.InmemStorage{}
p, _, err := lm.GetPolicy(ctx, PolicyRequest{
Upsert: true,
@@ -533,7 +539,7 @@ func Test_BadUpgrade(t *testing.T) {
func Test_BadArchive(t *testing.T) {
ctx := context.Background()
lm := NewLockManager(false)
lm, _ := NewLockManager(true, 0)
storage := &logical.InmemStorage{}
p, _, err := lm.GetPolicy(ctx, PolicyRequest{
Upsert: true,

View File

@@ -0,0 +1,29 @@
package keysutil
import lru "github.com/hashicorp/golang-lru"
type TransitLRU struct {
size int
lru *lru.TwoQueueCache
}
func NewTransitLRU(size int) (*TransitLRU, error) {
lru, err := lru.New2Q(size)
return &TransitLRU{lru: lru, size: size}, err
}
func (c *TransitLRU) Delete(key interface{}) {
c.lru.Remove(key)
}
func (c *TransitLRU) Load(key interface{}) (value interface{}, ok bool) {
return c.lru.Get(key)
}
func (c *TransitLRU) Store(key, value interface{}) {
c.lru.Add(key, value)
}
func (c *TransitLRU) Size() int {
return c.size
}

View File

@@ -0,0 +1,29 @@
package keysutil
import (
"sync"
)
type TransitSyncMap struct {
syncmap sync.Map
}
func NewTransitSyncMap() *TransitSyncMap {
return &TransitSyncMap{syncmap: sync.Map{}}
}
func (c *TransitSyncMap) Delete(key interface{}) {
c.syncmap.Delete(key)
}
func (c *TransitSyncMap) Load(key interface{}) (value interface{}, ok bool) {
return c.syncmap.Load(key)
}
func (c *TransitSyncMap) Store(key, value interface{}) {
c.syncmap.Store(key, value)
}
func (c *TransitSyncMap) Size() int {
return 0
}