diff options
Diffstat (limited to 'vendor/github.com/xordataexchange/crypt/config/config.go')
-rw-r--r-- | vendor/github.com/xordataexchange/crypt/config/config.go | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/vendor/github.com/xordataexchange/crypt/config/config.go b/vendor/github.com/xordataexchange/crypt/config/config.go new file mode 100644 index 00000000..30864ae9 --- /dev/null +++ b/vendor/github.com/xordataexchange/crypt/config/config.go @@ -0,0 +1,201 @@ +package config + +import ( + "bytes" + "io" + "io/ioutil" + + "github.com/xordataexchange/crypt/backend" + "github.com/xordataexchange/crypt/backend/consul" + "github.com/xordataexchange/crypt/backend/etcd" + "github.com/xordataexchange/crypt/encoding/secconf" +) + +type KVPair struct { + backend.KVPair +} + +type KVPairs []*KVPair + +type configManager struct { + keystore []byte + store backend.Store +} + +// A ConfigManager retrieves and decrypts configuration from a key/value store. +type ConfigManager interface { + Get(key string) ([]byte, error) + List(key string) (KVPairs, error) + Set(key string, value []byte) error + Watch(key string, stop chan bool) <-chan *Response +} + +type standardConfigManager struct { + store backend.Store +} + +func NewStandardConfigManager(client backend.Store) (ConfigManager, error) { + return standardConfigManager{client}, nil +} + +func NewConfigManager(client backend.Store, keystore io.Reader) (ConfigManager, error) { + bytes, err := ioutil.ReadAll(keystore) + if err != nil { + return nil, err + } + return configManager{bytes, client}, nil +} + +// NewStandardEtcdConfigManager returns a new ConfigManager backed by etcd. +func NewStandardEtcdConfigManager(machines []string) (ConfigManager, error) { + store, err := etcd.New(machines) + if err != nil { + return nil, err + } + + return NewStandardConfigManager(store) +} + +// NewStandardConsulConfigManager returns a new ConfigManager backed by consul. +func NewStandardConsulConfigManager(machines []string) (ConfigManager, error) { + store, err := consul.New(machines) + if err != nil { + return nil, err + } + return NewStandardConfigManager(store) +} + +// NewEtcdConfigManager returns a new ConfigManager backed by etcd. +// Data will be encrypted. +func NewEtcdConfigManager(machines []string, keystore io.Reader) (ConfigManager, error) { + store, err := etcd.New(machines) + if err != nil { + return nil, err + } + return NewConfigManager(store, keystore) +} + +// NewConsulConfigManager returns a new ConfigManager backed by consul. +// Data will be encrypted. +func NewConsulConfigManager(machines []string, keystore io.Reader) (ConfigManager, error) { + store, err := consul.New(machines) + if err != nil { + return nil, err + } + return NewConfigManager(store, keystore) +} + +// Get retrieves and decodes a secconf value stored at key. +func (c configManager) Get(key string) ([]byte, error) { + value, err := c.store.Get(key) + if err != nil { + return nil, err + } + return secconf.Decode(value, bytes.NewBuffer(c.keystore)) +} + +// Get retrieves a value stored at key. +// convenience function, no additional value provided over +// `etcdctl` +func (c standardConfigManager) Get(key string) ([]byte, error) { + value, err := c.store.Get(key) + if err != nil { + return nil, err + } + return value, err +} + +// List retrieves and decodes all secconf value stored under key. +func (c configManager) List(key string) (KVPairs, error) { + list, err := c.store.List(key) + retList := make(KVPairs, len(list)) + if err != nil { + return nil, err + } + for i, kv := range list { + retList[i].Key = kv.Key + retList[i].Value, err = secconf.Decode(kv.Value, bytes.NewBuffer(c.keystore)) + if err != nil { + return nil, err + } + } + return retList, nil +} + +// List retrieves all values under key. +// convenience function, no additional value provided over +// `etcdctl` +func (c standardConfigManager) List(key string) (KVPairs, error) { + list, err := c.store.List(key) + retList := make(KVPairs, len(list)) + if err != nil { + return nil, err + } + for i, kv := range list { + retList[i].Key = kv.Key + retList[i].Value = kv.Value + } + return retList, err +} + +// Set will put a key/value into the data store +// and encode it with secconf +func (c configManager) Set(key string, value []byte) error { + encodedValue, err := secconf.Encode(value, bytes.NewBuffer(c.keystore)) + if err == nil { + err = c.store.Set(key, encodedValue) + } + return err +} + +// Set will put a key/value into the data store +func (c standardConfigManager) Set(key string, value []byte) error { + err := c.store.Set(key, value) + return err +} + +type Response struct { + Value []byte + Error error +} + +func (c configManager) Watch(key string, stop chan bool) <-chan *Response { + resp := make(chan *Response, 0) + backendResp := c.store.Watch(key, stop) + go func() { + for { + select { + case <-stop: + return + case r := <-backendResp: + if r.Error != nil { + resp <- &Response{nil, r.Error} + continue + } + value, err := secconf.Decode(r.Value, bytes.NewBuffer(c.keystore)) + resp <- &Response{value, err} + } + } + }() + return resp +} + +func (c standardConfigManager) Watch(key string, stop chan bool) <-chan *Response { + resp := make(chan *Response, 0) + backendResp := c.store.Watch(key, stop) + go func() { + for { + select { + case <-stop: + return + case r := <-backendResp: + if r.Error != nil { + resp <- &Response{nil, r.Error} + continue + } + resp <- &Response{r.Value, nil} + } + } + }() + return resp +} |