From c90471d770860bfe0bbd60541672356f6cdb0271 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Thu, 3 Jun 2021 13:47:39 -0500 Subject: [PATCH] consul/connect: use additional constraints in scheduling connect tasks This PR adds two additional constraints on Connect sidecar and gateway tasks, making sure Nomad schedules them only onto nodes where Connect is actually enabled on the Consul agent. Consul requires `connect.enabled = true` and `ports.grpc = ` to be explicitly set on agent configuration before Connect APIs will work. Until now, Nomad would only validate a minimum version of Consul, which would cause confusion for users who try to run Connect tasks on nodes where Consul is not yet sufficiently configured. These contstraints prevent job scheduling on nodes where Connect is not actually use-able. Closes #10700 --- CHANGELOG.md | 1 + nomad/job_endpoint_hook_connect.go | 20 ++++++++++++++++++++ nomad/job_endpoint_hook_connect_test.go | 2 ++ nomad/structs/structs.go | 4 ++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6aa48f588db..fb36264ac425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ IMPROVEMENTS: * cli: Added success confirmation message for `nomad volume delete` and `nomad volume deregister`. [[GH-10591](https://github.com/hashicorp/nomad/issues/10591)] * cli: Cross-namespace `nomad job` commands will now select exact matches if the selection is unambiguous. [[GH-10648](https://github.com/hashicorp/nomad/issues/10648)] * client/fingerprint: Consul fingerprinter probes for additional enterprise and connect related attributes [[GH-10699](https://github.com/hashicorp/nomad/pull/10699)] +* consul/connect: Only schedule connect tasks on nodes where connect is enabled in Consul [[GH-10702](https://github.com/hashicorp/nomad/pull/10702)] * csi: Validate that `volume` blocks for CSI volumes include the required `attachment_mode` and `access_mode` fields. [[GH-10651](https://github.com/hashicorp/nomad/issues/10651)] BUG FIXES: diff --git a/nomad/job_endpoint_hook_connect.go b/nomad/job_endpoint_hook_connect.go index 560a993f863b..9add49fb83f6 100644 --- a/nomad/job_endpoint_hook_connect.go +++ b/nomad/job_endpoint_hook_connect.go @@ -89,6 +89,22 @@ func connectGatewayVersionConstraint() *structs.Constraint { } } +func connectEnabledConstraint() *structs.Constraint { + return &structs.Constraint{ + LTarget: "${attr.consul.connect}", + RTarget: "true", + Operand: "=", + } +} + +func connectListenerConstraint() *structs.Constraint { + return &structs.Constraint{ + LTarget: "${attr.consul.grpc}", + RTarget: "0", + Operand: ">", + } +} + // jobConnectHook implements a job Mutating and Validating admission controller type jobConnectHook struct{} @@ -414,6 +430,8 @@ func newConnectGatewayTask(prefix, service string, netHost bool) *structs.Task { Resources: connectSidecarResources(), Constraints: structs.Constraints{ connectGatewayVersionConstraint(), + connectEnabledConstraint(), + connectListenerConstraint(), }, } } @@ -437,6 +455,8 @@ func newConnectSidecarTask(service string) *structs.Task { }, Constraints: structs.Constraints{ connectSidecarVersionConstraint(), + connectEnabledConstraint(), + connectListenerConstraint(), }, } } diff --git a/nomad/job_endpoint_hook_connect_test.go b/nomad/job_endpoint_hook_connect_test.go index 6d37c238f95c..d5df76a72787 100644 --- a/nomad/job_endpoint_hook_connect_test.go +++ b/nomad/job_endpoint_hook_connect_test.go @@ -197,6 +197,8 @@ func TestJobEndpointConnect_groupConnectHook_IngressGateway_CustomTask(t *testin KillSignal: "SIGHUP", Constraints: structs.Constraints{ connectGatewayVersionConstraint(), + connectEnabledConstraint(), + connectListenerConstraint(), }, }, } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index f44d5136b7f8..bb61726ac571 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -8234,7 +8234,7 @@ const ( ConstraintAttributeIsNotSet = "is_not_set" ) -// Constraints are used to restrict placement options. +// A Constraint is used to restrict placement options. type Constraint struct { LTarget string // Left-hand target RTarget string // Right-hand target @@ -8242,7 +8242,7 @@ type Constraint struct { str string // Memoized string } -// Equal checks if two constraints are equal +// Equals checks if two constraints are equal func (c *Constraint) Equals(o *Constraint) bool { return c == o || c.LTarget == o.LTarget &&