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