github.com/taylorchu/nomad@v0.5.3-rc1.0.20170407200202-db11e7dd7b55/client/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"strconv"
     8  	"strings"
     9  	"time"
    10  
    11  	"github.com/hashicorp/nomad/helper"
    12  	"github.com/hashicorp/nomad/helper/tlsutil"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/nomad/structs/config"
    15  )
    16  
    17  var (
    18  	// DefaultEnvBlacklist is the default set of environment variables that are
    19  	// filtered when passing the environment variables of the host to a task.
    20  	DefaultEnvBlacklist = strings.Join([]string{
    21  		"CONSUL_TOKEN",
    22  		"VAULT_TOKEN",
    23  		"ATLAS_TOKEN",
    24  		"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN",
    25  		"GOOGLE_APPLICATION_CREDENTIALS",
    26  	}, ",")
    27  
    28  	// DefaulUserBlacklist is the default set of users that tasks are not
    29  	// allowed to run as when using a driver in "user.checked_drivers"
    30  	DefaultUserBlacklist = strings.Join([]string{
    31  		"root",
    32  		"Administrator",
    33  	}, ",")
    34  
    35  	// DefaultUserCheckedDrivers is the set of drivers we apply the user
    36  	// blacklist onto. For virtualized drivers it often doesn't make sense to
    37  	// make this stipulation so by default they are ignored.
    38  	DefaultUserCheckedDrivers = strings.Join([]string{
    39  		"exec",
    40  		"qemu",
    41  		"java",
    42  	}, ",")
    43  
    44  	// A mapping of directories on the host OS to attempt to embed inside each
    45  	// task's chroot.
    46  	DefaultChrootEnv = map[string]string{
    47  		"/bin":            "/bin",
    48  		"/etc":            "/etc",
    49  		"/lib":            "/lib",
    50  		"/lib32":          "/lib32",
    51  		"/lib64":          "/lib64",
    52  		"/run/resolvconf": "/run/resolvconf",
    53  		"/sbin":           "/sbin",
    54  		"/usr":            "/usr",
    55  	}
    56  )
    57  
    58  // RPCHandler can be provided to the Client if there is a local server
    59  // to avoid going over the network. If not provided, the Client will
    60  // maintain a connection pool to the servers
    61  type RPCHandler interface {
    62  	RPC(method string, args interface{}, reply interface{}) error
    63  }
    64  
    65  // Config is used to parameterize and configure the behavior of the client
    66  type Config struct {
    67  	// DevMode controls if we are in a development mode which
    68  	// avoids persistent storage.
    69  	DevMode bool
    70  
    71  	// StateDir is where we store our state
    72  	StateDir string
    73  
    74  	// AllocDir is where we store data for allocations
    75  	AllocDir string
    76  
    77  	// LogOutput is the destination for logs
    78  	LogOutput io.Writer
    79  
    80  	// Region is the clients region
    81  	Region string
    82  
    83  	// Network interface to be used in network fingerprinting
    84  	NetworkInterface string
    85  
    86  	// Network speed is the default speed of network interfaces if they can not
    87  	// be determined dynamically.
    88  	NetworkSpeed int
    89  
    90  	// CpuCompute is the default total CPU compute if they can not be determined
    91  	// dynamically. It should be given as Cores * MHz (2 Cores * 2 Ghz = 4000)
    92  	CpuCompute int
    93  
    94  	// MaxKillTimeout allows capping the user-specifiable KillTimeout. If the
    95  	// task's KillTimeout is greater than the MaxKillTimeout, MaxKillTimeout is
    96  	// used.
    97  	MaxKillTimeout time.Duration
    98  
    99  	// Servers is a list of known server addresses. These are as "host:port"
   100  	Servers []string
   101  
   102  	// RPCHandler can be provided to avoid network traffic if the
   103  	// server is running locally.
   104  	RPCHandler RPCHandler
   105  
   106  	// Node provides the base node
   107  	Node *structs.Node
   108  
   109  	// ClientMaxPort is the upper range of the ports that the client uses for
   110  	// communicating with plugin subsystems over loopback
   111  	ClientMaxPort uint
   112  
   113  	// ClientMinPort is the lower range of the ports that the client uses for
   114  	// communicating with plugin subsystems over loopback
   115  	ClientMinPort uint
   116  
   117  	// GloballyReservedPorts are ports that are reserved across all network
   118  	// devices and IPs.
   119  	GloballyReservedPorts []int
   120  
   121  	// A mapping of directories on the host OS to attempt to embed inside each
   122  	// task's chroot.
   123  	ChrootEnv map[string]string
   124  
   125  	// Options provides arbitrary key-value configuration for nomad internals,
   126  	// like fingerprinters and drivers. The format is:
   127  	//
   128  	//	namespace.option = value
   129  	Options map[string]string
   130  
   131  	// Version is the version of the Nomad client
   132  	Version string
   133  
   134  	// Revision is the commit number of the Nomad client
   135  	Revision string
   136  
   137  	// ConsulConfig is this Agent's Consul configuration
   138  	ConsulConfig *config.ConsulConfig
   139  
   140  	// VaultConfig is this Agent's Vault configuration
   141  	VaultConfig *config.VaultConfig
   142  
   143  	// StatsCollectionInterval is the interval at which the Nomad client
   144  	// collects resource usage stats
   145  	StatsCollectionInterval time.Duration
   146  
   147  	// PublishNodeMetrics determines whether nomad is going to publish node
   148  	// level metrics to remote Telemetry sinks
   149  	PublishNodeMetrics bool
   150  
   151  	// PublishAllocationMetrics determines whether nomad is going to publish
   152  	// allocation metrics to remote Telemetry sinks
   153  	PublishAllocationMetrics bool
   154  
   155  	// TLSConfig holds various TLS related configurations
   156  	TLSConfig *config.TLSConfig
   157  
   158  	// GCInterval is the time interval at which the client triggers garbage
   159  	// collection
   160  	GCInterval time.Duration
   161  
   162  	// GCParallelDestroys is the number of parallel destroys the garbage
   163  	// collector will allow.
   164  	GCParallelDestroys int
   165  
   166  	// GCDiskUsageThreshold is the disk usage threshold given as a percent
   167  	// beyond which the Nomad client triggers GC of terminal allocations
   168  	GCDiskUsageThreshold float64
   169  
   170  	// GCInodeUsageThreshold is the inode usage threshold given as a percent
   171  	// beyond which the Nomad client triggers GC of the terminal allocations
   172  	GCInodeUsageThreshold float64
   173  
   174  	// LogLevel is the level of the logs to putout
   175  	LogLevel string
   176  
   177  	// NoHostUUID disables using the host's UUID and will force generation of a
   178  	// random UUID.
   179  	NoHostUUID bool
   180  }
   181  
   182  func (c *Config) Copy() *Config {
   183  	nc := new(Config)
   184  	*nc = *c
   185  	nc.Node = nc.Node.Copy()
   186  	nc.Servers = helper.CopySliceString(nc.Servers)
   187  	nc.Options = helper.CopyMapStringString(nc.Options)
   188  	nc.GloballyReservedPorts = helper.CopySliceInt(c.GloballyReservedPorts)
   189  	nc.ConsulConfig = c.ConsulConfig.Copy()
   190  	nc.VaultConfig = c.VaultConfig.Copy()
   191  	return nc
   192  }
   193  
   194  // DefaultConfig returns the default configuration
   195  func DefaultConfig() *Config {
   196  	return &Config{
   197  		VaultConfig:             config.DefaultVaultConfig(),
   198  		ConsulConfig:            config.DefaultConsulConfig(),
   199  		LogOutput:               os.Stderr,
   200  		Region:                  "global",
   201  		StatsCollectionInterval: 1 * time.Second,
   202  		TLSConfig:               &config.TLSConfig{},
   203  		LogLevel:                "DEBUG",
   204  		GCInterval:              1 * time.Minute,
   205  		GCParallelDestroys:      2,
   206  		GCDiskUsageThreshold:    80,
   207  		GCInodeUsageThreshold:   70,
   208  	}
   209  }
   210  
   211  // Read returns the specified configuration value or "".
   212  func (c *Config) Read(id string) string {
   213  	return c.Options[id]
   214  }
   215  
   216  // ReadDefault returns the specified configuration value, or the specified
   217  // default value if none is set.
   218  func (c *Config) ReadDefault(id string, defaultValue string) string {
   219  	val, ok := c.Options[id]
   220  	if !ok {
   221  		return defaultValue
   222  	}
   223  	return val
   224  }
   225  
   226  // ReadBool parses the specified option as a boolean.
   227  func (c *Config) ReadBool(id string) (bool, error) {
   228  	val, ok := c.Options[id]
   229  	if !ok {
   230  		return false, fmt.Errorf("Specified config is missing from options")
   231  	}
   232  	bval, err := strconv.ParseBool(val)
   233  	if err != nil {
   234  		return false, fmt.Errorf("Failed to parse %s as bool: %s", val, err)
   235  	}
   236  	return bval, nil
   237  }
   238  
   239  // ReadBoolDefault tries to parse the specified option as a boolean. If there is
   240  // an error in parsing, the default option is returned.
   241  func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool {
   242  	val, err := c.ReadBool(id)
   243  	if err != nil {
   244  		return defaultValue
   245  	}
   246  	return val
   247  }
   248  
   249  // ReadInt parses the specified option as a int.
   250  func (c *Config) ReadInt(id string) (int, error) {
   251  	val, ok := c.Options[id]
   252  	if !ok {
   253  		return 0, fmt.Errorf("Specified config is missing from options")
   254  	}
   255  	ival, err := strconv.Atoi(val)
   256  	if err != nil {
   257  		return 0, fmt.Errorf("Failed to parse %s as int: %s", val, err)
   258  	}
   259  	return ival, nil
   260  }
   261  
   262  // ReadIntDefault tries to parse the specified option as a int. If there is
   263  // an error in parsing, the default option is returned.
   264  func (c *Config) ReadIntDefault(id string, defaultValue int) int {
   265  	val, err := c.ReadInt(id)
   266  	if err != nil {
   267  		return defaultValue
   268  	}
   269  	return val
   270  }
   271  
   272  // ReadDuration parses the specified option as a duration.
   273  func (c *Config) ReadDuration(id string) (time.Duration, error) {
   274  	val, ok := c.Options[id]
   275  	if !ok {
   276  		return time.Duration(0), fmt.Errorf("Specified config is missing from options")
   277  	}
   278  	dval, err := time.ParseDuration(val)
   279  	if err != nil {
   280  		return time.Duration(0), fmt.Errorf("Failed to parse %s as time duration: %s", val, err)
   281  	}
   282  	return dval, nil
   283  }
   284  
   285  // ReadDurationDefault tries to parse the specified option as a duration. If there is
   286  // an error in parsing, the default option is returned.
   287  func (c *Config) ReadDurationDefault(id string, defaultValue time.Duration) time.Duration {
   288  	val, err := c.ReadDuration(id)
   289  	if err != nil {
   290  		return defaultValue
   291  	}
   292  	return val
   293  }
   294  
   295  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   296  // If there is an error in parsing, an empty list is returned.
   297  func (c *Config) ReadStringListToMap(key string) map[string]struct{} {
   298  	s := strings.TrimSpace(c.Read(key))
   299  	list := make(map[string]struct{})
   300  	if s != "" {
   301  		for _, e := range strings.Split(s, ",") {
   302  			trimmed := strings.TrimSpace(e)
   303  			list[trimmed] = struct{}{}
   304  		}
   305  	}
   306  	return list
   307  }
   308  
   309  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   310  // If there is an error in parsing, an empty list is returned.
   311  func (c *Config) ReadStringListToMapDefault(key, defaultValue string) map[string]struct{} {
   312  	val, ok := c.Options[key]
   313  	if !ok {
   314  		val = defaultValue
   315  	}
   316  
   317  	list := make(map[string]struct{})
   318  	if val != "" {
   319  		for _, e := range strings.Split(val, ",") {
   320  			trimmed := strings.TrimSpace(e)
   321  			list[trimmed] = struct{}{}
   322  		}
   323  	}
   324  	return list
   325  }
   326  
   327  // TLSConfig returns a TLSUtil Config based on the client configuration
   328  func (c *Config) TLSConfiguration() *tlsutil.Config {
   329  	tlsConf := &tlsutil.Config{
   330  		VerifyIncoming:       true,
   331  		VerifyOutgoing:       true,
   332  		VerifyServerHostname: c.TLSConfig.VerifyServerHostname,
   333  		CAFile:               c.TLSConfig.CAFile,
   334  		CertFile:             c.TLSConfig.CertFile,
   335  		KeyFile:              c.TLSConfig.KeyFile,
   336  	}
   337  	return tlsConf
   338  }