From a9447addd374109c1ac2fb47f3798898452e5e1b Mon Sep 17 00:00:00 2001 From: Chelsea Holland Komlo Date: Tue, 30 Jan 2018 12:57:37 -0500 Subject: [PATCH] add applicable boolean to fingerprint response public fields and remove getter functions --- client/client.go | 25 +++++---- client/driver/docker.go | 1 + client/driver/docker_test.go | 19 ++++++- client/driver/exec_default.go | 1 + client/driver/exec_linux.go | 1 + client/driver/exec_test.go | 7 ++- client/driver/java.go | 1 + client/driver/java_test.go | 9 ++-- client/driver/lxc.go | 1 + client/driver/lxc_test.go | 7 ++- client/driver/mock_driver.go | 1 + client/driver/qemu.go | 1 + client/driver/qemu_test.go | 11 +++- client/driver/raw_exec.go | 1 + client/driver/raw_exec_test.go | 8 ++- client/driver/rkt.go | 1 + client/driver/rkt_test.go | 9 +++- client/fingerprint/arch.go | 1 + client/fingerprint/arch_test.go | 6 ++- client/fingerprint/cgroup_linux.go | 1 + client/fingerprint/cgroup_test.go | 8 +-- client/fingerprint/consul.go | 10 ++-- client/fingerprint/consul_test.go | 29 ++++++----- client/fingerprint/cpu.go | 7 ++- client/fingerprint/cpu_test.go | 26 ++++++---- client/fingerprint/env_aws.go | 13 ++--- client/fingerprint/env_aws_test.go | 35 +++++++------ client/fingerprint/env_gce.go | 6 ++- client/fingerprint/env_gce_test.go | 55 +++++++++++--------- client/fingerprint/fingerprint_test.go | 15 +++++- client/fingerprint/host.go | 1 + client/fingerprint/host_test.go | 9 ++-- client/fingerprint/memory.go | 6 ++- client/fingerprint/memory_test.go | 11 ++-- client/fingerprint/network.go | 6 ++- client/fingerprint/network_test.go | 59 ++++++++++++++------- client/fingerprint/nomad.go | 1 + client/fingerprint/nomad_test.go | 11 ++-- client/fingerprint/signal.go | 1 + client/fingerprint/signal_test.go | 2 +- client/fingerprint/storage.go | 7 ++- client/fingerprint/storage_test.go | 19 +++---- client/fingerprint/vault.go | 1 + client/fingerprint/vault_test.go | 13 +++-- client/structs/structs.go | 72 ++++++++------------------ 45 files changed, 329 insertions(+), 206 deletions(-) diff --git a/client/client.go b/client/client.go index d8d6516e3801..09e69dc36ec2 100644 --- a/client/client.go +++ b/client/client.go @@ -951,9 +951,6 @@ func (c *Client) fingerprint() error { return err } - // Apply the finerprint to our list so that we can log it later - appliedFingerprints = append(appliedFingerprints, name) - request := &cstructs.FingerprintRequest{Config: c.config, Node: c.config.Node} var response cstructs.FingerprintResponse c.configLock.Lock() @@ -963,6 +960,11 @@ func (c *Client) fingerprint() error { return err } + // log the fingerprinters which have been applied + if response.Applicable { + appliedFingerprints = append(appliedFingerprints, name) + } + // add the diff found from each fingerprinter c.updateNodeFromFingerprint(&response) @@ -1029,10 +1031,6 @@ func (c *Client) setupDrivers() error { continue } - // Add this driver to our list of available drivers so that we can log it - // later - availDrivers = append(availDrivers, name) - d, err := driver.NewDriver(name, driverCtx) if err != nil { return err @@ -1046,6 +1044,11 @@ func (c *Client) setupDrivers() error { } c.configLock.Unlock() + // log the fingerprinters which have been applied + if response.Applicable { + availDrivers = append(availDrivers, name) + } + c.updateNodeFromFingerprint(&response) p, period := d.Periodic() @@ -1068,7 +1071,7 @@ func (c *Client) setupDrivers() error { func (c *Client) updateNodeFromFingerprint(response *cstructs.FingerprintResponse) { c.configLock.Lock() defer c.configLock.Unlock() - for name, val := range response.GetAttributes() { + for name, val := range response.Attributes { if val == "" { delete(c.config.Node.Attributes, name) } else { @@ -1078,7 +1081,7 @@ func (c *Client) updateNodeFromFingerprint(response *cstructs.FingerprintRespons // update node links and resources from the diff created from // fingerprinting - for name, val := range response.GetLinks() { + for name, val := range response.Links { if val == "" { delete(c.config.Node.Links, name) } else { @@ -1086,7 +1089,9 @@ func (c *Client) updateNodeFromFingerprint(response *cstructs.FingerprintRespons } } - c.config.Node.Resources.Merge(response.GetResources()) + if response.Resources != nil { + c.config.Node.Resources.Merge(response.Resources) + } } // retryIntv calculates a retry interval value given the base diff --git a/client/driver/docker.go b/client/driver/docker.go index 7fa709d2e659..887e68aae8fb 100644 --- a/client/driver/docker.go +++ b/client/driver/docker.go @@ -501,6 +501,7 @@ func (d *DockerDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstru resp.AddAttribute(dockerDriverAttr, "1") resp.AddAttribute("driver.docker.version", env.Get("Version")) + resp.Applicable = true privileged := d.config.ReadBoolDefault(dockerPrivilegedConfigOption, false) if privileged { diff --git a/client/driver/docker_test.go b/client/driver/docker_test.go index 844f06d79d02..bfb3d955417d 100644 --- a/client/driver/docker_test.go +++ b/client/driver/docker_test.go @@ -179,13 +179,20 @@ func TestDockerDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + attributes := response.Attributes if testutil.DockerIsConnected(t) && attributes["driver.docker"] == "" { t.Fatalf("Fingerprinter should detect when docker is available") } if attributes["driver.docker"] != "1" { t.Log("Docker daemon not available. The remainder of the docker tests will be skipped.") + } else { + + // if docker is available, make sure that the response is tagged as + // applicable + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } } t.Logf("Found docker version %s", attributes["driver.docker.version"]) @@ -225,7 +232,15 @@ func TestDockerDriver_Fingerprint_Bridge(t *testing.T) { t.Fatalf("error fingerprinting docker: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes + if attributes == nil { + t.Fatalf("expected attributes to be set") + } + if attributes["driver.docker"] == "" { t.Fatalf("expected Docker to be enabled but false was returned") } diff --git a/client/driver/exec_default.go b/client/driver/exec_default.go index 65011c3ddd6a..a0e84e50f5e8 100644 --- a/client/driver/exec_default.go +++ b/client/driver/exec_default.go @@ -9,5 +9,6 @@ import ( func (d *ExecDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { d.fingerprintSuccess = helper.BoolToPtr(false) + resp.Applicable = true return nil } diff --git a/client/driver/exec_linux.go b/client/driver/exec_linux.go index e35c81683724..cca4eb11f234 100644 --- a/client/driver/exec_linux.go +++ b/client/driver/exec_linux.go @@ -35,5 +35,6 @@ func (d *ExecDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstruct } resp.AddAttribute(execDriverAttr, "1") d.fingerprintSuccess = helper.BoolToPtr(true) + resp.Applicable = true return nil } diff --git a/client/driver/exec_test.go b/client/driver/exec_test.go index ca4874dbeda3..1e3414d2b437 100644 --- a/client/driver/exec_test.go +++ b/client/driver/exec_test.go @@ -45,7 +45,12 @@ func TestExecDriver_Fingerprint(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - if response.GetAttributes()["driver.exec"] == "" { + + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if response.Attributes == nil || response.Attributes["driver.exec"] == "" { t.Fatalf("missing driver") } } diff --git a/client/driver/java.go b/client/driver/java.go index d3ee3df17252..296d2699087b 100644 --- a/client/driver/java.go +++ b/client/driver/java.go @@ -170,6 +170,7 @@ func (d *JavaDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstruct resp.AddAttribute("driver.java.runtime", info[1]) resp.AddAttribute("driver.java.vm", info[2]) d.fingerprintSuccess = helper.BoolToPtr(true) + resp.Applicable = true return nil } diff --git a/client/driver/java_test.go b/client/driver/java_test.go index 2c3ac2b2c392..6c952310d53b 100644 --- a/client/driver/java_test.go +++ b/client/driver/java_test.go @@ -58,8 +58,11 @@ func TestJavaDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() - if attributes["driver.java"] != "1" && javaLocated() { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if response.Attributes["driver.java"] != "1" && javaLocated() { if v, ok := osJavaDriverSupport[runtime.GOOS]; v && ok { t.Fatalf("missing java driver") } else { @@ -67,7 +70,7 @@ func TestJavaDriver_Fingerprint(t *testing.T) { } } for _, key := range []string{"driver.java.version", "driver.java.runtime", "driver.java.vm"} { - if attributes[key] == "" { + if response.Attributes[key] == "" { t.Fatalf("missing driver key (%s)", key) } } diff --git a/client/driver/lxc.go b/client/driver/lxc.go index 70700420c27c..763807a6128d 100644 --- a/client/driver/lxc.go +++ b/client/driver/lxc.go @@ -196,6 +196,7 @@ func (d *LxcDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs } resp.AddAttribute("driver.lxc.version", version) resp.AddAttribute("driver.lxc", "1") + resp.Applicable = true // Advertise if this node supports lxc volumes if d.config.ReadBoolDefault(lxcVolumesConfigOption, lxcVolumesConfigDefault) { diff --git a/client/driver/lxc_test.go b/client/driver/lxc_test.go index 5086097f54e0..e1ba19f6ed3e 100644 --- a/client/driver/lxc_test.go +++ b/client/driver/lxc_test.go @@ -59,7 +59,12 @@ func TestLxcDriver_Fingerprint(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - if response.GetAttributes()["driver.lxc"] == "" { + + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if response.Attributes["driver.lxc"] == "" { t.Fatalf("missing driver") } } diff --git a/client/driver/mock_driver.go b/client/driver/mock_driver.go index 065c38d9d0d0..406157e7c318 100644 --- a/client/driver/mock_driver.go +++ b/client/driver/mock_driver.go @@ -229,6 +229,7 @@ func (m *MockDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstruct resp.RemoveAttribute("driver.mock_driver") default: resp.AddAttribute("driver.mock_driver", "1") + resp.Applicable = true } return nil } diff --git a/client/driver/qemu.go b/client/driver/qemu.go index b03c858427a0..9d2b025bb2b5 100644 --- a/client/driver/qemu.go +++ b/client/driver/qemu.go @@ -178,6 +178,7 @@ func (d *QemuDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstruct resp.AddAttribute(qemuDriverAttr, "1") resp.AddAttribute(qemuDriverVersionAttr, currentQemuVersion) + resp.Applicable = true return nil } diff --git a/client/driver/qemu_test.go b/client/driver/qemu_test.go index 3b0cf4e5268e..52fe05acab08 100644 --- a/client/driver/qemu_test.go +++ b/client/driver/qemu_test.go @@ -43,7 +43,14 @@ func TestQemuDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes + if attributes == nil { + t.Fatalf("attributes should not be nil") + } if attributes[qemuDriverAttr] == "" { t.Fatalf("Missing Qemu driver") @@ -176,7 +183,7 @@ func TestQemuDriver_GracefulShutdown(t *testing.T) { t.Fatalf("err: %v", err) } - for name, value := range response.GetAttributes() { + for name, value := range response.Attributes { ctx.DriverCtx.node.Attributes[name] = value } diff --git a/client/driver/raw_exec.go b/client/driver/raw_exec.go index bb11387e1638..f39a25fb4bf6 100644 --- a/client/driver/raw_exec.go +++ b/client/driver/raw_exec.go @@ -98,6 +98,7 @@ func (d *RawExecDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstr if enabled || req.Config.DevMode { d.logger.Printf("[WARN] driver.raw_exec: raw exec is enabled. Only enable if needed") resp.AddAttribute(rawExecDriverAttr, "1") + resp.Applicable = true return nil } diff --git a/client/driver/raw_exec_test.go b/client/driver/raw_exec_test.go index 62021e9cc00d..21d3bccbdd20 100644 --- a/client/driver/raw_exec_test.go +++ b/client/driver/raw_exec_test.go @@ -42,7 +42,7 @@ func TestRawExecDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - if response.GetAttributes()["driver.raw_exec"] != "" { + if response.Attributes["driver.raw_exec"] != "" { t.Fatalf("driver incorrectly enabled") } @@ -53,7 +53,11 @@ func TestRawExecDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - if response.GetAttributes()["driver.raw_exec"] != "1" { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if response.Attributes["driver.raw_exec"] != "1" { t.Fatalf("driver not enabled") } } diff --git a/client/driver/rkt.go b/client/driver/rkt.go index 1ace66bd7d0d..8c5447922c90 100644 --- a/client/driver/rkt.go +++ b/client/driver/rkt.go @@ -354,6 +354,7 @@ func (d *RktDriver) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs resp.AddAttribute(rktDriverAttr, "1") resp.AddAttribute("driver.rkt.version", rktMatches[1]) resp.AddAttribute("driver.rkt.appc.version", appcMatches[1]) + resp.Applicable = true // Advertise if this node supports rkt volumes if d.config.ReadBoolDefault(rktVolumesConfigOption, rktVolumesConfigDefault) { diff --git a/client/driver/rkt_test.go b/client/driver/rkt_test.go index dd2f65699b34..0de3e130fd27 100644 --- a/client/driver/rkt_test.go +++ b/client/driver/rkt_test.go @@ -66,7 +66,14 @@ func TestRktDriver_Fingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes + if attributes == nil { + t.Fatalf("expected attributes to not equal nil") + } if attributes["driver.rkt"] != "1" { t.Fatalf("Missing Rkt driver") } diff --git a/client/fingerprint/arch.go b/client/fingerprint/arch.go index d71c86a8d285..0c6c95ed2fa0 100644 --- a/client/fingerprint/arch.go +++ b/client/fingerprint/arch.go @@ -21,5 +21,6 @@ func NewArchFingerprint(logger *log.Logger) Fingerprint { func (f *ArchFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { resp.AddAttribute("cpu.arch", runtime.GOARCH) + resp.Applicable = true return nil } diff --git a/client/fingerprint/arch_test.go b/client/fingerprint/arch_test.go index 660ff7f0ccb7..8463f803c173 100644 --- a/client/fingerprint/arch_test.go +++ b/client/fingerprint/arch_test.go @@ -21,5 +21,9 @@ func TestArchFingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - assertNodeAttributeContains(t, response.GetAttributes(), "cpu.arch") + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + assertNodeAttributeContains(t, response.Attributes, "cpu.arch") } diff --git a/client/fingerprint/cgroup_linux.go b/client/fingerprint/cgroup_linux.go index a13e17d3b517..19c69b4f8ec6 100644 --- a/client/fingerprint/cgroup_linux.go +++ b/client/fingerprint/cgroup_linux.go @@ -47,6 +47,7 @@ func (f *CGroupFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * } resp.AddAttribute("unique.cgroup.mountpoint", mount) + resp.Applicable = true if f.lastState == cgroupUnavailable { f.logger.Printf("[INFO] fingerprint.cgroups: cgroups are available") diff --git a/client/fingerprint/cgroup_test.go b/client/fingerprint/cgroup_test.go index 93ee44eb9223..2dc1d51ecddc 100644 --- a/client/fingerprint/cgroup_test.go +++ b/client/fingerprint/cgroup_test.go @@ -58,7 +58,7 @@ func TestCGroupFingerprint(t *testing.T) { t.Fatalf("expected an error") } - if a, _ := response.GetAttributes()["unique.cgroup.mountpoint"]; a != "" { + if a, _ := response.Attributes["unique.cgroup.mountpoint"]; a != "" { t.Fatalf("unexpected attribute found, %s", a) } } @@ -80,7 +80,7 @@ func TestCGroupFingerprint(t *testing.T) { if err != nil { t.Fatalf("unexpected error, %s", err) } - if a, ok := response.GetAttributes()["unique.cgroup.mountpoint"]; !ok { + if a, ok := response.Attributes["unique.cgroup.mountpoint"]; !ok { t.Fatalf("unable to find attribute: %s", a) } } @@ -102,7 +102,7 @@ func TestCGroupFingerprint(t *testing.T) { if err != nil { t.Fatalf("unexpected error, %s", err) } - if a, _ := response.GetAttributes()["unique.cgroup.mountpoint"]; a != "" { + if a, _ := response.Attributes["unique.cgroup.mountpoint"]; a != "" { t.Fatalf("unexpected attribute found, %s", a) } } @@ -123,7 +123,7 @@ func TestCGroupFingerprint(t *testing.T) { if err != nil { t.Fatalf("unexpected error, %s", err) } - if a, _ := response.GetAttributes()["unique.cgroup.mountpoint"]; a == "" { + if a, _ := response.Attributes["unique.cgroup.mountpoint"]; a == "" { t.Fatalf("expected attribute to be found, %s", a) } } diff --git a/client/fingerprint/consul.go b/client/fingerprint/consul.go index d4088614c024..35691716779d 100644 --- a/client/fingerprint/consul.go +++ b/client/fingerprint/consul.go @@ -84,11 +84,10 @@ func (f *ConsulFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * f.logger.Printf("[WARN] fingerprint.consul: unable to fingerprint consul.datacenter") } - attributes := resp.GetAttributes() - if attributes["consul.datacenter"] != "" || attributes["unique.consul.name"] != "" { - resp.AddLink("consul", fmt.Sprintf("%s.%s", - attributes["consul.datacenter"], - attributes["unique.consul.name"])) + if dc, ok := resp.Attributes["consul.datacenter"]; ok { + if name, ok2 := resp.Attributes["unique.consul.name"]; ok2 { + resp.AddLink("consul", fmt.Sprintf("%s.%s", dc, name)) + } } else { f.logger.Printf("[WARN] fingerprint.consul: malformed Consul response prevented linking") } @@ -99,6 +98,7 @@ func (f *ConsulFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * f.logger.Printf("[INFO] fingerprint.consul: consul agent is available") } f.lastState = consulAvailable + resp.Applicable = true return nil } diff --git a/client/fingerprint/consul_test.go b/client/fingerprint/consul_test.go index 51df918b6d4d..d97e0d6fa938 100644 --- a/client/fingerprint/consul_test.go +++ b/client/fingerprint/consul_test.go @@ -35,15 +35,17 @@ func TestConsulFingerprint(t *testing.T) { t.Fatalf("Failed to fingerprint: %s", err) } - attributes := response.GetAttributes() - assertNodeAttributeContains(t, attributes, "consul.server") - assertNodeAttributeContains(t, attributes, "consul.version") - assertNodeAttributeContains(t, attributes, "consul.revision") - assertNodeAttributeContains(t, attributes, "unique.consul.name") - assertNodeAttributeContains(t, attributes, "consul.datacenter") - - links := response.GetLinks() - if _, ok := links["consul"]; !ok { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + assertNodeAttributeContains(t, response.Attributes, "consul.server") + assertNodeAttributeContains(t, response.Attributes, "consul.version") + assertNodeAttributeContains(t, response.Attributes, "consul.revision") + assertNodeAttributeContains(t, response.Attributes, "unique.consul.name") + assertNodeAttributeContains(t, response.Attributes, "consul.datacenter") + + if _, ok := response.Links["consul"]; !ok { t.Errorf("Expected a link to consul, none found") } } @@ -187,6 +189,10 @@ func TestConsulFingerprint_UnexpectedResponse(t *testing.T) { err := fp.Fingerprint(request, &response) assert.Nil(err) + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + attrs := []string{ "consul.server", "consul.version", @@ -195,14 +201,13 @@ func TestConsulFingerprint_UnexpectedResponse(t *testing.T) { "consul.datacenter", } - returnedAttrs := response.GetAttributes() for _, attr := range attrs { - if v, ok := returnedAttrs[attr]; ok { + if v, ok := response.Attributes[attr]; ok { t.Errorf("unexpected node attribute %q with vlaue %q", attr, v) } } - if v, ok := node.Links["consul"]; ok { + if v, ok := response.Links["consul"]; ok { t.Errorf("Unexpected link to consul: %v", v) } } diff --git a/client/fingerprint/cpu.go b/client/fingerprint/cpu.go index 23809fc9e83e..8b032e0fd94c 100644 --- a/client/fingerprint/cpu.go +++ b/client/fingerprint/cpu.go @@ -6,6 +6,7 @@ import ( cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/stats" + "github.com/hashicorp/nomad/nomad/structs" ) // CPUFingerprint is used to fingerprint the CPU @@ -23,8 +24,9 @@ func NewCPUFingerprint(logger *log.Logger) Fingerprint { func (f *CPUFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { cfg := req.Config setResourcesCPU := func(totalCompute int) { - resources := resp.GetResources() - resources.CPU = totalCompute + resp.Resources = &structs.Resources{ + CPU: totalCompute, + } } if err := stats.Init(); err != nil { @@ -66,6 +68,7 @@ func (f *CPUFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cst resp.AddAttribute("cpu.totalcompute", fmt.Sprintf("%d", tt)) setResourcesCPU(tt) + resp.Applicable = true return nil } diff --git a/client/fingerprint/cpu_test.go b/client/fingerprint/cpu_test.go index 1081bb9877cf..fc7b7757146b 100644 --- a/client/fingerprint/cpu_test.go +++ b/client/fingerprint/cpu_test.go @@ -21,8 +21,15 @@ func TestCPUFingerprint(t *testing.T) { t.Fatalf("err: %v", err) } + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + // CPU info - attributes := response.GetAttributes() + attributes := response.Attributes + if attributes == nil { + t.Fatalf("expected attributes to be initialized") + } if attributes["cpu.numcores"] == "" { t.Fatalf("Missing Num Cores") } @@ -37,8 +44,7 @@ func TestCPUFingerprint(t *testing.T) { t.Fatalf("Missing CPU Total Compute") } - resources := response.GetResources() - if resources.CPU == 0 { + if response.Resources == nil || response.Resources.CPU == 0 { t.Fatalf("Expected to find CPU Resources") } } @@ -61,12 +67,15 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) { t.Fatalf("err: %v", err) } - resources := response.GetResources() - if resources.CPU == 0 { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if response.Resources.CPU == 0 { t.Fatalf("expected fingerprint of cpu of but found 0") } - originalCPU = resources.CPU + originalCPU = response.Resources.CPU } { @@ -81,9 +90,8 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) { t.Fatalf("err: %v", err) } - resources := response.GetResources() - if resources.CPU != cfg.CpuCompute { - t.Fatalf("expected override cpu of %d but found %d", cfg.CpuCompute, resources.CPU) + if response.Resources.CPU != cfg.CpuCompute { + t.Fatalf("expected override cpu of %d but found %d", cfg.CpuCompute, response.Resources.CPU) } } } diff --git a/client/fingerprint/env_aws.go b/client/fingerprint/env_aws.go index b994d67eba71..a8b572d0fb7c 100644 --- a/client/fingerprint/env_aws.go +++ b/client/fingerprint/env_aws.go @@ -135,7 +135,7 @@ func (f *EnvAWSFingerprint) Fingerprint(request *cstructs.FingerprintRequest, re } // copy over network specific information - if val := response.GetAttributes()["unique.platform.aws.local-ipv4"]; val != "" { + if val, ok := response.Attributes["unique.platform.aws.local-ipv4"]; ok && val != "" { response.AddAttribute("unique.network.ip-address", val) newNetwork.IP = val newNetwork.CIDR = newNetwork.IP + "/32" @@ -165,14 +165,15 @@ func (f *EnvAWSFingerprint) Fingerprint(request *cstructs.FingerprintRequest, re } newNetwork.MBits = throughput - res := response.GetResources() - res.Networks = []*structs.NetworkResource{newNetwork} + response.Resources = &structs.Resources{ + Networks: []*structs.NetworkResource{newNetwork}, + } // populate Links - attributes := response.GetAttributes() response.AddLink("aws.ec2", fmt.Sprintf("%s.%s", - attributes["platform.aws.placement.availability-zone"], - attributes["unique.platform.aws.instance-id"])) + response.Attributes["platform.aws.placement.availability-zone"], + response.Attributes["unique.platform.aws.instance-id"])) + response.Applicable = true return nil } diff --git a/client/fingerprint/env_aws_test.go b/client/fingerprint/env_aws_test.go index 1bf5d28e81ea..df924590f8f1 100644 --- a/client/fingerprint/env_aws_test.go +++ b/client/fingerprint/env_aws_test.go @@ -27,7 +27,7 @@ func TestEnvAWSFingerprint_nonAws(t *testing.T) { t.Fatalf("err: %v", err) } - if len(response.GetAttributes()) > 0 { + if len(response.Attributes) > 0 { t.Fatalf("Should not apply") } } @@ -75,16 +75,16 @@ func TestEnvAWSFingerprint_aws(t *testing.T) { } for _, k := range keys { - assertNodeAttributeContains(t, response.GetAttributes(), k) + assertNodeAttributeContains(t, response.Attributes, k) } - if len(response.GetLinks()) == 0 { + if len(response.Links) == 0 { t.Fatalf("Empty links for Node in AWS Fingerprint test") } // confirm we have at least instance-id and ami-id for _, k := range []string{"aws.ec2"} { - assertNodeLinksContains(t, response.GetLinks(), k) + assertNodeLinksContains(t, response.Links, k) } } @@ -179,15 +179,14 @@ func TestNetworkFingerprint_AWS(t *testing.T) { t.Fatalf("err: %v", err) } - assertNodeAttributeContains(t, response.GetAttributes(), "unique.network.ip-address") + assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") - res := response.GetResources() - if len(res.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := res.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to have an IP") } @@ -230,15 +229,18 @@ func TestNetworkFingerprint_AWS_network(t *testing.T) { t.Fatalf("err: %v", err) } - assertNodeAttributeContains(t, response.GetAttributes(), "unique.network.ip-address") + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") - res := response.GetResources() - if len(res.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := res.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to have an IP") } @@ -270,15 +272,14 @@ func TestNetworkFingerprint_AWS_network(t *testing.T) { t.Fatalf("err: %v", err) } - assertNodeAttributeContains(t, response.GetAttributes(), "unique.network.ip-address") + assertNodeAttributeContains(t, response.Attributes, "unique.network.ip-address") - res := response.GetResources() - if len(res.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := res.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to have an IP") } @@ -308,7 +309,7 @@ func TestNetworkFingerprint_notAWS(t *testing.T) { t.Fatalf("err: %v", err) } - if len(response.GetAttributes()) > 0 { + if len(response.Attributes) > 0 { t.Fatalf("Should not apply") } } diff --git a/client/fingerprint/env_gce.go b/client/fingerprint/env_gce.go index 8352a63d41a9..3e717d13e143 100644 --- a/client/fingerprint/env_gce.go +++ b/client/fingerprint/env_gce.go @@ -257,7 +257,11 @@ func (f *EnvGCEFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * } // populate Links - resp.AddLink("gce", resp.GetAttributes()["unique.platform.gce.id"]) + if id, ok := resp.Attributes["unique.platform.gce.id"]; ok { + resp.AddLink("gce", id) + } + + resp.Applicable = true return nil } diff --git a/client/fingerprint/env_gce_test.go b/client/fingerprint/env_gce_test.go index 49d693b72f07..9ccd736cd560 100644 --- a/client/fingerprint/env_gce_test.go +++ b/client/fingerprint/env_gce_test.go @@ -27,7 +27,11 @@ func TestGCEFingerprint_nonGCE(t *testing.T) { t.Fatalf("err: %v", err) } - if len(response.GetAttributes()) > 0 { + if response.Applicable { + t.Fatalf("expected response to not be applicable") + } + + if len(response.Attributes) > 0 { t.Fatalf("Should have zero attributes without test server") } } @@ -86,6 +90,10 @@ func testFingerprint_GCE(t *testing.T, withExternalIp bool) { t.Fatalf("err: %v", err) } + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + keys := []string{ "unique.platform.gce.id", "unique.platform.gce.hostname", @@ -100,44 +108,41 @@ func testFingerprint_GCE(t *testing.T, withExternalIp bool) { "unique.platform.gce.attr.bar", } - attributes := response.GetAttributes() - links := response.GetLinks() - for _, k := range keys { - assertNodeAttributeContains(t, attributes, k) + assertNodeAttributeContains(t, response.Attributes, k) } - if len(links) == 0 { + if len(response.Links) == 0 { t.Fatalf("Empty links for Node in GCE Fingerprint test") } // Make sure Links contains the GCE ID. for _, k := range []string{"gce"} { - assertNodeLinksContains(t, links, k) + assertNodeLinksContains(t, response.Links, k) } - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.id", "12345") - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.hostname", "instance-1.c.project.internal") - assertNodeAttributeEquals(t, attributes, "platform.gce.zone", "us-central1-f") - assertNodeAttributeEquals(t, attributes, "platform.gce.machine-type", "n1-standard-1") - assertNodeAttributeEquals(t, attributes, "platform.gce.network.default", "true") - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.network.default.ip", "10.240.0.5") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.id", "12345") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.hostname", "instance-1.c.project.internal") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.zone", "us-central1-f") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.machine-type", "n1-standard-1") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.network.default", "true") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.network.default.ip", "10.240.0.5") if withExternalIp { - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.network.default.external-ip.0", "104.44.55.66") - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.network.default.external-ip.1", "104.44.55.67") - } else if _, ok := attributes["unique.platform.gce.network.default.external-ip.0"]; ok { + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.network.default.external-ip.0", "104.44.55.66") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.network.default.external-ip.1", "104.44.55.67") + } else if _, ok := response.Attributes["unique.platform.gce.network.default.external-ip.0"]; ok { t.Fatal("unique.platform.gce.network.default.external-ip is set without an external IP") } - assertNodeAttributeEquals(t, attributes, "platform.gce.scheduling.automatic-restart", "TRUE") - assertNodeAttributeEquals(t, attributes, "platform.gce.scheduling.on-host-maintenance", "MIGRATE") - assertNodeAttributeEquals(t, attributes, "platform.gce.cpu-platform", "Intel Ivy Bridge") - assertNodeAttributeEquals(t, attributes, "platform.gce.tag.abc", "true") - assertNodeAttributeEquals(t, attributes, "platform.gce.tag.def", "true") - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.tag.foo", "true") - assertNodeAttributeEquals(t, attributes, "platform.gce.attr.ghi", "111") - assertNodeAttributeEquals(t, attributes, "platform.gce.attr.jkl", "222") - assertNodeAttributeEquals(t, attributes, "unique.platform.gce.attr.bar", "333") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.scheduling.automatic-restart", "TRUE") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.scheduling.on-host-maintenance", "MIGRATE") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.cpu-platform", "Intel Ivy Bridge") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.tag.abc", "true") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.tag.def", "true") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.tag.foo", "true") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.attr.ghi", "111") + assertNodeAttributeEquals(t, response.Attributes, "platform.gce.attr.jkl", "222") + assertNodeAttributeEquals(t, response.Attributes, "unique.platform.gce.attr.bar", "333") } const GCE_routes = ` diff --git a/client/fingerprint/fingerprint_test.go b/client/fingerprint/fingerprint_test.go index 9e3dab5443ba..41a7e6549a54 100644 --- a/client/fingerprint/fingerprint_test.go +++ b/client/fingerprint/fingerprint_test.go @@ -24,7 +24,7 @@ func assertFingerprintOK(t *testing.T, fp Fingerprint, node *structs.Node) *cstr t.Fatalf("Failed to fingerprint: %s", err) } - if len(response.GetAttributes()) == 0 { + if len(response.Attributes) == 0 { t.Fatalf("Failed to apply node attributes") } @@ -32,6 +32,11 @@ func assertFingerprintOK(t *testing.T, fp Fingerprint, node *structs.Node) *cstr } func assertNodeAttributeContains(t *testing.T, nodeAttributes map[string]string, attribute string) { + if nodeAttributes == nil { + t.Errorf("expected an initialized map for node attributes") + return + } + actual, found := nodeAttributes[attribute] if !found { t.Errorf("Expected to find Attribute `%s`\n\n[DEBUG] %#v", attribute, nodeAttributes) @@ -43,6 +48,10 @@ func assertNodeAttributeContains(t *testing.T, nodeAttributes map[string]string, } func assertNodeAttributeEquals(t *testing.T, nodeAttributes map[string]string, attribute string, expected string) { + if nodeAttributes == nil { + t.Errorf("expected an initialized map for node attributes") + return + } actual, found := nodeAttributes[attribute] if !found { t.Errorf("Expected to find Attribute `%s`; unable to check value\n\n[DEBUG] %#v", attribute, nodeAttributes) @@ -54,6 +63,10 @@ func assertNodeAttributeEquals(t *testing.T, nodeAttributes map[string]string, a } func assertNodeLinksContains(t *testing.T, nodeLinks map[string]string, link string) { + if nodeLinks == nil { + t.Errorf("expected an initialized map for node links") + return + } actual, found := nodeLinks[link] if !found { t.Errorf("Expected to find Link `%s`\n\n[DEBUG]", link) diff --git a/client/fingerprint/host.go b/client/fingerprint/host.go index 1273e89f8999..0bc34a474326 100644 --- a/client/fingerprint/host.go +++ b/client/fingerprint/host.go @@ -34,6 +34,7 @@ func (f *HostFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cs resp.AddAttribute("kernel.version", hostInfo.KernelVersion) resp.AddAttribute("unique.hostname", hostInfo.Hostname) + resp.Applicable = true return nil } diff --git a/client/fingerprint/host_test.go b/client/fingerprint/host_test.go index 433f40c6a765..5dba118c5081 100644 --- a/client/fingerprint/host_test.go +++ b/client/fingerprint/host_test.go @@ -21,13 +21,16 @@ func TestHostFingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() - if len(attributes) == 0 { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if len(response.Attributes) == 0 { t.Fatalf("should generate a diff of node attributes") } // Host info for _, key := range []string{"os.name", "os.version", "unique.hostname", "kernel.name"} { - assertNodeAttributeContains(t, attributes, key) + assertNodeAttributeContains(t, response.Attributes, key) } } diff --git a/client/fingerprint/memory.go b/client/fingerprint/memory.go index 473b624f42ef..c24937a43002 100644 --- a/client/fingerprint/memory.go +++ b/client/fingerprint/memory.go @@ -5,6 +5,7 @@ import ( "log" cstructs "github.com/hashicorp/nomad/client/structs" + "github.com/hashicorp/nomad/nomad/structs" "github.com/shirou/gopsutil/mem" ) @@ -32,8 +33,9 @@ func (f *MemoryFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * if memInfo.Total > 0 { resp.AddAttribute("memory.totalbytes", fmt.Sprintf("%d", memInfo.Total)) - res := resp.GetResources() - res.MemoryMB = int(memInfo.Total / 1024 / 1024) + resp.Resources = &structs.Resources{ + MemoryMB: int(memInfo.Total / 1024 / 1024), + } } return nil diff --git a/client/fingerprint/memory_test.go b/client/fingerprint/memory_test.go index 190c6f126f11..1b2cebb5bb84 100644 --- a/client/fingerprint/memory_test.go +++ b/client/fingerprint/memory_test.go @@ -21,11 +21,12 @@ func TestMemoryFingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - assertNodeAttributeContains(t, response.GetAttributes(), "memory.totalbytes") + assertNodeAttributeContains(t, response.Attributes, "memory.totalbytes") - res := response.GetResources() - if res.MemoryMB == 0 { - t.Errorf("Expected node.Resources.MemoryMB to be non-zero") + if response.Resources == nil { + t.Fatalf("response resources should not be nil") + } + if response.Resources.MemoryMB == 0 { + t.Fatalf("Expected node.Resources.MemoryMB to be non-zero") } - } diff --git a/client/fingerprint/network.go b/client/fingerprint/network.go index d9c59225650f..22ea9bcb58bf 100644 --- a/client/fingerprint/network.go +++ b/client/fingerprint/network.go @@ -95,8 +95,9 @@ func (f *NetworkFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp return err } - res := resp.GetResources() - res.Networks = nwResources + resp.Resources = &structs.Resources{ + Networks: nwResources, + } for _, nwResource := range nwResources { f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP: %v", intf.Name, nwResource.IP) } @@ -105,6 +106,7 @@ func (f *NetworkFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp if len(nwResources) > 0 { resp.AddAttribute("unique.network.ip-address", nwResources[0].IP) } + resp.Applicable = true return nil } diff --git a/client/fingerprint/network_test.go b/client/fingerprint/network_test.go index eff2e119a00a..606cfd741977 100644 --- a/client/fingerprint/network_test.go +++ b/client/fingerprint/network_test.go @@ -197,7 +197,11 @@ func TestNetworkFingerprint_basic(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes if len(attributes) == 0 { t.Fatalf("should apply (HINT: working offline? Set env %q=y", skipOnlineTestsEnvVar) } @@ -210,13 +214,12 @@ func TestNetworkFingerprint_basic(t *testing.T) { t.Fatalf("Bad IP match: %s", ip) } - resources := response.GetResources() - if resources == nil || len(resources.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := resources.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to not be empty") } @@ -245,8 +248,12 @@ func TestNetworkFingerprint_default_device_absent(t *testing.T) { t.Fatalf("err: %v", err) } - if len(response.GetAttributes()) != 0 { - t.Fatalf("attributes should be zero but instead are: %v", response.GetAttributes()) + if response.Applicable { + t.Fatalf("expected response to not be applicable") + } + + if len(response.Attributes) != 0 { + t.Fatalf("attributes should be zero but instead are: %v", response.Attributes) } } @@ -264,7 +271,11 @@ func TestNetworkFingerPrint_default_device(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes if len(attributes) == 0 { t.Fatalf("should apply") } @@ -277,13 +288,12 @@ func TestNetworkFingerPrint_default_device(t *testing.T) { t.Fatalf("Bad IP match: %s", ip) } - resources := response.GetResources() - if len(resources.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := resources.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to not be empty") } @@ -312,7 +322,11 @@ func TestNetworkFingerPrint_LinkLocal_Allowed(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes assertNodeAttributeContains(t, attributes, "unique.network.ip-address") ip := attributes["unique.network.ip-address"] @@ -321,13 +335,12 @@ func TestNetworkFingerPrint_LinkLocal_Allowed(t *testing.T) { t.Fatalf("Bad IP match: %s", ip) } - resources := response.GetResources() - if resources == nil || len(resources.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := resources.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to not be empty") } @@ -356,7 +369,11 @@ func TestNetworkFingerPrint_LinkLocal_Allowed_MixedIntf(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + attributes := response.Attributes if len(attributes) == 0 { t.Fatalf("should apply attributes") } @@ -369,13 +386,12 @@ func TestNetworkFingerPrint_LinkLocal_Allowed_MixedIntf(t *testing.T) { t.Fatalf("Bad IP match: %s", ip) } - resources := response.GetResources() - if resources == nil || len(resources.Networks) == 0 { + if response.Resources == nil || len(response.Resources.Networks) == 0 { t.Fatal("Expected to find Network Resources") } // Test at least the first Network Resource - net := resources.Networks[0] + net := response.Resources.Networks[0] if net.IP == "" { t.Fatal("Expected Network Resource to not be empty") } @@ -412,7 +428,12 @@ func TestNetworkFingerPrint_LinkLocal_Disallowed(t *testing.T) { if err != nil { t.Fatalf("err: %v", err) } - if len(response.GetAttributes()) != 0 { + + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if len(response.Attributes) != 0 { t.Fatalf("should not apply attributes") } } diff --git a/client/fingerprint/nomad.go b/client/fingerprint/nomad.go index 32c5913bf9c1..3b30f9e75a49 100644 --- a/client/fingerprint/nomad.go +++ b/client/fingerprint/nomad.go @@ -21,5 +21,6 @@ func NewNomadFingerprint(logger *log.Logger) Fingerprint { func (f *NomadFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { resp.AddAttribute("nomad.version", req.Config.Version.VersionNumber()) resp.AddAttribute("nomad.revision", req.Config.Version.Revision) + resp.Applicable = true return nil } diff --git a/client/fingerprint/nomad_test.go b/client/fingerprint/nomad_test.go index 3daa97d4726d..bdab1b9e90ec 100644 --- a/client/fingerprint/nomad_test.go +++ b/client/fingerprint/nomad_test.go @@ -30,16 +30,19 @@ func TestNomadFingerprint(t *testing.T) { t.Fatalf("err: %v", err) } - attributes := response.GetAttributes() - if len(attributes) == 0 { + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + if len(response.Attributes) == 0 { t.Fatalf("should apply") } - if attributes["nomad.version"] != v { + if response.Attributes["nomad.version"] != v { t.Fatalf("incorrect version") } - if attributes["nomad.revision"] != r { + if response.Attributes["nomad.revision"] != r { t.Fatalf("incorrect revision") } } diff --git a/client/fingerprint/signal.go b/client/fingerprint/signal.go index dbf0669f28cf..139f4c3fb1fd 100644 --- a/client/fingerprint/signal.go +++ b/client/fingerprint/signal.go @@ -28,5 +28,6 @@ func (f *SignalFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * } resp.AddAttribute("os.signals", strings.Join(sigs, ",")) + resp.Applicable = true return nil } diff --git a/client/fingerprint/signal_test.go b/client/fingerprint/signal_test.go index 6d05456f73a5..bf61f754408f 100644 --- a/client/fingerprint/signal_test.go +++ b/client/fingerprint/signal_test.go @@ -13,5 +13,5 @@ func TestSignalFingerprint(t *testing.T) { } response := assertFingerprintOK(t, fp, node) - assertNodeAttributeContains(t, response.GetAttributes(), "os.signals") + assertNodeAttributeContains(t, response.Attributes, "os.signals") } diff --git a/client/fingerprint/storage.go b/client/fingerprint/storage.go index 96332531651c..7ec43104debc 100644 --- a/client/fingerprint/storage.go +++ b/client/fingerprint/storage.go @@ -7,6 +7,7 @@ import ( "strconv" cstructs "github.com/hashicorp/nomad/client/structs" + "github.com/hashicorp/nomad/nomad/structs" ) const bytesPerMegabyte = 1024 * 1024 @@ -46,8 +47,10 @@ func (f *StorageFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp resp.AddAttribute("unique.storage.bytesfree", strconv.FormatUint(free, 10)) // set the disk size for the response - res := resp.GetResources() - res.DiskMB = int(free / bytesPerMegabyte) + resp.Resources = &structs.Resources{ + DiskMB: int(free / bytesPerMegabyte), + } + resp.Applicable = true return nil } diff --git a/client/fingerprint/storage_test.go b/client/fingerprint/storage_test.go index 8d26a6bcb416..86b15cecb8b5 100644 --- a/client/fingerprint/storage_test.go +++ b/client/fingerprint/storage_test.go @@ -15,17 +15,19 @@ func TestStorageFingerprint(t *testing.T) { response := assertFingerprintOK(t, fp, node) - attributes := response.GetAttributes() + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } - assertNodeAttributeContains(t, attributes, "unique.storage.volume") - assertNodeAttributeContains(t, attributes, "unique.storage.bytestotal") - assertNodeAttributeContains(t, attributes, "unique.storage.bytesfree") + assertNodeAttributeContains(t, response.Attributes, "unique.storage.volume") + assertNodeAttributeContains(t, response.Attributes, "unique.storage.bytestotal") + assertNodeAttributeContains(t, response.Attributes, "unique.storage.bytesfree") - total, err := strconv.ParseInt(attributes["unique.storage.bytestotal"], 10, 64) + total, err := strconv.ParseInt(response.Attributes["unique.storage.bytestotal"], 10, 64) if err != nil { t.Fatalf("Failed to parse unique.storage.bytestotal: %s", err) } - free, err := strconv.ParseInt(attributes["unique.storage.bytesfree"], 10, 64) + free, err := strconv.ParseInt(response.Attributes["unique.storage.bytesfree"], 10, 64) if err != nil { t.Fatalf("Failed to parse unique.storage.bytesfree: %s", err) } @@ -34,11 +36,10 @@ func TestStorageFingerprint(t *testing.T) { t.Fatalf("unique.storage.bytesfree %d is larger than unique.storage.bytestotal %d", free, total) } - resources := response.GetResources() - if resources == nil { + if response.Resources == nil { t.Fatalf("Node Resources was nil") } - if resources.DiskMB == 0 { + if response.Resources.DiskMB == 0 { t.Errorf("Expected node.Resources.DiskMB to be non-zero") } } diff --git a/client/fingerprint/vault.go b/client/fingerprint/vault.go index 04d8e1eba97e..b7cee695ff01 100644 --- a/client/fingerprint/vault.go +++ b/client/fingerprint/vault.go @@ -74,6 +74,7 @@ func (f *VaultFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *c f.logger.Printf("[INFO] fingerprint.vault: Vault is available") } f.lastState = vaultAvailable + resp.Applicable = true return nil } diff --git a/client/fingerprint/vault_test.go b/client/fingerprint/vault_test.go index f036e280e94b..76eb347e1b5d 100644 --- a/client/fingerprint/vault_test.go +++ b/client/fingerprint/vault_test.go @@ -28,9 +28,12 @@ func TestVaultFingerprint(t *testing.T) { t.Fatalf("Failed to fingerprint: %s", err) } - attributes := response.GetAttributes() - assertNodeAttributeContains(t, attributes, "vault.accessible") - assertNodeAttributeContains(t, attributes, "vault.version") - assertNodeAttributeContains(t, attributes, "vault.cluster_id") - assertNodeAttributeContains(t, attributes, "vault.cluster_name") + if !response.Applicable { + t.Fatalf("expected response to be applicable") + } + + assertNodeAttributeContains(t, response.Attributes, "vault.accessible") + assertNodeAttributeContains(t, response.Attributes, "vault.version") + assertNodeAttributeContains(t, response.Attributes, "vault.cluster_id") + assertNodeAttributeContains(t, response.Attributes, "vault.cluster_name") } diff --git a/client/structs/structs.go b/client/structs/structs.go index 9d21b436260c..98980da796cc 100644 --- a/client/structs/structs.go +++ b/client/structs/structs.go @@ -194,80 +194,54 @@ type FingerprintRequest struct { } type FingerprintResponse struct { - attributes map[string]string - links map[string]string - resources *structs.Resources + Attributes map[string]string + Links map[string]string + Resources *structs.Resources + + // Applicable is a boolean indicating whether the fingerprint should be + // applied + Applicable bool } // AddAttribute adds the name and value for a node attribute to the fingerprint // response func (f *FingerprintResponse) AddAttribute(name, value string) { - // initialize attributes if it has not been already - if f.attributes == nil { - f.attributes = make(map[string]string, 0) + // initialize Attributes if it has not been already + if f.Attributes == nil { + f.Attributes = make(map[string]string, 0) } - f.attributes[name] = value + f.Attributes[name] = value } // RemoveAttribute sets the given attribute to empty, which will later remove // it entirely from the node func (f *FingerprintResponse) RemoveAttribute(name string) { - // initialize attributes if it has not been already - if f.attributes == nil { - f.attributes = make(map[string]string, 0) + // initialize Attributes if it has not been already + if f.Attributes == nil { + f.Attributes = make(map[string]string, 0) } - f.attributes[name] = "" -} - -// GetAttributes fetches the attributes for the fingerprint response -func (f *FingerprintResponse) GetAttributes() map[string]string { - // initialize attributes if it has not been already - if f.attributes == nil { - f.attributes = make(map[string]string, 0) - } - - return f.attributes + f.Attributes[name] = "" } // AddLink adds a link entry to the fingerprint response func (f *FingerprintResponse) AddLink(name, value string) { - // initialize links if it has not been already - if f.links == nil { - f.links = make(map[string]string, 0) + // initialize Links if it has not been already + if f.Links == nil { + f.Links = make(map[string]string, 0) } - f.links[name] = value + f.Links[name] = value } // RemoveLink removes a link entry from the fingerprint response. This will // later remove it entirely from the node func (f *FingerprintResponse) RemoveLink(name string) { - // initialize links if it has not been already - if f.links == nil { - f.links = make(map[string]string, 0) - } - - f.links[name] = "" -} - -// GetLinks returns the links for the fingerprint response -func (f *FingerprintResponse) GetLinks() map[string]string { - // initialize links if it has not been already - if f.links == nil { - f.links = make(map[string]string, 0) - } - - return f.links -} - -// GetResources returns the resources for a fingerprint response -func (f *FingerprintResponse) GetResources() *structs.Resources { - // initialize resourcesif it has not been already - if f.resources == nil { - f.resources = &structs.Resources{} + // initialize Links if it has not been already + if f.Links == nil { + f.Links = make(map[string]string, 0) } - return f.resources + f.Links[name] = "" }