github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/libnetwork/config/config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/BurntSushi/toml" 8 "github.com/docker/docker/pkg/discovery" 9 "github.com/docker/docker/pkg/plugingetter" 10 "github.com/docker/go-connections/tlsconfig" 11 "github.com/docker/libkv/store" 12 "github.com/docker/libnetwork/cluster" 13 "github.com/docker/libnetwork/datastore" 14 "github.com/docker/libnetwork/ipamutils" 15 "github.com/docker/libnetwork/netlabel" 16 "github.com/docker/libnetwork/osl" 17 "github.com/docker/libnetwork/portallocator" 18 "github.com/sirupsen/logrus" 19 ) 20 21 const ( 22 warningThNetworkControlPlaneMTU = 1500 23 minimumNetworkControlPlaneMTU = 500 24 ) 25 26 // Config encapsulates configurations of various Libnetwork components 27 type Config struct { 28 Daemon DaemonCfg 29 Cluster ClusterCfg 30 Scopes map[string]*datastore.ScopeCfg 31 ActiveSandboxes map[string]interface{} 32 PluginGetter plugingetter.PluginGetter 33 } 34 35 // DaemonCfg represents libnetwork core configuration 36 type DaemonCfg struct { 37 Debug bool 38 Experimental bool 39 DataDir string 40 ExecRoot string 41 DefaultNetwork string 42 DefaultDriver string 43 Labels []string 44 DriverCfg map[string]interface{} 45 ClusterProvider cluster.Provider 46 NetworkControlPlaneMTU int 47 DefaultAddressPool []*ipamutils.NetworkToSplit 48 } 49 50 // ClusterCfg represents cluster configuration 51 type ClusterCfg struct { 52 Watcher discovery.Watcher 53 Address string 54 Discovery string 55 Heartbeat uint64 56 } 57 58 // LoadDefaultScopes loads default scope configs for scopes which 59 // doesn't have explicit user specified configs. 60 func (c *Config) LoadDefaultScopes(dataDir string) { 61 for k, v := range datastore.DefaultScopes(dataDir) { 62 if _, ok := c.Scopes[k]; !ok { 63 c.Scopes[k] = v 64 } 65 } 66 } 67 68 // ParseConfig parses the libnetwork configuration file 69 func ParseConfig(tomlCfgFile string) (*Config, error) { 70 cfg := &Config{ 71 Scopes: map[string]*datastore.ScopeCfg{}, 72 } 73 74 if _, err := toml.DecodeFile(tomlCfgFile, cfg); err != nil { 75 return nil, err 76 } 77 78 cfg.LoadDefaultScopes(cfg.Daemon.DataDir) 79 return cfg, nil 80 } 81 82 // ParseConfigOptions parses the configuration options and returns 83 // a reference to the corresponding Config structure 84 func ParseConfigOptions(cfgOptions ...Option) *Config { 85 cfg := &Config{ 86 Daemon: DaemonCfg{ 87 DriverCfg: make(map[string]interface{}), 88 }, 89 Scopes: make(map[string]*datastore.ScopeCfg), 90 } 91 92 cfg.ProcessOptions(cfgOptions...) 93 cfg.LoadDefaultScopes(cfg.Daemon.DataDir) 94 95 return cfg 96 } 97 98 // Option is an option setter function type used to pass various configurations 99 // to the controller 100 type Option func(c *Config) 101 102 // OptionDefaultNetwork function returns an option setter for a default network 103 func OptionDefaultNetwork(dn string) Option { 104 return func(c *Config) { 105 logrus.Debugf("Option DefaultNetwork: %s", dn) 106 c.Daemon.DefaultNetwork = strings.TrimSpace(dn) 107 } 108 } 109 110 // OptionDefaultDriver function returns an option setter for default driver 111 func OptionDefaultDriver(dd string) Option { 112 return func(c *Config) { 113 logrus.Debugf("Option DefaultDriver: %s", dd) 114 c.Daemon.DefaultDriver = strings.TrimSpace(dd) 115 } 116 } 117 118 // OptionDefaultAddressPoolConfig function returns an option setter for default address pool 119 func OptionDefaultAddressPoolConfig(addressPool []*ipamutils.NetworkToSplit) Option { 120 return func(c *Config) { 121 c.Daemon.DefaultAddressPool = addressPool 122 } 123 } 124 125 // OptionDriverConfig returns an option setter for driver configuration. 126 func OptionDriverConfig(networkType string, config map[string]interface{}) Option { 127 return func(c *Config) { 128 c.Daemon.DriverCfg[networkType] = config 129 } 130 } 131 132 // OptionLabels function returns an option setter for labels 133 func OptionLabels(labels []string) Option { 134 return func(c *Config) { 135 for _, label := range labels { 136 if strings.HasPrefix(label, netlabel.Prefix) { 137 c.Daemon.Labels = append(c.Daemon.Labels, label) 138 } 139 } 140 } 141 } 142 143 // OptionKVProvider function returns an option setter for kvstore provider 144 func OptionKVProvider(provider string) Option { 145 return func(c *Config) { 146 logrus.Debugf("Option OptionKVProvider: %s", provider) 147 if _, ok := c.Scopes[datastore.GlobalScope]; !ok { 148 c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{} 149 } 150 c.Scopes[datastore.GlobalScope].Client.Provider = strings.TrimSpace(provider) 151 } 152 } 153 154 // OptionKVProviderURL function returns an option setter for kvstore url 155 func OptionKVProviderURL(url string) Option { 156 return func(c *Config) { 157 logrus.Debugf("Option OptionKVProviderURL: %s", url) 158 if _, ok := c.Scopes[datastore.GlobalScope]; !ok { 159 c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{} 160 } 161 c.Scopes[datastore.GlobalScope].Client.Address = strings.TrimSpace(url) 162 } 163 } 164 165 // OptionKVOpts function returns an option setter for kvstore options 166 func OptionKVOpts(opts map[string]string) Option { 167 return func(c *Config) { 168 if opts["kv.cacertfile"] != "" && opts["kv.certfile"] != "" && opts["kv.keyfile"] != "" { 169 logrus.Info("Option Initializing KV with TLS") 170 tlsConfig, err := tlsconfig.Client(tlsconfig.Options{ 171 CAFile: opts["kv.cacertfile"], 172 CertFile: opts["kv.certfile"], 173 KeyFile: opts["kv.keyfile"], 174 }) 175 if err != nil { 176 logrus.Errorf("Unable to set up TLS: %s", err) 177 return 178 } 179 if _, ok := c.Scopes[datastore.GlobalScope]; !ok { 180 c.Scopes[datastore.GlobalScope] = &datastore.ScopeCfg{} 181 } 182 if c.Scopes[datastore.GlobalScope].Client.Config == nil { 183 c.Scopes[datastore.GlobalScope].Client.Config = &store.Config{TLS: tlsConfig} 184 } else { 185 c.Scopes[datastore.GlobalScope].Client.Config.TLS = tlsConfig 186 } 187 // Workaround libkv/etcd bug for https 188 c.Scopes[datastore.GlobalScope].Client.Config.ClientTLS = &store.ClientTLSConfig{ 189 CACertFile: opts["kv.cacertfile"], 190 CertFile: opts["kv.certfile"], 191 KeyFile: opts["kv.keyfile"], 192 } 193 } else { 194 logrus.Info("Option Initializing KV without TLS") 195 } 196 } 197 } 198 199 // OptionDiscoveryWatcher function returns an option setter for discovery watcher 200 func OptionDiscoveryWatcher(watcher discovery.Watcher) Option { 201 return func(c *Config) { 202 c.Cluster.Watcher = watcher 203 } 204 } 205 206 // OptionDiscoveryAddress function returns an option setter for self discovery address 207 func OptionDiscoveryAddress(address string) Option { 208 return func(c *Config) { 209 c.Cluster.Address = address 210 } 211 } 212 213 // OptionDataDir function returns an option setter for data folder 214 func OptionDataDir(dataDir string) Option { 215 return func(c *Config) { 216 c.Daemon.DataDir = dataDir 217 } 218 } 219 220 // OptionExecRoot function returns an option setter for exec root folder 221 func OptionExecRoot(execRoot string) Option { 222 return func(c *Config) { 223 c.Daemon.ExecRoot = execRoot 224 osl.SetBasePath(execRoot) 225 } 226 } 227 228 // OptionPluginGetter returns a plugingetter for remote drivers. 229 func OptionPluginGetter(pg plugingetter.PluginGetter) Option { 230 return func(c *Config) { 231 c.PluginGetter = pg 232 } 233 } 234 235 // OptionExperimental function returns an option setter for experimental daemon 236 func OptionExperimental(exp bool) Option { 237 return func(c *Config) { 238 logrus.Debugf("Option Experimental: %v", exp) 239 c.Daemon.Experimental = exp 240 } 241 } 242 243 // OptionDynamicPortRange function returns an option setter for service port allocation range 244 func OptionDynamicPortRange(in string) Option { 245 return func(c *Config) { 246 start, end := 0, 0 247 if len(in) > 0 { 248 n, err := fmt.Sscanf(in, "%d-%d", &start, &end) 249 if n != 2 || err != nil { 250 logrus.Errorf("Failed to parse range string with err %v", err) 251 return 252 } 253 } 254 if err := portallocator.Get().SetPortRange(start, end); err != nil { 255 logrus.Errorf("Failed to set port range with err %v", err) 256 } 257 } 258 } 259 260 // OptionNetworkControlPlaneMTU function returns an option setter for control plane MTU 261 func OptionNetworkControlPlaneMTU(exp int) Option { 262 return func(c *Config) { 263 logrus.Debugf("Network Control Plane MTU: %d", exp) 264 if exp < warningThNetworkControlPlaneMTU { 265 logrus.Warnf("Received a MTU of %d, this value is very low, the network control plane can misbehave,"+ 266 " defaulting to minimum value (%d)", exp, minimumNetworkControlPlaneMTU) 267 if exp < minimumNetworkControlPlaneMTU { 268 exp = minimumNetworkControlPlaneMTU 269 } 270 } 271 c.Daemon.NetworkControlPlaneMTU = exp 272 } 273 } 274 275 // ProcessOptions processes options and stores it in config 276 func (c *Config) ProcessOptions(options ...Option) { 277 for _, opt := range options { 278 if opt != nil { 279 opt(c) 280 } 281 } 282 } 283 284 // IsValidName validates configuration objects supported by libnetwork 285 func IsValidName(name string) bool { 286 return strings.TrimSpace(name) != "" 287 } 288 289 // OptionLocalKVProvider function returns an option setter for kvstore provider 290 func OptionLocalKVProvider(provider string) Option { 291 return func(c *Config) { 292 logrus.Debugf("Option OptionLocalKVProvider: %s", provider) 293 if _, ok := c.Scopes[datastore.LocalScope]; !ok { 294 c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{} 295 } 296 c.Scopes[datastore.LocalScope].Client.Provider = strings.TrimSpace(provider) 297 } 298 } 299 300 // OptionLocalKVProviderURL function returns an option setter for kvstore url 301 func OptionLocalKVProviderURL(url string) Option { 302 return func(c *Config) { 303 logrus.Debugf("Option OptionLocalKVProviderURL: %s", url) 304 if _, ok := c.Scopes[datastore.LocalScope]; !ok { 305 c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{} 306 } 307 c.Scopes[datastore.LocalScope].Client.Address = strings.TrimSpace(url) 308 } 309 } 310 311 // OptionLocalKVProviderConfig function returns an option setter for kvstore config 312 func OptionLocalKVProviderConfig(config *store.Config) Option { 313 return func(c *Config) { 314 logrus.Debugf("Option OptionLocalKVProviderConfig: %v", config) 315 if _, ok := c.Scopes[datastore.LocalScope]; !ok { 316 c.Scopes[datastore.LocalScope] = &datastore.ScopeCfg{} 317 } 318 c.Scopes[datastore.LocalScope].Client.Config = config 319 } 320 } 321 322 // OptionActiveSandboxes function returns an option setter for passing the sandboxes 323 // which were active during previous daemon life 324 func OptionActiveSandboxes(sandboxes map[string]interface{}) Option { 325 return func(c *Config) { 326 c.ActiveSandboxes = sandboxes 327 } 328 }