github.com/hhrutter/nomad@v0.6.0-rc2.0.20170723054333-80c4b03f0705/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  	// GCMaxAllocs is the maximum number of allocations a node can have
   175  	// before garbage collection is triggered.
   176  	GCMaxAllocs int
   177  
   178  	// LogLevel is the level of the logs to putout
   179  	LogLevel string
   180  
   181  	// NoHostUUID disables using the host's UUID and will force generation of a
   182  	// random UUID.
   183  	NoHostUUID bool
   184  }
   185  
   186  func (c *Config) Copy() *Config {
   187  	nc := new(Config)
   188  	*nc = *c
   189  	nc.Node = nc.Node.Copy()
   190  	nc.Servers = helper.CopySliceString(nc.Servers)
   191  	nc.Options = helper.CopyMapStringString(nc.Options)
   192  	nc.GloballyReservedPorts = helper.CopySliceInt(c.GloballyReservedPorts)
   193  	nc.ConsulConfig = c.ConsulConfig.Copy()
   194  	nc.VaultConfig = c.VaultConfig.Copy()
   195  	return nc
   196  }
   197  
   198  // DefaultConfig returns the default configuration
   199  func DefaultConfig() *Config {
   200  	return &Config{
   201  		VaultConfig:             config.DefaultVaultConfig(),
   202  		ConsulConfig:            config.DefaultConsulConfig(),
   203  		LogOutput:               os.Stderr,
   204  		Region:                  "global",
   205  		StatsCollectionInterval: 1 * time.Second,
   206  		TLSConfig:               &config.TLSConfig{},
   207  		LogLevel:                "DEBUG",
   208  		GCInterval:              1 * time.Minute,
   209  		GCParallelDestroys:      2,
   210  		GCDiskUsageThreshold:    80,
   211  		GCInodeUsageThreshold:   70,
   212  		GCMaxAllocs:             50,
   213  		NoHostUUID:              true,
   214  	}
   215  }
   216  
   217  // Read returns the specified configuration value or "".
   218  func (c *Config) Read(id string) string {
   219  	return c.Options[id]
   220  }
   221  
   222  // ReadDefault returns the specified configuration value, or the specified
   223  // default value if none is set.
   224  func (c *Config) ReadDefault(id string, defaultValue string) string {
   225  	val, ok := c.Options[id]
   226  	if !ok {
   227  		return defaultValue
   228  	}
   229  	return val
   230  }
   231  
   232  // ReadBool parses the specified option as a boolean.
   233  func (c *Config) ReadBool(id string) (bool, error) {
   234  	val, ok := c.Options[id]
   235  	if !ok {
   236  		return false, fmt.Errorf("Specified config is missing from options")
   237  	}
   238  	bval, err := strconv.ParseBool(val)
   239  	if err != nil {
   240  		return false, fmt.Errorf("Failed to parse %s as bool: %s", val, err)
   241  	}
   242  	return bval, nil
   243  }
   244  
   245  // ReadBoolDefault tries to parse the specified option as a boolean. If there is
   246  // an error in parsing, the default option is returned.
   247  func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool {
   248  	val, err := c.ReadBool(id)
   249  	if err != nil {
   250  		return defaultValue
   251  	}
   252  	return val
   253  }
   254  
   255  // ReadInt parses the specified option as a int.
   256  func (c *Config) ReadInt(id string) (int, error) {
   257  	val, ok := c.Options[id]
   258  	if !ok {
   259  		return 0, fmt.Errorf("Specified config is missing from options")
   260  	}
   261  	ival, err := strconv.Atoi(val)
   262  	if err != nil {
   263  		return 0, fmt.Errorf("Failed to parse %s as int: %s", val, err)
   264  	}
   265  	return ival, nil
   266  }
   267  
   268  // ReadIntDefault tries to parse the specified option as a int. If there is
   269  // an error in parsing, the default option is returned.
   270  func (c *Config) ReadIntDefault(id string, defaultValue int) int {
   271  	val, err := c.ReadInt(id)
   272  	if err != nil {
   273  		return defaultValue
   274  	}
   275  	return val
   276  }
   277  
   278  // ReadDuration parses the specified option as a duration.
   279  func (c *Config) ReadDuration(id string) (time.Duration, error) {
   280  	val, ok := c.Options[id]
   281  	if !ok {
   282  		return time.Duration(0), fmt.Errorf("Specified config is missing from options")
   283  	}
   284  	dval, err := time.ParseDuration(val)
   285  	if err != nil {
   286  		return time.Duration(0), fmt.Errorf("Failed to parse %s as time duration: %s", val, err)
   287  	}
   288  	return dval, nil
   289  }
   290  
   291  // ReadDurationDefault tries to parse the specified option as a duration. If there is
   292  // an error in parsing, the default option is returned.
   293  func (c *Config) ReadDurationDefault(id string, defaultValue time.Duration) time.Duration {
   294  	val, err := c.ReadDuration(id)
   295  	if err != nil {
   296  		return defaultValue
   297  	}
   298  	return val
   299  }
   300  
   301  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   302  // If there is an error in parsing, an empty list is returned.
   303  func (c *Config) ReadStringListToMap(key string) map[string]struct{} {
   304  	s := strings.TrimSpace(c.Read(key))
   305  	list := make(map[string]struct{})
   306  	if s != "" {
   307  		for _, e := range strings.Split(s, ",") {
   308  			trimmed := strings.TrimSpace(e)
   309  			list[trimmed] = struct{}{}
   310  		}
   311  	}
   312  	return list
   313  }
   314  
   315  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   316  // If there is an error in parsing, an empty list is returned.
   317  func (c *Config) ReadStringListToMapDefault(key, defaultValue string) map[string]struct{} {
   318  	val, ok := c.Options[key]
   319  	if !ok {
   320  		val = defaultValue
   321  	}
   322  
   323  	list := make(map[string]struct{})
   324  	if val != "" {
   325  		for _, e := range strings.Split(val, ",") {
   326  			trimmed := strings.TrimSpace(e)
   327  			list[trimmed] = struct{}{}
   328  		}
   329  	}
   330  	return list
   331  }
   332  
   333  // TLSConfig returns a TLSUtil Config based on the client configuration
   334  func (c *Config) TLSConfiguration() *tlsutil.Config {
   335  	tlsConf := &tlsutil.Config{
   336  		VerifyIncoming:       true,
   337  		VerifyOutgoing:       true,
   338  		VerifyServerHostname: c.TLSConfig.VerifyServerHostname,
   339  		CAFile:               c.TLSConfig.CAFile,
   340  		CertFile:             c.TLSConfig.CertFile,
   341  		KeyFile:              c.TLSConfig.KeyFile,
   342  	}
   343  	return tlsConf
   344  }