Server has Vault API client

This commit is contained in:
Alex Dadgar 2016-08-09 20:15:13 -07:00
parent cef5464e47
commit 6e2f0a2776
3 changed files with 86 additions and 1 deletions

View File

@ -26,6 +26,7 @@ import (
"github.com/hashicorp/raft"
"github.com/hashicorp/raft-boltdb"
"github.com/hashicorp/serf/serf"
vaultapi "github.com/hashicorp/vault/api"
)
const (
@ -139,6 +140,9 @@ type Server struct {
// consulSyncer advertises this Nomad Agent with Consul
consulSyncer *consul.Syncer
// vault is the client for communicating with Vault.
vault *vaultapi.Client
// Worker used for processing
workers []*Worker
@ -201,6 +205,27 @@ func NewServer(config *Config, consulSyncer *consul.Syncer, logger *log.Logger)
shutdownCh: make(chan struct{}),
}
// Get the Vault API configuration
c, err := config.VaultConfig.ApiConfig(true)
if err != nil {
s.logger.Printf("[ERR] nomad: failed to create Vault API config: %v", err)
return nil, fmt.Errorf("Failed to create Vault API config: %v", err)
}
// Create the Vault API client
v, err := vaultapi.NewClient(c)
if err != nil {
s.logger.Printf("[ERR] nomad: failed to create Vault API client: %v", err)
return nil, fmt.Errorf("Failed to create Vault API client: %v", err)
}
// Set the wrapping function such that token creation is wrapped
v.SetWrappingLookupFunc(config.VaultConfig.GetWrappingFn())
// Set the token and store the client
v.SetToken(config.VaultConfig.PeriodicToken)
s.vault = v
// Create the periodic dispatcher for launching periodic jobs.
s.periodicDispatcher = NewPeriodicDispatch(s.logger, s)

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/hashicorp/nomad/command/agent/consul"
"github.com/hashicorp/nomad/nomad/structs/config"
"github.com/hashicorp/nomad/testutil"
)
@ -132,3 +133,39 @@ func TestServer_Regions(t *testing.T) {
t.Fatalf("err: %v", err)
})
}
func TestServer_VaultAPIClient(t *testing.T) {
// Create a server with a Vault Config
token := "123"
role := "foo"
s1 := testServer(t, func(c *Config) {
c.VaultConfig.TokenRoleName = role
c.VaultConfig.PeriodicToken = token
})
defer s1.Shutdown()
if s1.vault == nil {
t.Fatalf("expected a Vault API client")
}
if act := s1.vault.Token(); act != token {
t.Fatalf("Vault client not set up correctly; got %v; want %v for token", act, token)
}
createPath := "/v1/auth/token/create/" + role
wReq := s1.vault.NewRequest("POST", createPath)
if wReq.WrapTTL != config.VaultTokenCreateTTL {
t.Fatalf("Bad WrapTTL; got %q; want %q", wReq.WrapTTL, config.VaultTokenCreateTTL)
}
wReq = s1.vault.NewRequest("GET", createPath)
if wReq.WrapTTL != "" {
t.Fatalf("Bad WrapTTL; got %q; want %q", wReq.WrapTTL, "")
}
badPath := "/v1/auth/token/lookup-self"
wReq = s1.vault.NewRequest("PUT", badPath)
if wReq.WrapTTL != "" {
t.Fatalf("Bad WrapTTL; got %q; want %q", wReq.WrapTTL, "")
}
}

View File

@ -1,6 +1,16 @@
package config
import vault "github.com/hashicorp/vault/api"
import (
"fmt"
vault "github.com/hashicorp/vault/api"
)
const (
// VaultTokenCreateTTL is the duration the wrapped token for the client is
// valid for. The units are in seconds.
VaultTokenCreateTTL = "60s"
)
// VaultConfig contains the configuration information necessary to
// communicate with Vault in order to:
@ -135,3 +145,16 @@ func (c *VaultConfig) Copy() *VaultConfig {
*nc = *c
return nc
}
// GetWrappingFn returns an appropriate wrapping function for Nomad
func (c *VaultConfig) GetWrappingFn() func(operation, path string) string {
createPath := fmt.Sprintf("auth/token/create/%s", c.TokenRoleName)
return func(operation, path string) string {
// Only wrap the token create operation
if operation != "POST" || path != createPath {
return ""
}
return VaultTokenCreateTTL
}
}