Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vault: configure user agent on Nomad vault clients #15745

Merged
merged 2 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/15745.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
vault: configure Nomad User-Agent on vault clients
```
6 changes: 3 additions & 3 deletions client/fingerprint/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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
Expand Down
16 changes: 7 additions & 9 deletions client/vaultclient/vaultclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand Down Expand Up @@ -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 != "" {
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions client/vaultclient/vaultclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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)
}
11 changes: 6 additions & 5 deletions e2e/e2eutil/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,32 @@ 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
}

// ConsulClient creates a default Consul client based on the env vars
// 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
}

// VaultClient creates a default Vault client based on the env vars
// 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
}
2 changes: 2 additions & 0 deletions e2e/framework/provisioner.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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",
Expand Down
13 changes: 13 additions & 0 deletions helper/useragent/useragent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package useragent

import (
"fmt"
"net/http"
"runtime"

"github.com/hashicorp/nomad/version"
Expand All @@ -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()},
lgfa29 marked this conversation as resolved.
Show resolved Hide resolved
})
}
3 changes: 3 additions & 0 deletions nomad/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions testutil/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand Down