2015-10-12 23:04:58 +02:00
|
|
|
package remote
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/md5"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
etcdapi "github.com/coreos/etcd/client"
|
2015-10-22 20:03:25 +02:00
|
|
|
"golang.org/x/net/context"
|
2015-10-12 23:04:58 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func etcdFactory(conf map[string]string) (Client, error) {
|
|
|
|
path, ok := conf["path"]
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("missing 'path' configuration")
|
|
|
|
}
|
|
|
|
|
|
|
|
endpoints, ok := conf["endpoints"]
|
|
|
|
if !ok || endpoints == "" {
|
|
|
|
return nil, fmt.Errorf("missing 'endpoints' configuration")
|
|
|
|
}
|
|
|
|
|
|
|
|
config := etcdapi.Config{
|
|
|
|
Endpoints: strings.Split(endpoints, " "),
|
|
|
|
}
|
|
|
|
if username, ok := conf["username"]; ok && username != "" {
|
|
|
|
config.Username = username
|
|
|
|
}
|
|
|
|
if password, ok := conf["password"]; ok && password != "" {
|
|
|
|
config.Password = password
|
|
|
|
}
|
|
|
|
|
|
|
|
client, err := etcdapi.New(config)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &EtcdClient{
|
|
|
|
Client: client,
|
|
|
|
Path: path,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// EtcdClient is a remote client that stores data in etcd.
|
|
|
|
type EtcdClient struct {
|
|
|
|
Client etcdapi.Client
|
|
|
|
Path string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *EtcdClient) Get() (*Payload, error) {
|
|
|
|
resp, err := etcdapi.NewKeysAPI(c.Client).Get(context.Background(), c.Path, &etcdapi.GetOptions{Quorum: true})
|
|
|
|
if err != nil {
|
|
|
|
if err, ok := err.(etcdapi.Error); ok && err.Code == etcdapi.ErrorCodeKeyNotFound {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if resp.Node.Dir {
|
|
|
|
return nil, fmt.Errorf("path is a directory")
|
|
|
|
}
|
|
|
|
|
|
|
|
data := []byte(resp.Node.Value)
|
|
|
|
md5 := md5.Sum(data)
|
|
|
|
return &Payload{
|
|
|
|
Data: data,
|
|
|
|
MD5: md5[:],
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *EtcdClient) Put(data []byte) error {
|
|
|
|
_, err := etcdapi.NewKeysAPI(c.Client).Set(context.Background(), c.Path, string(data), nil)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *EtcdClient) Delete() error {
|
|
|
|
_, err := etcdapi.NewKeysAPI(c.Client).Delete(context.Background(), c.Path, nil)
|
|
|
|
return err
|
|
|
|
}
|