-
Notifications
You must be signed in to change notification settings - Fork 112
/
config.go
138 lines (124 loc) · 3.21 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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"
)
// A ConfigManager retrieves and decrypts configuration from a key/value store.
type ConfigManager interface {
Get(key string) ([]byte, error)
Watch(key string, stop chan bool) <-chan *Response
}
type configManager struct {
keystore []byte
store backend.Store
}
type standardConfigManager struct {
store backend.Store
}
// 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 standardConfigManager{store}, nil
}
// 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 standardConfigManager{store}, nil
}
// 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
}
bytes, err := ioutil.ReadAll(keystore)
if err != nil {
return nil, err
}
return configManager{bytes, store}, nil
}
// NewConsulConfigManager returns a new ConfigManager backed by consul.
func NewConsulConfigManager(machines []string, keystore io.Reader) (ConfigManager, error) {
store, err := consul.New(machines)
if err != nil {
return nil, err
}
bytes, err := ioutil.ReadAll(keystore)
if err != nil {
return nil, err
}
return configManager{bytes, store}, nil
}
// 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
}
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
}