mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
client version constraints for implicit identities for WI (#18932)
Clients prior to Nomad 1.7 cannot support the new workload identity-based authentication to Consul and Vault. Add an implicit Nomad version constraint on job submission for task groups that use the new workflow. Includes a constraint test showing same-version prelease handling.
This commit is contained in:
@@ -19,24 +19,46 @@ func (jobImplicitIdentitiesHook) Name() string {
|
||||
|
||||
func (h jobImplicitIdentitiesHook) Mutate(job *structs.Job) (*structs.Job, []error, error) {
|
||||
for _, tg := range job.TaskGroups {
|
||||
var hasIdentity bool
|
||||
|
||||
for _, s := range tg.Services {
|
||||
h.handleConsulService(s, tg)
|
||||
hasIdentity = hasIdentity || s.Identity != nil
|
||||
}
|
||||
|
||||
for _, t := range tg.Tasks {
|
||||
for _, s := range t.Services {
|
||||
h.handleConsulService(s, tg)
|
||||
hasIdentity = hasIdentity || s.Identity != nil
|
||||
}
|
||||
if len(t.Templates) > 0 {
|
||||
h.handleConsulTasks(t, tg)
|
||||
}
|
||||
h.handleVault(t)
|
||||
hasIdentity = hasIdentity || (len(t.Identities) > 0)
|
||||
}
|
||||
|
||||
if hasIdentity {
|
||||
tg.Constraints = append(tg.Constraints, implicitIdentityClientVersionConstraint())
|
||||
}
|
||||
}
|
||||
|
||||
return job, nil, nil
|
||||
}
|
||||
|
||||
// implicitIdentityClientVersionConstraint is used when the client needs to
|
||||
// support a workload identity workflow for Consul or Vault, or multiple
|
||||
// identities in general.
|
||||
func implicitIdentityClientVersionConstraint() *structs.Constraint {
|
||||
// "-a" is used here so that it is "less than" all pre-release versions of
|
||||
// Nomad 1.7.0 as well
|
||||
return &structs.Constraint{
|
||||
LTarget: "${attr.nomad.version}",
|
||||
RTarget: ">= 1.7.0-a",
|
||||
Operand: structs.ConstraintSemver,
|
||||
}
|
||||
}
|
||||
|
||||
// handleConsulService injects a workload identity to the service if:
|
||||
// 1. The service uses the Consul provider, and
|
||||
// 2. The server is configured with `consul.service_identity`
|
||||
|
||||
@@ -119,6 +119,8 @@ func Test_jobImplicitIdentitiesHook_Mutate_consul_service(t *testing.T) {
|
||||
},
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Services: []*structs.Service{
|
||||
{
|
||||
Provider: "consul",
|
||||
@@ -195,6 +197,8 @@ func Test_jobImplicitIdentitiesHook_Mutate_consul_service(t *testing.T) {
|
||||
},
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Services: []*structs.Service{{
|
||||
Provider: "consul",
|
||||
PortLabel: "80",
|
||||
@@ -245,6 +249,8 @@ func Test_jobImplicitIdentitiesHook_Mutate_consul_service(t *testing.T) {
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Name: "group",
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Tasks: []*structs.Task{{
|
||||
Name: "web-task",
|
||||
Templates: []*structs.Template{{}},
|
||||
@@ -371,6 +377,8 @@ func Test_jobImplicitIndentitiesHook_Mutate_vault(t *testing.T) {
|
||||
},
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Tasks: []*structs.Task{{
|
||||
Identities: []*structs.WorkloadIdentity{{
|
||||
Name: "vault_default",
|
||||
@@ -405,6 +413,8 @@ func Test_jobImplicitIndentitiesHook_Mutate_vault(t *testing.T) {
|
||||
},
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Tasks: []*structs.Task{{
|
||||
Identities: []*structs.WorkloadIdentity{{
|
||||
Name: "vault_default",
|
||||
@@ -444,6 +454,8 @@ func Test_jobImplicitIndentitiesHook_Mutate_vault(t *testing.T) {
|
||||
},
|
||||
expectedOutputJob: &structs.Job{
|
||||
TaskGroups: []*structs.TaskGroup{{
|
||||
Constraints: []*structs.Constraint{
|
||||
implicitIdentityClientVersionConstraint()},
|
||||
Tasks: []*structs.Task{{
|
||||
Identities: []*structs.WorkloadIdentity{{
|
||||
Name: "vault_other",
|
||||
|
||||
@@ -1315,6 +1315,26 @@ func TestCheckSemverConstraint(t *testing.T) {
|
||||
lVal: "1.7.0-alpha1", rVal: ">= 1.6.0-beta1",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "Prereleases of same version handled according to semver",
|
||||
lVal: "1.7.0-beta", rVal: ">= 1.7.0",
|
||||
result: false,
|
||||
},
|
||||
{
|
||||
name: "Prereleases constraints allow GA version according to semver",
|
||||
lVal: "1.7.0", rVal: ">= 1.7.0-dev",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "Prereleases constraints allow beta according to semver",
|
||||
lVal: "1.7.0-beta.1", rVal: ">= 1.7.0-a",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "Prereleases constraints allow RC version according to semver",
|
||||
lVal: "1.7.0-rc.1", rVal: ">= 1.7.0-dev",
|
||||
result: true,
|
||||
},
|
||||
{
|
||||
name: "Meta is ignored according to semver",
|
||||
lVal: "1.3.0-beta1+ent", rVal: "= 1.3.0-beta1",
|
||||
|
||||
Reference in New Issue
Block a user