github.com/r3vit/terraform@v0.11.9-beta1.0.20181016131357-87d05607d3c5/state/remote/etcd.go (about) 1 package remote 2 3 import ( 4 "crypto/md5" 5 "fmt" 6 "strings" 7 8 etcdapi "github.com/coreos/etcd/client" 9 "golang.org/x/net/context" 10 ) 11 12 func etcdFactory(conf map[string]string) (Client, error) { 13 path, ok := conf["path"] 14 if !ok { 15 return nil, fmt.Errorf("missing 'path' configuration") 16 } 17 18 endpoints, ok := conf["endpoints"] 19 if !ok || endpoints == "" { 20 return nil, fmt.Errorf("missing 'endpoints' configuration") 21 } 22 23 config := etcdapi.Config{ 24 Endpoints: strings.Split(endpoints, " "), 25 } 26 if username, ok := conf["username"]; ok && username != "" { 27 config.Username = username 28 } 29 if password, ok := conf["password"]; ok && password != "" { 30 config.Password = password 31 } 32 33 client, err := etcdapi.New(config) 34 if err != nil { 35 return nil, err 36 } 37 38 return &EtcdClient{ 39 Client: client, 40 Path: path, 41 }, nil 42 } 43 44 // EtcdClient is a remote client that stores data in etcd. 45 type EtcdClient struct { 46 Client etcdapi.Client 47 Path string 48 } 49 50 func (c *EtcdClient) Get() (*Payload, error) { 51 resp, err := etcdapi.NewKeysAPI(c.Client).Get(context.Background(), c.Path, &etcdapi.GetOptions{Quorum: true}) 52 if err != nil { 53 if err, ok := err.(etcdapi.Error); ok && err.Code == etcdapi.ErrorCodeKeyNotFound { 54 return nil, nil 55 } 56 return nil, err 57 } 58 if resp.Node.Dir { 59 return nil, fmt.Errorf("path is a directory") 60 } 61 62 data := []byte(resp.Node.Value) 63 md5 := md5.Sum(data) 64 return &Payload{ 65 Data: data, 66 MD5: md5[:], 67 }, nil 68 } 69 70 func (c *EtcdClient) Put(data []byte) error { 71 _, err := etcdapi.NewKeysAPI(c.Client).Set(context.Background(), c.Path, string(data), nil) 72 return err 73 } 74 75 func (c *EtcdClient) Delete() error { 76 _, err := etcdapi.NewKeysAPI(c.Client).Delete(context.Background(), c.Path, nil) 77 return err 78 }