github.com/m3db/m3@v1.5.0/src/cluster/client/etcd/config.go (about) 1 // Copyright (c) 2017 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package etcd 22 23 import ( 24 "os" 25 "time" 26 27 "github.com/uber-go/tally" 28 "google.golang.org/grpc" 29 30 "github.com/m3db/m3/src/cluster/client" 31 "github.com/m3db/m3/src/cluster/services" 32 "github.com/m3db/m3/src/x/instrument" 33 "github.com/m3db/m3/src/x/retry" 34 ) 35 36 // ClusterConfig is the config for a zoned etcd cluster. 37 type ClusterConfig struct { 38 Zone string `yaml:"zone"` 39 Endpoints []string `yaml:"endpoints"` 40 KeepAlive *KeepAliveConfig `yaml:"keepAlive"` 41 TLS *TLSConfig `yaml:"tls"` 42 AutoSyncInterval time.Duration `yaml:"autoSyncInterval"` 43 44 DialOptions []grpc.DialOption `yaml:"-"` // nonserializable 45 } 46 47 // NewCluster creates a new Cluster. 48 func (c ClusterConfig) NewCluster() Cluster { 49 keepAliveOpts := NewKeepAliveOptions() 50 if c.KeepAlive != nil { 51 keepAliveOpts = c.KeepAlive.NewOptions() 52 } 53 return NewCluster(). 54 SetZone(c.Zone). 55 SetEndpoints(c.Endpoints). 56 SetDialOptions(c.DialOptions). 57 SetKeepAliveOptions(keepAliveOpts). 58 SetTLSOptions(c.TLS.newOptions()). 59 SetAutoSyncInterval(c.AutoSyncInterval) 60 } 61 62 // TLSConfig is the config for TLS. 63 type TLSConfig struct { 64 CrtPath string `yaml:"crtPath"` 65 CACrtPath string `yaml:"caCrtPath"` 66 KeyPath string `yaml:"keyPath"` 67 } 68 69 func (c *TLSConfig) newOptions() TLSOptions { 70 opts := NewTLSOptions() 71 if c == nil { 72 return opts 73 } 74 75 return opts. 76 SetCrtPath(c.CrtPath). 77 SetKeyPath(c.KeyPath). 78 SetCACrtPath(c.CACrtPath) 79 } 80 81 // KeepAliveConfig configures keepAlive behavior. 82 type KeepAliveConfig struct { 83 Enabled bool `yaml:"enabled"` 84 Period time.Duration `yaml:"period"` 85 Jitter time.Duration `yaml:"jitter"` 86 Timeout time.Duration `yaml:"timeout"` 87 } 88 89 // NewOptions constructs options based on the config. 90 func (c *KeepAliveConfig) NewOptions() KeepAliveOptions { 91 return NewKeepAliveOptions(). 92 SetKeepAliveEnabled(c.Enabled). 93 SetKeepAlivePeriod(c.Period). 94 SetKeepAlivePeriodMaxJitter(c.Jitter). 95 SetKeepAliveTimeout(c.Timeout) 96 } 97 98 // Configuration is for config service client. 99 type Configuration struct { 100 Zone string `yaml:"zone"` 101 Env string `yaml:"env"` 102 Service string `yaml:"service" validate:"nonzero"` 103 CacheDir string `yaml:"cacheDir"` 104 ETCDClusters []ClusterConfig `yaml:"etcdClusters"` 105 SDConfig services.Configuration `yaml:"m3sd"` 106 WatchWithRevision int64 `yaml:"watchWithRevision"` 107 NewDirectoryMode *os.FileMode `yaml:"newDirectoryMode"` 108 109 Retry retry.Configuration `yaml:"retry"` 110 RequestTimeout time.Duration `yaml:"requestTimeout"` 111 WatchChanInitTimeout time.Duration `yaml:"watchChanInitTimeout"` 112 WatchChanCheckInterval time.Duration `yaml:"watchChanCheckInterval"` 113 WatchChanResetInterval time.Duration `yaml:"watchChanResetInterval"` 114 // EnableFastGets trades consistency for latency and throughput using clientv3.WithSerializable() 115 // on etcd ops. 116 EnableFastGets bool `yaml:"enableFastGets"` 117 } 118 119 // NewClient creates a new config service client. 120 func (cfg Configuration) NewClient(iopts instrument.Options) (client.Client, error) { 121 return NewConfigServiceClient(cfg.NewOptions().SetInstrumentOptions(iopts)) 122 } 123 124 // NewOptions returns a new Options. 125 func (cfg Configuration) NewOptions() Options { 126 opts := NewOptions(). 127 SetZone(cfg.Zone). 128 SetEnv(cfg.Env). 129 SetService(cfg.Service). 130 SetCacheDir(cfg.CacheDir). 131 SetClusters(cfg.etcdClusters()). 132 SetServicesOptions(cfg.SDConfig.NewOptions()). 133 SetWatchWithRevision(cfg.WatchWithRevision). 134 SetEnableFastGets(cfg.EnableFastGets). 135 SetRetryOptions(cfg.Retry.NewOptions(tally.NoopScope)) 136 137 if cfg.RequestTimeout > 0 { 138 opts = opts.SetRequestTimeout(cfg.RequestTimeout) 139 } 140 141 if cfg.WatchChanInitTimeout > 0 { 142 opts = opts.SetWatchChanInitTimeout(cfg.WatchChanInitTimeout) 143 } 144 145 if cfg.WatchChanCheckInterval > 0 { 146 opts = opts.SetWatchChanCheckInterval(cfg.WatchChanCheckInterval) 147 } 148 149 if cfg.WatchChanResetInterval > 0 { 150 opts = opts.SetWatchChanResetInterval(cfg.WatchChanResetInterval) 151 } 152 153 if v := cfg.NewDirectoryMode; v != nil { 154 opts = opts.SetNewDirectoryMode(*v) 155 } else { 156 opts = opts.SetNewDirectoryMode(defaultDirectoryMode) 157 } 158 159 return opts 160 } 161 162 func (cfg Configuration) etcdClusters() []Cluster { 163 res := make([]Cluster, len(cfg.ETCDClusters)) 164 for i, c := range cfg.ETCDClusters { 165 res[i] = c.NewCluster() 166 } 167 168 return res 169 }