feat: working version

1. implemented filesystem storage, NATS object storage
and saving to Vault.
2. Test coverage is fine for filesystem and Vault
(and NATS object does not really require extensive tests)
This commit is contained in:
2025-07-27 19:02:05 +03:00
parent 854de3865b
commit 48878e8433
13 changed files with 265 additions and 153 deletions

View File

@@ -1,11 +1,24 @@
package storage
import (
"github.com/hashicorp/vault/api"
"github.com/nats-io/nats.go"
"code.uint32.ru/tiny/storage/internal/errinternal"
"code.uint32.ru/tiny/storage/internal/filesystem"
"code.uint32.ru/tiny/storage/internal/natsobj"
"code.uint32.ru/tiny/storage/internal/vault"
)
var (
// ErrInvalidKey is returned when key validation
// for particular implementation of Storage fails.
ErrInvalidKey = errinternal.ErrInvalidKey
// ErrNotFound is returned when object is not found
// in Storage.
ErrNotFound = errinternal.ErrNotFound
)
var (
_ Storage = (*natsobj.Storage)(nil)
_ Storage = (*filesystem.Storage)(nil)
@@ -17,32 +30,34 @@ type Storage interface {
// Save puts object with name 'key' into the store.
// If a key already exists it gets overwritten.
Save(key string, data []byte) error
// Load returns contents of object named 'key'.
// Load returns contents of object named 'key' or
// ErrNotFound.
Load(key string) ([]byte, error)
// Delete removes object named 'key' from the store.
// If key does not exist Delete returns nil.
Delete(key string) error
// Close must be called when you're done working with Storage.
Close() error
}
// NewNats connects to NATS messaging system and tries to create
// a new object storage with name 'bucket'. The returned Storage
// uses the created bucket as underlying physical store.
func NewNats(bucket string, url string) (Storage, error) {
return natsobj.Open(bucket, url)
// NewNats wraps the provided ObjectStore with Storage interface.
func NewNats(store nats.ObjectStore) Storage {
return natsobj.New(store)
}
// NewFS established a key/value within the directory 'path'
// and uses is as underlying physical store.
// and uses it as underlying physical store.
// Note that the implementation requires keys to be at least
// 3 characters long.
// Key "abcd" will be stored in /path/a/b/abcd.
func NewFS(path string) (Storage, error) {
return filesystem.Open(path)
return filesystem.New(path)
}
// NewVault connects to Vault at addr and uses path as base path for
// NewVault uses provided Vault client to store objects.
// The provided path is used as base path for
// keys. Objects saved to Storage will be put at
// /path/key as new secrets.
// Bytes passed to storage will be base64 encoded and saved as string.
func NewVault(token string, path string, addr string) (Storage, error) {
return vault.Open(token, path, addr)
// Bytes passed to storage will be base64 encoded and saved
// in Vault as string.
func NewVault(client *api.Client, path string) Storage {
return vault.New(client, path)
}