terraform/state/remote/etcd.go

79 lines
1.7 KiB
Go

package remote
import (
"crypto/md5"
"fmt"
"strings"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
etcdapi "github.com/coreos/etcd/client"
)
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
}