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  }