Convert logical.InmemStorage to a wrapper around physical/inmem.
The original reason for the split was physical's dependencies, but those haven't been onerous for a long time. Meanwhile it's a totally separate implementation so we could be getting faulty results from tests. Get rid of it and use the unified physical/inmem.
This commit is contained in:
parent
2ff01bb3ec
commit
609648de4f
|
@ -2,10 +2,10 @@ package logical
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
radix "github.com/armon/go-radix"
|
"github.com/hashicorp/vault/physical"
|
||||||
|
"github.com/hashicorp/vault/physical/inmem"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InmemStorage implements Storage and stores all data in memory. It is
|
// InmemStorage implements Storage and stores all data in memory. It is
|
||||||
|
@ -13,79 +13,55 @@ import (
|
||||||
// having to load all of physical's dependencies (which are legion) just to
|
// having to load all of physical's dependencies (which are legion) just to
|
||||||
// have some testing storage.
|
// have some testing storage.
|
||||||
type InmemStorage struct {
|
type InmemStorage struct {
|
||||||
sync.RWMutex
|
underlying physical.Backend
|
||||||
root *radix.Tree
|
once sync.Once
|
||||||
once sync.Once
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InmemStorage) Get(ctx context.Context, key string) (*StorageEntry, error) {
|
func (s *InmemStorage) Get(ctx context.Context, key string) (*StorageEntry, error) {
|
||||||
s.once.Do(s.init)
|
s.once.Do(s.init)
|
||||||
|
|
||||||
s.RLock()
|
entry, err := s.underlying.Get(ctx, key)
|
||||||
defer s.RUnlock()
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
if raw, ok := s.root.Get(key); ok {
|
|
||||||
se := raw.(*StorageEntry)
|
|
||||||
return &StorageEntry{
|
|
||||||
Key: se.Key,
|
|
||||||
Value: se.Value,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
if entry == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
}
|
||||||
|
return &StorageEntry{
|
||||||
|
Key: entry.Key,
|
||||||
|
Value: entry.Value,
|
||||||
|
SealWrap: entry.SealWrap,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InmemStorage) Put(ctx context.Context, entry *StorageEntry) error {
|
func (s *InmemStorage) Put(ctx context.Context, entry *StorageEntry) error {
|
||||||
s.once.Do(s.init)
|
s.once.Do(s.init)
|
||||||
|
|
||||||
s.Lock()
|
return s.underlying.Put(ctx, &physical.Entry{
|
||||||
defer s.Unlock()
|
Key: entry.Key,
|
||||||
|
Value: entry.Value,
|
||||||
s.root.Insert(entry.Key, &StorageEntry{
|
SealWrap: entry.SealWrap,
|
||||||
Key: entry.Key,
|
|
||||||
Value: entry.Value,
|
|
||||||
})
|
})
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InmemStorage) Delete(ctx context.Context, key string) error {
|
func (s *InmemStorage) Delete(ctx context.Context, key string) error {
|
||||||
s.once.Do(s.init)
|
s.once.Do(s.init)
|
||||||
|
|
||||||
s.Lock()
|
return s.underlying.Delete(ctx, key)
|
||||||
defer s.Unlock()
|
|
||||||
|
|
||||||
s.root.Delete(key)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InmemStorage) List(ctx context.Context, prefix string) ([]string, error) {
|
func (s *InmemStorage) List(ctx context.Context, prefix string) ([]string, error) {
|
||||||
s.once.Do(s.init)
|
s.once.Do(s.init)
|
||||||
|
|
||||||
s.RLock()
|
return s.underlying.List(ctx, prefix)
|
||||||
defer s.RUnlock()
|
}
|
||||||
|
|
||||||
var out []string
|
func (s *InmemStorage) Underlying() *inmem.InmemBackend {
|
||||||
seen := make(map[string]interface{})
|
s.once.Do(s.init)
|
||||||
walkFn := func(s string, v interface{}) bool {
|
|
||||||
trimmed := strings.TrimPrefix(s, prefix)
|
|
||||||
sep := strings.Index(trimmed, "/")
|
|
||||||
if sep == -1 {
|
|
||||||
out = append(out, trimmed)
|
|
||||||
} else {
|
|
||||||
trimmed = trimmed[:sep+1]
|
|
||||||
if _, ok := seen[trimmed]; !ok {
|
|
||||||
out = append(out, trimmed)
|
|
||||||
seen[trimmed] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
s.root.WalkPrefix(prefix, walkFn)
|
|
||||||
|
|
||||||
return out, nil
|
|
||||||
|
|
||||||
|
return s.underlying.(*inmem.InmemBackend)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *InmemStorage) init() {
|
func (s *InmemStorage) init() {
|
||||||
s.root = radix.New()
|
s.underlying, _ = inmem.NewInmem(nil, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@ package inmem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/physical"
|
"github.com/hashicorp/vault/physical"
|
||||||
log "github.com/mgutz/logxi/v1"
|
log "github.com/mgutz/logxi/v1"
|
||||||
|
@ -19,6 +21,13 @@ var _ physical.Lock = (*InmemLock)(nil)
|
||||||
var _ physical.Transactional = (*TransactionalInmemBackend)(nil)
|
var _ physical.Transactional = (*TransactionalInmemBackend)(nil)
|
||||||
var _ physical.Transactional = (*TransactionalInmemHABackend)(nil)
|
var _ physical.Transactional = (*TransactionalInmemHABackend)(nil)
|
||||||
|
|
||||||
|
var (
|
||||||
|
PutDisabledError = errors.New("put operations disabled in inmem backend")
|
||||||
|
GetDisabledError = errors.New("get operations disabled in inmem backend")
|
||||||
|
DeleteDisabledError = errors.New("delete operations disabled in inmem backend")
|
||||||
|
ListDisabledError = errors.New("list operations disabled in inmem backend")
|
||||||
|
)
|
||||||
|
|
||||||
// InmemBackend is an in-memory only physical backend. It is useful
|
// InmemBackend is an in-memory only physical backend. It is useful
|
||||||
// for testing and development situations where the data is not
|
// for testing and development situations where the data is not
|
||||||
// expected to be durable.
|
// expected to be durable.
|
||||||
|
@ -27,6 +36,10 @@ type InmemBackend struct {
|
||||||
root *radix.Tree
|
root *radix.Tree
|
||||||
permitPool *physical.PermitPool
|
permitPool *physical.PermitPool
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
|
FailGet *uint32
|
||||||
|
FailPut *uint32
|
||||||
|
FailDelete *uint32
|
||||||
|
FailList *uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionalInmemBackend struct {
|
type TransactionalInmemBackend struct {
|
||||||
|
@ -39,6 +52,10 @@ func NewInmem(_ map[string]string, logger log.Logger) (physical.Backend, error)
|
||||||
root: radix.New(),
|
root: radix.New(),
|
||||||
permitPool: physical.NewPermitPool(physical.DefaultParallelOperations),
|
permitPool: physical.NewPermitPool(physical.DefaultParallelOperations),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
FailGet: new(uint32),
|
||||||
|
FailPut: new(uint32),
|
||||||
|
FailDelete: new(uint32),
|
||||||
|
FailList: new(uint32),
|
||||||
}
|
}
|
||||||
return in, nil
|
return in, nil
|
||||||
}
|
}
|
||||||
|
@ -51,6 +68,10 @@ func NewTransactionalInmem(_ map[string]string, logger log.Logger) (physical.Bac
|
||||||
root: radix.New(),
|
root: radix.New(),
|
||||||
permitPool: physical.NewPermitPool(1),
|
permitPool: physical.NewPermitPool(1),
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
FailGet: new(uint32),
|
||||||
|
FailPut: new(uint32),
|
||||||
|
FailDelete: new(uint32),
|
||||||
|
FailList: new(uint32),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return in, nil
|
return in, nil
|
||||||
|
@ -68,6 +89,10 @@ func (i *InmemBackend) Put(ctx context.Context, entry *physical.Entry) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InmemBackend) PutInternal(ctx context.Context, entry *physical.Entry) error {
|
func (i *InmemBackend) PutInternal(ctx context.Context, entry *physical.Entry) error {
|
||||||
|
if i.FailPut != nil && atomic.LoadUint32(i.FailPut) != 0 {
|
||||||
|
return PutDisabledError
|
||||||
|
}
|
||||||
|
|
||||||
i.root.Insert(entry.Key, entry.Value)
|
i.root.Insert(entry.Key, entry.Value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -84,6 +109,10 @@ func (i *InmemBackend) Get(ctx context.Context, key string) (*physical.Entry, er
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InmemBackend) GetInternal(ctx context.Context, key string) (*physical.Entry, error) {
|
func (i *InmemBackend) GetInternal(ctx context.Context, key string) (*physical.Entry, error) {
|
||||||
|
if i.FailGet != nil && atomic.LoadUint32(i.FailGet) != 0 {
|
||||||
|
return nil, GetDisabledError
|
||||||
|
}
|
||||||
|
|
||||||
if raw, ok := i.root.Get(key); ok {
|
if raw, ok := i.root.Get(key); ok {
|
||||||
return &physical.Entry{
|
return &physical.Entry{
|
||||||
Key: key,
|
Key: key,
|
||||||
|
@ -105,6 +134,10 @@ func (i *InmemBackend) Delete(ctx context.Context, key string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InmemBackend) DeleteInternal(ctx context.Context, key string) error {
|
func (i *InmemBackend) DeleteInternal(ctx context.Context, key string) error {
|
||||||
|
if i.FailDelete != nil && atomic.LoadUint32(i.FailDelete) != 0 {
|
||||||
|
return DeleteDisabledError
|
||||||
|
}
|
||||||
|
|
||||||
i.root.Delete(key)
|
i.root.Delete(key)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -122,6 +155,10 @@ func (i *InmemBackend) List(ctx context.Context, prefix string) ([]string, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InmemBackend) ListInternal(prefix string) ([]string, error) {
|
func (i *InmemBackend) ListInternal(prefix string) ([]string, error) {
|
||||||
|
if i.FailList != nil && atomic.LoadUint32(i.FailList) != 0 {
|
||||||
|
return nil, ListDisabledError
|
||||||
|
}
|
||||||
|
|
||||||
var out []string
|
var out []string
|
||||||
seen := make(map[string]interface{})
|
seen := make(map[string]interface{})
|
||||||
walkFn := func(s string, v interface{}) bool {
|
walkFn := func(s string, v interface{}) bool {
|
||||||
|
|
Loading…
Reference in a new issue