From 7f0771d0a9caf2d3294bfced9e66fac03334d9ba Mon Sep 17 00:00:00 2001 From: Laria Carolin Chabowski Date: Sun, 1 Oct 2017 01:07:05 +0200 Subject: Redo storage config --- config/config.go | 59 +++++++++++++++------------- storage/cloud/cloudstorage.go | 16 +++++--- storage/cloud/swift.go | 91 +++++++++++++++++++++++-------------------- storage/local/local.go | 7 ++-- storage/registry/registry.go | 8 +--- 5 files changed, 97 insertions(+), 84 deletions(-) diff --git a/config/config.go b/config/config.go index 7454d7a..46d1b47 100644 --- a/config/config.go +++ b/config/config.go @@ -2,23 +2,35 @@ package config import ( "code.laria.me/petrific/gpg" + "errors" "fmt" "github.com/BurntSushi/toml" "github.com/adrg/xdg" "os" "os/user" - "reflect" "strings" ) -type StorageConfig map[string]interface{} +type StorageConfigErr struct { + Name string + Err error +} + +func (sce StorageConfigErr) Error() string { + return fmt.Sprintf("Could not get configuration for storage %s: %s", sce.Name, sce.Err.Error()) +} + +var ( + StorageConfigNotFound = errors.New("Not found") +) type Config struct { DefaultStorage string `toml:"default_storage"` Signing struct { Key string } - Storage map[string]StorageConfig + Storage map[string]toml.Primitive + meta toml.MetaData `toml:"-"` } func LoadConfig(path string) (config Config, err error) { @@ -29,42 +41,37 @@ func LoadConfig(path string) (config Config, err error) { } } - _, err = toml.DecodeFile(path, &config) - return + meta, err := toml.DecodeFile(path, &config) + config.meta = meta + return config, err } func (c Config) GPGSigner() gpg.Signer { return gpg.Signer{c.Signing.Key} } -// Get gets a value from the StorageConfig, taking care about type checking. -// ptr must be a pointer or this method will panic. -// ptr will only be changed, if returned error != nil -func (s StorageConfig) Get(k string, ptr interface{}) error { - ptrval := reflect.ValueOf(ptr) - - if ptrval.Kind() != reflect.Ptr { - panic("ptr must be a pointer") - } - - ptrelem := ptrval.Elem() - if !ptrelem.CanSet() { - panic("*ptr not settable?!") +func (c Config) GetStorageMethod(name string) (string, error) { + prim, ok := c.Storage[name] + if !ok { + return "", StorageConfigErr{name, StorageConfigNotFound} } - v, ok := s[k] - if !ok { - return fmt.Errorf("Key '%s' is missing", k) + var method_wrap struct{ Method string } + err := c.meta.PrimitiveDecode(prim, &method_wrap) + if err != nil { + return "", StorageConfigErr{name, err} } - vval := reflect.ValueOf(v) + return method_wrap.Method, nil +} - if vval.Type() != ptrelem.Type() { - return fmt.Errorf("Expected config '%s' to be of type %s, got %s", k, ptrelem.Type(), vval.Type()) +func (c Config) GetStorageConfData(name string, v interface{}) error { + prim, ok := c.Storage[name] + if !ok { + return StorageConfigErr{name, StorageConfigNotFound} } - ptrelem.Set(vval) - return nil + return c.meta.PrimitiveDecode(prim, v) } func ExpandTilde(path string) string { diff --git a/storage/cloud/cloudstorage.go b/storage/cloud/cloudstorage.go index 9ae8ee8..261a034 100644 --- a/storage/cloud/cloudstorage.go +++ b/storage/cloud/cloudstorage.go @@ -158,16 +158,20 @@ func cloudStorageCreator(cloudCreator cloudObjectStorageCreator) storage.CreateS return func(conf config.Config, name string) (storage.Storage, error) { var cbos CloudBasedObjectStorage - storageconf := conf.Storage[name] + var storageconf struct { + Prefix string `toml:"prefix,omitempty"` + EncryptFor string `toml:"encrypt_for,omitempty"` + } - storageconf.Get("prefix", &cbos.Prefix) + if err := conf.GetStorageConfData(name, &storageconf); err != nil { + return nil, err + } - encrypt_for := "" - storageconf.Get("encrypt_for", &encrypt_for) + cbos.Prefix = storageconf.Prefix - if encrypt_for != "" { + if storageconf.EncryptFor != "" { cbos.Crypter = gpg.Crypter{ - gpg.Encrypter{Key: encrypt_for}, + gpg.Encrypter{Key: storageconf.EncryptFor}, gpg.Decrypter{}, } } diff --git a/storage/cloud/swift.go b/storage/cloud/swift.go index 41a13c6..a721f67 100644 --- a/storage/cloud/swift.go +++ b/storage/cloud/swift.go @@ -3,7 +3,6 @@ package cloud import ( "code.laria.me/petrific/config" "code.laria.me/petrific/storage" - "fmt" "github.com/ncw/swift" "time" ) @@ -13,61 +12,67 @@ type SwiftCloudStorage struct { container string } -type SwiftStorageConfigMandatoryError struct { - Key string - Err error -} - -func (e SwiftStorageConfigMandatoryError) Error() string { - return fmt.Sprintf("Could not get mandatory key %s for swift storage: %s", e.Key, e.Err.Error()) +type SwiftConfig struct { + // Mandatory options + Container string `toml:"container"` + UserName string `toml:"user_name"` + ApiKey string `toml:"api_key"` + AuthURL string `toml:"auth_url"` + + // Optional... options + Domain string `toml:"domain,omitempty"` + DomainID string `toml:"domain_id,omitempty"` + UserID string `toml:"user_id,omitempty"` + Retries int `toml:"retries,omitempty"` + Region string `toml:"region,omitempty"` + AuthVersion int `toml:"auth_version,omitempty"` + Tenant string `toml:"tenant,omitempty"` + TenantID string `toml:"tenant_id,omitempty"` + TenantDomain string `toml:"tenant_domain,omitempty"` + TenantDomainID string `toml:"tenant_domain_id,omitempty"` + TrustID string `toml:"trust_id,omitempty"` + ConnectTimeout string `toml:"connect_timeout,omitempty"` + Timeout string `toml:"timeout,omitempty"` } func SwiftStorageCreator() storage.CreateStorageFromConfig { return cloudStorageCreator(func(conf config.Config, name string) (CloudStorage, error) { - storage_conf := conf.Storage[name] - storage := SwiftCloudStorage{} - storage.con = new(swift.Connection) + var storage_conf SwiftConfig - // Mandatory options - if err := storage_conf.Get("container", &storage.container); err != nil { - return nil, SwiftStorageConfigMandatoryError{"container", err} - } - if err := storage_conf.Get("user_name", &storage.con.UserName); err != nil { - return nil, SwiftStorageConfigMandatoryError{"user_name", err} - } - if err := storage_conf.Get("api_key", &storage.con.ApiKey); err != nil { - return nil, SwiftStorageConfigMandatoryError{"api_key", err} - } - if err := storage_conf.Get("auth_url", &storage.con.AuthUrl); err != nil { - return nil, SwiftStorageConfigMandatoryError{"auth_url", err} + if err := conf.GetStorageConfData(name, &storage_conf); err != nil { + return nil, err } - // Optional... options - - storage_conf.Get("domain", &storage.con.Domain) - storage_conf.Get("domain_id", &storage.con.DomainId) - storage_conf.Get("user_id", &storage.con.UserId) - storage_conf.Get("retries", &storage.con.Retries) - storage_conf.Get("region", &storage.con.Region) - storage_conf.Get("auth_version", &storage.con.AuthVersion) - storage_conf.Get("tenant", &storage.con.Tenant) - storage_conf.Get("tenant_id", &storage.con.TenantId) - storage_conf.Get("tenant_domain", &storage.con.TenantDomain) - storage_conf.Get("tenant_domain_id", &storage.con.TenantDomainId) - storage_conf.Get("trust_id", &storage.con.TrustId) - - var connect_timeout_str string - if storage_conf.Get("connect_timeout", &connect_timeout_str) == nil { - d, err := time.ParseDuration(connect_timeout_str) + storage := SwiftCloudStorage{} + storage.con = new(swift.Connection) + + storage.container = storage_conf.Container + storage.con.UserName = storage_conf.UserName + storage.con.ApiKey = storage_conf.ApiKey + storage.con.AuthUrl = storage_conf.AuthURL + + storage.con.Domain = storage_conf.Domain + storage.con.DomainId = storage_conf.DomainID + storage.con.UserId = storage_conf.UserID + storage.con.Retries = storage_conf.Retries + storage.con.Region = storage_conf.Region + storage.con.AuthVersion = storage_conf.AuthVersion + storage.con.Tenant = storage_conf.Tenant + storage.con.TenantId = storage_conf.TenantID + storage.con.TenantDomain = storage_conf.TenantDomain + storage.con.TenantDomainId = storage_conf.TenantDomainID + storage.con.TrustId = storage_conf.TrustID + + if storage_conf.ConnectTimeout != "" { + d, err := time.ParseDuration(storage_conf.ConnectTimeout) if err != nil { return nil, err } storage.con.ConnectTimeout = d } - var timeout_str string - if storage_conf.Get("timeout", &timeout_str) == nil { - d, err := time.ParseDuration(timeout_str) + if storage_conf.Timeout != "" { + d, err := time.ParseDuration(storage_conf.Timeout) if err != nil { return nil, err } diff --git a/storage/local/local.go b/storage/local/local.go index 4869bb2..7dc59cb 100644 --- a/storage/local/local.go +++ b/storage/local/local.go @@ -26,12 +26,13 @@ type LocalStorage struct { } func LocalStorageFromConfig(conf config.Config, name string) (storage.Storage, error) { - var path string - if err := conf.Storage[name].Get("path", &path); err != nil { + var path_wrap struct{ Path string } + + if err := conf.GetStorageConfData(name, &path_wrap); err != nil { return nil, err } - return OpenLocalStorage(config.ExpandTilde(path)) + return OpenLocalStorage(config.ExpandTilde(path_wrap.Path)) } func OpenLocalStorage(path string) (l LocalStorage, err error) { diff --git a/storage/registry/registry.go b/storage/registry/registry.go index ad66c6a..f792946 100644 --- a/storage/registry/registry.go +++ b/storage/registry/registry.go @@ -35,13 +35,9 @@ func (e storageConfErr) Error() string { } func loadStorage(conf config.Config, storageName string) (storage.Storage, error) { - storageOptions, ok := conf.Storage[storageName] - if !ok { - return nil, notFoundErr - } + method, err := conf.GetStorageMethod(storageName) - var method string - if err := storageOptions.Get("method", &method); err != nil { + if err != nil { return nil, err } -- cgit v1.2.3-54-g00ecf