spf13--viper/remote/remote.go

118 lines
2.8 KiB
Go
Raw Normal View History

2015-05-30 19:28:33 +00:00
// Copyright © 2015 Steve Francia <spf@spf13.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
// Package remote integrates the remote features of Viper.
package remote
import (
"bytes"
"io"
"os"
"strings"
crypt "github.com/sagikazarmark/crypt/config"
"github.com/spf13/viper"
2015-05-30 19:28:33 +00:00
)
type remoteConfigProvider struct{}
func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) {
cm, err := getConfigManager(rp)
if err != nil {
return nil, err
}
b, err := cm.Get(rp.Path())
if err != nil {
return nil, err
}
return bytes.NewReader(b), nil
}
func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) {
cm, err := getConfigManager(rp)
if err != nil {
return nil, err
}
resp, err := cm.Get(rp.Path())
2015-05-30 19:28:33 +00:00
if err != nil {
return nil, err
}
return bytes.NewReader(resp), nil
2015-05-30 19:28:33 +00:00
}
func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
cm, err := getConfigManager(rp)
if err != nil {
return nil, nil
}
quit := make(chan bool)
quitwc := make(chan bool)
viperResponsCh := make(chan *viper.RemoteResponse)
cryptoResponseCh := cm.Watch(rp.Path(), quit)
// need this function to convert the Channel response form crypt.Response to viper.Response
go func(cr <-chan *crypt.Response, vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) {
for {
select {
case <-quitwc:
quit <- true
return
case resp := <-cr:
vr <- &viper.RemoteResponse{
Error: resp.Error,
Value: resp.Value,
}
}
}
}(cryptoResponseCh, viperResponsCh, quitwc, quit)
return viperResponsCh, quitwc
}
2015-05-30 19:28:33 +00:00
func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) {
var cm crypt.ConfigManager
var err error
endpoints := strings.Split(rp.Endpoint(), ";")
2015-05-30 19:28:33 +00:00
if rp.SecretKeyring() != "" {
2019-09-18 15:47:54 +00:00
var kr *os.File
kr, err = os.Open(rp.SecretKeyring())
2015-05-30 19:28:33 +00:00
if err != nil {
return nil, err
}
2019-09-18 15:47:54 +00:00
defer kr.Close()
2020-01-16 16:20:46 +00:00
switch rp.Provider() {
case "etcd":
cm, err = crypt.NewEtcdConfigManager(endpoints, kr)
case "etcd3":
cm, err = crypt.NewEtcdV3ConfigManager(endpoints, kr)
2020-01-16 16:20:46 +00:00
case "firestore":
cm, err = crypt.NewFirestoreConfigManager(endpoints, kr)
2020-01-16 16:20:46 +00:00
default:
cm, err = crypt.NewConsulConfigManager(endpoints, kr)
2015-05-30 19:28:33 +00:00
}
} else {
2020-01-16 16:20:46 +00:00
switch rp.Provider() {
case "etcd":
cm, err = crypt.NewStandardEtcdConfigManager(endpoints)
case "etcd3":
cm, err = crypt.NewStandardEtcdV3ConfigManager(endpoints)
2020-01-16 16:20:46 +00:00
case "firestore":
cm, err = crypt.NewStandardFirestoreConfigManager(endpoints)
2020-01-16 16:20:46 +00:00
default:
cm, err = crypt.NewStandardConsulConfigManager(endpoints)
2015-05-30 19:28:33 +00:00
}
}
if err != nil {
return nil, err
}
return cm, nil
}
func init() {
viper.RemoteConfig = &remoteConfigProvider{}
}