diff --git a/config/source/vault/README.md b/config/source/vault/README.md deleted file mode 100644 index 186433c8..00000000 --- a/config/source/vault/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Vault Source - -The vault source reads config from different secret engines in a Vault server. For example: -``` -kv: secret/data/ -database credentials: database/creds/ -``` - -## New Source - -Specify source with data - -```go -vaultSource := vault.NewSource( - // mandatory: it specifies server address. - // It could have different formats: - // 127.0.0.1 -> https://127.0.0.1:8200 - // http://127.0.0.1 -> http://127.0.0.1:8200 - // http://127.0.0.1:2233 - vault.WithAddress("http://127.0.0.1:8200"), - // mandatory: it specifies a resource to been access - vault.WithResourcePath("secret/data/my/secret"), - // mandatory: it specifies a resource to been access - vault.WithToken(""), - // optional: path to store my secret. - // By default use resourcePath value - vault.WithSecretName("my/secret"), - // optional: namespace. - vault.WithNameSpace("myNameSpace"), -) -``` - -## Load Source - -Load the source into config - -```go -// Create new config -conf := config.NewConfig() - -// Load file source -conf.Load(vaultSource) -``` diff --git a/config/source/vault/options.go b/config/source/vault/options.go deleted file mode 100644 index 43903b4a..00000000 --- a/config/source/vault/options.go +++ /dev/null @@ -1,63 +0,0 @@ -package vault - -import ( - "context" - - "github.com/micro/go-micro/config/source" -) - -type addressKey struct{} -type resourcePath struct{} -type nameSpace struct{} -type tokenKey struct{} -type secretName struct{} - -// WithAddress sets the server address -func WithAddress(a string) source.Option { - return func(o *source.Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, addressKey{}, a) - } -} - -// WithResourcePath sets the resource that will be access -func WithResourcePath(p string) source.Option { - return func(o *source.Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, resourcePath{}, p) - } -} - -// WithNameSpace sets the namespace that its going to be access -func WithNameSpace(n string) source.Option { - return func(o *source.Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, nameSpace{}, n) - } -} - -// WithToken sets the key token to use -func WithToken(t string) source.Option { - return func(o *source.Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, tokenKey{}, t) - } -} - -// WithSecretName sets the name of the secret to wrap in on a map -func WithSecretName(t string) source.Option { - return func(o *source.Options) { - if o.Context == nil { - o.Context = context.Background() - } - o.Context = context.WithValue(o.Context, secretName{}, t) - } -} diff --git a/config/source/vault/testdata/vault_init_commands b/config/source/vault/testdata/vault_init_commands deleted file mode 100644 index 4b8d26e0..00000000 --- a/config/source/vault/testdata/vault_init_commands +++ /dev/null @@ -1 +0,0 @@ -vault kv put secret/data/db/auth user=myuser password=mypassword2 host=128.23.33.21 port=3307 \ No newline at end of file diff --git a/config/source/vault/util.go b/config/source/vault/util.go deleted file mode 100644 index cdd5a149..00000000 --- a/config/source/vault/util.go +++ /dev/null @@ -1,98 +0,0 @@ -package vault - -import ( - "fmt" - "github.com/micro/go-micro/config/source" - "net" - "net/url" - "strings" -) - -func makeMap(kv map[string]interface{}, secretName string) (map[string]interface{}, error) { - data := make(map[string]interface{}) - - // if secret version included - if kv["data"] != nil && kv["metadata"] != nil { - kv = kv["data"].(map[string]interface{}) - } - - target := data - - // if secretName defined, wrap secrets under a map - if secretName != "" { - path := strings.Split(secretName, "/") - // find (or create) the location we want to put this value at - for i, dir := range path { - if _, ok := target[dir]; !ok { - target[dir] = make(map[string]interface{}) - } - if i < len(path)-1 { - target = target[dir].(map[string]interface{}) - } else { - target[dir] = kv - } - } - } - - return data, nil -} - -func getAddress(options source.Options) string { - // check if there are any addrs - a, ok := options.Context.Value(addressKey{}).(string) - if ok { - // check if http protocol is defined - if a[0] != 'h' { - addr, port, err := net.SplitHostPort(a) - if ae, ok := err.(*net.AddrError); ok && ae.Err == "missing port in address" { - port = "8200" - addr = a - return fmt.Sprintf("https://%s:%s", addr, port) - } else if err == nil { - return fmt.Sprintf("https://%s:%s", addr, port) - } - } else { - u, _ := url.Parse(a) - - if host, port, _ := net.SplitHostPort(u.Host); host == "" { - port = "8200" - return fmt.Sprintf("%s://%s:%s", u.Scheme, u.Host, port) - } else { - return fmt.Sprintf("%s://%s", u.Scheme, u.Host) - } - } - } - return "" -} - -func getToken(options source.Options) string { - token, ok := options.Context.Value(tokenKey{}).(string) - if ok { - return token - } - return "" -} - -func getResourcePath(options source.Options) string { - path, ok := options.Context.Value(resourcePath{}).(string) - if ok { - return path - } - return "" -} - -func getNameSpace(options source.Options) string { - ns, ok := options.Context.Value(nameSpace{}).(string) - if ok { - return ns - } - return "" -} - -func getSecretName(options source.Options) string { - ns, ok := options.Context.Value(secretName{}).(string) - if ok { - return ns - } - return "" -} diff --git a/config/source/vault/vault.go b/config/source/vault/vault.go deleted file mode 100644 index d3945a0f..00000000 --- a/config/source/vault/vault.go +++ /dev/null @@ -1,97 +0,0 @@ -package vault - -import ( - "fmt" - "time" - - "github.com/hashicorp/vault/api" - "github.com/micro/go-micro/config/source" -) - -// Currently a single vault reader -type vault struct { - secretPath string - secretName string - opts source.Options - client *api.Client -} - -func (c *vault) Read() (*source.ChangeSet, error) { - secret, err := c.client.Logical().Read(c.secretPath) - if err != nil { - return nil, err - } - - if secret == nil { - return nil, fmt.Errorf("source not found: %s", c.secretPath) - } - - if secret.Data == nil && secret.Warnings != nil { - return nil, fmt.Errorf("source: %s errors: %v", c.secretPath, secret.Warnings) - } - - data, err := makeMap(secret.Data, c.secretName) - if err != nil { - return nil, fmt.Errorf("error reading data: %v", err) - } - - b, err := c.opts.Encoder.Encode(data) - if err != nil { - return nil, fmt.Errorf("error reading source: %v", err) - } - - cs := &source.ChangeSet{ - Timestamp: time.Now(), - Format: c.opts.Encoder.String(), - Source: c.String(), - Data: b, - } - cs.Checksum = cs.Sum() - - return cs, nil - //return nil, nil -} - -func (c *vault) String() string { - return "vault" -} - -func (c *vault) Watch() (source.Watcher, error) { - w := newWatcher(c.client) - - return w, nil -} - -// NewSource creates a new vault source -func NewSource(opts ...source.Option) source.Source { - options := source.NewOptions(opts...) - - // create the client - client, _ := api.NewClient(api.DefaultConfig()) - - // get and set options - if address := getAddress(options); address != "" { - _ = client.SetAddress(address) - } - - if nameSpace := getNameSpace(options); nameSpace != "" { - client.SetNamespace(nameSpace) - } - - if token := getToken(options); token != "" { - client.SetToken(token) - } - - path := getResourcePath(options) - name := getSecretName(options) - if name == "" { - name = path - } - - return &vault{ - opts: options, - client: client, - secretPath: path, - secretName: name, - } -} diff --git a/config/source/vault/vault_test.go b/config/source/vault/vault_test.go deleted file mode 100644 index e5c3d309..00000000 --- a/config/source/vault/vault_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package vault - -import ( - "encoding/json" - "fmt" - "os" - "reflect" - "strings" - "testing" - - "github.com/micro/go-micro/config" -) - -func TestVaultMakeMap(t *testing.T) { - tt := []struct { - name string - expected []byte - input []byte - secretName string - }{ - { - name: "simple valid data 1", - secretName: "my/secret", - input: []byte(`{"data":{"bar":"bazz", "tar":"par"}, "metadata":{"version":1, "destroyed": false}}`), - expected: []byte(`{"my":{"secret":{"bar":"bazz", "tar":"par"}}}`), - }, - { - name: "simple valid data 2", - secretName: "my/secret", - input: []byte(`{"bar":"bazz", "tar":"par"}`), - expected: []byte(`{"my":{"secret":{"bar":"bazz", "tar":"par"}}}`), - }, - } - - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - var input map[string]interface{} - var expected map[string]interface{} - - _ = json.Unmarshal(tc.input, &input) - _ = json.Unmarshal(tc.expected, &expected) - - out, _ := makeMap(input, tc.secretName) - - if eq := reflect.DeepEqual(out, expected); !eq { - fmt.Println(eq) - t.Fatalf("expected %v and got %v", expected, out) - } - }) - } -} - -func TestVault_Read(t *testing.T) { - if tr := os.Getenv("TRAVIS"); len(tr) > 0 { - t.Skip() - } - - var ( - address = "http://127.0.0.1" - resource = "secret/data/db/auth" - token = "s.Q4Zi0CSowXZl7sh0z96ijcT4" - ) - - data := []byte(`{"secret":{"data":{"db":{"auth":{"host":"128.23.33.21","password":"mypassword","port":"3306","user":"myuser"}}}}}`) - - tt := []struct { - name string - addr string - resource string - token string - }{ - {name: "read data basic", addr: address, resource: resource, token: token}, - {name: "read data without token", addr: address, resource: resource, token: ""}, - {name: "read data full address format", addr: "http://127.0.0.1:8200", resource: resource, token: token}, - {name: "read data wrong resource path", addr: address, resource: "secrets/data/db/auth", token: token}, - } - - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - source := NewSource( - WithAddress(tc.addr), - WithResourcePath(tc.resource), - WithToken(tc.token), - ) - - r, err := source.Read() - if err != nil { - if tc.token == "" { - return - } else if strings.Compare(err.Error(), "source not found: secrets/data/db/auth") == 0 { - return - } - t.Errorf("%s: not able to read the config values because: %v", tc.name, err) - return - } - - if string(r.Data) != string(data) { - t.Logf("data expected: %v", string(data)) - t.Logf("data got from configmap: %v", string(r.Data)) - t.Errorf("data from configmap does not match.") - } - }) - } -} - -func TestVault_String(t *testing.T) { - source := NewSource() - - if source.String() != "vault" { - t.Errorf("expecting to get %v and instead got %v", "vault", source) - } -} - -func TestVaultNewSource(t *testing.T) { - if tr := os.Getenv("TRAVIS"); len(tr) > 0 { - t.Skip() - } - - conf := config.NewConfig() - - _ = conf.Load(NewSource( - WithAddress("http://127.0.0.1"), - WithResourcePath("secret/data/db/auth"), - WithToken("s.Q4Zi0CSowXZl7sh0z96ijcT4"), - )) - - if user := conf.Get("secret", "data", "db", "auth", "user").String("user"); user != "myuser" { - t.Errorf("expected %v and got %v", "myuser", user) - } - - if addr := conf.Get("secret", "data", "db", "auth", "host").String("host"); addr != "128.23.33.21" { - t.Errorf("expected %v and got %v", "128.23.33.21", addr) - } -} diff --git a/config/source/vault/watcher.go b/config/source/vault/watcher.go deleted file mode 100644 index a377295c..00000000 --- a/config/source/vault/watcher.go +++ /dev/null @@ -1,32 +0,0 @@ -package vault - -import ( - "errors" - "github.com/hashicorp/vault/api" - "github.com/micro/go-micro/config/source" -) - -type watcher struct { - c *api.Client - exit chan bool -} - -func newWatcher(c *api.Client) *watcher { - return &watcher{ - c: c, - exit: make(chan bool), - } -} - -func (w *watcher) Next() (*source.ChangeSet, error) { - <-w.exit - return nil, errors.New("url watcher stopped") -} - -func (w *watcher) Stop() error { - select { - case <-w.exit: - default: - } - return nil -} diff --git a/sync/cron.go b/sync/cron.go index 52ef20d5..be7ea908 100644 --- a/sync/cron.go +++ b/sync/cron.go @@ -5,7 +5,7 @@ import ( "math" "time" - "github.com/micro/go-log" + "github.com/micro/go-micro/util/log" "github.com/micro/go-micro/sync/leader/consul" "github.com/micro/go-micro/sync/task" "github.com/micro/go-micro/sync/task/local"