From 19980044839fd56aa91398c71d5b3746eae32bcd Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Tue, 7 Nov 2023 08:37:06 -0500 Subject: [PATCH] move deprecation warning for Vault/Consul token to admission hook (#18995) Submitting a Consul or Vault token with a job is deprecated in Nomad 1.7 and intended for removal in Nomad 1.9. We added a deprecation warning to the CLI when the user passes in the appropriate flag or environment variable in does not use Vault or Consul but happen to have the appropriate environment variable in your environment. While this is generally a bad practice (because the token is leaked to Nomad), it's also the existing practice for some users. Move the warning to the job admission hook. This will allow us to warn only when appropriate, and that will also help the migration process by producing warnings only for the relevant jobs. --- command/job_plan.go | 3 --- command/job_revert.go | 11 --------- command/job_run.go | 6 ----- nomad/job_endpoint_hook_consul_ce.go | 37 ++++++++++++++++++++++++++++ nomad/job_endpoint_hook_vault.go | 12 ++++++--- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/command/job_plan.go b/command/job_plan.go index e6de95552..3fbf346c7 100644 --- a/command/job_plan.go +++ b/command/job_plan.go @@ -227,9 +227,6 @@ func (c *JobPlanCommand) Run(args []string) int { } if vaultToken != "" { - c.Ui.Warn(strings.TrimSpace(` -Warning: setting a Vault token when submitting a job is deprecated and will be -removed in Nomad 1.9. Migrate your Vault configuration to use workload identity.`)) job.VaultToken = pointer.Of(vaultToken) } diff --git a/command/job_revert.go b/command/job_revert.go index 189db7abb..713c06e09 100644 --- a/command/job_revert.go +++ b/command/job_revert.go @@ -132,17 +132,6 @@ func (c *JobRevertCommand) Run(args []string) int { vaultToken = os.Getenv("VAULT_TOKEN") } - if consulToken != "" { - c.Ui.Warn(strings.TrimSpace(` -Warning: setting a Consul token when submitting a job is deprecated and will be -removed in Nomad 1.9. Migrate your Consul configuration to use workload identity.`)) - } - if vaultToken != "" { - c.Ui.Warn(strings.TrimSpace(` -Warning: setting a Vault token when submitting a job is deprecated and will be -removed in Nomad 1.9. Migrate your Vault configuration to use workload identity.`)) - } - // Parse the job version revertVersion, ok, err := parseVersion(args[1]) if !ok { diff --git a/command/job_run.go b/command/job_run.go index 67e121dd9..cd20e95b2 100644 --- a/command/job_run.go +++ b/command/job_run.go @@ -280,9 +280,6 @@ func (c *JobRunCommand) Run(args []string) int { } if consulToken != "" { - c.Ui.Warn(strings.TrimSpace(` -Warning: setting a Consul token when submitting a job is deprecated and will be -removed in Nomad 1.9. Migrate your Consul configuration to use workload identity.`)) job.ConsulToken = pointer.Of(consulToken) } @@ -297,9 +294,6 @@ removed in Nomad 1.9. Migrate your Consul configuration to use workload identity } if vaultToken != "" { - c.Ui.Warn(strings.TrimSpace(` -Warning: setting a Vault token when submitting a job is deprecated and will be -removed in Nomad 1.9. Migrate your Vault configuration to use workload identity.`)) job.VaultToken = pointer.Of(vaultToken) } diff --git a/nomad/job_endpoint_hook_consul_ce.go b/nomad/job_endpoint_hook_consul_ce.go index 711de2096..9607fa084 100644 --- a/nomad/job_endpoint_hook_consul_ce.go +++ b/nomad/job_endpoint_hook_consul_ce.go @@ -14,6 +14,19 @@ import ( func (h jobConsulHook) Validate(job *structs.Job) ([]error, error) { + requiresToken := false + + clusterNeedsToken := func(name string, identity *structs.WorkloadIdentity) bool { + if identity != nil { + return false + } + config := h.srv.config.ConsulConfigs[name] + if config != nil { + return !*config.AllowUnauthenticated + } + return false + } + for _, group := range job.TaskGroups { if group.Consul != nil { if err := h.validateCluster(group.Consul.Cluster); err != nil { @@ -26,6 +39,8 @@ func (h jobConsulHook) Validate(job *structs.Job) ([]error, error) { if err := h.validateCluster(service.Cluster); err != nil { return nil, err } + requiresToken = clusterNeedsToken( + service.Cluster, service.Identity) || requiresToken } } @@ -35,11 +50,33 @@ func (h jobConsulHook) Validate(job *structs.Job) ([]error, error) { if err := h.validateCluster(service.Cluster); err != nil { return nil, err } + requiresToken = clusterNeedsToken( + service.Cluster, service.Identity) || requiresToken } } + + if task.Consul != nil { + if err := h.validateCluster(task.Consul.Cluster); err != nil { + return nil, err + } + var clusterIdentity *structs.WorkloadIdentity + for _, identity := range task.Identities { + if identity.Name == "consul_"+task.Consul.Cluster { + clusterIdentity = identity + break + } + } + requiresToken = clusterNeedsToken( + task.Consul.Cluster, clusterIdentity) || requiresToken + } } } + if requiresToken { + return []error{ + errors.New("Setting a Consul token when submitting a job is deprecated and will be removed in Nomad 1.9. Migrate your Consul configuration to use workload identity")}, nil + } + return nil, nil } diff --git a/nomad/job_endpoint_hook_vault.go b/nomad/job_endpoint_hook_vault.go index 7453db75e..78af2db88 100644 --- a/nomad/job_endpoint_hook_vault.go +++ b/nomad/job_endpoint_hook_vault.go @@ -5,6 +5,7 @@ package nomad import ( "context" + "errors" "fmt" "slices" "strings" @@ -59,24 +60,27 @@ func (h jobVaultHook) Validate(job *structs.Job) ([]error, error) { return nil, fmt.Errorf("Vault used in the job but missing Vault token") } + warnings := []error{ + errors.New("Setting a Vault token when submitting a job is deprecated and will be removed in Nomad 1.9. Migrate your Vault configuration to use workload identity")} + tokenSecret, err := h.srv.vault.LookupToken(context.Background(), job.VaultToken) if err != nil { - return nil, fmt.Errorf("failed to lookup Vault token: %v", err) + return warnings, fmt.Errorf("failed to lookup Vault token: %v", err) } // Check namespaces. err = h.validateNamespaces(vaultBlocks, tokenSecret) if err != nil { - return nil, err + return warnings, err } // Check policies. err = h.validatePolicies(vaultBlocks, tokenSecret) if err != nil { - return nil, err + return warnings, err } - return nil, nil + return warnings, nil } // validatePolicies returns an error if the job contains Vault blocks that