OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / spf13 / viper / remote / remote.go
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
44 func (rc remoteConfigProvider) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
45         cm, err := getConfigManager(rp)
46         if err != nil {
47                 return nil, nil
48         }
49         quit := make(chan bool)
50         quitwc := make(chan bool)
51         viperResponsCh := make(chan *viper.RemoteResponse)
52         cryptoResponseCh := cm.Watch(rp.Path(), quit)
53         // need this function to convert the Channel response form crypt.Response to viper.Response
54         go func(cr <-chan *crypt.Response, vr chan<- *viper.RemoteResponse, quitwc <-chan bool, quit chan<- bool) {
55                 for {
56                         select {
57                         case <-quitwc:
58                                 quit <- true
59                                 return
60                         case resp := <-cr:
61                                 vr <- &viper.RemoteResponse{
62                                         Error: resp.Error,
63                                         Value: resp.Value,
64                                 }
65
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                 kr, err := os.Open(rp.SecretKeyring())
80                 defer kr.Close()
81                 if err != nil {
82                         return nil, err
83                 }
84                 if rp.Provider() == "etcd" {
85                         cm, err = crypt.NewEtcdConfigManager([]string{rp.Endpoint()}, kr)
86                 } else {
87                         cm, err = crypt.NewConsulConfigManager([]string{rp.Endpoint()}, kr)
88                 }
89         } else {
90                 if rp.Provider() == "etcd" {
91                         cm, err = crypt.NewStandardEtcdConfigManager([]string{rp.Endpoint()})
92                 } else {
93                         cm, err = crypt.NewStandardConsulConfigManager([]string{rp.Endpoint()})
94                 }
95         }
96         if err != nil {
97                 return nil, err
98         }
99         return cm, nil
100 }
101
102 func init() {
103         viper.RemoteConfig = &remoteConfigProvider{}
104 }