Files
storage/internal/vault/vault.go
Dmitry Fedotov 48878e8433 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)
2025-07-27 19:02:05 +03:00

87 lines
1.6 KiB
Go

package vault
import (
"context"
"encoding/base64"
"errors"
"code.uint32.ru/tiny/storage/internal/errinternal"
"github.com/hashicorp/vault/api"
)
var (
ErrNotFound = errinternal.ErrNotFound
)
type Storage struct {
kv *api.KVv1
// TODO: kv2: *api.KVv2
}
// New returns Storage writing to the specified vault path.
// Object will be base64 encoded and written to path/key.
func New(c *api.Client, path string) *Storage {
return &Storage{kv: c.KVv1(path)}
}
func (s *Storage) Save(key string, data []byte) error {
str := base64.StdEncoding.EncodeToString(data)
m := map[string]any{
"data": map[string]string{
"payload": str,
},
}
if err := s.kv.Put(context.Background(), "testkey", m); err != nil {
return err
}
return nil
}
func (s *Storage) Load(key string) ([]byte, error) {
m, err := s.kv.Get(context.Background(), key)
if err != nil && errors.Is(err, api.ErrSecretNotFound) {
return nil, errors.Join(ErrNotFound, err)
} else if err != nil {
return nil, err
}
data, ok := m.Data["data"] // map[string]any
if !ok {
return nil, errors.New("no data found")
}
payloadmap, ok := data.(map[string]any)
if !ok {
return nil, errors.New("no payload map")
}
rawb, ok := payloadmap["payload"]
if !ok {
return nil, errors.New("no payload bytes")
}
str, ok := rawb.(string)
if !ok {
return nil, errors.New("could not convert payload to bytes")
}
b := []byte{}
b, err = base64.StdEncoding.AppendDecode(b, []byte(str))
if err != nil {
return nil, err
}
return b, nil
}
func (s *Storage) Delete(key string) error {
if err := s.kv.Delete(context.Background(), key); err != nil {
return err
}
return nil
}