consul: only add fingerprint link if unique.consul.name is set (#26787)

In Nomad Enterprise we can fingerprint multiple Consul datacenters. If neither
is `"default"` then we end up with warning logs about adding a "link".

The `Link` field on the `Node` struct is a map of attributes that only
contributes to the node's computed hash. The `"consul"` key's value is derived
from the `unique.consul.name` attribute, which only exists if there's a default
Consul cluster.

Update the fingerprint to skip setting the link field if there's no
`unique.consul.name`, and lower the warning log for malformed fields to debug;
this is a minor scheduling optimization largely captured by existing Consul
fields in the node computed class. The only reason not to remove it entirely is
to avoid changing computed classes on existing large clusters.

Fixes: https://github.com/hashicorp/nomad/issues/26781
Ref: https://hashicorp.atlassian.net/browse/NMD-998
This commit is contained in:
Tim Gross
2025-09-17 13:23:01 -04:00
committed by GitHub
parent 6dce21bc85
commit 3432b0a2d6
3 changed files with 10 additions and 5 deletions

3
.changelog/26787.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
consul (Enterprise): Fixed a bug where Consul fingerprinting would generate warning logs if there was no default cluster
```

View File

@@ -242,12 +242,12 @@ func (cfs *consulState) query(logger hclog.Logger) agentconsul.Self {
}
func (f *ConsulFingerprint) link(resp *FingerprintResponse) {
if uniqueName, ok := resp.Attributes["unique.consul.name"]; ok {
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))
}
resp.AddLink("consul", fmt.Sprintf("%s.%s", dc, uniqueName))
} else {
f.logger.Warn("malformed Consul response prevented linking")
f.logger.Debug("malformed Consul response prevented adding link")
}
}
}

View File

@@ -620,6 +620,7 @@ func TestConsulFingerprint_Fingerprint_oss(t *testing.T) {
"unique.consul.name": "HAL9000",
}, resp.Attributes)
must.True(t, resp.Detected)
must.Eq(t, "dc1.HAL9000", resp.Links["consul"])
// consul now available
must.NotNil(t, cf.clusters[structs.ConsulDefaultCluster])
@@ -711,6 +712,7 @@ func TestConsulFingerprint_Fingerprint_ent(t *testing.T) {
"unique.consul.name": "HAL9000",
}, resp.Attributes)
must.True(t, resp.Detected)
must.Eq(t, "dc1.HAL9000", resp.Links["consul"])
// consul now available
must.NotNil(t, cf.clusters[structs.ConsulDefaultCluster])