github.com/andrewseidl/viper@v0.0.0-20191228040610-757ecc9b7b3e/remote/remote.go (about) 1 // Copyright © 2015 Steve Francia <spf@spf13.com>. 2 // 3 // Use of this source code is governed by an MIT-style 4 // license that can be found in the LICENSE file. 5 6 // Package remote integrates the remote features of Viper. 7 package remote 8 9 import ( 10 "bytes" 11 "github.com/spf13/viper" 12 crypt "github.com/xordataexchange/crypt/config" 13 "io" 14 "os" 15 ) 16 17 type remoteConfigProvider struct{} 18 19 func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) { 20 cm, err := getConfigManager(rp) 21 if err != nil { 22 return nil, err 23 } 24 b, err := cm.Get(rp.Path()) 25 if err != nil { 26 return nil, err 27 } 28 return bytes.NewReader(b), nil 29 } 30 31 func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) { 32 cm, err := getConfigManager(rp) 33 if err != nil { 34 return nil, err 35 } 36 resp,err := cm.Get(rp.Path()) 37 if err != nil { 38 return nil, err 39 } 40 41 return bytes.NewReader(resp), nil 42 } 43 func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) { 44 cm, err := getConfigManager(rp) 45 if err != nil { 46 return nil, nil 47 } 48 quit := make(chan bool) 49 quitwc := make(chan bool) 50 viperResponsCh := make(chan *viper.RemoteResponse) 51 cryptoResponseCh := cm.Watch(rp.Path(), quit) 52 // need this function to convert the Channel response form crypt.Response to viper.Response 53 go func(cr <-chan *crypt.Response,vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) { 54 for { 55 select { 56 case <- quitwc: 57 quit <- true 58 return 59 case resp := <-cr: 60 vr <- &viper.RemoteResponse{ 61 Error: resp.Error, 62 Value: resp.Value, 63 } 64 65 } 66 67 } 68 }(cryptoResponseCh,viperResponsCh,quitwc,quit) 69 70 return viperResponsCh,quitwc 71 72 } 73 74 75 func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) { 76 77 var cm crypt.ConfigManager 78 var err error 79 80 if rp.SecretKeyring() != "" { 81 kr, err := os.Open(rp.SecretKeyring()) 82 defer kr.Close() 83 if err != nil { 84 return nil, err 85 } 86 if rp.Provider() == "etcd" { 87 cm, err = crypt.NewEtcdConfigManager([]string{rp.Endpoint()}, kr) 88 } else { 89 cm, err = crypt.NewConsulConfigManager([]string{rp.Endpoint()}, kr) 90 } 91 } else { 92 if rp.Provider() == "etcd" { 93 cm, err = crypt.NewStandardEtcdConfigManager([]string{rp.Endpoint()}) 94 } else { 95 cm, err = crypt.NewStandardConsulConfigManager([]string{rp.Endpoint()}) 96 } 97 } 98 if err != nil { 99 return nil, err 100 } 101 return cm, nil 102 103 } 104 105 func init() { 106 viper.RemoteConfig = &remoteConfigProvider{} 107 }