introduces storage pkg (#25) (#73)

* introduces storage pkg (#25)

Adds a new package /pkg/storage.  Storage is used to
communicate storage provider information throughout the corso
app.  In particular, it allows per-provider data to cross interface
boundaries without slicing their details.

* use consts for s3 config keys
This commit is contained in:
Keepers 2022-05-25 09:50:52 -06:00 committed by GitHub
parent 06608be38e
commit 99358c5d6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 191 additions and 0 deletions

32
src/pkg/storage/s3.go Normal file
View File

@ -0,0 +1,32 @@
package storage
type S3Config struct {
Bucket string
AccessKey string
SecretKey string
}
const (
keyS3Bucket = "s3_bucket"
keyS3AccessKey = "s3_accessKey"
keyS3SecretKey = "s3_secretKey"
)
func (c S3Config) Config() config {
return config{
keyS3Bucket: c.Bucket,
keyS3AccessKey: c.AccessKey,
keyS3SecretKey: c.SecretKey,
}
}
// S3Config retrieves the S3Config details from the Storage config.
func (s Storage) S3Config() S3Config {
c := S3Config{}
if len(s.Config) > 0 {
c.Bucket = s.Config[keyS3Bucket].(string)
c.AccessKey = s.Config[keyS3AccessKey].(string)
c.SecretKey = s.Config[keyS3SecretKey].(string)
}
return c
}

View File

@ -0,0 +1,42 @@
package storage_test
import (
"testing"
"github.com/alcionai/corso/pkg/storage"
)
func TestS3Config_Config(t *testing.T) {
s3 := storage.S3Config{"bkt", "ak", "sk"}
c := s3.Config()
table := []struct {
key string
expect string
}{
{"s3_bucket", s3.Bucket},
{"s3_accessKey", s3.AccessKey},
{"s3_secretKey", s3.SecretKey},
}
for _, test := range table {
key := test.key
expect := test.expect
if c[key] != expect {
t.Errorf("expected config key [%s] to hold value [%s], got [%s]", key, expect, c[key])
}
}
}
func TestStorage_S3Config(t *testing.T) {
in := storage.S3Config{"bkt", "ak", "sk"}
s := storage.NewStorage(storage.ProviderS3, in)
out := s.S3Config()
if in.Bucket != out.Bucket {
t.Errorf("expected S3Config.Bucket to be [%s], got [%s]", in.Bucket, out.Bucket)
}
if in.AccessKey != out.AccessKey {
t.Errorf("expected S3Config.AccessKey to be [%s], got [%s]", in.AccessKey, out.AccessKey)
}
if in.SecretKey != out.SecretKey {
t.Errorf("expected S3Config.SecretKey to be [%s], got [%s]", in.SecretKey, out.SecretKey)
}
}

View File

@ -0,0 +1,41 @@
package storage
type storageProvider int
//go:generate stringer -type=storageProvider -linecomment
const (
ProviderUnknown storageProvider = iota // Unknown Provider
ProviderS3 // S3
)
type (
config map[string]any
configurer interface {
Config() config
}
)
// Storage defines a storage provider, along with any configuration
// requried to set up or communicate with that provider.
type Storage struct {
Provider storageProvider
Config config
}
// NewStorage aggregates all the supplied configurations into a single configuration.
func NewStorage(p storageProvider, cfgs ...configurer) Storage {
return Storage{
Provider: p,
Config: unionConfigs(cfgs...),
}
}
func unionConfigs(cfgs ...configurer) config {
c := config{}
for _, cfg := range cfgs {
for k, v := range cfg.Config() {
c[k] = v
}
}
return c
}

View File

@ -0,0 +1,52 @@
package storage
import (
"testing"
)
type testConfig struct {
expect string
}
func (c testConfig) Config() config {
return config{"expect": c.expect}
}
func TestNewStorage(t *testing.T) {
table := []struct {
p storageProvider
c testConfig
}{
{ProviderUnknown, testConfig{"unknown"}},
{ProviderS3, testConfig{"s3"}},
}
for _, test := range table {
s := NewStorage(test.p, test.c)
if s.Provider != test.p {
t.Errorf("expected storage provider [%s], got [%s]", test.p, s.Provider)
}
if s.Config["expect"] != test.c.expect {
t.Errorf("expected storage config [%s], got [%s]", test.c.expect, s.Config["expect"])
}
}
}
type fooConfig struct {
foo string
}
func (c fooConfig) Config() config {
return config{"foo": c.foo}
}
func TestUnionConfigs(t *testing.T) {
te := testConfig{"test"}
f := fooConfig{"foo"}
cs := unionConfigs(te, f)
if cs["expect"] != te.expect {
t.Errorf("expected unioned config to have value [%s] at key [expect], got [%s]", te.expect, cs["expect"])
}
if cs["foo"] != f.foo {
t.Errorf("expected unioned config to have value [%s] at key [foo], got [%s]", f.foo, cs["foo"])
}
}

View File

@ -0,0 +1,24 @@
// Code generated by "stringer -type=storageProvider -linecomment"; DO NOT EDIT.
package storage
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[ProviderUnknown-0]
_ = x[ProviderS3-1]
}
const _storageProvider_name = "Unknown ProviderS3"
var _storageProvider_index = [...]uint8{0, 16, 18}
func (i storageProvider) String() string {
if i < 0 || i >= storageProvider(len(_storageProvider_index)-1) {
return "storageProvider(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _storageProvider_name[_storageProvider_index[i]:_storageProvider_index[i+1]]
}