github.com/blixtra/nomad@v0.7.2-0.20171221000451-da9a1d7bb050/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  	"github.com/hashicorp/nomad/version"
    16  )
    17  
    18  var (
    19  	// DefaultEnvBlacklist is the default set of environment variables that are
    20  	// filtered when passing the environment variables of the host to a task.
    21  	DefaultEnvBlacklist = strings.Join([]string{
    22  		"CONSUL_TOKEN",
    23  		"VAULT_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 *version.VersionInfo
   133  
   134  	// ConsulConfig is this Agent's Consul configuration
   135  	ConsulConfig *config.ConsulConfig
   136  
   137  	// VaultConfig is this Agent's Vault configuration
   138  	VaultConfig *config.VaultConfig
   139  
   140  	// StatsCollectionInterval is the interval at which the Nomad client
   141  	// collects resource usage stats
   142  	StatsCollectionInterval time.Duration
   143  
   144  	// PublishNodeMetrics determines whether nomad is going to publish node
   145  	// level metrics to remote Telemetry sinks
   146  	PublishNodeMetrics bool
   147  
   148  	// PublishAllocationMetrics determines whether nomad is going to publish
   149  	// allocation metrics to remote Telemetry sinks
   150  	PublishAllocationMetrics bool
   151  
   152  	// TLSConfig holds various TLS related configurations
   153  	TLSConfig *config.TLSConfig
   154  
   155  	// GCInterval is the time interval at which the client triggers garbage
   156  	// collection
   157  	GCInterval time.Duration
   158  
   159  	// GCParallelDestroys is the number of parallel destroys the garbage
   160  	// collector will allow.
   161  	GCParallelDestroys int
   162  
   163  	// GCDiskUsageThreshold is the disk usage threshold given as a percent
   164  	// beyond which the Nomad client triggers GC of terminal allocations
   165  	GCDiskUsageThreshold float64
   166  
   167  	// GCInodeUsageThreshold is the inode usage threshold given as a percent
   168  	// beyond which the Nomad client triggers GC of the terminal allocations
   169  	GCInodeUsageThreshold float64
   170  
   171  	// GCMaxAllocs is the maximum number of allocations a node can have
   172  	// before garbage collection is triggered.
   173  	GCMaxAllocs int
   174  
   175  	// LogLevel is the level of the logs to putout
   176  	LogLevel string
   177  
   178  	// NoHostUUID disables using the host's UUID and will force generation of a
   179  	// random UUID.
   180  	NoHostUUID bool
   181  
   182  	// ACLEnabled controls if ACL enforcement and management is enabled.
   183  	ACLEnabled bool
   184  
   185  	// ACLTokenTTL is how long we cache token values for
   186  	ACLTokenTTL time.Duration
   187  
   188  	// ACLPolicyTTL is how long we cache policy values for
   189  	ACLPolicyTTL time.Duration
   190  
   191  	// DisableTaggedMetrics determines whether metrics will be displayed via a
   192  	// key/value/tag format, or simply a key/value format
   193  	DisableTaggedMetrics bool
   194  
   195  	// BackwardsCompatibleMetrics determines whether to show methods of
   196  	// displaying metrics for older verions, or to only show the new format
   197  	BackwardsCompatibleMetrics bool
   198  }
   199  
   200  func (c *Config) Copy() *Config {
   201  	nc := new(Config)
   202  	*nc = *c
   203  	nc.Node = nc.Node.Copy()
   204  	nc.Servers = helper.CopySliceString(nc.Servers)
   205  	nc.Options = helper.CopyMapStringString(nc.Options)
   206  	nc.GloballyReservedPorts = helper.CopySliceInt(c.GloballyReservedPorts)
   207  	nc.ConsulConfig = c.ConsulConfig.Copy()
   208  	nc.VaultConfig = c.VaultConfig.Copy()
   209  	return nc
   210  }
   211  
   212  // DefaultConfig returns the default configuration
   213  func DefaultConfig() *Config {
   214  	return &Config{
   215  		Version:                    version.GetVersion(),
   216  		VaultConfig:                config.DefaultVaultConfig(),
   217  		ConsulConfig:               config.DefaultConsulConfig(),
   218  		LogOutput:                  os.Stderr,
   219  		Region:                     "global",
   220  		StatsCollectionInterval:    1 * time.Second,
   221  		TLSConfig:                  &config.TLSConfig{},
   222  		LogLevel:                   "DEBUG",
   223  		GCInterval:                 1 * time.Minute,
   224  		GCParallelDestroys:         2,
   225  		GCDiskUsageThreshold:       80,
   226  		GCInodeUsageThreshold:      70,
   227  		GCMaxAllocs:                50,
   228  		NoHostUUID:                 true,
   229  		DisableTaggedMetrics:       false,
   230  		BackwardsCompatibleMetrics: false,
   231  	}
   232  }
   233  
   234  // Read returns the specified configuration value or "".
   235  func (c *Config) Read(id string) string {
   236  	return c.Options[id]
   237  }
   238  
   239  // ReadDefault returns the specified configuration value, or the specified
   240  // default value if none is set.
   241  func (c *Config) ReadDefault(id string, defaultValue string) string {
   242  	val, ok := c.Options[id]
   243  	if !ok {
   244  		return defaultValue
   245  	}
   246  	return val
   247  }
   248  
   249  // ReadBool parses the specified option as a boolean.
   250  func (c *Config) ReadBool(id string) (bool, error) {
   251  	val, ok := c.Options[id]
   252  	if !ok {
   253  		return false, fmt.Errorf("Specified config is missing from options")
   254  	}
   255  	bval, err := strconv.ParseBool(val)
   256  	if err != nil {
   257  		return false, fmt.Errorf("Failed to parse %s as bool: %s", val, err)
   258  	}
   259  	return bval, nil
   260  }
   261  
   262  // ReadBoolDefault tries to parse the specified option as a boolean. If there is
   263  // an error in parsing, the default option is returned.
   264  func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool {
   265  	val, err := c.ReadBool(id)
   266  	if err != nil {
   267  		return defaultValue
   268  	}
   269  	return val
   270  }
   271  
   272  // ReadInt parses the specified option as a int.
   273  func (c *Config) ReadInt(id string) (int, error) {
   274  	val, ok := c.Options[id]
   275  	if !ok {
   276  		return 0, fmt.Errorf("Specified config is missing from options")
   277  	}
   278  	ival, err := strconv.Atoi(val)
   279  	if err != nil {
   280  		return 0, fmt.Errorf("Failed to parse %s as int: %s", val, err)
   281  	}
   282  	return ival, nil
   283  }
   284  
   285  // ReadIntDefault tries to parse the specified option as a int. If there is
   286  // an error in parsing, the default option is returned.
   287  func (c *Config) ReadIntDefault(id string, defaultValue int) int {
   288  	val, err := c.ReadInt(id)
   289  	if err != nil {
   290  		return defaultValue
   291  	}
   292  	return val
   293  }
   294  
   295  // ReadDuration parses the specified option as a duration.
   296  func (c *Config) ReadDuration(id string) (time.Duration, error) {
   297  	val, ok := c.Options[id]
   298  	if !ok {
   299  		return time.Duration(0), fmt.Errorf("Specified config is missing from options")
   300  	}
   301  	dval, err := time.ParseDuration(val)
   302  	if err != nil {
   303  		return time.Duration(0), fmt.Errorf("Failed to parse %s as time duration: %s", val, err)
   304  	}
   305  	return dval, nil
   306  }
   307  
   308  // ReadDurationDefault tries to parse the specified option as a duration. If there is
   309  // an error in parsing, the default option is returned.
   310  func (c *Config) ReadDurationDefault(id string, defaultValue time.Duration) time.Duration {
   311  	val, err := c.ReadDuration(id)
   312  	if err != nil {
   313  		return defaultValue
   314  	}
   315  	return val
   316  }
   317  
   318  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   319  // If there is an error in parsing, an empty list is returned.
   320  func (c *Config) ReadStringListToMap(key string) map[string]struct{} {
   321  	s := strings.TrimSpace(c.Read(key))
   322  	list := make(map[string]struct{})
   323  	if s != "" {
   324  		for _, e := range strings.Split(s, ",") {
   325  			trimmed := strings.TrimSpace(e)
   326  			list[trimmed] = struct{}{}
   327  		}
   328  	}
   329  	return list
   330  }
   331  
   332  // ReadStringListToMap tries to parse the specified option as a comma separated list.
   333  // If there is an error in parsing, an empty list is returned.
   334  func (c *Config) ReadStringListToMapDefault(key, defaultValue string) map[string]struct{} {
   335  	val, ok := c.Options[key]
   336  	if !ok {
   337  		val = defaultValue
   338  	}
   339  
   340  	list := make(map[string]struct{})
   341  	if val != "" {
   342  		for _, e := range strings.Split(val, ",") {
   343  			trimmed := strings.TrimSpace(e)
   344  			list[trimmed] = struct{}{}
   345  		}
   346  	}
   347  	return list
   348  }
   349  
   350  // TLSConfig returns a TLSUtil Config based on the client configuration
   351  func (c *Config) TLSConfiguration() *tlsutil.Config {
   352  	tlsConf := &tlsutil.Config{
   353  		VerifyIncoming:       true,
   354  		VerifyOutgoing:       true,
   355  		VerifyServerHostname: c.TLSConfig.VerifyServerHostname,
   356  		CAFile:               c.TLSConfig.CAFile,
   357  		CertFile:             c.TLSConfig.CertFile,
   358  		KeyFile:              c.TLSConfig.KeyFile,
   359  		KeyLoader:            c.TLSConfig.GetKeyLoader(),
   360  	}
   361  	return tlsConf
   362  }