diff --git a/client/allocrunner/taskrunner/task_dir_hook.go b/client/allocrunner/taskrunner/task_dir_hook.go index dce355bc9903..10f9827bedd6 100644 --- a/client/allocrunner/taskrunner/task_dir_hook.go +++ b/client/allocrunner/taskrunner/task_dir_hook.go @@ -92,7 +92,12 @@ func setEnvvars(envBuilder *taskenv.Builder, fsi drivers.FSIsolation, taskDir *a // Set the host environment variables for non-image based drivers if fsi != drivers.FSIsolationImage { - filter := strings.Split(conf.ReadDefault("env.blacklist", cconfig.DefaultEnvBlacklist), ",") + // COMPAT(0.13) using inclusive language, blacklist is kept for backward compatibility. + denylist := conf.ReadAlternativeDefault( + []string{"env.denylist", "env.blacklist"}, + cconfig.DefaultEnvDenylist, + ) + filter := strings.Split(denylist, ",") envBuilder.SetHostEnvvars(filter) } } diff --git a/client/allocrunner/taskrunner/validate_hook.go b/client/allocrunner/taskrunner/validate_hook.go index 418f9084b7a7..07d5f5adcd02 100644 --- a/client/allocrunner/taskrunner/validate_hook.go +++ b/client/allocrunner/taskrunner/validate_hook.go @@ -43,7 +43,11 @@ func validateTask(task *structs.Task, taskEnv *taskenv.TaskEnv, conf *config.Con var mErr multierror.Error // Validate the user - unallowedUsers := conf.ReadStringListToMapDefault("user.blacklist", config.DefaultUserBlacklist) + // COMPAT(0.13) uses inclusive language. blacklist is kept for backward compatilibity. + unallowedUsers := conf.ReadStringListAlternativeToMapDefault( + []string{"user.denylist", "user.blacklist"}, + config.DefaultUserDenylist, + ) checkDrivers := conf.ReadStringListToMapDefault("user.checked_drivers", config.DefaultUserCheckedDrivers) if _, driverMatch := checkDrivers[task.Driver]; driverMatch { if _, unallowed := unallowedUsers[task.User]; unallowed { diff --git a/client/client.go b/client/client.go index 115e5086705d..697c457ef998 100644 --- a/client/client.go +++ b/client/client.go @@ -409,9 +409,10 @@ func NewClient(cfg *config.Config, consulCatalog consul.CatalogAPI, consulServic return nil, fmt.Errorf("fingerprinting failed: %v", err) } - // Build the white/blacklists of drivers. - allowlistDrivers := cfg.ReadStringListToMap("driver.whitelist") - blocklistDrivers := cfg.ReadStringListToMap("driver.blacklist") + // Build the allow/denylists of drivers. + // COMPAT(0.13) uses inclusive language. white/blacklist are there for backward compatible reasons only. + allowlistDrivers := cfg.ReadStringListToMap("driver.allowlist", "driver.whitelist") + blocklistDrivers := cfg.ReadStringListToMap("driver.denylist", "driver.blacklist") // Setup the csi manager csiConfig := &csimanager.Config{ diff --git a/client/client_test.go b/client/client_test.go index 96bf55f44a73..faa124da99f3 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1211,7 +1211,7 @@ func TestClient_UpdateNodeFromFingerprintKeepsConfig(t *testing.T) { client, cleanup = TestClient(t, func(c *config.Config) { c.NetworkInterface = dev c.Node.Name = name - c.Options["fingerprint.blacklist"] = "network" + c.Options["fingerprint.denylist"] = "network" // Node is already a mock.Node, with a device c.Node.NodeResources.Networks[0].Device = dev }) @@ -1265,7 +1265,7 @@ func Test_UpdateNodeFromFingerprintMultiIP(t *testing.T) { // Client without network configured updates to match fingerprint client, cleanup := TestClient(t, func(c *config.Config) { c.NetworkInterface = dev - c.Options["fingerprint.blacklist"] = "network,cni,bridge" + c.Options["fingerprint.denylist"] = "network,cni,bridge" c.Node.Resources.Networks = c.Node.NodeResources.Networks }) defer cleanup() diff --git a/client/config/config.go b/client/config/config.go index 8c93891f5069..d34183d98a6b 100644 --- a/client/config/config.go +++ b/client/config/config.go @@ -19,10 +19,10 @@ import ( ) var ( - // DefaultEnvBlacklist is the default set of environment variables that are + // DefaultEnvDenylist is the default set of environment variables that are // filtered when passing the environment variables of the host to a task. // duplicated in command/agent/host, update that if this changes. - DefaultEnvBlacklist = strings.Join([]string{ + DefaultEnvDenylist = strings.Join([]string{ "CONSUL_TOKEN", "CONSUL_HTTP_TOKEN", "VAULT_TOKEN", @@ -30,15 +30,15 @@ var ( "GOOGLE_APPLICATION_CREDENTIALS", }, ",") - // DefaultUserBlacklist is the default set of users that tasks are not + // DefaultUserDenylist is the default set of users that tasks are not // allowed to run as when using a driver in "user.checked_drivers" - DefaultUserBlacklist = strings.Join([]string{ + DefaultUserDenylist = strings.Join([]string{ "root", "Administrator", }, ",") // DefaultUserCheckedDrivers is the set of drivers we apply the user - // blacklist onto. For virtualized drivers it often doesn't make sense to + // denylist onto. For virtualized drivers it often doesn't make sense to // make this stipulation so by default they are ignored. DefaultUserCheckedDrivers = strings.Join([]string{ "exec", @@ -344,11 +344,20 @@ func (c *Config) Read(id string) string { // ReadDefault returns the specified configuration value, or the specified // default value if none is set. func (c *Config) ReadDefault(id string, defaultValue string) string { - val, ok := c.Options[id] - if !ok { - return defaultValue + return c.ReadAlternativeDefault([]string{id}, defaultValue) +} + +// ReadAlternativeDefault returns the specified configuration value, or the +// specified value if none is set. +func (c *Config) ReadAlternativeDefault(ids []string, defaultValue string) string { + for _, id := range ids { + val, ok := c.Options[id] + if ok { + return val + } } - return val + + return defaultValue } // ReadBool parses the specified option as a boolean. @@ -420,28 +429,30 @@ func (c *Config) ReadDurationDefault(id string, defaultValue time.Duration) time return val } -// ReadStringListToMap tries to parse the specified option as a comma separated list. +// ReadStringListToMap tries to parse the specified option(s) as a comma separated list. // If there is an error in parsing, an empty list is returned. -func (c *Config) ReadStringListToMap(key string) map[string]struct{} { - s := strings.TrimSpace(c.Read(key)) - list := make(map[string]struct{}) - if s != "" { - for _, e := range strings.Split(s, ",") { - trimmed := strings.TrimSpace(e) - list[trimmed] = struct{}{} - } - } - return list +func (c *Config) ReadStringListToMap(keys ...string) map[string]struct{} { + val := c.ReadAlternativeDefault(keys, "") + + return splitValue(val) } // ReadStringListToMap tries to parse the specified option as a comma separated list. // If there is an error in parsing, an empty list is returned. func (c *Config) ReadStringListToMapDefault(key, defaultValue string) map[string]struct{} { - val, ok := c.Options[key] - if !ok { - val = defaultValue - } + return c.ReadStringListAlternativeToMapDefault([]string{key}, defaultValue) +} + +// ReadStringListAlternativeToMapDefault tries to parse the specified options as a comma sparated list. +// If there is an error in parsing, an empty list is returned. +func (c *Config) ReadStringListAlternativeToMapDefault(keys []string, defaultValue string) map[string]struct{} { + val := c.ReadAlternativeDefault(keys, defaultValue) + + return splitValue(val) +} +// splitValue parses the value as a comma separated list. +func splitValue(val string) map[string]struct{} { list := make(map[string]struct{}) if val != "" { for _, e := range strings.Split(val, ",") { diff --git a/client/fingerprint_manager.go b/client/fingerprint_manager.go index e8993526ffaf..db162c66f37b 100644 --- a/client/fingerprint_manager.go +++ b/client/fingerprint_manager.go @@ -65,28 +65,30 @@ func (fm *FingerprintManager) getNode() *structs.Node { } // Run starts the process of fingerprinting the node. It does an initial pass, -// identifying whitelisted and blacklisted fingerprints/drivers. Then, for +// identifying allowlisted and denylisted fingerprints/drivers. Then, for // those which require periotic checking, it starts a periodic process for // each. func (fp *FingerprintManager) Run() error { // First, set up all fingerprints cfg := fp.getConfig() - whitelistFingerprints := cfg.ReadStringListToMap("fingerprint.whitelist") - whitelistFingerprintsEnabled := len(whitelistFingerprints) > 0 - blacklistFingerprints := cfg.ReadStringListToMap("fingerprint.blacklist") + // COMPAT(0.13) using inclusive language, whitelist is kept for backward compatibility. + allowlistFingerprints := cfg.ReadStringListToMap("fingerprint.allowlist", "fingerprint.whitelist") + allowlistFingerprintsEnabled := len(allowlistFingerprints) > 0 + // COMPAT(0.13) using inclusive language, blacklist is kept for backward compatibility. + denylistFingerprints := cfg.ReadStringListToMap("fingerprint.denylist", "fingerprint.blacklist") fp.logger.Debug("built-in fingerprints", "fingerprinters", fingerprint.BuiltinFingerprints()) var availableFingerprints []string var skippedFingerprints []string for _, name := range fingerprint.BuiltinFingerprints() { - // Skip modules that are not in the whitelist if it is enabled. - if _, ok := whitelistFingerprints[name]; whitelistFingerprintsEnabled && !ok { + // Skip modules that are not in the allowlist if it is enabled. + if _, ok := allowlistFingerprints[name]; allowlistFingerprintsEnabled && !ok { skippedFingerprints = append(skippedFingerprints, name) continue } - // Skip modules that are in the blacklist - if _, ok := blacklistFingerprints[name]; ok { + // Skip modules that are in the denylist + if _, ok := denylistFingerprints[name]; ok { skippedFingerprints = append(skippedFingerprints, name) continue } @@ -99,7 +101,7 @@ func (fp *FingerprintManager) Run() error { } if len(skippedFingerprints) != 0 { - fp.logger.Debug("fingerprint modules skipped due to white/blacklist", + fp.logger.Debug("fingerprint modules skipped due to allow/denylist", "skipped_fingerprinters", skippedFingerprints) } diff --git a/client/fingerprint_manager_test.go b/client/fingerprint_manager_test.go index a7000095460e..a4ba0184a584 100644 --- a/client/fingerprint_manager_test.go +++ b/client/fingerprint_manager_test.go @@ -61,13 +61,13 @@ func TestFimgerprintManager_Run_InWhitelist(t *testing.T) { require.NotEqual(node.Attributes["cpu.frequency"], "") } -func TestFingerprintManager_Run_InBlacklist(t *testing.T) { +func TestFingerprintManager_Run_InDenylist(t *testing.T) { t.Parallel() require := require.New(t) testClient, cleanup := TestClient(t, func(c *config.Config) { c.Options = map[string]string{ - "fingerprint.whitelist": " arch,memory,foo,bar ", - "fingerprint.blacklist": " cpu ", + "fingerprint.allowlist": " arch,memory,foo,bar ", + "fingerprint.denylist": " cpu ", } }) defer cleanup() @@ -94,6 +94,38 @@ func TestFingerprintManager_Run_Combination(t *testing.T) { t.Parallel() require := require.New(t) + testClient, cleanup := TestClient(t, func(c *config.Config) { + c.Options = map[string]string{ + "fingerprint.allowlist": " arch,cpu,memory,foo,bar ", + "fingerprint.denylist": " memory,host ", + } + }) + defer cleanup() + + fm := NewFingerprintManager( + testClient.config.PluginSingletonLoader, + testClient.GetConfig, + testClient.config.Node, + testClient.shutdownCh, + testClient.updateNodeFromFingerprint, + testClient.logger, + ) + + err := fm.Run() + require.Nil(err) + + node := testClient.config.Node + + require.NotEqual(node.Attributes["cpu.frequency"], "") + require.NotEqual(node.Attributes["cpu.arch"], "") + require.NotContains(node.Attributes, "memory.totalbytes") + require.NotContains(node.Attributes, "os.name") +} + +func TestFingerprintManager_Run_CombinationLegacyNames(t *testing.T) { + t.Parallel() + require := require.New(t) + testClient, cleanup := TestClient(t, func(c *config.Config) { c.Options = map[string]string{ "fingerprint.whitelist": " arch,cpu,memory,foo,bar ", diff --git a/command/acl_policy.go b/command/acl_policy.go index f10718149f80..a742d75c4302 100644 --- a/command/acl_policy.go +++ b/command/acl_policy.go @@ -16,7 +16,7 @@ Usage: nomad acl policy [options] [args] This command groups subcommands for interacting with ACL policies. Nomad's ACL system can be used to control access to data and APIs. ACL policies allow a - set of capabilities or actions to be granted or whitelisted. For a full guide + set of capabilities or actions to be granted or allowlisted. For a full guide see: https://www.nomadproject.io/guides/acl.html Create an ACL policy: diff --git a/command/agent/config.go b/command/agent/config.go index 240e3d9c06c6..939dcaf4288b 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -311,7 +311,7 @@ type ClientTemplateConfig struct { // are unsafe because they expose information from the client host. FunctionDenylist []string `hcl:"function_denylist"` - // COMPAT(0.13) consul-template uses inclusive language from v0.25.0 - function_blacklist is kept for compatibility + // Deprecated: COMPAT(0.13) consul-template uses inclusive language from v0.25.0 - function_blacklist is kept for compatibility FunctionBlacklist []string `hcl:"function_blacklist"` // DisableSandbox allows templates to access arbitrary files on the diff --git a/command/agent/testdata/obj-len-one.hcl b/command/agent/testdata/obj-len-one.hcl index ba8a549f193b..7d1485a2998b 100644 --- a/command/agent/testdata/obj-len-one.hcl +++ b/command/agent/testdata/obj-len-one.hcl @@ -1,5 +1,5 @@ client { options { - driver.whitelist = "docker" + driver.allowlist = "docker" } } diff --git a/command/agent/testdata/obj-len-one.json b/command/agent/testdata/obj-len-one.json index a1e46acea245..7228771e2107 100644 --- a/command/agent/testdata/obj-len-one.json +++ b/command/agent/testdata/obj-len-one.json @@ -1,7 +1,7 @@ { "client": { "options": { - "driver.whitelist": "docker" + "driver.allowlist": "docker" } }, "server": {} diff --git a/drivers/docker/config.go b/drivers/docker/config.go index 99e48eb4e012..e4abc6cfd1f5 100644 --- a/drivers/docker/config.go +++ b/drivers/docker/config.go @@ -96,7 +96,10 @@ func PluginLoader(opts map[string]string) (map[string]interface{}, error) { conf["volumes"] = volConf // capabilities - if v, ok := opts["docker.caps.whitelist"]; ok { + // COMPAT(0.13) uses inclusive language. whitelist is used for backward compatibility. + if v, ok := opts["docker.caps.allowlist"]; ok { + conf["allow_caps"] = strings.Split(v, ",") + } else if v, ok := opts["docker.caps.whitelist"]; ok { conf["allow_caps"] = strings.Split(v, ",") } @@ -497,7 +500,7 @@ type DockerMount struct { func (m DockerMount) toDockerHostMount() (docker.HostMount, error) { if m.Type == "" { - // for backward compatbility, as type is optional + // for backward compatibility, as type is optional m.Type = "volume" } diff --git a/drivers/docker/driver.go b/drivers/docker/driver.go index d4fd72a2af5d..c5b70469b0c9 100644 --- a/drivers/docker/driver.go +++ b/drivers/docker/driver.go @@ -909,7 +909,7 @@ func (d *Driver) createContainerConfig(task *drivers.TaskConfig, driverConfig *T } } if len(missingCaps) > 0 { - return c, fmt.Errorf("Docker driver doesn't have the following caps whitelisted on this Nomad agent: %s", missingCaps) + return c, fmt.Errorf("Docker driver doesn't have the following caps allowlisted on this Nomad agent: %s", missingCaps) } } diff --git a/drivers/docker/driver_darwin_test.go b/drivers/docker/driver_darwin_test.go index 53392b1937bc..18bfddd6828c 100644 --- a/drivers/docker/driver_darwin_test.go +++ b/drivers/docker/driver_darwin_test.go @@ -11,7 +11,7 @@ import ( // be mounted into Docker containers on macOS without needing dev performing // special setup. // -// macOS sets tempdir as `/var`, which Docker does not whitelist as a path that +// macOS sets tempdir as `/var`, which Docker does not allowlist as a path that // can be bind-mounted. func TestMain(m *testing.M) { tmpdir := fmt.Sprintf("/tmp/nomad-docker-tests-%d", time.Now().Unix()) diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index 40e178e2dfce..8780d56f5237 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -1235,50 +1235,50 @@ func TestDockerDriver_Capabilities(t *testing.T) { Name string CapAdd []string CapDrop []string - Whitelist string + Allowlist string StartError string }{ { - Name: "default-whitelist-add-allowed", + Name: "default-allowlist-add-allowed", CapAdd: []string{"fowner", "mknod"}, CapDrop: []string{"all"}, }, { - Name: "default-whitelist-add-forbidden", + Name: "default-allowlist-add-forbidden", CapAdd: []string{"net_admin"}, StartError: "net_admin", }, { - Name: "default-whitelist-drop-existing", + Name: "default-allowlist-drop-existing", CapDrop: []string{"fowner", "mknod"}, }, { - Name: "restrictive-whitelist-drop-all", + Name: "restrictive-allowlist-drop-all", CapDrop: []string{"all"}, - Whitelist: "fowner,mknod", + Allowlist: "fowner,mknod", }, { - Name: "restrictive-whitelist-add-allowed", + Name: "restrictive-allowlist-add-allowed", CapAdd: []string{"fowner", "mknod"}, CapDrop: []string{"all"}, - Whitelist: "fowner,mknod", + Allowlist: "fowner,mknod", }, { - Name: "restrictive-whitelist-add-forbidden", + Name: "restrictive-allowlist-add-forbidden", CapAdd: []string{"net_admin", "mknod"}, CapDrop: []string{"all"}, - Whitelist: "fowner,mknod", + Allowlist: "fowner,mknod", StartError: "net_admin", }, { - Name: "permissive-whitelist", + Name: "permissive-allowlist", CapAdd: []string{"net_admin", "mknod"}, - Whitelist: "all", + Allowlist: "all", }, { - Name: "permissive-whitelist-add-all", + Name: "permissive-allowlist-add-all", CapAdd: []string{"all"}, - Whitelist: "all", + Allowlist: "all", }, } @@ -1299,8 +1299,8 @@ func TestDockerDriver_Capabilities(t *testing.T) { d := dockerDriverHarness(t, nil) dockerDriver, ok := d.Impl().(*Driver) require.True(t, ok) - if tc.Whitelist != "" { - dockerDriver.config.AllowCaps = strings.Split(tc.Whitelist, ",") + if tc.Allowlist != "" { + dockerDriver.config.AllowCaps = strings.Split(tc.Allowlist, ",") } cleanup := d.MkAllocDir(task, true) diff --git a/e2e/terraform/config/dev-cluster/nomad/client-linux/client.hcl b/e2e/terraform/config/dev-cluster/nomad/client-linux/client.hcl index 07c7ee9850e0..34ab5996a3c8 100644 --- a/e2e/terraform/config/dev-cluster/nomad/client-linux/client.hcl +++ b/e2e/terraform/config/dev-cluster/nomad/client-linux/client.hcl @@ -5,7 +5,7 @@ client { options { # Allow jobs to run as root - "user.blacklist" = "" + "user.denylist" = "" # Allow rawexec jobs "driver.raw_exec.enable" = "1" diff --git a/nomad/structs/node_class.go b/nomad/structs/node_class.go index fbeb93966a19..22613f850520 100644 --- a/nomad/structs/node_class.go +++ b/nomad/structs/node_class.go @@ -38,7 +38,7 @@ func (n *Node) ComputeClass() error { return nil } -// HashInclude is used to blacklist uniquely identifying node fields from being +// HashInclude is used to denylist uniquely identifying node fields from being // included in the computed node class. func (n Node) HashInclude(field string, v interface{}) (bool, error) { switch field { @@ -49,7 +49,7 @@ func (n Node) HashInclude(field string, v interface{}) (bool, error) { } } -// HashIncludeMap is used to blacklist uniquely identifying node map keys from being +// HashIncludeMap is used to denylist uniquely identifying node map keys from being // included in the computed node class. func (n Node) HashIncludeMap(field string, k, v interface{}) (bool, error) { key, ok := k.(string) @@ -65,7 +65,7 @@ func (n Node) HashIncludeMap(field string, k, v interface{}) (bool, error) { } } -// HashInclude is used to blacklist uniquely identifying node fields from being +// HashInclude is used to denylist uniquely identifying node fields from being // included in the computed node class. func (n NodeResources) HashInclude(field string, v interface{}) (bool, error) { switch field { @@ -76,7 +76,7 @@ func (n NodeResources) HashInclude(field string, v interface{}) (bool, error) { } } -// HashInclude is used to blacklist uniquely identifying node fields from being +// HashInclude is used to denylist uniquely identifying node fields from being // included in the computed node class. func (n NodeDeviceResource) HashInclude(field string, v interface{}) (bool, error) { switch field { @@ -87,7 +87,7 @@ func (n NodeDeviceResource) HashInclude(field string, v interface{}) (bool, erro } } -// HashIncludeMap is used to blacklist uniquely identifying node map keys from being +// HashIncludeMap is used to denylist uniquely identifying node map keys from being // included in the computed node class. func (n NodeDeviceResource) HashIncludeMap(field string, k, v interface{}) (bool, error) { key, ok := k.(string) diff --git a/plugins/drivers/testutils/testing.go b/plugins/drivers/testutils/testing.go index 85152a540f2d..6fab6a36b988 100644 --- a/plugins/drivers/testutils/testing.go +++ b/plugins/drivers/testutils/testing.go @@ -266,7 +266,11 @@ func SetEnvvars(envBuilder *taskenv.Builder, fsi drivers.FSIsolation, taskDir *a // Set the host environment variables for non-image based drivers if fsi != drivers.FSIsolationImage { - filter := strings.Split(conf.ReadDefault("env.blacklist", config.DefaultEnvBlacklist), ",") + // COMPAT(0.13) using inclusive language, blacklist is kept for backward compatibility. + filter := strings.Split(conf.ReadAlternativeDefault( + []string{"env.denylist", "env.blacklist"}, + config.DefaultEnvDenylist, + ), ",") envBuilder.SetHostEnvvars(filter) } }