Skip to content

Commit

Permalink
consul: fingerprint Consul Enterprise admin partitions
Browse files Browse the repository at this point in the history
Consul Enterprise agents all belong to an admin partition. Fingerprint this
attribute when available. When a Consul agent is not explicitly configured with
"default" it is in the default partition but will not report this in its
`/v1/agent/self` endpoint. Fallback to "default" when missing only for Consul
Enterprise.

This feature provides users the ability to add constraints for jobs to land on
Nomad nodes that have a Consul in that partition. Or it can allow cluster
administrators to pair Consul partitions 1:1 with Nomad node pools. We'll also
have the option to implement a future `partition` field in the jobspec's
`consul` block to create an implicit constraint.

Ref: #13139 (comment)
  • Loading branch information
tgross committed Dec 14, 2023
1 parent 0e42569 commit d69b713
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/19485.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
consul: Add fingerprint for Consul Enterprise admin partitions
```
14 changes: 14 additions & 0 deletions client/fingerprint/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ func (cfs *consulFingerprintState) initialize(cfg *config.ConsulConfig, logger h
"consul.connect": cfs.connect,
"consul.grpc": cfs.grpc(consulConfig.Scheme, logger),
"consul.ft.namespaces": cfs.namespaces,
"consul.partition": cfs.partition,
}
} else {
cfs.extractors = map[string]consulExtractor{
Expand All @@ -176,6 +177,7 @@ func (cfs *consulFingerprintState) initialize(cfg *config.ConsulConfig, logger h
fmt.Sprintf("consul.%s.connect", cfg.Name): cfs.connect,
fmt.Sprintf("consul.%s.grpc", cfg.Name): cfs.grpc(consulConfig.Scheme, logger),
fmt.Sprintf("consul.%s.ft.namespaces", cfg.Name): cfs.namespaces,
fmt.Sprintf("consul.%s.partition", cfg.Name): cfs.partition,
}
}

Expand Down Expand Up @@ -299,3 +301,15 @@ func (cfs *consulFingerprintState) grpcTLSPort(info agentconsul.Self) (string, b
func (cfs *consulFingerprintState) namespaces(info agentconsul.Self) (string, bool) {
return strconv.FormatBool(agentconsul.Namespaces(info)), true
}

func (cfs *consulFingerprintState) partition(info agentconsul.Self) (string, bool) {
sku, ok := agentconsul.SKU(info)
if ok && sku == "ent" {
p, ok := info["Config"]["Partition"].(string)
if !ok {
p = "default"
}
return p, true
}
return "", false
}
48 changes: 48 additions & 0 deletions client/fingerprint/consul_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,52 @@ func TestConsulFingerprint_namespaces(t *testing.T) {
})
}

func TestConsulFingerprint_partition(t *testing.T) {
ci.Parallel(t)

cfs := consulFingerprintState{}

t.Run("oss", func(t *testing.T) {
p, ok := cfs.partition(agentconsul.Self{
"Config": {"Version": "v1.9.5"},
})
must.False(t, ok)
must.Eq(t, "", p)
})

t.Run("ent default partition", func(t *testing.T) {
p, ok := cfs.partition(agentconsul.Self{
"Config": {"Version": "v1.9.5+ent"},
})
must.True(t, ok)
must.Eq(t, "default", p)
})

t.Run("ent nondefault partition", func(t *testing.T) {
p, ok := cfs.partition(agentconsul.Self{
"Config": {"Version": "v1.9.5+ent", "Partition": "test"},
})
must.True(t, ok)
must.Eq(t, "test", p)
})

t.Run("missing", func(t *testing.T) {
p, ok := cfs.partition(agentconsul.Self{
"Config": {},
})
must.False(t, ok)
must.Eq(t, "", p)
})

t.Run("malformed", func(t *testing.T) {
p, ok := cfs.partition(agentconsul.Self{
"Config": {"Version": "***"},
})
must.False(t, ok)
must.Eq(t, "", p)
})
}

func TestConsulFingerprint_Fingerprint_oss(t *testing.T) {
ci.Parallel(t)

Expand Down Expand Up @@ -554,6 +600,7 @@ func TestConsulFingerprint_Fingerprint_ent(t *testing.T) {
"consul.ft.namespaces": "true",
"consul.connect": "true",
"consul.grpc": "8502",
"consul.partition": "default",
"unique.consul.name": "HAL9000",
}, resp.Attributes)
must.True(t, resp.Detected)
Expand Down Expand Up @@ -602,6 +649,7 @@ func TestConsulFingerprint_Fingerprint_ent(t *testing.T) {
"consul.ft.namespaces": "true",
"consul.connect": "true",
"consul.grpc": "8502",
"consul.partition": "default",
"unique.consul.name": "HAL9000",
}, resp3.Attributes)

Expand Down

0 comments on commit d69b713

Please sign in to comment.