github.com/gemini-platform/viper@v1.1.1/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 "io" 12 "os" 13 14 "github.com/spf13/viper" 15 crypt "github.com/xordataexchange/crypt/config" 16 ) 17 18 type remoteConfigProvider struct{} 19 20 func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) { 21 cm, err := getConfigManager(rp) 22 if err != nil { 23 return nil, err 24 } 25 b, err := cm.Get(rp.Path()) 26 if err != nil { 27 return nil, err 28 } 29 return bytes.NewReader(b), nil 30 } 31 32 func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) { 33 cm, err := getConfigManager(rp) 34 if err != nil { 35 return nil, err 36 } 37 resp, err := cm.Get(rp.Path()) 38 if err != nil { 39 return nil, err 40 } 41 42 return bytes.NewReader(resp), nil 43 } 44 45 func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) { 46 cm, err := getConfigManager(rp) 47 if err != nil { 48 return nil, nil 49 } 50 quit := make(chan bool) 51 quitwc := make(chan bool) 52 viperResponsCh := make(chan *viper.RemoteResponse) 53 cryptoResponseCh := cm.Watch(rp.Path(), quit) 54 // need this function to convert the Channel response form crypt.Response to viper.Response 55 go func(cr <-chan *crypt.Response, vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) { 56 for { 57 select { 58 case <-quitwc: 59 quit <- true 60 return 61 case resp := <-cr: 62 vr <- &viper.RemoteResponse{ 63 Error: resp.Error, 64 Value: resp.Value, 65 } 66 67 } 68 69 } 70 }(cryptoResponseCh, viperResponsCh, quitwc, quit) 71 72 return viperResponsCh, quitwc 73 } 74 75 func getConfigManager(rp viper.RemoteProvider) (crypt.ConfigManager, error) { 76 var cm crypt.ConfigManager 77 var err error 78 79 if rp.SecretKeyring() != "" { 80 kr, err := os.Open(rp.SecretKeyring()) 81 defer kr.Close() 82 if err != nil { 83 return nil, err 84 } 85 if rp.Provider() == "etcd" { 86 cm, err = crypt.NewEtcdConfigManager([]string{rp.Endpoint()}, kr) 87 } else { 88 cm, err = crypt.NewConsulConfigManager([]string{rp.Endpoint()}, kr) 89 } 90 } else { 91 if rp.Provider() == "etcd" { 92 cm, err = crypt.NewStandardEtcdConfigManager([]string{rp.Endpoint()}) 93 } else { 94 cm, err = crypt.NewStandardConsulConfigManager([]string{rp.Endpoint()}) 95 } 96 } 97 if err != nil { 98 return nil, err 99 } 100 return cm, nil 101 } 102 103 func init() { 104 viper.RemoteConfig = &remoteConfigProvider{} 105 }