github.com/xl1605368195/viper@v1.1.8/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 "strings" 14 15 crypt "github.com/xl1605368195/crypt/config" 16 17 "github.com/xl1605368195/viper" 18 ) 19 20 type remoteConfigProvider struct{} 21 22 func (rc remoteConfigProvider) Get(rp viper.RemoteProvider) (io.Reader, error) { 23 cm, err := getConfigManager(rp) 24 if err != nil { 25 return nil, err 26 } 27 b, err := cm.Get(rp.Path()) 28 if err != nil { 29 return nil, err 30 } 31 return bytes.NewReader(b), nil 32 } 33 34 func (rc remoteConfigProvider) Watch(rp viper.RemoteProvider) (io.Reader, error) { 35 cm, err := getConfigManager(rp) 36 if err != nil { 37 return nil, err 38 } 39 resp, err := cm.Get(rp.Path()) 40 if err != nil { 41 return nil, err 42 } 43 44 return bytes.NewReader(resp), nil 45 } 46 47 func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) { 48 cm, err := getConfigManager(rp) 49 if err != nil { 50 return nil, nil 51 } 52 quit := make(chan bool) 53 quitwc := make(chan bool) 54 viperResponsCh := make(chan *viper.RemoteResponse) 55 cryptoResponseCh := cm.Watch(rp.Path(), quit) 56 // need this function to convert the Channel response form crypt.Response to viper.Response 57 go func(cr <-chan *crypt.Response, vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) { 58 for { 59 select { 60 case <-quitwc: 61 quit <- true 62 return 63 case resp := <-cr: 64 vr <- &viper.RemoteResponse{ 65 Error: resp.Error, 66 Value: resp.Value, 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 endpoints := strings.Split(rp.Endpoint(), ";") 80 if rp.SecretKeyring() != "" { 81 var kr *os.File 82 kr, err = os.Open(rp.SecretKeyring()) 83 if err != nil { 84 return nil, err 85 } 86 defer kr.Close() 87 switch rp.Provider() { 88 case "etcd": 89 cm, err = crypt.NewEtcdConfigManager(endpoints, kr) 90 case "etcd3": 91 cm, err = crypt.NewEtcdV3ConfigManager(endpoints, kr) 92 case "firestore": 93 cm, err = crypt.NewFirestoreConfigManager(endpoints, kr) 94 case "http": 95 cm, err = crypt.NewHttpConfigManager(endpoints, kr) 96 default: 97 cm, err = crypt.NewConsulConfigManager(endpoints, kr) 98 } 99 } else { 100 switch rp.Provider() { 101 case "etcd": 102 cm, err = crypt.NewStandardEtcdConfigManager(endpoints) 103 case "etcd3": 104 cm, err = crypt.NewStandardEtcdV3ConfigManager(endpoints) 105 case "firestore": 106 cm, err = crypt.NewStandardFirestoreConfigManager(endpoints) 107 case "http": 108 cm, err = crypt.NewStandardHttpConfigManager(endpoints) 109 default: 110 cm, err = crypt.NewStandardConsulConfigManager(endpoints) 111 } 112 } 113 if err != nil { 114 return nil, err 115 } 116 return cm, nil 117 } 118 119 func init() { 120 viper.RemoteConfig = &remoteConfigProvider{} 121 }