Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support blacklisting fingerprinters #1949

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ func (c *Client) reservePorts() {
func (c *Client) fingerprint() error {
whitelist := c.config.ReadStringListToMap("fingerprint.whitelist")
whitelistEnabled := len(whitelist) > 0
blacklist := c.config.ReadStringListToMap("fingerprint.blacklist")

c.logger.Printf("[DEBUG] client: built-in fingerprints: %v", fingerprint.BuiltinFingerprints())

var applied []string
Expand All @@ -730,6 +732,11 @@ func (c *Client) fingerprint() error {
skipped = append(skipped, name)
continue
}
// Skip modules that are in the blacklist
if _, ok := blacklist[name]; ok {
skipped = append(skipped, name)
continue
}
f, err := fingerprint.NewFingerprint(name, c.logger)
if err != nil {
return err
Expand All @@ -754,7 +761,7 @@ func (c *Client) fingerprint() error {
}
c.logger.Printf("[DEBUG] client: applied fingerprints %v", applied)
if len(skipped) != 0 {
c.logger.Printf("[DEBUG] client: fingerprint modules skipped due to whitelist: %v", skipped)
c.logger.Printf("[DEBUG] client: fingerprint modules skipped due to white/blacklist: %v", skipped)
}
return nil
}
Expand All @@ -778,9 +785,10 @@ func (c *Client) fingerprintPeriodic(name string, f fingerprint.Fingerprint, d t

// setupDrivers is used to find the available drivers
func (c *Client) setupDrivers() error {
// Build the whitelist of drivers.
// Build the white/blacklists of drivers.
whitelist := c.config.ReadStringListToMap("driver.whitelist")
whitelistEnabled := len(whitelist) > 0
blacklist := c.config.ReadStringListToMap("driver.blacklist")

var avail []string
var skipped []string
Expand All @@ -792,6 +800,11 @@ func (c *Client) setupDrivers() error {
skipped = append(skipped, name)
continue
}
// Skip fingerprinting drivers that are in the blacklist
if _, ok := blacklist[name]; ok {
skipped = append(skipped, name)
continue
}

d, err := driver.NewDriver(name, driverCtx)
if err != nil {
Expand All @@ -817,7 +830,7 @@ func (c *Client) setupDrivers() error {
c.logger.Printf("[DEBUG] client: available drivers %v", avail)

if len(skipped) != 0 {
c.logger.Printf("[DEBUG] client: drivers skipped due to whitelist: %v", skipped)
c.logger.Printf("[DEBUG] client: drivers skipped due to white/blacklist: %v", skipped)
}

return nil
Expand Down
90 changes: 90 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,23 @@ func TestClient_Fingerprint_InWhitelist(t *testing.T) {
}
}

func TestClient_Fingerprint_InBlacklist(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
c.Options = make(map[string]string)
}

// Weird spacing to test trimming. Blacklist cpu.
c.Options["fingerprint.blacklist"] = " cpu "
})
defer c.Shutdown()

node := c.Node()
if node.Attributes["cpu.frequency"] != "" {
t.Fatalf("cpu fingerprint module loaded despite blacklisting")
}
}

func TestClient_Fingerprint_OutOfWhitelist(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
Expand All @@ -232,6 +249,35 @@ func TestClient_Fingerprint_OutOfWhitelist(t *testing.T) {
}
}

func TestClient_Fingerprint_WhitelistBlacklistCombination(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
c.Options = make(map[string]string)
}

// With both white- and blacklist, should return the set difference of modules (arch, cpu)
c.Options["fingerprint.whitelist"] = "arch,memory,cpu"
c.Options["fingerprint.blacklist"] = "memory,nomad"
})
defer c.Shutdown()

node := c.Node()
// Check expected modules are present
if node.Attributes["cpu.frequency"] == "" {
t.Fatalf("missing cpu fingerprint module")
}
if node.Attributes["arch"] == "" {
t.Fatalf("missing arch fingerprint module")
}
// Check remainder _not_ present
if node.Attributes["memory.totalbytes"] != "" {
t.Fatalf("found memory fingerprint module")
}
if node.Attributes["nomad.version"] != "" {
t.Fatalf("found nomad fingerprint module")
}
}

func TestClient_Drivers(t *testing.T) {
c := testClient(t, nil)
defer c.Shutdown()
Expand Down Expand Up @@ -267,6 +313,27 @@ func TestClient_Drivers_InWhitelist(t *testing.T) {
}
}

func TestClient_Drivers_InBlacklist(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
c.Options = make(map[string]string)
}

// Weird spacing to test trimming
c.Options["driver.blacklist"] = " exec , foo "
})
defer c.Shutdown()

node := c.Node()
if node.Attributes["driver.exec"] != "" {
if v, ok := osExecDriverSupport[runtime.GOOS]; !v && ok {
t.Fatalf("exec driver loaded despite blacklist")
} else {
t.Skipf("missing exec driver, no OS support")
}
}
}

func TestClient_Drivers_OutOfWhitelist(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
Expand All @@ -283,6 +350,29 @@ func TestClient_Drivers_OutOfWhitelist(t *testing.T) {
}
}

func TestClient_Drivers_WhitelistBlacklistCombination(t *testing.T) {
c := testClient(t, func(c *config.Config) {
if c.Options == nil {
c.Options = make(map[string]string)
}

// Expected output is set difference (raw_exec)
c.Options["driver.whitelist"] = "raw_exec,exec"
c.Options["driver.blacklist"] = "exec"
})
defer c.Shutdown()

node := c.Node()
// Check expected present
if node.Attributes["driver.raw_exec"] == "" {
t.Fatalf("missing raw_exec driver")
}
// Check expected absent
if node.Attributes["driver.exec"] != "" {
t.Fatalf("exec driver loaded despite blacklist")
}
}

func TestClient_Register(t *testing.T) {
s1, _ := testServer(t, nil)
defer s1.Shutdown()
Expand Down
24 changes: 24 additions & 0 deletions website/source/docs/agent/configuration/client.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ see the [drivers documentation](/docs/drivers/index.html).
}
```

- `"driver.blacklist"` `(string: "")` - Specifies a comma-separated list of
blacklisted drivers . If specified, drivers in the blacklist will be
disabled.

```hcl
client {
options = {
"driver.blacklist" = "docker,qemu"
}
}
```

- `"env.blacklist"` `(string: see below)` - Specifies a comma-separated list of
environment variable keys not to pass to these tasks. Nomad passes the host
environment variables to `exec`, `raw_exec` and `java` tasks. If specified,
Expand Down Expand Up @@ -213,6 +225,18 @@ see the [drivers documentation](/docs/drivers/index.html).
}
```

- `"fingerprint.blacklist"` `(string: "")` - Specifies a comma-separated list of
blacklisted fingerprinters. If specified, any fingerprinters in the blacklist
will be disabled.

```hcl
client {
options = {
"fingerprint.blacklist" = "network"
}
}
```

### `reserved` Parameters

- `cpu` `(int: 0)` - Specifies the amount of CPU to reserve, in MHz.
Expand Down