vault: configure user agent on Nomad vault clients (#15745)
* vault: configure user agent on Nomad vault clients This PR attempts to set the User-Agent header on each Vault API client created by Nomad. Still need to figure a way to set User-Agent on the Vault client created internally by consul-template. * vault: fixup find-and-replace gone awry
This commit is contained in:
parent
32f6ce1c54
commit
83450c8762
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
vault: configure Nomad User-Agent on vault clients
|
||||
```
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
vapi "github.com/hashicorp/vault/api"
|
||||
)
|
||||
|
||||
|
@ -35,18 +36,17 @@ func (f *VaultFingerprint) Fingerprint(req *FingerprintRequest, resp *Fingerprin
|
|||
return nil
|
||||
}
|
||||
|
||||
// Only create the client once to avoid creating too many connections to
|
||||
// Vault.
|
||||
// Only create the client once to avoid creating too many connections to Vault
|
||||
if f.client == nil {
|
||||
vaultConfig, err := config.VaultConfig.ApiConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to initialize the Vault client config: %v", err)
|
||||
}
|
||||
|
||||
f.client, err = vapi.NewClient(vaultConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to initialize Vault client: %s", err)
|
||||
}
|
||||
useragent.SetHeaders(f.client)
|
||||
}
|
||||
|
||||
// Connect to vault and parse its information
|
||||
|
|
|
@ -4,13 +4,13 @@ import (
|
|||
"container/heap"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
metrics "github.com/armon/go-metrics"
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
"github.com/hashicorp/nomad/nomad/structs/config"
|
||||
vaultapi "github.com/hashicorp/vault/api"
|
||||
|
@ -21,7 +21,7 @@ import (
|
|||
// wrapped tokens will be unwrapped using the vault API client.
|
||||
type TokenDeriverFunc func(*structs.Allocation, []string, *vaultapi.Client) (map[string]string, error)
|
||||
|
||||
// The interface which nomad client uses to interact with vault and
|
||||
// VaultClient is the interface which nomad client uses to interact with vault and
|
||||
// periodically renews the tokens and secrets.
|
||||
type VaultClient interface {
|
||||
// Start initiates the renewal loop of tokens and secrets
|
||||
|
@ -151,9 +151,8 @@ func NewVaultClient(config *config.VaultConfig, logger hclog.Logger, tokenDerive
|
|||
return nil, err
|
||||
}
|
||||
|
||||
client.SetHeaders(http.Header{
|
||||
"User-Agent": []string{"hashicorp/nomad"},
|
||||
})
|
||||
// Set our Nomad user agent
|
||||
useragent.SetHeaders(client)
|
||||
|
||||
// SetHeaders above will replace all headers, make this call second
|
||||
if config.Namespace != "" {
|
||||
|
@ -193,7 +192,7 @@ func (c *vaultClient) isRunning() bool {
|
|||
return c.running
|
||||
}
|
||||
|
||||
// Starts the renewal loop of vault client
|
||||
// Start starts the renewal loop of vault client
|
||||
func (c *vaultClient) Start() {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
@ -207,7 +206,7 @@ func (c *vaultClient) Start() {
|
|||
go c.run()
|
||||
}
|
||||
|
||||
// Stops the renewal loop of vault client
|
||||
// Stop stops the renewal loop of vault client
|
||||
func (c *vaultClient) Stop() {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
|
@ -353,8 +352,7 @@ func (c *vaultClient) renew(req *vaultClientRenewalRequest) error {
|
|||
var renewalErr error
|
||||
leaseDuration := req.increment
|
||||
if req.isToken {
|
||||
// Set the token in the API client to the one that needs
|
||||
// renewal
|
||||
// Set the token in the API client to the one that needs renewal
|
||||
c.client.SetToken(req.id)
|
||||
|
||||
// Renew the token
|
||||
|
|
|
@ -7,10 +7,13 @@ import (
|
|||
|
||||
"github.com/hashicorp/nomad/ci"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/helper/pointer"
|
||||
"github.com/hashicorp/nomad/helper/testlog"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
vaultapi "github.com/hashicorp/vault/api"
|
||||
vaultconsts "github.com/hashicorp/vault/sdk/helper/consts"
|
||||
"github.com/shoenig/test/must"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -354,3 +357,16 @@ func TestVaultClient_RenewalTime_Short(t *testing.T) {
|
|||
assert.Equal(t, 15*time.Second, renewalTime(dice, 30))
|
||||
assert.Equal(t, 1*time.Second, renewalTime(dice, 2))
|
||||
}
|
||||
|
||||
func TestVaultClient_SetUserAgent(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
conf := config.DefaultConfig()
|
||||
conf.VaultConfig.Enabled = pointer.Of(true)
|
||||
logger := testlog.HCLogger(t)
|
||||
c, err := NewVaultClient(conf.VaultConfig, logger, nil)
|
||||
must.NoError(t, err)
|
||||
|
||||
ua := c.client.Headers().Get("User-Agent")
|
||||
must.Eq(t, useragent.String(), ua)
|
||||
}
|
||||
|
|
|
@ -5,16 +5,16 @@ import (
|
|||
|
||||
capi "github.com/hashicorp/consul/api"
|
||||
napi "github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
vapi "github.com/hashicorp/vault/api"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/shoenig/test/must"
|
||||
)
|
||||
|
||||
// NomadClient creates a default Nomad client based on the env vars
|
||||
// from the test environment. Fails the test if it can't be created
|
||||
func NomadClient(t *testing.T) *napi.Client {
|
||||
client, err := napi.NewClient(napi.DefaultConfig())
|
||||
require.NoError(t, err, "could not create Nomad client")
|
||||
must.NoError(t, err)
|
||||
return client
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ func NomadClient(t *testing.T) *napi.Client {
|
|||
// from the test environment. Fails the test if it can't be created
|
||||
func ConsulClient(t *testing.T) *capi.Client {
|
||||
client, err := capi.NewClient(capi.DefaultConfig())
|
||||
require.NoError(t, err, "could not create Consul client")
|
||||
must.NoError(t, err)
|
||||
return client
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ func ConsulClient(t *testing.T) *capi.Client {
|
|||
// from the test environment. Fails the test if it can't be created
|
||||
func VaultClient(t *testing.T) *vapi.Client {
|
||||
client, err := vapi.NewClient(vapi.DefaultConfig())
|
||||
require.NoError(t, err, "could not create Vault client")
|
||||
useragent.SetHeaders(client)
|
||||
must.NoError(t, err)
|
||||
return client
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
capi "github.com/hashicorp/consul/api"
|
||||
napi "github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
"github.com/hashicorp/nomad/helper/uuid"
|
||||
vapi "github.com/hashicorp/vault/api"
|
||||
)
|
||||
|
@ -115,6 +116,7 @@ func (p *singleClusterProvisioner) SetupTestCase(t *testing.T, opts SetupOptions
|
|||
if err != nil && opts.ExpectVault {
|
||||
return nil, err
|
||||
}
|
||||
useragent.SetHeaders(vaultClient)
|
||||
info.VaultClient = vaultClient
|
||||
} else if opts.ExpectVault {
|
||||
return nil, fmt.Errorf("vault client expected but environment variable %s not set",
|
||||
|
|
|
@ -2,6 +2,7 @@ package useragent
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
|
||||
"github.com/hashicorp/nomad/version"
|
||||
|
@ -27,3 +28,15 @@ func String() string {
|
|||
return fmt.Sprintf("Nomad/%s (+%s; %s)",
|
||||
versionFunc(), projectURL, rt)
|
||||
}
|
||||
|
||||
// HeaderSetter is anything that implements SetHeaders(http.Header).
|
||||
type HeaderSetter interface {
|
||||
SetHeaders(http.Header)
|
||||
}
|
||||
|
||||
// SetHeaders configures the User-Agent http.Header for the client.
|
||||
func SetHeaders(client HeaderSetter) {
|
||||
client.SetHeaders(http.Header{
|
||||
"User-Agent": []string{String()},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
tomb "gopkg.in/tomb.v2"
|
||||
|
||||
metrics "github.com/armon/go-metrics"
|
||||
|
@ -452,6 +453,7 @@ func (v *vaultClient) buildClient() error {
|
|||
v.logger.Error("failed to create Vault client and not retrying", "error", err)
|
||||
return err
|
||||
}
|
||||
useragent.SetHeaders(client)
|
||||
|
||||
// Store the client, create/assign the /sys client
|
||||
v.client = client
|
||||
|
@ -462,6 +464,7 @@ func (v *vaultClient) buildClient() error {
|
|||
v.logger.Error("failed to create Vault sys client and not retrying", "error", err)
|
||||
return err
|
||||
}
|
||||
useragent.SetHeaders(v.clientSys)
|
||||
client.SetNamespace(v.config.Namespace)
|
||||
} else {
|
||||
v.clientSys = client
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/nomad/ci"
|
||||
"github.com/hashicorp/nomad/helper/testlog"
|
||||
"github.com/hashicorp/nomad/helper/useragent"
|
||||
"github.com/hashicorp/nomad/helper/uuid"
|
||||
"github.com/hashicorp/nomad/nomad/structs/config"
|
||||
vapi "github.com/hashicorp/vault/api"
|
||||
|
@ -57,6 +58,7 @@ func NewTestVaultFromPath(t testing.T, binary string) *TestVault {
|
|||
t.Fatalf("failed to build Vault API client: %v", err)
|
||||
}
|
||||
client.SetToken(token)
|
||||
useragent.SetHeaders(client)
|
||||
|
||||
enable := true
|
||||
tv := &TestVault{
|
||||
|
@ -133,6 +135,7 @@ func NewTestVaultDelayed(t testing.T) *TestVault {
|
|||
t.Fatalf("failed to build Vault API client: %v", err)
|
||||
}
|
||||
client.SetToken(token)
|
||||
useragent.SetHeaders(client)
|
||||
|
||||
enable := true
|
||||
tv := &TestVault{
|
||||
|
|
Loading…
Reference in New Issue