mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
VAULT-12940 Vault Agent uses Vault Agent specific User-Agent header when issuing requests (#19776)
* VAULT-12940 test for templating user agent * VAULT-12940 User agent work so far * VAULT-12940 Vault Agent uses Vault Agent specific User-Agent header when issuing requests * VAULT-12940 Clean-up and godocs * VAULT-12940 changelog * VAULT-12940 Fix test checking headers * VAULT-12940 Fix test checking headers * VAULT-12940 Fix test checking headers * VAULT-12940 Fix test checking headers * VAULT-12940 copy/paste typos * VAULT-12940 improve comments, use make(http.Header) * VAULT-12940 small typos and clean-up
This commit is contained in:
3
changelog/19776.txt
Normal file
3
changelog/19776.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:improvement
|
||||||
|
agent: Vault Agent now reports its name and version as part of the User-Agent header in all requests issued.
|
||||||
|
```
|
||||||
@@ -290,7 +290,7 @@ func (c *AgentCommand) Run(args []string) int {
|
|||||||
Ui: c.UI,
|
Ui: c.UI,
|
||||||
ServiceName: "vault",
|
ServiceName: "vault",
|
||||||
DisplayName: "Vault",
|
DisplayName: "Vault",
|
||||||
UserAgent: useragent.String(),
|
UserAgent: useragent.AgentString(),
|
||||||
ClusterName: config.ClusterName,
|
ClusterName: config.ClusterName,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/armon/go-metrics"
|
"github.com/armon/go-metrics"
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
"github.com/hashicorp/vault/sdk/helper/jsonutil"
|
"github.com/hashicorp/vault/sdk/helper/jsonutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -156,6 +157,15 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
|
|||||||
credCh = make(chan struct{})
|
credCh = make(chan struct{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ah.client != nil {
|
||||||
|
headers := ah.client.Headers()
|
||||||
|
if headers == nil {
|
||||||
|
headers = make(http.Header)
|
||||||
|
}
|
||||||
|
headers.Set("User-Agent", useragent.AgentAutoAuthString())
|
||||||
|
ah.client.SetHeaders(headers)
|
||||||
|
}
|
||||||
|
|
||||||
var watcher *api.LifetimeWatcher
|
var watcher *api.LifetimeWatcher
|
||||||
first := true
|
first := true
|
||||||
|
|
||||||
|
|||||||
16
command/agent/cache/api_proxy.go
vendored
16
command/agent/cache/api_proxy.go
vendored
@@ -6,11 +6,13 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
gohttp "net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
hclog "github.com/hashicorp/go-hclog"
|
hclog "github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-retryablehttp"
|
"github.com/hashicorp/go-retryablehttp"
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
"github.com/hashicorp/vault/http"
|
"github.com/hashicorp/vault/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -76,6 +78,20 @@ func (ap *APIProxy) Send(ctx context.Context, req *SendRequest) (*SendResponse,
|
|||||||
// the client doesn't manually set the header. Removing any Accept-Encoding header allows the
|
// the client doesn't manually set the header. Removing any Accept-Encoding header allows the
|
||||||
// transparent compression to occur.
|
// transparent compression to occur.
|
||||||
req.Request.Header.Del("Accept-Encoding")
|
req.Request.Header.Del("Accept-Encoding")
|
||||||
|
|
||||||
|
if req.Request.Header == nil {
|
||||||
|
req.Request.Header = make(gohttp.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set our User-Agent to be one indicating we are Vault Agent's API proxy.
|
||||||
|
// If the sending client had one, preserve it.
|
||||||
|
if req.Request.Header.Get("User-Agent") != "" {
|
||||||
|
initialUserAgent := req.Request.Header.Get("User-Agent")
|
||||||
|
req.Request.Header.Set("User-Agent", useragent.AgentProxyStringWithProxiedUserAgent(initialUserAgent))
|
||||||
|
} else {
|
||||||
|
req.Request.Header.Set("User-Agent", useragent.AgentProxyString())
|
||||||
|
}
|
||||||
|
|
||||||
client.SetHeaders(req.Request.Header)
|
client.SetHeaders(req.Request.Header)
|
||||||
|
|
||||||
fwReq := client.NewRequest(req.Request.Method, req.Request.URL.Path)
|
fwReq := client.NewRequest(req.Request.Method, req.Request.URL.Path)
|
||||||
|
|||||||
14
command/agent/cache/lease_cache.go
vendored
14
command/agent/cache/lease_cache.go
vendored
@@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/hashicorp/vault/command/agent/cache/cachememdb"
|
"github.com/hashicorp/vault/command/agent/cache/cachememdb"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
nshelper "github.com/hashicorp/vault/helper/namespace"
|
nshelper "github.com/hashicorp/vault/helper/namespace"
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
vaulthttp "github.com/hashicorp/vault/http"
|
vaulthttp "github.com/hashicorp/vault/http"
|
||||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||||
"github.com/hashicorp/vault/sdk/helper/cryptoutil"
|
"github.com/hashicorp/vault/sdk/helper/cryptoutil"
|
||||||
@@ -477,7 +478,18 @@ func (c *LeaseCache) startRenewing(ctx context.Context, index *cachememdb.Index,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
client.SetToken(req.Token)
|
client.SetToken(req.Token)
|
||||||
client.SetHeaders(req.Request.Header)
|
|
||||||
|
headers := client.Headers()
|
||||||
|
if headers == nil {
|
||||||
|
headers = make(http.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do not preserve the initial User-Agent here (i.e. use
|
||||||
|
// AgentProxyStringWithProxiedUserAgent) since these requests are from
|
||||||
|
// the proxy subsystem, but are made by Agent's lifetime watcher,
|
||||||
|
// not triggered by a specific request.
|
||||||
|
headers.Set("User-Agent", useragent.AgentProxyString())
|
||||||
|
client.SetHeaders(headers)
|
||||||
|
|
||||||
watcher, err := client.NewLifetimeWatcher(&api.LifetimeWatcherInput{
|
watcher, err := client.NewLifetimeWatcher(&api.LifetimeWatcherInput{
|
||||||
Secret: secret,
|
Secret: secret,
|
||||||
|
|||||||
21
command/agent/cache/lease_cache_test.go
vendored
21
command/agent/cache/lease_cache_test.go
vendored
@@ -17,6 +17,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
|
|
||||||
"github.com/go-test/deep"
|
"github.com/go-test/deep"
|
||||||
hclog "github.com/hashicorp/go-hclog"
|
hclog "github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
@@ -737,7 +739,7 @@ func compareBeforeAndAfter(t *testing.T, before, after *LeaseCache, beforeLen, a
|
|||||||
assert.Equal(t, cachedItem.Lease, restoredItem.Lease)
|
assert.Equal(t, cachedItem.Lease, restoredItem.Lease)
|
||||||
assert.Equal(t, cachedItem.LeaseToken, restoredItem.LeaseToken)
|
assert.Equal(t, cachedItem.LeaseToken, restoredItem.LeaseToken)
|
||||||
assert.Equal(t, cachedItem.Namespace, restoredItem.Namespace)
|
assert.Equal(t, cachedItem.Namespace, restoredItem.Namespace)
|
||||||
assert.Equal(t, cachedItem.RequestHeader, restoredItem.RequestHeader)
|
assert.EqualValues(t, cachedItem.RequestHeader, restoredItem.RequestHeader)
|
||||||
assert.Equal(t, cachedItem.RequestMethod, restoredItem.RequestMethod)
|
assert.Equal(t, cachedItem.RequestMethod, restoredItem.RequestMethod)
|
||||||
assert.Equal(t, cachedItem.RequestPath, restoredItem.RequestPath)
|
assert.Equal(t, cachedItem.RequestPath, restoredItem.RequestPath)
|
||||||
assert.Equal(t, cachedItem.RequestToken, restoredItem.RequestToken)
|
assert.Equal(t, cachedItem.RequestToken, restoredItem.RequestToken)
|
||||||
@@ -842,16 +844,21 @@ func TestLeaseCache_PersistAndRestore(t *testing.T) {
|
|||||||
var deleteIDs []string
|
var deleteIDs []string
|
||||||
for i, ct := range cacheTests {
|
for i, ct := range cacheTests {
|
||||||
// Send once to cache
|
// Send once to cache
|
||||||
|
req := httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body))
|
||||||
|
req.Header.Set("User-Agent", useragent.AgentProxyString())
|
||||||
|
|
||||||
sendReq := &SendRequest{
|
sendReq := &SendRequest{
|
||||||
Token: ct.token,
|
Token: ct.token,
|
||||||
Request: httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body)),
|
Request: req,
|
||||||
}
|
}
|
||||||
if ct.deleteFromPersistentStore {
|
if ct.deleteFromPersistentStore {
|
||||||
deleteID, err := computeIndexID(sendReq)
|
deleteID, err := computeIndexID(sendReq)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
deleteIDs = append(deleteIDs, deleteID)
|
deleteIDs = append(deleteIDs, deleteID)
|
||||||
// Now reset the body after calculating the index
|
// Now reset the body after calculating the index
|
||||||
sendReq.Request = httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body))
|
req = httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body))
|
||||||
|
req.Header.Set("User-Agent", useragent.AgentProxyString())
|
||||||
|
sendReq.Request = req
|
||||||
}
|
}
|
||||||
resp, err := lc.Send(context.Background(), sendReq)
|
resp, err := lc.Send(context.Background(), sendReq)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -860,9 +867,11 @@ func TestLeaseCache_PersistAndRestore(t *testing.T) {
|
|||||||
|
|
||||||
// Send again to test cache. If this isn't cached, the response returned
|
// Send again to test cache. If this isn't cached, the response returned
|
||||||
// will be the next in the list and the status code will not match.
|
// will be the next in the list and the status code will not match.
|
||||||
|
req = httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body))
|
||||||
|
req.Header.Set("User-Agent", useragent.AgentProxyString())
|
||||||
sendCacheReq := &SendRequest{
|
sendCacheReq := &SendRequest{
|
||||||
Token: ct.token,
|
Token: ct.token,
|
||||||
Request: httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body)),
|
Request: req,
|
||||||
}
|
}
|
||||||
respCached, err := lc.Send(context.Background(), sendCacheReq)
|
respCached, err := lc.Send(context.Background(), sendCacheReq)
|
||||||
require.NoError(t, err, "failed to send request %+v", ct)
|
require.NoError(t, err, "failed to send request %+v", ct)
|
||||||
@@ -894,9 +903,11 @@ func TestLeaseCache_PersistAndRestore(t *testing.T) {
|
|||||||
// And finally send the cache requests once to make sure they're all being
|
// And finally send the cache requests once to make sure they're all being
|
||||||
// served from the restoredCache unless they were intended to be missing after restore.
|
// served from the restoredCache unless they were intended to be missing after restore.
|
||||||
for i, ct := range cacheTests {
|
for i, ct := range cacheTests {
|
||||||
|
req := httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body))
|
||||||
|
req.Header.Set("User-Agent", useragent.AgentProxyString())
|
||||||
sendCacheReq := &SendRequest{
|
sendCacheReq := &SendRequest{
|
||||||
Token: ct.token,
|
Token: ct.token,
|
||||||
Request: httptest.NewRequest(ct.method, ct.urlPath, strings.NewReader(ct.body)),
|
Request: req,
|
||||||
}
|
}
|
||||||
respCached, err := restoredCache.Send(context.Background(), sendCacheReq)
|
respCached, err := restoredCache.Send(context.Background(), sendCacheReq)
|
||||||
require.NoError(t, err, "failed to send request %+v", ct)
|
require.NoError(t, err, "failed to send request %+v", ct)
|
||||||
|
|||||||
6
command/agent/cache/testing.go
vendored
6
command/agent/cache/testing.go
vendored
@@ -13,6 +13,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/api"
|
"github.com/hashicorp/vault/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -47,11 +49,13 @@ func (p *mockProxier) ResponseIndex() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newTestSendResponse(status int, body string) *SendResponse {
|
func newTestSendResponse(status int, body string) *SendResponse {
|
||||||
|
headers := make(http.Header)
|
||||||
|
headers.Add("User-Agent", useragent.AgentProxyString())
|
||||||
resp := &SendResponse{
|
resp := &SendResponse{
|
||||||
Response: &api.Response{
|
Response: &api.Response{
|
||||||
Response: &http.Response{
|
Response: &http.Response{
|
||||||
StatusCode: status,
|
StatusCode: status,
|
||||||
Header: http.Header{},
|
Header: headers,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/hashicorp/consul-template/manager"
|
"github.com/hashicorp/consul-template/manager"
|
||||||
"github.com/hashicorp/go-hclog"
|
"github.com/hashicorp/go-hclog"
|
||||||
"github.com/hashicorp/vault/command/agent/config"
|
"github.com/hashicorp/vault/command/agent/config"
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
"github.com/hashicorp/vault/sdk/helper/pointerutil"
|
"github.com/hashicorp/vault/sdk/helper/pointerutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -160,7 +161,8 @@ func (ts *Server) Run(ctx context.Context, incoming chan string, templates []*ct
|
|||||||
*latestToken = token
|
*latestToken = token
|
||||||
ctv := ctconfig.Config{
|
ctv := ctconfig.Config{
|
||||||
Vault: &ctconfig.VaultConfig{
|
Vault: &ctconfig.VaultConfig{
|
||||||
Token: latestToken,
|
Token: latestToken,
|
||||||
|
ClientUserAgent: pointerutil.StringPtr(useragent.AgentTemplatingString()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,6 +241,7 @@ func newRunnerConfig(sc *ServerConfig, templates ctconfig.TemplateConfigs) (*ctc
|
|||||||
conf.Vault.RenewToken = pointerutil.BoolPtr(false)
|
conf.Vault.RenewToken = pointerutil.BoolPtr(false)
|
||||||
conf.Vault.Token = pointerutil.StringPtr("")
|
conf.Vault.Token = pointerutil.StringPtr("")
|
||||||
conf.Vault.Address = &sc.AgentConfig.Vault.Address
|
conf.Vault.Address = &sc.AgentConfig.Vault.Address
|
||||||
|
conf.Vault.ClientUserAgent = pointerutil.StringPtr(useragent.AgentTemplatingString())
|
||||||
|
|
||||||
if sc.Namespace != "" {
|
if sc.Namespace != "" {
|
||||||
conf.Vault.Namespace = &sc.Namespace
|
conf.Vault.Namespace = &sc.Namespace
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
credAppRole "github.com/hashicorp/vault/builtin/credential/approle"
|
credAppRole "github.com/hashicorp/vault/builtin/credential/approle"
|
||||||
"github.com/hashicorp/vault/command/agent"
|
"github.com/hashicorp/vault/command/agent"
|
||||||
agentConfig "github.com/hashicorp/vault/command/agent/config"
|
agentConfig "github.com/hashicorp/vault/command/agent/config"
|
||||||
|
"github.com/hashicorp/vault/helper/useragent"
|
||||||
vaulthttp "github.com/hashicorp/vault/http"
|
vaulthttp "github.com/hashicorp/vault/http"
|
||||||
"github.com/hashicorp/vault/sdk/helper/consts"
|
"github.com/hashicorp/vault/sdk/helper/consts"
|
||||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||||
@@ -514,6 +515,258 @@ listener "tcp" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAgent_Template_UserAgent Validates that the User-Agent sent to Vault
|
||||||
|
// as part of Templating requests is correct. Uses the custom handler
|
||||||
|
// userAgentHandler struct defined in this test package, so that Vault validates the
|
||||||
|
// User-Agent on requests sent by Agent.
|
||||||
|
func TestAgent_Template_UserAgent(t *testing.T) {
|
||||||
|
//----------------------------------------------------
|
||||||
|
// Start the server and agent
|
||||||
|
//----------------------------------------------------
|
||||||
|
logger := logging.NewVaultLogger(hclog.Trace)
|
||||||
|
var h userAgentHandler
|
||||||
|
cluster := vault.NewTestCluster(t,
|
||||||
|
&vault.CoreConfig{
|
||||||
|
Logger: logger,
|
||||||
|
CredentialBackends: map[string]logical.Factory{
|
||||||
|
"approle": credAppRole.Factory,
|
||||||
|
},
|
||||||
|
LogicalBackends: map[string]logical.Factory{
|
||||||
|
"kv": logicalKv.Factory,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&vault.TestClusterOptions{
|
||||||
|
NumCores: 1,
|
||||||
|
HandlerFunc: vaulthttp.HandlerFunc(
|
||||||
|
func(properties *vault.HandlerProperties) http.Handler {
|
||||||
|
h.props = properties
|
||||||
|
h.userAgentToCheckFor = useragent.AgentTemplatingString()
|
||||||
|
h.pathToCheck = "/v1/secret/data"
|
||||||
|
h.requestMethodToCheck = "GET"
|
||||||
|
h.t = t
|
||||||
|
return &h
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
cluster.Start()
|
||||||
|
defer cluster.Cleanup()
|
||||||
|
|
||||||
|
vault.TestWaitActive(t, cluster.Cores[0].Core)
|
||||||
|
serverClient := cluster.Cores[0].Client
|
||||||
|
|
||||||
|
// Unset the environment variable so that agent picks up the right test
|
||||||
|
// cluster address
|
||||||
|
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
|
||||||
|
os.Setenv(api.EnvVaultAddress, serverClient.Address())
|
||||||
|
|
||||||
|
// Enable the approle auth method
|
||||||
|
req := serverClient.NewRequest("POST", "/v1/sys/auth/approle")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"type": "approle"
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 204)
|
||||||
|
|
||||||
|
// give test-role permissions to read the kv secret
|
||||||
|
req = serverClient.NewRequest("PUT", "/v1/sys/policy/myapp-read")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"policy": "path \"secret/*\" { capabilities = [\"read\", \"list\"] }"
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 204)
|
||||||
|
|
||||||
|
// Create a named role
|
||||||
|
req = serverClient.NewRequest("PUT", "/v1/auth/approle/role/test-role")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"token_ttl": "5m",
|
||||||
|
"token_policies":"default,myapp-read",
|
||||||
|
"policies":"default,myapp-read"
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 204)
|
||||||
|
|
||||||
|
// Fetch the RoleID of the named role
|
||||||
|
req = serverClient.NewRequest("GET", "/v1/auth/approle/role/test-role/role-id")
|
||||||
|
body := request(t, serverClient, req, 200)
|
||||||
|
data := body["data"].(map[string]interface{})
|
||||||
|
roleID := data["role_id"].(string)
|
||||||
|
|
||||||
|
// Get a SecretID issued against the named role
|
||||||
|
req = serverClient.NewRequest("PUT", "/v1/auth/approle/role/test-role/secret-id")
|
||||||
|
body = request(t, serverClient, req, 200)
|
||||||
|
data = body["data"].(map[string]interface{})
|
||||||
|
secretID := data["secret_id"].(string)
|
||||||
|
|
||||||
|
// Write the RoleID and SecretID to temp files
|
||||||
|
roleIDPath := makeTempFile(t, "role_id.txt", roleID+"\n")
|
||||||
|
secretIDPath := makeTempFile(t, "secret_id.txt", secretID+"\n")
|
||||||
|
defer os.Remove(roleIDPath)
|
||||||
|
defer os.Remove(secretIDPath)
|
||||||
|
|
||||||
|
// setup the kv secrets
|
||||||
|
req = serverClient.NewRequest("POST", "/v1/sys/mounts/secret/tune")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"options": {"version": "2"}
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 200)
|
||||||
|
|
||||||
|
// populate a secret
|
||||||
|
req = serverClient.NewRequest("POST", "/v1/secret/data/myapp")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"data": {
|
||||||
|
"username": "bar",
|
||||||
|
"password": "zap"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 200)
|
||||||
|
|
||||||
|
// populate another secret
|
||||||
|
req = serverClient.NewRequest("POST", "/v1/secret/data/otherapp")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"data": {
|
||||||
|
"username": "barstuff",
|
||||||
|
"password": "zap",
|
||||||
|
"cert": "something"
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 200)
|
||||||
|
|
||||||
|
// make a temp directory to hold renders. Each test will create a temp dir
|
||||||
|
// inside this one
|
||||||
|
tmpDirRoot, err := os.MkdirTemp("", "agent-test-renders")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDirRoot)
|
||||||
|
// create temp dir for this test run
|
||||||
|
tmpDir, err := os.MkdirTemp(tmpDirRoot, "TestAgent_Template_UserAgent")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// make some template files
|
||||||
|
var templatePaths []string
|
||||||
|
fileName := filepath.Join(tmpDir, "render_0.tmpl")
|
||||||
|
if err := os.WriteFile(fileName, []byte(templateContents(0)), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
templatePaths = append(templatePaths, fileName)
|
||||||
|
|
||||||
|
// build up the template config to be added to the Agent config.hcl file
|
||||||
|
var templateConfigStrings []string
|
||||||
|
for i, t := range templatePaths {
|
||||||
|
index := fmt.Sprintf("render_%d.json", i)
|
||||||
|
s := fmt.Sprintf(templateConfigString, t, tmpDir, index)
|
||||||
|
templateConfigStrings = append(templateConfigStrings, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a config file
|
||||||
|
config := `
|
||||||
|
vault {
|
||||||
|
address = "%s"
|
||||||
|
tls_skip_verify = true
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_auth {
|
||||||
|
method "approle" {
|
||||||
|
mount_path = "auth/approle"
|
||||||
|
config = {
|
||||||
|
role_id_file_path = "%s"
|
||||||
|
secret_id_file_path = "%s"
|
||||||
|
remove_secret_id_file_after_reading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%s
|
||||||
|
`
|
||||||
|
|
||||||
|
// flatten the template configs
|
||||||
|
templateConfig := strings.Join(templateConfigStrings, " ")
|
||||||
|
|
||||||
|
config = fmt.Sprintf(config, serverClient.Address(), roleIDPath, secretIDPath, templateConfig)
|
||||||
|
configPath := makeTempFile(t, "config.hcl", config)
|
||||||
|
defer os.Remove(configPath)
|
||||||
|
|
||||||
|
// Start the agent
|
||||||
|
ui, cmd := testAgentCommand(t, logger)
|
||||||
|
cmd.client = serverClient
|
||||||
|
cmd.startedCh = make(chan struct{})
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
code := cmd.Run([]string{"-config", configPath})
|
||||||
|
if code != 0 {
|
||||||
|
t.Errorf("non-zero return code when running agent: %d", code)
|
||||||
|
t.Logf("STDOUT from agent:\n%s", ui.OutputWriter.String())
|
||||||
|
t.Logf("STDERR from agent:\n%s", ui.ErrorWriter.String())
|
||||||
|
}
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-cmd.startedCh:
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Errorf("timeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to shut down the Agent command
|
||||||
|
defer func() {
|
||||||
|
cmd.ShutdownCh <- struct{}{}
|
||||||
|
wg.Wait()
|
||||||
|
}()
|
||||||
|
|
||||||
|
verify := func(suffix string) {
|
||||||
|
t.Helper()
|
||||||
|
// We need to poll for a bit to give Agent time to render the
|
||||||
|
// templates. Without this, the test will attempt to read
|
||||||
|
// the temp dir before Agent has had time to render and will
|
||||||
|
// likely fail the test
|
||||||
|
tick := time.Tick(1 * time.Second)
|
||||||
|
timeout := time.After(10 * time.Second)
|
||||||
|
var err error
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-timeout:
|
||||||
|
t.Fatalf("timed out waiting for templates to render, last error: %v", err)
|
||||||
|
case <-tick:
|
||||||
|
}
|
||||||
|
// Check for files rendered in the directory and break
|
||||||
|
// early for shutdown if we do have all the files
|
||||||
|
// rendered
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// Perform the tests
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
||||||
|
if numFiles := testListFiles(t, tmpDir, ".json"); numFiles != len(templatePaths) {
|
||||||
|
err = fmt.Errorf("expected (%d) templates, got (%d)", len(templatePaths), numFiles)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range templatePaths {
|
||||||
|
fileName := filepath.Join(tmpDir, fmt.Sprintf("render_%d.json", i))
|
||||||
|
var c []byte
|
||||||
|
c, err = os.ReadFile(fileName)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if string(c) != templateRendered(i)+suffix {
|
||||||
|
err = fmt.Errorf("expected=%q, got=%q", templateRendered(i)+suffix, string(c))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verify("")
|
||||||
|
|
||||||
|
fileName = filepath.Join(tmpDir, "render_0.tmpl")
|
||||||
|
if err := os.WriteFile(fileName, []byte(templateContents(0)+"{}"), 0o600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
verify("{}")
|
||||||
|
}
|
||||||
|
|
||||||
// TestAgent_Template tests rendering templates
|
// TestAgent_Template tests rendering templates
|
||||||
func TestAgent_Template_Basic(t *testing.T) {
|
func TestAgent_Template_Basic(t *testing.T) {
|
||||||
//----------------------------------------------------
|
//----------------------------------------------------
|
||||||
@@ -1151,6 +1404,27 @@ func (h *handler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
|
|||||||
vaulthttp.Handler.Handler(h.props).ServeHTTP(resp, req)
|
vaulthttp.Handler.Handler(h.props).ServeHTTP(resp, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// userAgentHandler makes it easy to test the User-Agent header received
|
||||||
|
// by Vault
|
||||||
|
type userAgentHandler struct {
|
||||||
|
props *vault.HandlerProperties
|
||||||
|
failCount int
|
||||||
|
userAgentToCheckFor string
|
||||||
|
pathToCheck string
|
||||||
|
requestMethodToCheck string
|
||||||
|
t *testing.T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *userAgentHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||||
|
if req.Method == h.requestMethodToCheck && strings.Contains(req.RequestURI, h.pathToCheck) {
|
||||||
|
userAgent := req.UserAgent()
|
||||||
|
if !(userAgent == h.userAgentToCheckFor) {
|
||||||
|
h.t.Fatalf("User-Agent string not as expected. Expected to find %s, got %s", h.userAgentToCheckFor, userAgent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vaulthttp.Handler.Handler(h.props).ServeHTTP(w, req)
|
||||||
|
}
|
||||||
|
|
||||||
// TestAgent_Template_Retry verifies that the template server retries requests
|
// TestAgent_Template_Retry verifies that the template server retries requests
|
||||||
// based on retry configuration.
|
// based on retry configuration.
|
||||||
func TestAgent_Template_Retry(t *testing.T) {
|
func TestAgent_Template_Retry(t *testing.T) {
|
||||||
@@ -1441,6 +1715,345 @@ auto_auth {
|
|||||||
return config, cleanup
|
return config, cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestAgent_AutoAuth_UserAgent tests that the User-Agent sent
|
||||||
|
// to Vault by Vault Agent is correct when performing Auto-Auth.
|
||||||
|
// Uses the custom handler userAgentHandler (defined above) so
|
||||||
|
// that Vault validates the User-Agent on requests sent by Agent.
|
||||||
|
func TestAgent_AutoAuth_UserAgent(t *testing.T) {
|
||||||
|
logger := logging.NewVaultLogger(hclog.Trace)
|
||||||
|
var h userAgentHandler
|
||||||
|
cluster := vault.NewTestCluster(t, &vault.CoreConfig{
|
||||||
|
Logger: logger,
|
||||||
|
CredentialBackends: map[string]logical.Factory{
|
||||||
|
"approle": credAppRole.Factory,
|
||||||
|
},
|
||||||
|
}, &vault.TestClusterOptions{
|
||||||
|
NumCores: 1,
|
||||||
|
HandlerFunc: vaulthttp.HandlerFunc(
|
||||||
|
func(properties *vault.HandlerProperties) http.Handler {
|
||||||
|
h.props = properties
|
||||||
|
h.userAgentToCheckFor = useragent.AgentAutoAuthString()
|
||||||
|
h.requestMethodToCheck = "PUT"
|
||||||
|
h.pathToCheck = "auth/approle/login"
|
||||||
|
h.t = t
|
||||||
|
return &h
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
cluster.Start()
|
||||||
|
defer cluster.Cleanup()
|
||||||
|
|
||||||
|
serverClient := cluster.Cores[0].Client
|
||||||
|
|
||||||
|
// Enable the approle auth method
|
||||||
|
req := serverClient.NewRequest("POST", "/v1/sys/auth/approle")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"type": "approle"
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 204)
|
||||||
|
|
||||||
|
// Create a named role
|
||||||
|
req = serverClient.NewRequest("PUT", "/v1/auth/approle/role/test-role")
|
||||||
|
req.BodyBytes = []byte(`{
|
||||||
|
"secret_id_num_uses": "10",
|
||||||
|
"secret_id_ttl": "1m",
|
||||||
|
"token_max_ttl": "1m",
|
||||||
|
"token_num_uses": "10",
|
||||||
|
"token_ttl": "1m",
|
||||||
|
"policies": "default"
|
||||||
|
}`)
|
||||||
|
request(t, serverClient, req, 204)
|
||||||
|
|
||||||
|
// Fetch the RoleID of the named role
|
||||||
|
req = serverClient.NewRequest("GET", "/v1/auth/approle/role/test-role/role-id")
|
||||||
|
body := request(t, serverClient, req, 200)
|
||||||
|
data := body["data"].(map[string]interface{})
|
||||||
|
roleID := data["role_id"].(string)
|
||||||
|
|
||||||
|
// Get a SecretID issued against the named role
|
||||||
|
req = serverClient.NewRequest("PUT", "/v1/auth/approle/role/test-role/secret-id")
|
||||||
|
body = request(t, serverClient, req, 200)
|
||||||
|
data = body["data"].(map[string]interface{})
|
||||||
|
secretID := data["secret_id"].(string)
|
||||||
|
|
||||||
|
// Write the RoleID and SecretID to temp files
|
||||||
|
roleIDPath := makeTempFile(t, "role_id.txt", roleID+"\n")
|
||||||
|
secretIDPath := makeTempFile(t, "secret_id.txt", secretID+"\n")
|
||||||
|
defer os.Remove(roleIDPath)
|
||||||
|
defer os.Remove(secretIDPath)
|
||||||
|
|
||||||
|
sinkf, err := os.CreateTemp("", "sink.test.")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sink := sinkf.Name()
|
||||||
|
sinkf.Close()
|
||||||
|
os.Remove(sink)
|
||||||
|
|
||||||
|
autoAuthConfig := fmt.Sprintf(`
|
||||||
|
auto_auth {
|
||||||
|
method "approle" {
|
||||||
|
mount_path = "auth/approle"
|
||||||
|
config = {
|
||||||
|
role_id_file_path = "%s"
|
||||||
|
secret_id_file_path = "%s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sink "file" {
|
||||||
|
config = {
|
||||||
|
path = "%s"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`, roleIDPath, secretIDPath, sink)
|
||||||
|
|
||||||
|
listenAddr := generateListenerAddress(t)
|
||||||
|
listenConfig := fmt.Sprintf(`
|
||||||
|
listener "tcp" {
|
||||||
|
address = "%s"
|
||||||
|
tls_disable = true
|
||||||
|
}
|
||||||
|
`, listenAddr)
|
||||||
|
|
||||||
|
config := fmt.Sprintf(`
|
||||||
|
vault {
|
||||||
|
address = "%s"
|
||||||
|
tls_skip_verify = true
|
||||||
|
}
|
||||||
|
api_proxy {
|
||||||
|
use_auto_auth_token = true
|
||||||
|
}
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
`, serverClient.Address(), listenConfig, autoAuthConfig)
|
||||||
|
configPath := makeTempFile(t, "config.hcl", config)
|
||||||
|
defer os.Remove(configPath)
|
||||||
|
|
||||||
|
// Unset the environment variable so that agent picks up the right test
|
||||||
|
// cluster address
|
||||||
|
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
|
||||||
|
os.Unsetenv(api.EnvVaultAddress)
|
||||||
|
|
||||||
|
// Start the agent
|
||||||
|
_, cmd := testAgentCommand(t, logger)
|
||||||
|
cmd.startedCh = make(chan struct{})
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
cmd.Run([]string{"-config", configPath})
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-cmd.startedCh:
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Errorf("timeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that the auto-auth token has been correctly attained
|
||||||
|
// and works for LookupSelf
|
||||||
|
conf := api.DefaultConfig()
|
||||||
|
conf.Address = "http://" + listenAddr
|
||||||
|
agentClient, err := api.NewClient(conf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
agentClient.SetToken("")
|
||||||
|
err = agentClient.SetAddress("http://" + listenAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the token to be sent to syncs and be available to be used
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
|
req = agentClient.NewRequest("GET", "/v1/auth/token/lookup-self")
|
||||||
|
body = request(t, agentClient, req, 200)
|
||||||
|
|
||||||
|
close(cmd.ShutdownCh)
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAgent_APIProxyWithoutCache_UserAgent tests that the User-Agent sent
|
||||||
|
// to Vault by Vault Agent is correct using the API proxy without
|
||||||
|
// the cache configured. Uses the custom handler
|
||||||
|
// userAgentHandler struct defined in this test package, so that Vault validates the
|
||||||
|
// User-Agent on requests sent by Agent.
|
||||||
|
func TestAgent_APIProxyWithoutCache_UserAgent(t *testing.T) {
|
||||||
|
logger := logging.NewVaultLogger(hclog.Trace)
|
||||||
|
userAgentForProxiedClient := "proxied-client"
|
||||||
|
var h userAgentHandler
|
||||||
|
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
|
||||||
|
NumCores: 1,
|
||||||
|
HandlerFunc: vaulthttp.HandlerFunc(
|
||||||
|
func(properties *vault.HandlerProperties) http.Handler {
|
||||||
|
h.props = properties
|
||||||
|
h.userAgentToCheckFor = useragent.AgentProxyStringWithProxiedUserAgent(userAgentForProxiedClient)
|
||||||
|
h.pathToCheck = "/v1/auth/token/lookup-self"
|
||||||
|
h.requestMethodToCheck = "GET"
|
||||||
|
h.t = t
|
||||||
|
return &h
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
cluster.Start()
|
||||||
|
defer cluster.Cleanup()
|
||||||
|
|
||||||
|
serverClient := cluster.Cores[0].Client
|
||||||
|
|
||||||
|
// Unset the environment variable so that agent picks up the right test
|
||||||
|
// cluster address
|
||||||
|
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
|
||||||
|
os.Unsetenv(api.EnvVaultAddress)
|
||||||
|
|
||||||
|
listenAddr := generateListenerAddress(t)
|
||||||
|
listenConfig := fmt.Sprintf(`
|
||||||
|
listener "tcp" {
|
||||||
|
address = "%s"
|
||||||
|
tls_disable = true
|
||||||
|
}
|
||||||
|
`, listenAddr)
|
||||||
|
|
||||||
|
config := fmt.Sprintf(`
|
||||||
|
vault {
|
||||||
|
address = "%s"
|
||||||
|
tls_skip_verify = true
|
||||||
|
}
|
||||||
|
%s
|
||||||
|
`, serverClient.Address(), listenConfig)
|
||||||
|
configPath := makeTempFile(t, "config.hcl", config)
|
||||||
|
defer os.Remove(configPath)
|
||||||
|
|
||||||
|
// Start the agent
|
||||||
|
_, cmd := testAgentCommand(t, logger)
|
||||||
|
cmd.startedCh = make(chan struct{})
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
cmd.Run([]string{"-config", configPath})
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-cmd.startedCh:
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Errorf("timeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
agentClient, err := api.NewClient(api.DefaultConfig())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
agentClient.AddHeader("User-Agent", userAgentForProxiedClient)
|
||||||
|
agentClient.SetToken(serverClient.Token())
|
||||||
|
agentClient.SetMaxRetries(0)
|
||||||
|
err = agentClient.SetAddress("http://" + listenAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = agentClient.Auth().Token().LookupSelf()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
close(cmd.ShutdownCh)
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestAgent_APIProxyWithCache_UserAgent tests that the User-Agent sent
|
||||||
|
// to Vault by Vault Agent is correct using the API proxy with
|
||||||
|
// the cache configured. Uses the custom handler
|
||||||
|
// userAgentHandler struct defined in this test package, so that Vault validates the
|
||||||
|
// User-Agent on requests sent by Agent.
|
||||||
|
func TestAgent_APIProxyWithCache_UserAgent(t *testing.T) {
|
||||||
|
logger := logging.NewVaultLogger(hclog.Trace)
|
||||||
|
userAgentForProxiedClient := "proxied-client"
|
||||||
|
var h userAgentHandler
|
||||||
|
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
|
||||||
|
NumCores: 1,
|
||||||
|
HandlerFunc: vaulthttp.HandlerFunc(
|
||||||
|
func(properties *vault.HandlerProperties) http.Handler {
|
||||||
|
h.props = properties
|
||||||
|
h.userAgentToCheckFor = useragent.AgentProxyStringWithProxiedUserAgent(userAgentForProxiedClient)
|
||||||
|
h.pathToCheck = "/v1/auth/token/lookup-self"
|
||||||
|
h.requestMethodToCheck = "GET"
|
||||||
|
h.t = t
|
||||||
|
return &h
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
cluster.Start()
|
||||||
|
defer cluster.Cleanup()
|
||||||
|
|
||||||
|
serverClient := cluster.Cores[0].Client
|
||||||
|
|
||||||
|
// Unset the environment variable so that agent picks up the right test
|
||||||
|
// cluster address
|
||||||
|
defer os.Setenv(api.EnvVaultAddress, os.Getenv(api.EnvVaultAddress))
|
||||||
|
os.Unsetenv(api.EnvVaultAddress)
|
||||||
|
|
||||||
|
listenAddr := generateListenerAddress(t)
|
||||||
|
listenConfig := fmt.Sprintf(`
|
||||||
|
listener "tcp" {
|
||||||
|
address = "%s"
|
||||||
|
tls_disable = true
|
||||||
|
}
|
||||||
|
`, listenAddr)
|
||||||
|
|
||||||
|
cacheConfig := `
|
||||||
|
cache {
|
||||||
|
}`
|
||||||
|
|
||||||
|
config := fmt.Sprintf(`
|
||||||
|
vault {
|
||||||
|
address = "%s"
|
||||||
|
tls_skip_verify = true
|
||||||
|
}
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
`, serverClient.Address(), listenConfig, cacheConfig)
|
||||||
|
configPath := makeTempFile(t, "config.hcl", config)
|
||||||
|
defer os.Remove(configPath)
|
||||||
|
|
||||||
|
// Start the agent
|
||||||
|
_, cmd := testAgentCommand(t, logger)
|
||||||
|
cmd.startedCh = make(chan struct{})
|
||||||
|
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
cmd.Run([]string{"-config", configPath})
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-cmd.startedCh:
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
t.Errorf("timeout")
|
||||||
|
}
|
||||||
|
|
||||||
|
agentClient, err := api.NewClient(api.DefaultConfig())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
agentClient.AddHeader("User-Agent", userAgentForProxiedClient)
|
||||||
|
agentClient.SetToken(serverClient.Token())
|
||||||
|
agentClient.SetMaxRetries(0)
|
||||||
|
err = agentClient.SetAddress("http://" + listenAddr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = agentClient.Auth().Token().LookupSelf()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
close(cmd.ShutdownCh)
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func TestAgent_Cache_DynamicSecret(t *testing.T) {
|
func TestAgent_Cache_DynamicSecret(t *testing.T) {
|
||||||
logger := logging.NewVaultLogger(hclog.Trace)
|
logger := logging.NewVaultLogger(hclog.Trace)
|
||||||
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
|
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
|
||||||
|
|||||||
18
go.mod
18
go.mod
@@ -63,8 +63,8 @@ require (
|
|||||||
github.com/google/go-metrics-stackdriver v0.2.0
|
github.com/google/go-metrics-stackdriver v0.2.0
|
||||||
github.com/google/tink/go v1.6.1
|
github.com/google/tink/go v1.6.1
|
||||||
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220
|
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220
|
||||||
github.com/hashicorp/consul-template v0.29.5
|
github.com/hashicorp/consul-template v0.30.1-0.20230322153229-821bc07137f5
|
||||||
github.com/hashicorp/consul/api v1.17.0
|
github.com/hashicorp/consul/api v1.18.0
|
||||||
github.com/hashicorp/errwrap v1.1.0
|
github.com/hashicorp/errwrap v1.1.0
|
||||||
github.com/hashicorp/eventlogger v0.1.1
|
github.com/hashicorp/eventlogger v0.1.1
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||||
@@ -105,7 +105,7 @@ require (
|
|||||||
github.com/hashicorp/hcp-link v0.1.0
|
github.com/hashicorp/hcp-link v0.1.0
|
||||||
github.com/hashicorp/hcp-scada-provider v0.2.1
|
github.com/hashicorp/hcp-scada-provider v0.2.1
|
||||||
github.com/hashicorp/hcp-sdk-go v0.23.0
|
github.com/hashicorp/hcp-sdk-go v0.23.0
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20220707195938-75f4c2237b28
|
github.com/hashicorp/nomad/api v0.0.0-20230103221135-ce00d683f9be
|
||||||
github.com/hashicorp/raft v1.3.10
|
github.com/hashicorp/raft v1.3.10
|
||||||
github.com/hashicorp/raft-autopilot v0.2.0
|
github.com/hashicorp/raft-autopilot v0.2.0
|
||||||
github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c
|
github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c
|
||||||
@@ -192,7 +192,7 @@ require (
|
|||||||
go.opentelemetry.io/otel v1.11.2
|
go.opentelemetry.io/otel v1.11.2
|
||||||
go.opentelemetry.io/otel/sdk v1.11.2
|
go.opentelemetry.io/otel/sdk v1.11.2
|
||||||
go.opentelemetry.io/otel/trace v1.11.2
|
go.opentelemetry.io/otel/trace v1.11.2
|
||||||
go.uber.org/atomic v1.9.0
|
go.uber.org/atomic v1.10.0
|
||||||
go.uber.org/goleak v1.1.12
|
go.uber.org/goleak v1.1.12
|
||||||
golang.org/x/crypto v0.6.0
|
golang.org/x/crypto v0.6.0
|
||||||
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
|
golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb
|
||||||
@@ -247,7 +247,9 @@ require (
|
|||||||
github.com/Jeffail/gabs v1.1.1 // indirect
|
github.com/Jeffail/gabs v1.1.1 // indirect
|
||||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||||
github.com/Masterminds/semver v1.5.0 // indirect
|
github.com/Masterminds/semver v1.5.0 // indirect
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
|
||||||
github.com/Microsoft/go-winio v0.5.2 // indirect
|
github.com/Microsoft/go-winio v0.5.2 // indirect
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
@@ -356,8 +358,8 @@ require (
|
|||||||
github.com/hashicorp/serf v0.10.1 // indirect
|
github.com/hashicorp/serf v0.10.1 // indirect
|
||||||
github.com/hashicorp/vault/api/auth/kubernetes v0.3.0 // indirect
|
github.com/hashicorp/vault/api/auth/kubernetes v0.3.0 // indirect
|
||||||
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
|
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
|
||||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect
|
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||||
github.com/huandu/xstrings v1.3.2 // indirect
|
github.com/huandu/xstrings v1.4.0 // indirect
|
||||||
github.com/imdario/mergo v0.3.13 // indirect
|
github.com/imdario/mergo v0.3.13 // indirect
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||||
github.com/jackc/pgconn v1.11.0 // indirect
|
github.com/jackc/pgconn v1.11.0 // indirect
|
||||||
@@ -417,11 +419,13 @@ require (
|
|||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
github.com/rogpeppe/go-internal v1.9.0 // indirect
|
||||||
|
github.com/shopspring/decimal v1.3.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||||
github.com/snowflakedb/gosnowflake v1.6.3 // indirect
|
github.com/snowflakedb/gosnowflake v1.6.3 // indirect
|
||||||
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
|
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
|
||||||
github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
|
github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
|
||||||
|
github.com/spf13/cast v1.5.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/stretchr/objx v0.5.0 // indirect
|
github.com/stretchr/objx v0.5.0 // indirect
|
||||||
github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect
|
github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect
|
||||||
@@ -448,7 +452,7 @@ require (
|
|||||||
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect
|
||||||
golang.org/x/mod v0.8.0 // indirect
|
golang.org/x/mod v0.8.0 // indirect
|
||||||
golang.org/x/text v0.8.0 // indirect
|
golang.org/x/text v0.8.0 // indirect
|
||||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
|
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
|
||||||
|
|||||||
43
go.sum
43
go.sum
@@ -141,10 +141,13 @@ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy86
|
|||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
|
||||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||||
|
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
|
||||||
|
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||||
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
|
||||||
@@ -784,10 +787,10 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc
|
|||||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||||
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220 h1:Vgv3jG0kicczshK+lOHWJ9OososZjnjSu1YslqofFYY=
|
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220 h1:Vgv3jG0kicczshK+lOHWJ9OososZjnjSu1YslqofFYY=
|
||||||
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220/go.mod h1:zb3VvIFA0lM2lbmO69NjowV9dJzJnZS89TaM9blXPJA=
|
github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220/go.mod h1:zb3VvIFA0lM2lbmO69NjowV9dJzJnZS89TaM9blXPJA=
|
||||||
github.com/hashicorp/consul-template v0.29.5 h1:tzEo93RqODAX2cgOe/ke8xcpdPdxg5rxl6d22wE3f6c=
|
github.com/hashicorp/consul-template v0.30.1-0.20230322153229-821bc07137f5 h1:Z5Pzj0hUZzjWtaKATeWzTHfsr+onJEwBVe7JBiJiemM=
|
||||||
github.com/hashicorp/consul-template v0.29.5/go.mod h1:SZGBPz/t0JaBwMOqM6q/mG66cBRA8IeDUjOwjO0Pa5M=
|
github.com/hashicorp/consul-template v0.30.1-0.20230322153229-821bc07137f5/go.mod h1:KfaZbjtDruE5wsV9fBimP30C6xnF3cHJUX7/AQOFgM4=
|
||||||
github.com/hashicorp/consul/api v1.17.0 h1:aqytbw31uCPNn37ST+717IyGod+P1eTgSGu3yjRo4bs=
|
github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g=
|
||||||
github.com/hashicorp/consul/api v1.17.0/go.mod h1:ZNwemOPAdgtV4cCx9fqxNmw+PI3vliW6gYin2WD+F2g=
|
github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4=
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU=
|
github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU=
|
||||||
github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE=
|
github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE=
|
||||||
@@ -931,8 +934,8 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR
|
|||||||
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
|
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
|
||||||
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w=
|
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w=
|
||||||
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo=
|
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20220707195938-75f4c2237b28 h1:fo8EbQ6tc9hYqxik9CAdFMqy48TW8hh2I3znysPqf+0=
|
github.com/hashicorp/nomad/api v0.0.0-20230103221135-ce00d683f9be h1:bJ/jBA5pt/5OT1oaApx8B5g/nRyohn61Q8TyUp4PoEI=
|
||||||
github.com/hashicorp/nomad/api v0.0.0-20220707195938-75f4c2237b28/go.mod h1:FslB+3eLbZgkuPWffqO1GeNzBFw1SuVqN2PXsMNe0Fg=
|
github.com/hashicorp/nomad/api v0.0.0-20230103221135-ce00d683f9be/go.mod h1:EM/2XaEwHziSB4NdWZ6MfE65TcvgWwVawOUBT8kVRqE=
|
||||||
github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
|
github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
|
||||||
github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
|
github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
|
||||||
github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
|
github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8=
|
||||||
@@ -1008,11 +1011,13 @@ github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 h1:O/pT5C1Q3mVXMyu
|
|||||||
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo=
|
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443/go.mod h1:bEpDU35nTu0ey1EXjwNwPjI9xErAsoOCmcMb9GKvyxo=
|
||||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I=
|
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||||
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
|
||||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
|
github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
|
||||||
|
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@@ -1467,9 +1472,11 @@ github.com/sethvargo/go-limiter v0.7.1 h1:wWNhTj0pxjyJ7wuJHpRJpYwJn+bUnjYfw2a85e
|
|||||||
github.com/sethvargo/go-limiter v0.7.1/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=
|
github.com/sethvargo/go-limiter v0.7.1/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=
|
github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
|
github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
|
||||||
|
github.com/shoenig/test v0.5.2 h1:ELZ7qZ/6CPrT71PXrSe2TFzLs4/cGCqqU5lZ5RhZ+B8=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
|
||||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
|
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||||
|
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
@@ -1499,6 +1506,9 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
|
|||||||
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
|
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
|
||||||
|
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
|
||||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||||
@@ -1643,8 +1653,9 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
|||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
|
||||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
|
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||||
|
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
@@ -1695,6 +1706,7 @@ golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0
|
|||||||
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220313003712-b769efc7c000/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
@@ -1805,6 +1817,7 @@ golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qx
|
|||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM=
|
golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM=
|
||||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||||
|
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
@@ -1939,6 +1952,7 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
@@ -1947,6 +1961,7 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX
|
|||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -1967,8 +1982,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
|
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|||||||
@@ -32,3 +32,45 @@ func String() string {
|
|||||||
return fmt.Sprintf("Vault/%s (+%s; %s)",
|
return fmt.Sprintf("Vault/%s (+%s; %s)",
|
||||||
versionFunc(), projectURL, rt)
|
versionFunc(), projectURL, rt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AgentString returns the consistent user-agent string for Vault Agent.
|
||||||
|
//
|
||||||
|
// e.g. Vault Agent/0.10.4 (+https://www.vaultproject.io/; go1.10.1)
|
||||||
|
func AgentString() string {
|
||||||
|
return fmt.Sprintf("Vault Agent/%s (+%s; %s)",
|
||||||
|
versionFunc(), projectURL, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AgentTemplatingString returns the consistent user-agent string for Vault Agent Templating.
|
||||||
|
//
|
||||||
|
// e.g. Vault Agent Templating/0.10.4 (+https://www.vaultproject.io/; go1.10.1)
|
||||||
|
func AgentTemplatingString() string {
|
||||||
|
return fmt.Sprintf("Vault Agent Templating/%s (+%s; %s)",
|
||||||
|
versionFunc(), projectURL, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AgentProxyString returns the consistent user-agent string for Vault Agent API Proxying.
|
||||||
|
//
|
||||||
|
// e.g. Vault Agent API Proxy/0.10.4 (+https://www.vaultproject.io/; go1.10.1)
|
||||||
|
func AgentProxyString() string {
|
||||||
|
return fmt.Sprintf("Vault Agent API Proxy/%s (+%s; %s)",
|
||||||
|
versionFunc(), projectURL, rt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AgentProxyStringWithProxiedUserAgent returns the consistent user-agent
|
||||||
|
// string for Vault Agent API Proxying, keeping the User-Agent of the proxied
|
||||||
|
// client as an extension to this UserAgent
|
||||||
|
//
|
||||||
|
// e.g. Vault Agent API Proxy/0.10.4 (+https://www.vaultproject.io/; go1.10.1); proxiedUserAgent
|
||||||
|
func AgentProxyStringWithProxiedUserAgent(proxiedUserAgent string) string {
|
||||||
|
return fmt.Sprintf("Vault Agent API Proxy/%s (+%s; %s); %s",
|
||||||
|
versionFunc(), projectURL, rt, proxiedUserAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AgentAutoAuthString returns the consistent user-agent string for Vault Agent Auto-Auth.
|
||||||
|
//
|
||||||
|
// e.g. Vault Agent Auto-Auth/0.10.4 (+https://www.vaultproject.io/; go1.10.1)
|
||||||
|
func AgentAutoAuthString() string {
|
||||||
|
return fmt.Sprintf("Vault Agent Auto-Auth/%s (+%s; %s)",
|
||||||
|
versionFunc(), projectURL, rt)
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ package useragent
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUserAgent(t *testing.T) {
|
func TestUserAgent(t *testing.T) {
|
||||||
@@ -15,7 +17,71 @@ func TestUserAgent(t *testing.T) {
|
|||||||
act := String()
|
act := String()
|
||||||
|
|
||||||
exp := "Vault/1.2.3 (+https://vault-test.com; go5.0)"
|
exp := "Vault/1.2.3 (+https://vault-test.com; go5.0)"
|
||||||
if exp != act {
|
require.Equal(t, exp, act)
|
||||||
t.Errorf("expected %q to be %q", act, exp)
|
}
|
||||||
}
|
|
||||||
|
// TestUserAgent_VaultAgent tests the AgentString() function works
|
||||||
|
// as expected
|
||||||
|
func TestUserAgent_VaultAgent(t *testing.T) {
|
||||||
|
projectURL = "https://vault-test.com"
|
||||||
|
rt = "go5.0"
|
||||||
|
versionFunc = func() string { return "1.2.3" }
|
||||||
|
|
||||||
|
act := AgentString()
|
||||||
|
|
||||||
|
exp := "Vault Agent/1.2.3 (+https://vault-test.com; go5.0)"
|
||||||
|
require.Equal(t, exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUserAgent_VaultAgentTemplating tests the AgentTemplatingString() function works
|
||||||
|
// as expected
|
||||||
|
func TestUserAgent_VaultAgentTemplating(t *testing.T) {
|
||||||
|
projectURL = "https://vault-test.com"
|
||||||
|
rt = "go5.0"
|
||||||
|
versionFunc = func() string { return "1.2.3" }
|
||||||
|
|
||||||
|
act := AgentTemplatingString()
|
||||||
|
|
||||||
|
exp := "Vault Agent Templating/1.2.3 (+https://vault-test.com; go5.0)"
|
||||||
|
require.Equal(t, exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUserAgent_VaultAgentProxy tests the AgentProxyString() function works
|
||||||
|
// as expected
|
||||||
|
func TestUserAgent_VaultAgentProxy(t *testing.T) {
|
||||||
|
projectURL = "https://vault-test.com"
|
||||||
|
rt = "go5.0"
|
||||||
|
versionFunc = func() string { return "1.2.3" }
|
||||||
|
|
||||||
|
act := AgentProxyString()
|
||||||
|
|
||||||
|
exp := "Vault Agent API Proxy/1.2.3 (+https://vault-test.com; go5.0)"
|
||||||
|
require.Equal(t, exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUserAgent_VaultAgentProxyWithProxiedUserAgent tests the AgentProxyStringWithProxiedUserAgent()
|
||||||
|
// function works as expected
|
||||||
|
func TestUserAgent_VaultAgentProxyWithProxiedUserAgent(t *testing.T) {
|
||||||
|
projectURL = "https://vault-test.com"
|
||||||
|
rt = "go5.0"
|
||||||
|
versionFunc = func() string { return "1.2.3" }
|
||||||
|
userAgent := "my-user-agent"
|
||||||
|
|
||||||
|
act := AgentProxyStringWithProxiedUserAgent(userAgent)
|
||||||
|
|
||||||
|
exp := "Vault Agent API Proxy/1.2.3 (+https://vault-test.com; go5.0); my-user-agent"
|
||||||
|
require.Equal(t, exp, act)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUserAgent_VaultAgentAutoAuth tests the AgentAutoAuthString() function works
|
||||||
|
// as expected
|
||||||
|
func TestUserAgent_VaultAgentAutoAuth(t *testing.T) {
|
||||||
|
projectURL = "https://vault-test.com"
|
||||||
|
rt = "go5.0"
|
||||||
|
versionFunc = func() string { return "1.2.3" }
|
||||||
|
|
||||||
|
act := AgentAutoAuthString()
|
||||||
|
|
||||||
|
exp := "Vault Agent Auto-Auth/1.2.3 (+https://vault-test.com; go5.0)"
|
||||||
|
require.Equal(t, exp, act)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user