Skip to content

Commit

Permalink
Merge pull request #5556 from hashicorp/nmd-1403-vault-namespace-task…
Browse files Browse the repository at this point in the history
…-env

vault namespaces: inject VAULT_NAMESPACE alongside VAULT_TOKEN
  • Loading branch information
Chris Baker committed Apr 12, 2019
2 parents 176b48c + 377c1d6 commit 7a6a2d3
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 9 deletions.
2 changes: 1 addition & 1 deletion client/allocrunner/taskrunner/task_runner_getters.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (tr *TaskRunner) setVaultToken(token string) {
tr.vaultToken = token

// Update the task's environment
tr.envBuilder.SetVaultToken(token, tr.task.Vault.Env)
tr.envBuilder.SetVaultToken(token, tr.clientConfig.VaultConfig.Namespace, tr.task.Vault.Env)
}

// getDriverHandle returns a driver handle.
Expand Down
12 changes: 11 additions & 1 deletion client/taskenv/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ const (

// VaultToken is the environment variable for passing the Vault token
VaultToken = "VAULT_TOKEN"

// VaultNamespace is the environment variable for passing the Vault namespace, if applicable
VaultNamespace = "VAULT_NAMESPACE"
)

// The node values that can be interpreted.
Expand Down Expand Up @@ -305,6 +308,7 @@ type Builder struct {
allocName string
groupName string
vaultToken string
vaultNamespace string
injectVaultToken bool
jobName string

Expand Down Expand Up @@ -423,6 +427,11 @@ func (b *Builder) Build() *TaskEnv {
envMap[VaultToken] = b.vaultToken
}

// Build the Vault Namespace
if b.injectVaultToken && b.vaultNamespace != "" {
envMap[VaultNamespace] = b.vaultNamespace
}

// Copy task meta
for k, v := range b.taskMeta {
envMap[k] = v
Expand Down Expand Up @@ -753,9 +762,10 @@ func (b *Builder) SetTemplateEnv(m map[string]string) *Builder {
return b
}

func (b *Builder) SetVaultToken(token string, inject bool) *Builder {
func (b *Builder) SetVaultToken(token, namespace string, inject bool) *Builder {
b.mu.Lock()
b.vaultToken = token
b.vaultNamespace = namespace
b.injectVaultToken = inject
b.mu.Unlock()
return b
Expand Down
37 changes: 34 additions & 3 deletions client/taskenv/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,28 +468,59 @@ func TestEnvironment_VaultToken(t *testing.T) {
n := mock.Node()
a := mock.Alloc()
env := NewBuilder(n, a, a.Job.TaskGroups[0].Tasks[0], "global")
env.SetVaultToken("123", false)
env.SetVaultToken("123", "vault-namespace", false)

{
act := env.Build().All()
if act[VaultToken] != "" {
t.Fatalf("Unexpected environment variables: %s=%q", VaultToken, act[VaultToken])
}
if act[VaultNamespace] != "" {
t.Fatalf("Unexpected environment variables: %s=%q", VaultNamespace, act[VaultNamespace])
}
}

{
act := env.SetVaultToken("123", "", true).Build().List()
exp := "VAULT_TOKEN=123"
found := false
foundNs := false
for _, entry := range act {
if entry == exp {
found = true
}
if strings.HasPrefix(entry, "VAULT_NAMESPACE=") {
foundNs = true
}
}
if !found {
t.Fatalf("did not find %q in:\n%s", exp, strings.Join(act, "\n"))
}
if foundNs {
t.Fatalf("found unwanted VAULT_NAMESPACE in:\n%s", strings.Join(act, "\n"))
}
}

{
act := env.SetVaultToken("123", true).Build().List()
act := env.SetVaultToken("123", "vault-namespace", true).Build().List()
exp := "VAULT_TOKEN=123"
expNs := "VAULT_NAMESPACE=vault-namespace"
found := false
foundNs := false
for _, entry := range act {
if entry == exp {
found = true
break
}
if entry == expNs {
foundNs = true
}
}
if !found {
t.Fatalf("did not find %q in:\n%s", exp, strings.Join(act, "\n"))
}
if !foundNs {
t.Fatalf("did not find %q in:\n%s", expNs, strings.Join(act, "\n"))
}
}
}

Expand Down
10 changes: 6 additions & 4 deletions website/source/docs/job-specification/vault.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ job "docs" {
```

The Nomad client will make the Vault token available to the task by writing it
to the secret directory at `secrets/vault_token` and by injecting a VAULT_TOKEN
environment variable.
to the secret directory at `secrets/vault_token` and by injecting a `VAULT_TOKEN`
environment variable. If the Nomad cluster is [configured](http://localhost:4567/docs/configuration/vault.html#namespace)
to use [Vault Namespaces](https://www.vaultproject.io/docs/enterprise/namespaces/index.html),
a `VAULT_NAMESPACE` environment variable will be injected whenever `VAULT_TOKEN` is.

If Nomad is unable to renew the Vault token (perhaps due to a Vault outage or
network error), the client will attempt to retrieve a new Vault token. If successful, the
Expand All @@ -71,8 +73,8 @@ with Vault as well.
string like `"SIGUSR1"` or `"SIGINT"`. This option is required if the
`change_mode` is `signal`.

- `env` `(bool: true)` - Specifies if the `VAULT_TOKEN` environment variable
should be set when starting the task.
- `env` `(bool: true)` - Specifies if the `VAULT_TOKEN` and `VAULT_NAMESPACE`
environment variables should be set when starting the task.

- `policies` `(array<string>: [])` - Specifies the set of Vault policies that
the task requires. The Nomad client will retrieve a Vault token that is
Expand Down

0 comments on commit 7a6a2d3

Please sign in to comment.