From 5db81957ff00fcc44aedc0b8e7e63ee78955192f Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Wed, 3 Apr 2019 11:58:34 +0000 Subject: [PATCH] wip: added config parsing support, CLI flag, still need more testing, VAULT_ var, documentation --- command/agent/command.go | 1 + command/agent/config_parse.go | 1 + nomad/structs/config/vault.go | 3 +++ nomad/vault.go | 26 ++++++++++++++++++++++---- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/command/agent/command.go b/command/agent/command.go index a1658eb50..1ac133e53 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -163,6 +163,7 @@ func (c *Command) readConfig() *Config { }), "vault-allow-unauthenticated", "") flags.StringVar(&cmdConfig.Vault.Token, "vault-token", "", "") flags.StringVar(&cmdConfig.Vault.Addr, "vault-address", "", "") + flags.StringVar(&cmdConfig.Vault.Namespace, "vault-namespace", "", "") flags.StringVar(&cmdConfig.Vault.Role, "vault-create-from-role", "", "") flags.StringVar(&cmdConfig.Vault.TLSCaFile, "vault-ca-file", "", "") flags.StringVar(&cmdConfig.Vault.TLSCaPath, "vault-ca-path", "", "") diff --git a/command/agent/config_parse.go b/command/agent/config_parse.go index f46fb0894..52d452736 100644 --- a/command/agent/config_parse.go +++ b/command/agent/config_parse.go @@ -892,6 +892,7 @@ func parseVaultConfig(result **config.VaultConfig, list *ast.ObjectList) error { "tls_server_name", "tls_skip_verify", "token", + "namespace", } if err := helper.CheckHCLKeys(listVal, valid); err != nil { diff --git a/nomad/structs/config/vault.go b/nomad/structs/config/vault.go index d3e2028c5..c568a70ec 100644 --- a/nomad/structs/config/vault.go +++ b/nomad/structs/config/vault.go @@ -110,6 +110,9 @@ func (a *VaultConfig) Merge(b *VaultConfig) *VaultConfig { if b.Token != "" { result.Token = b.Token } + if b.Namespace != "" { + result.Namespace = b.Namespace + } if b.Role != "" { result.Role = b.Role } diff --git a/nomad/vault.go b/nomad/vault.go index 872245077..f2915345b 100644 --- a/nomad/vault.go +++ b/nomad/vault.go @@ -10,12 +10,13 @@ import ( "sync/atomic" "time" - tomb "gopkg.in/tomb.v2" + "gopkg.in/tomb.v2" - metrics "github.com/armon/go-metrics" + "github.com/armon/go-metrics" log "github.com/hashicorp/go-hclog" - multierror "github.com/hashicorp/go-multierror" + "github.com/hashicorp/go-multierror" vapi "github.com/hashicorp/vault/api" + vaultconsts "github.com/hashicorp/vault/helper/consts" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/nomad/structs/config" @@ -253,6 +254,7 @@ func NewVaultClient(c *config.VaultConfig, logger log.Logger, purgeFn PurgeVault } if c.Namespace != "" { + logger.Debug("Setting Vault namespace", "namespace", c.Namespace) v.client.SetNamespace(c.Namespace) } @@ -412,6 +414,22 @@ func (v *vaultClient) buildClient() error { return nil } +// getVaultInitStatus is used to get the init status. It first clears the namespace header, to work around an +// issue in Vault, then restores it. +func (v *vaultClient) getVaultInitStatus() (bool, error) { + v.l.Lock() + defer v.l.Unlock() + + // workaround for Vault behavior where namespace header causes /v1/sys/init (and other) endpoints to fail + if ns := v.client.Headers().Get(vaultconsts.NamespaceHeaderName); ns != "" { + v.client.SetNamespace("") + defer func() { + v.client.SetNamespace(ns) + }() + } + return v.client.Sys().InitStatus() +} + // establishConnection is used to make first contact with Vault. This should be // called in a go-routine since the connection is retried until the Vault Client // is stopped or the connection is successfully made at which point the renew @@ -429,7 +447,7 @@ OUTER: case <-retryTimer.C: // Ensure the API is reachable if !initStatus { - if _, err := v.client.Sys().InitStatus(); err != nil { + if _, err := v.getVaultInitStatus(); err != nil { v.logger.Warn("failed to contact Vault API", "retry", v.config.ConnectionRetryIntv, "error", err) retryTimer.Reset(v.config.ConnectionRetryIntv) continue OUTER