github.com/bigcommerce/nomad@v0.9.3-bc/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 log "github.com/hashicorp/go-hclog" 12 "github.com/hashicorp/nomad/client/state" 13 "github.com/hashicorp/nomad/helper" 14 "github.com/hashicorp/nomad/helper/pluginutils/loader" 15 "github.com/hashicorp/nomad/nomad/structs" 16 "github.com/hashicorp/nomad/nomad/structs/config" 17 "github.com/hashicorp/nomad/plugins/base" 18 "github.com/hashicorp/nomad/version" 19 ) 20 21 var ( 22 // DefaultEnvBlacklist is the default set of environment variables that are 23 // filtered when passing the environment variables of the host to a task. 24 DefaultEnvBlacklist = strings.Join([]string{ 25 "CONSUL_TOKEN", 26 "VAULT_TOKEN", 27 "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", 28 "GOOGLE_APPLICATION_CREDENTIALS", 29 }, ",") 30 31 // DefaultUserBlacklist is the default set of users that tasks are not 32 // allowed to run as when using a driver in "user.checked_drivers" 33 DefaultUserBlacklist = strings.Join([]string{ 34 "root", 35 "Administrator", 36 }, ",") 37 38 // DefaultUserCheckedDrivers is the set of drivers we apply the user 39 // blacklist onto. For virtualized drivers it often doesn't make sense to 40 // make this stipulation so by default they are ignored. 41 DefaultUserCheckedDrivers = strings.Join([]string{ 42 "exec", 43 "qemu", 44 "java", 45 }, ",") 46 47 // A mapping of directories on the host OS to attempt to embed inside each 48 // task's chroot. 49 DefaultChrootEnv = map[string]string{ 50 "/bin": "/bin", 51 "/etc": "/etc", 52 "/lib": "/lib", 53 "/lib32": "/lib32", 54 "/lib64": "/lib64", 55 "/run/resolvconf": "/run/resolvconf", 56 "/sbin": "/sbin", 57 "/usr": "/usr", 58 } 59 ) 60 61 // RPCHandler can be provided to the Client if there is a local server 62 // to avoid going over the network. If not provided, the Client will 63 // maintain a connection pool to the servers 64 type RPCHandler interface { 65 RPC(method string, args interface{}, reply interface{}) error 66 } 67 68 // Config is used to parameterize and configure the behavior of the client 69 type Config struct { 70 // DevMode controls if we are in a development mode which 71 // avoids persistent storage. 72 DevMode bool 73 74 // StateDir is where we store our state 75 StateDir string 76 77 // AllocDir is where we store data for allocations 78 AllocDir string 79 80 // LogOutput is the destination for logs 81 LogOutput io.Writer 82 83 // Logger provides a logger to thhe client 84 Logger log.Logger 85 86 // Region is the clients region 87 Region string 88 89 // Network interface to be used in network fingerprinting 90 NetworkInterface string 91 92 // Network speed is the default speed of network interfaces if they can not 93 // be determined dynamically. 94 NetworkSpeed int 95 96 // CpuCompute is the default total CPU compute if they can not be determined 97 // dynamically. It should be given as Cores * MHz (2 Cores * 2 Ghz = 4000) 98 CpuCompute int 99 100 // MemoryMB is the default node total memory in megabytes if it cannot be 101 // determined dynamically. 102 MemoryMB int 103 104 // MaxKillTimeout allows capping the user-specifiable KillTimeout. If the 105 // task's KillTimeout is greater than the MaxKillTimeout, MaxKillTimeout is 106 // used. 107 MaxKillTimeout time.Duration 108 109 // Servers is a list of known server addresses. These are as "host:port" 110 Servers []string 111 112 // RPCHandler can be provided to avoid network traffic if the 113 // server is running locally. 114 RPCHandler RPCHandler 115 116 // Node provides the base node 117 Node *structs.Node 118 119 // ClientMaxPort is the upper range of the ports that the client uses for 120 // communicating with plugin subsystems over loopback 121 ClientMaxPort uint 122 123 // ClientMinPort is the lower range of the ports that the client uses for 124 // communicating with plugin subsystems over loopback 125 ClientMinPort uint 126 127 // A mapping of directories on the host OS to attempt to embed inside each 128 // task's chroot. 129 ChrootEnv map[string]string 130 131 // Options provides arbitrary key-value configuration for nomad internals, 132 // like fingerprinters and drivers. The format is: 133 // 134 // namespace.option = value 135 Options map[string]string 136 137 // Version is the version of the Nomad client 138 Version *version.VersionInfo 139 140 // ConsulConfig is this Agent's Consul configuration 141 ConsulConfig *config.ConsulConfig 142 143 // VaultConfig is this Agent's Vault configuration 144 VaultConfig *config.VaultConfig 145 146 // StatsCollectionInterval is the interval at which the Nomad client 147 // collects resource usage stats 148 StatsCollectionInterval time.Duration 149 150 // PublishNodeMetrics determines whether nomad is going to publish node 151 // level metrics to remote Telemetry sinks 152 PublishNodeMetrics bool 153 154 // PublishAllocationMetrics determines whether nomad is going to publish 155 // allocation metrics to remote Telemetry sinks 156 PublishAllocationMetrics bool 157 158 // TLSConfig holds various TLS related configurations 159 TLSConfig *config.TLSConfig 160 161 // GCInterval is the time interval at which the client triggers garbage 162 // collection 163 GCInterval time.Duration 164 165 // GCParallelDestroys is the number of parallel destroys the garbage 166 // collector will allow. 167 GCParallelDestroys int 168 169 // GCDiskUsageThreshold is the disk usage threshold given as a percent 170 // beyond which the Nomad client triggers GC of terminal allocations 171 GCDiskUsageThreshold float64 172 173 // GCInodeUsageThreshold is the inode usage threshold given as a percent 174 // beyond which the Nomad client triggers GC of the terminal allocations 175 GCInodeUsageThreshold float64 176 177 // GCMaxAllocs is the maximum number of allocations a node can have 178 // before garbage collection is triggered. 179 GCMaxAllocs int 180 181 // LogLevel is the level of the logs to putout 182 LogLevel string 183 184 // NoHostUUID disables using the host's UUID and will force generation of a 185 // random UUID. 186 NoHostUUID bool 187 188 // ACLEnabled controls if ACL enforcement and management is enabled. 189 ACLEnabled bool 190 191 // ACLTokenTTL is how long we cache token values for 192 ACLTokenTTL time.Duration 193 194 // ACLPolicyTTL is how long we cache policy values for 195 ACLPolicyTTL time.Duration 196 197 // DisableTaggedMetrics determines whether metrics will be displayed via a 198 // key/value/tag format, or simply a key/value format 199 DisableTaggedMetrics bool 200 201 // DisableRemoteExec disables remote exec targeting tasks on this client 202 DisableRemoteExec bool 203 204 // BackwardsCompatibleMetrics determines whether to show methods of 205 // displaying metrics for older versions, or to only show the new format 206 BackwardsCompatibleMetrics bool 207 208 // RPCHoldTimeout is how long an RPC can be "held" before it is errored. 209 // This is used to paper over a loss of leadership by instead holding RPCs, 210 // so that the caller experiences a slow response rather than an error. 211 // This period is meant to be long enough for a leader election to take 212 // place, and a small jitter is applied to avoid a thundering herd. 213 RPCHoldTimeout time.Duration 214 215 // PluginLoader is used to load plugins. 216 PluginLoader loader.PluginCatalog 217 218 // PluginSingletonLoader is a plugin loader that will returns singleton 219 // instances of the plugins. 220 PluginSingletonLoader loader.PluginCatalog 221 222 // StateDBFactory is used to override stateDB implementations, 223 StateDBFactory state.NewStateDBFunc 224 } 225 226 func (c *Config) Copy() *Config { 227 nc := new(Config) 228 *nc = *c 229 nc.Node = nc.Node.Copy() 230 nc.Servers = helper.CopySliceString(nc.Servers) 231 nc.Options = helper.CopyMapStringString(nc.Options) 232 nc.ConsulConfig = c.ConsulConfig.Copy() 233 nc.VaultConfig = c.VaultConfig.Copy() 234 return nc 235 } 236 237 // DefaultConfig returns the default configuration 238 func DefaultConfig() *Config { 239 return &Config{ 240 Version: version.GetVersion(), 241 VaultConfig: config.DefaultVaultConfig(), 242 ConsulConfig: config.DefaultConsulConfig(), 243 LogOutput: os.Stderr, 244 Region: "global", 245 StatsCollectionInterval: 1 * time.Second, 246 TLSConfig: &config.TLSConfig{}, 247 LogLevel: "DEBUG", 248 GCInterval: 1 * time.Minute, 249 GCParallelDestroys: 2, 250 GCDiskUsageThreshold: 80, 251 GCInodeUsageThreshold: 70, 252 GCMaxAllocs: 50, 253 NoHostUUID: true, 254 DisableTaggedMetrics: false, 255 DisableRemoteExec: false, 256 BackwardsCompatibleMetrics: false, 257 RPCHoldTimeout: 5 * time.Second, 258 } 259 } 260 261 // Read returns the specified configuration value or "". 262 func (c *Config) Read(id string) string { 263 return c.Options[id] 264 } 265 266 // ReadDefault returns the specified configuration value, or the specified 267 // default value if none is set. 268 func (c *Config) ReadDefault(id string, defaultValue string) string { 269 val, ok := c.Options[id] 270 if !ok { 271 return defaultValue 272 } 273 return val 274 } 275 276 // ReadBool parses the specified option as a boolean. 277 func (c *Config) ReadBool(id string) (bool, error) { 278 val, ok := c.Options[id] 279 if !ok { 280 return false, fmt.Errorf("Specified config is missing from options") 281 } 282 bval, err := strconv.ParseBool(val) 283 if err != nil { 284 return false, fmt.Errorf("Failed to parse %s as bool: %s", val, err) 285 } 286 return bval, nil 287 } 288 289 // ReadBoolDefault tries to parse the specified option as a boolean. If there is 290 // an error in parsing, the default option is returned. 291 func (c *Config) ReadBoolDefault(id string, defaultValue bool) bool { 292 val, err := c.ReadBool(id) 293 if err != nil { 294 return defaultValue 295 } 296 return val 297 } 298 299 // ReadInt parses the specified option as a int. 300 func (c *Config) ReadInt(id string) (int, error) { 301 val, ok := c.Options[id] 302 if !ok { 303 return 0, fmt.Errorf("Specified config is missing from options") 304 } 305 ival, err := strconv.Atoi(val) 306 if err != nil { 307 return 0, fmt.Errorf("Failed to parse %s as int: %s", val, err) 308 } 309 return ival, nil 310 } 311 312 // ReadIntDefault tries to parse the specified option as a int. If there is 313 // an error in parsing, the default option is returned. 314 func (c *Config) ReadIntDefault(id string, defaultValue int) int { 315 val, err := c.ReadInt(id) 316 if err != nil { 317 return defaultValue 318 } 319 return val 320 } 321 322 // ReadDuration parses the specified option as a duration. 323 func (c *Config) ReadDuration(id string) (time.Duration, error) { 324 val, ok := c.Options[id] 325 if !ok { 326 return time.Duration(0), fmt.Errorf("Specified config is missing from options") 327 } 328 dval, err := time.ParseDuration(val) 329 if err != nil { 330 return time.Duration(0), fmt.Errorf("Failed to parse %s as time duration: %s", val, err) 331 } 332 return dval, nil 333 } 334 335 // ReadDurationDefault tries to parse the specified option as a duration. If there is 336 // an error in parsing, the default option is returned. 337 func (c *Config) ReadDurationDefault(id string, defaultValue time.Duration) time.Duration { 338 val, err := c.ReadDuration(id) 339 if err != nil { 340 return defaultValue 341 } 342 return val 343 } 344 345 // ReadStringListToMap tries to parse the specified option as a comma separated list. 346 // If there is an error in parsing, an empty list is returned. 347 func (c *Config) ReadStringListToMap(key string) map[string]struct{} { 348 s := strings.TrimSpace(c.Read(key)) 349 list := make(map[string]struct{}) 350 if s != "" { 351 for _, e := range strings.Split(s, ",") { 352 trimmed := strings.TrimSpace(e) 353 list[trimmed] = struct{}{} 354 } 355 } 356 return list 357 } 358 359 // ReadStringListToMap tries to parse the specified option as a comma separated list. 360 // If there is an error in parsing, an empty list is returned. 361 func (c *Config) ReadStringListToMapDefault(key, defaultValue string) map[string]struct{} { 362 val, ok := c.Options[key] 363 if !ok { 364 val = defaultValue 365 } 366 367 list := make(map[string]struct{}) 368 if val != "" { 369 for _, e := range strings.Split(val, ",") { 370 trimmed := strings.TrimSpace(e) 371 list[trimmed] = struct{}{} 372 } 373 } 374 return list 375 } 376 377 // NomadPluginConfig produces the NomadConfig struct which is sent to Nomad plugins 378 func (c *Config) NomadPluginConfig() *base.AgentConfig { 379 return &base.AgentConfig{ 380 Driver: &base.ClientDriverConfig{ 381 ClientMinPort: c.ClientMinPort, 382 ClientMaxPort: c.ClientMaxPort, 383 }, 384 } 385 }