Merge branch 'main' into raft-wal

This commit is contained in:
Josh Black
2024-01-04 17:19:00 -08:00
294 changed files with 3078 additions and 694 deletions

View File

@@ -2,13 +2,13 @@ schema_version = 1
project {
license = "BUSL-1.1"
copyright_year = 2023
copyright_year = 2024
# (OPTIONAL) A list of globs that should not have copyright/license headers.
# Supports doublestar glob patterns for more flexibility in defining which
# files or folders should be ignored
header_ignore = [
"builtin/credential/aws/pkcs7/**",
"helper/pkcs7/**",
"ui/node_modules/**",
"enos/modules/k8s_deploy_vault/raft-config.hcl",
"plugins/database/postgresql/scram/**",

View File

@@ -83,8 +83,6 @@ jobs:
- name: SARIF Output
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cat results.sarif

View File

@@ -4,7 +4,7 @@ License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
Parameters
Licensor: HashiCorp, Inc.
Licensed Work: Vault Version 1.15.0 or later. The Licensed Work is (c) 2023
Licensed Work: Vault Version 1.15.0 or later. The Licensed Work is (c) 2024
HashiCorp, Inc.
Additional Use Grant: You may make production use of the Licensed Work, provided
Your use does not include offering the Licensed Work to third

View File

@@ -2,7 +2,7 @@ schema_version = 1
project {
license = "MPL-2.0"
copyright_year = 2023
copyright_year = 2024
header_ignore = []
}

View File

@@ -3,8 +3,9 @@ module github.com/hashicorp/vault/api/auth/gcp
go 1.16
require (
cloud.google.com/go v0.97.0
cloud.google.com/go/compute/metadata v0.2.3
cloud.google.com/go/iam v0.13.0
github.com/hashicorp/vault/api v1.10.0
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0
google.golang.org/grpc v1.41.0 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1
google.golang.org/grpc v1.56.3 // indirect
)

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ require (
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2
github.com/hashicorp/hcl v1.0.0
github.com/mitchellh/mapstructure v1.5.0
golang.org/x/net v0.7.0
golang.org/x/net v0.17.0
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
)
@@ -33,7 +33,7 @@ require (
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
)

View File

@@ -68,11 +68,11 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
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.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -80,11 +80,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -26,14 +26,14 @@ import (
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/errwrap"
cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/go-secure-stdlib/awsutil"
"github.com/hashicorp/go-secure-stdlib/parseutil"
"github.com/hashicorp/go-secure-stdlib/strutil"
uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/builtin/credential/aws/pkcs7"
"github.com/hashicorp/vault/helper/pkcs7"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/cidrutil"
"github.com/hashicorp/vault/sdk/helper/jsonutil"

View File

@@ -586,10 +586,10 @@ func (b *databaseBackend) initQueue(ctx context.Context, conf *logical.BackendCo
queueTickerInterval := defaultQueueTickSeconds * time.Second
if strVal, ok := conf.Config[queueTickIntervalKey]; ok {
newVal, err := strconv.Atoi(strVal)
if err == nil {
if err == nil && newVal > 0 {
queueTickerInterval = time.Duration(newVal) * time.Second
} else {
b.Logger().Error("bad value for %q option: %q", queueTickIntervalKey, strVal)
b.Logger().Error("bad value for %q option: %q, default value of %d being used instead", queueTickIntervalKey, strVal, defaultQueueTickSeconds)
}
}
go b.runTicker(ctx, queueTickerInterval, conf.StorageView)

View File

@@ -28,6 +28,7 @@ import (
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/robfig/cron/v3"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
mongodbatlasapi "go.mongodb.org/atlas/mongodbatlas"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
@@ -998,6 +999,34 @@ func TestBackend_StaticRole_Rotation_MongoDBAtlas(t *testing.T) {
})
}
// TestQueueTickIntervalKeyConfig tests the configuration of queueTickIntervalKey
// does not break on invalid values.
func TestQueueTickIntervalKeyConfig(t *testing.T) {
t.Parallel()
cluster, sys := getClusterPostgresDB(t)
defer cluster.Cleanup()
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
config.System = sys
config.Config[queueTickIntervalKey] = "1"
// Rotation ticker starts running in Factory call
b, err := Factory(context.Background(), config)
require.Nil(t, err)
b.Cleanup(context.Background())
config.Config[queueTickIntervalKey] = "0"
b, err = Factory(context.Background(), config)
require.Nil(t, err)
b.Cleanup(context.Background())
config.Config[queueTickIntervalKey] = "-1"
b, err = Factory(context.Background(), config)
require.Nil(t, err)
b.Cleanup(context.Background())
}
func testBackend_StaticRole_Rotations(t *testing.T, createUser userCreator, opts map[string]interface{}) {
// We need to set this value for the plugin to run, but it doesn't matter what we set it to.
oldToken := os.Getenv(pluginutil.PluginUnwrapTokenEnv)

View File

@@ -14,8 +14,10 @@ import (
)
// Error prefix; see RFC 8555 Section 6.7. Errors.
const ErrorPrefix = "urn:ietf:params:acme:error:"
const ErrorContentType = "application/problem+json"
const (
ErrorPrefix = "urn:ietf:params:acme:error:"
ErrorContentType = "application/problem+json"
)
// See RFC 8555 Section 6.7. Errors.
var ErrAccountDoesNotExist = errors.New("The request specified an account that does not exist")

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: BUSL-1.1
package transit

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: BUSL-1.1
package transit

3
changelog/24548.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:improvement
agent/template: Added max_connections_per_host to limit total number of connections per Vault host.
```

3
changelog/24616.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
fairshare: fix a race condition in JobManager.GetWorkerCounts
```

3
changelog/24649.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
cassandra: Update Cassandra to set consistency prior to calling CreateSession, ensuring consistency setting is correct when opening connection.
```

6
changelog/24667.txt Normal file
View File

@@ -0,0 +1,6 @@
```release-note:improvement
agent: Added new namespace top level configuration parameter, which can be used to make requests made by Agent to go to that namespace.
```
```release-note:improvement
proxy: Added new namespace top level configuration parameter, and prepend_configured_namespace API Proxy configuration parameter, which can be used to make requests made to Proxy get proxied to that namespace.
```

View File

@@ -309,14 +309,25 @@ func (c *AgentCommand) Run(args []string) int {
}
c.metricsHelper = metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
var templateNamespace string
// This indicates whether the namespace for the client has been set by environment variable.
// If it has, we don't touch it
namespaceSetByEnvironmentVariable := client.Namespace() != ""
if !namespaceSetByEnvironmentVariable && config.Vault != nil && config.Vault.Namespace != "" {
client.SetNamespace(config.Vault.Namespace)
}
var method auth.AuthMethod
var sinks []*sink.SinkConfig
var templateNamespace string
if config.AutoAuth != nil {
if client.Headers().Get(consts.NamespaceHeaderName) == "" && config.AutoAuth.Method.Namespace != "" {
// Note: This will only set namespace header to the value in config.AutoAuth.Method.Namespace
// only if it hasn't been set by config.Vault.Namespace above. In that case, the config value
// present at config.AutoAuth.Method.Namespace will still be used for auto-auth.
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
client.SetNamespace(config.AutoAuth.Method.Namespace)
}
templateNamespace = client.Headers().Get(consts.NamespaceHeaderName)
templateNamespace = client.Namespace()
sinkClient, err := client.CloneWithHeaders()
if err != nil {
@@ -707,6 +718,11 @@ func (c *AgentCommand) Run(args []string) int {
return 1
}
// Override the set namespace with the auto-auth specific namespace
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
ahClient.SetNamespace(config.AutoAuth.Method.Namespace)
}
if config.DisableIdleConnsAutoAuth {
ahClient.SetMaxIdleConnections(-1)
}

View File

@@ -56,6 +56,8 @@ type Config struct {
const (
DisableIdleConnsEnv = "VAULT_AGENT_DISABLE_IDLE_CONNECTIONS"
DisableKeepAlivesEnv = "VAULT_AGENT_DISABLE_KEEP_ALIVES"
DefaultTemplateConfigMaxConnsPerHost = 10
)
func (c *Config) Prune() {
@@ -89,6 +91,7 @@ type Vault struct {
ClientCert string `hcl:"client_cert"`
ClientKey string `hcl:"client_key"`
TLSServerName string `hcl:"tls_server_name"`
Namespace string `hcl:"namespace"`
Retry *Retry `hcl:"retry"`
}
@@ -165,6 +168,8 @@ type TemplateConfig struct {
ExitOnRetryFailure bool `hcl:"exit_on_retry_failure"`
StaticSecretRenderIntRaw interface{} `hcl:"static_secret_render_interval"`
StaticSecretRenderInt time.Duration `hcl:"-"`
MaxConnectionsPerHostRaw interface{} `hcl:"max_connections_per_host"`
MaxConnectionsPerHost int `hcl:"-"`
}
type ExecConfig struct {
@@ -1126,6 +1131,17 @@ func parseTemplateConfig(result *Config, list *ast.ObjectList) error {
result.TemplateConfig.StaticSecretRenderIntRaw = nil
}
if result.TemplateConfig.MaxConnectionsPerHostRaw != nil {
var err error
if result.TemplateConfig.MaxConnectionsPerHost, err = parseutil.SafeParseInt(result.TemplateConfig.MaxConnectionsPerHostRaw); err != nil {
return err
}
result.TemplateConfig.MaxConnectionsPerHostRaw = nil
} else {
result.TemplateConfig.MaxConnectionsPerHost = DefaultTemplateConfigMaxConnsPerHost
}
return nil
}

View File

@@ -998,12 +998,14 @@ func TestLoadConfigFile_TemplateConfig(t *testing.T) {
TemplateConfig{
ExitOnRetryFailure: true,
StaticSecretRenderInt: 1 * time.Minute,
MaxConnectionsPerHost: 100,
},
},
"empty": {
"./test-fixtures/config-template_config-empty.hcl",
TemplateConfig{
ExitOnRetryFailure: false,
ExitOnRetryFailure: false,
MaxConnectionsPerHost: 10,
},
},
}

View File

@@ -11,6 +11,7 @@ vault {
template_config {
exit_on_retry_failure = true
static_secret_render_interval = 60
max_connections_per_host = 100
}
template {

View File

@@ -51,6 +51,10 @@ func NewConfig(mc ManagerConfig, templates ctconfig.TemplateConfigs) (*ctconfig.
conf.Vault.Transport.DisableKeepAlives = pointerutil.BoolPtr(true)
}
if mc.AgentConfig.TemplateConfig != nil && mc.AgentConfig.TemplateConfig.MaxConnectionsPerHost != 0 {
conf.Vault.Transport.MaxConnsPerHost = &mc.AgentConfig.TemplateConfig.MaxConnectionsPerHost
}
conf.Vault.SSL = &ctconfig.SSLConfig{
Enabled: pointerutil.BoolPtr(false),
Verify: pointerutil.BoolPtr(false),

View File

@@ -224,6 +224,7 @@ func generateConfiguration(ctx context.Context, client *api.Client, flagExec str
TemplateConfig: generatedConfigTemplateConfig{
StaticSecretRenderInterval: "5m",
ExitOnRetryFailure: true,
MaxConnectionsPerHost: 10,
},
Vault: generatedConfigVault{
Address: client.Address(),
@@ -410,6 +411,7 @@ type generatedConfig struct {
type generatedConfigTemplateConfig struct {
StaticSecretRenderInterval string `hcl:"static_secret_render_interval"`
ExitOnRetryFailure bool `hcl:"exit_on_retry_failure"`
MaxConnectionsPerHost int `hcl:"max_connections_per_host"`
}
type generatedConfigExec struct {

View File

@@ -180,6 +180,7 @@ auto_auth \{
template_config \{
static_secret_render_interval = "5m"
exit_on_retry_failure = true
max_connections_per_host = 10
}
vault \{
@@ -222,6 +223,7 @@ auto_auth \{
template_config \{
static_secret_render_interval = "5m"
exit_on_retry_failure = true
max_connections_per_host = 10
}
vault \{

View File

@@ -63,10 +63,10 @@ func NewAliCloudAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
// Check for an optional custom frequency at which we should poll for creds.
credCheckFreqSec := defaultCredCheckFreqSeconds
if checkFreqRaw, ok := conf.Config["credential_poll_interval"]; ok {
if credFreq, ok := checkFreqRaw.(int); ok {
if credFreq, ok := checkFreqRaw.(int); ok && credFreq > 0 {
credCheckFreqSec = credFreq
} else {
return nil, errors.New("could not convert 'credential_poll_interval' config value to int")
return nil, errors.New("could not convert 'credential_poll_interval' config value to positive int")
}
}

View File

@@ -7,12 +7,14 @@ import (
"context"
"encoding/json"
"errors"
"math"
"math/rand"
"net/http"
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/sdk/helper/backoff"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
@@ -113,19 +115,15 @@ func NewAuthHandler(conf *AuthHandlerConfig) *AuthHandler {
return ah
}
func backoff(ctx context.Context, backoff *autoAuthBackoff) bool {
if backoff.exitOnErr {
func backoffSleep(ctx context.Context, backoff *autoAuthBackoff) bool {
nextSleep, err := backoff.backoff.Next()
if err != nil {
return false
}
select {
case <-time.After(backoff.current):
case <-time.After(nextSleep):
case <-ctx.Done():
}
// Increase exponential backoff for the next time if we don't
// successfully auth/renew/etc.
backoff.next()
return true
}
@@ -137,12 +135,13 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
if ah.minBackoff <= 0 {
ah.minBackoff = defaultMinBackoff
}
backoffCfg := newAutoAuthBackoff(ah.minBackoff, ah.maxBackoff, ah.exitOnError)
if backoffCfg.min >= backoffCfg.max {
if ah.maxBackoff <= 0 {
ah.maxBackoff = defaultMaxBackoff
}
if ah.minBackoff > ah.maxBackoff {
return errors.New("auth handler: min_backoff cannot be greater than max_backoff")
}
backoffCfg := newAutoAuthBackoff(ah.minBackoff, ah.maxBackoff, ah.exitOnError)
ah.logger.Info("starting auth handler")
defer func() {
@@ -204,10 +203,10 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
case AuthMethodWithClient:
clientToUse, err = am.(AuthMethodWithClient).AuthClient(ah.client)
if err != nil {
ah.logger.Error("error creating client for authentication call", "error", err, "backoff", backoff)
ah.logger.Error("error creating client for authentication call", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
@@ -234,7 +233,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("could not look up token", "err", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -254,7 +253,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("error getting path or data from method", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -262,12 +261,12 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
}
if ah.wrapTTL > 0 {
wrapClient, err := clientToUse.Clone()
wrapClient, err := clientToUse.CloneWithHeaders()
if err != nil {
ah.logger.Error("error creating client for wrapped call", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -289,7 +288,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
isTokenFileMethod = path == "auth/token/lookup-self"
if isTokenFileMethod {
token, _ := data["token"].(string)
lookupSelfClient, err := clientToUse.Clone()
lookupSelfClient, err := clientToUse.CloneWithHeaders()
if err != nil {
ah.logger.Error("failed to clone client to perform token lookup")
return err
@@ -305,7 +304,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("error authenticating", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -320,7 +319,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("authentication returned nil wrap info", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -329,7 +328,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("authentication returned empty wrapped client token", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -339,7 +338,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("failed to encode wrapinfo", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -354,7 +353,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
}
am.CredSuccess()
backoffCfg.reset()
backoffCfg.backoff.Reset()
select {
case <-ctx.Done():
@@ -378,7 +377,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("token file validation failed, token may be invalid", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -388,7 +387,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("token file validation returned empty client token", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -420,7 +419,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("authentication returned nil auth info", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -429,7 +428,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("authentication returned empty client token", "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -447,7 +446,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
}
am.CredSuccess()
backoffCfg.reset()
backoffCfg.backoff.Reset()
}
if watcher != nil {
@@ -461,7 +460,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
ah.logger.Error("error creating lifetime watcher", "error", err, "backoff", backoffCfg)
metrics.IncrCounter([]string{ah.metricsSignifier, "auth", "failure"}, 1)
if backoff(ctx, backoffCfg) {
if backoffSleep(ctx, backoffCfg) {
continue
}
return err
@@ -507,10 +506,7 @@ func (ah *AuthHandler) Run(ctx context.Context, am AuthMethod) error {
// autoAuthBackoff tracks exponential backoff state.
type autoAuthBackoff struct {
min time.Duration
max time.Duration
current time.Duration
exitOnErr bool
backoff *backoff.Backoff
}
func newAutoAuthBackoff(min, max time.Duration, exitErr bool) *autoAuthBackoff {
@@ -522,32 +518,18 @@ func newAutoAuthBackoff(min, max time.Duration, exitErr bool) *autoAuthBackoff {
min = defaultMinBackoff
}
retries := math.MaxInt
if exitErr {
retries = 0
}
b := backoff.NewBackoff(retries, min, max)
return &autoAuthBackoff{
current: min,
max: max,
min: min,
exitOnErr: exitErr,
backoff: b,
}
}
// next determines the next backoff duration that is roughly twice
// the current value, capped to a max value, with a measure of randomness.
func (b *autoAuthBackoff) next() {
maxBackoff := 2 * b.current
if maxBackoff > b.max {
maxBackoff = b.max
}
// Trim a random amount (0-25%) off the doubled duration
trim := rand.Int63n(int64(maxBackoff) / 4)
b.current = maxBackoff - time.Duration(trim)
}
func (b *autoAuthBackoff) reset() {
b.current = b.min
}
func (b autoAuthBackoff) String() string {
return b.current.Truncate(10 * time.Millisecond).String()
return b.backoff.Current().Truncate(10 * time.Millisecond).String()
}

View File

@@ -113,35 +113,36 @@ func TestAgentBackoff(t *testing.T) {
backoff := newAutoAuthBackoff(defaultMinBackoff, max, false)
// Test initial value
if backoff.current != defaultMinBackoff {
t.Fatalf("expected 1s initial backoff, got: %v", backoff.current)
if backoff.backoff.Current() > defaultMinBackoff || backoff.backoff.Current() < defaultMinBackoff*3/4 {
t.Fatalf("expected 1s initial backoff, got: %v", backoff.backoff.Current())
}
// Test that backoff values are in expected range (75-100% of 2*previous)
// Test that backoffSleep values are in expected range (75-100% of 2*previous)
next, _ := backoff.backoff.Next()
for i := 0; i < 9; i++ {
old := backoff.current
backoff.next()
old := next
next, _ = backoff.backoff.Next()
expMax := 2 * old
expMin := 3 * expMax / 4
if backoff.current < expMin || backoff.current > expMax {
t.Fatalf("expected backoff in range %v to %v, got: %v", expMin, expMax, backoff)
if next < expMin || next > expMax {
t.Fatalf("expected backoffSleep in range %v to %v, got: %v", expMin, expMax, backoff)
}
}
// Test that backoff is capped
// Test that backoffSleep is capped
for i := 0; i < 100; i++ {
backoff.next()
if backoff.current > max {
_, _ = backoff.backoff.Next()
if backoff.backoff.Current() > max {
t.Fatalf("backoff exceeded max of 100s: %v", backoff)
}
}
// Test reset
backoff.reset()
if backoff.current != defaultMinBackoff {
t.Fatalf("expected 1s backoff after reset, got: %v", backoff.current)
backoff.backoff.Reset()
if backoff.backoff.Current() > defaultMinBackoff || backoff.backoff.Current() < defaultMinBackoff*3/4 {
t.Fatalf("expected 1s backoff after reset, got: %v", backoff.backoff.Current())
}
}
@@ -163,35 +164,36 @@ func TestAgentMinBackoffCustom(t *testing.T) {
backoff := newAutoAuthBackoff(test.minBackoff, max, false)
// Test initial value
if backoff.current != test.want {
t.Fatalf("expected %d initial backoff, got: %v", test.want, backoff.current)
if backoff.backoff.Current() > test.want || backoff.backoff.Current() < test.want*3/4 {
t.Fatalf("expected %d initial backoffSleep, got: %v", test.want, backoff.backoff.Current())
}
// Test that backoff values are in expected range (75-100% of 2*previous)
// Test that backoffSleep values are in expected range (75-100% of 2*previous)
next, _ := backoff.backoff.Next()
for i := 0; i < 5; i++ {
old := backoff.current
backoff.next()
old := next
next, _ = backoff.backoff.Next()
expMax := 2 * old
expMin := 3 * expMax / 4
if backoff.current < expMin || backoff.current > expMax {
t.Fatalf("expected backoff in range %v to %v, got: %v", expMin, expMax, backoff)
if next < expMin || next > expMax {
t.Fatalf("expected backoffSleep in range %v to %v, got: %v", expMin, expMax, backoff)
}
}
// Test that backoff is capped
// Test that backoffSleep is capped
for i := 0; i < 100; i++ {
backoff.next()
if backoff.current > max {
t.Fatalf("backoff exceeded max of 100s: %v", backoff)
next, _ = backoff.backoff.Next()
if next > max {
t.Fatalf("backoffSleep exceeded max of 100s: %v", backoff)
}
}
// Test reset
backoff.reset()
if backoff.current != test.want {
t.Fatalf("expected %d backoff after reset, got: %v", test.want, backoff.current)
backoff.backoff.Reset()
if backoff.backoff.Current() > test.want || backoff.backoff.Current() < test.want*3/4 {
t.Fatalf("expected %d backoffSleep after reset, got: %v", test.want, backoff.backoff.Current())
}
}
}

View File

@@ -158,10 +158,10 @@ func NewAWSAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
// Check for an optional custom frequency at which we should poll for creds.
credentialPollIntervalSec := defaultCredentialPollInterval
if credentialPollIntervalRaw, ok := conf.Config["credential_poll_interval"]; ok {
if credentialPollInterval, ok := credentialPollIntervalRaw.(int); ok {
if credentialPollInterval, ok := credentialPollIntervalRaw.(int); ok && credentialPollInterval > 0 {
credentialPollIntervalSec = credentialPollInterval
} else {
return nil, errors.New("could not convert 'credential_poll_interval' into int")
return nil, errors.New("could not convert 'credential_poll_interval' into positive int")
}
}

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: BUSL-1.1
package ldap
@@ -107,8 +107,8 @@ func NewLdapAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
if passReadPeriodRaw, ok := conf.Config["password_read_period"]; ok {
passReadPeriod, err := parseutil.ParseDurationSecond(passReadPeriodRaw)
if err != nil {
return nil, fmt.Errorf("error parsing 'pass_read_period' value: %w", err)
if err != nil || passReadPeriod <= 0 {
return nil, fmt.Errorf("error parsing 'password_read_period' value into a positive value: %w", err)
}
readPeriod = passReadPeriod
} else {

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: BUSL-1.1
package ldap

View File

@@ -12,6 +12,7 @@ import (
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/http"
)
@@ -41,6 +42,10 @@ type APIProxy struct {
lastIndexStates []string
userAgentString string
userAgentStringFunction func(string) string
// clientNamespace is a one-time set representation of the namespace of the client
// (i.e. client.Namespace()) to avoid repeated calls and lock usage.
clientNamespace string
prependConfiguredNamespace bool
}
var _ Proxier = &APIProxy{}
@@ -56,6 +61,9 @@ type APIProxyConfig struct {
// UserAgentStringFunction is the function to transform the proxied client's
// user agent into one that includes Vault-specific information.
UserAgentStringFunction func(string) string
// PrependConfiguredNamespace configures whether the client's namespace
// should be prepended to proxied requests
PrependConfiguredNamespace bool
}
func NewAPIProxy(config *APIProxyConfig) (Proxier, error) {
@@ -63,12 +71,14 @@ func NewAPIProxy(config *APIProxyConfig) (Proxier, error) {
return nil, fmt.Errorf("nil API client")
}
return &APIProxy{
client: config.Client,
logger: config.Logger,
enforceConsistency: config.EnforceConsistency,
whenInconsistentAction: config.WhenInconsistentAction,
userAgentString: config.UserAgentString,
userAgentStringFunction: config.UserAgentStringFunction,
client: config.Client,
logger: config.Logger,
enforceConsistency: config.EnforceConsistency,
whenInconsistentAction: config.WhenInconsistentAction,
userAgentString: config.UserAgentString,
userAgentStringFunction: config.UserAgentStringFunction,
prependConfiguredNamespace: config.PrependConfiguredNamespace,
clientNamespace: namespace.Canonicalize(config.Client.Namespace()),
}, nil
}
@@ -102,6 +112,11 @@ func (ap *APIProxy) Send(ctx context.Context, req *SendRequest) (*SendResponse,
}
client.SetHeaders(req.Request.Header)
if ap.prependConfiguredNamespace && ap.clientNamespace != "" {
currentNamespace := namespace.Canonicalize(client.Namespace())
newNamespace := namespace.Canonicalize(ap.clientNamespace + currentNamespace)
client.SetNamespace(newNamespace)
}
fwReq := client.NewRequest(req.Request.Method, req.Request.URL.Path)
fwReq.BodyBytes = req.RequestBody

View File

@@ -284,10 +284,21 @@ func (c *ProxyCommand) Run(args []string) int {
}
c.metricsHelper = metricsutil.NewMetricsHelper(inmemMetrics, prometheusEnabled)
// This indicates whether the namespace for the client has been set by environment variable.
// If it has, we don't touch it
namespaceSetByEnvironmentVariable := client.Namespace() != ""
if !namespaceSetByEnvironmentVariable && config.Vault != nil && config.Vault.Namespace != "" {
client.SetNamespace(config.Vault.Namespace)
}
var method auth.AuthMethod
var sinks []*sink.SinkConfig
if config.AutoAuth != nil {
if client.Headers().Get(consts.NamespaceHeaderName) == "" && config.AutoAuth.Method.Namespace != "" {
// Note: This will only set namespace header to the value in config.AutoAuth.Method.Namespace
// only if it hasn't been set by config.Vault.Namespace above. In that case, the config value
// present at config.AutoAuth.Method.Namespace will still be used for auto-auth.
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
client.SetNamespace(config.AutoAuth.Method.Namespace)
}
@@ -421,12 +432,13 @@ func (c *ProxyCommand) Run(args []string) int {
// The API proxy to be used, if listeners are configured
apiProxy, err := cache.NewAPIProxy(&cache.APIProxyConfig{
Client: proxyClient,
Logger: apiProxyLogger,
EnforceConsistency: enforceConsistency,
WhenInconsistentAction: whenInconsistent,
UserAgentStringFunction: useragent.ProxyStringWithProxiedUserAgent,
UserAgentString: useragent.ProxyAPIProxyString(),
Client: proxyClient,
Logger: apiProxyLogger,
EnforceConsistency: enforceConsistency,
WhenInconsistentAction: whenInconsistent,
UserAgentStringFunction: useragent.ProxyStringWithProxiedUserAgent,
UserAgentString: useragent.ProxyAPIProxyString(),
PrependConfiguredNamespace: config.APIProxy != nil && config.APIProxy.PrependConfiguredNamespace,
})
if err != nil {
c.UI.Error(fmt.Sprintf("Error creating API proxy: %v", err))
@@ -686,6 +698,11 @@ func (c *ProxyCommand) Run(args []string) int {
return 1
}
// Override the set namespace with the auto-auth specific namespace
if !namespaceSetByEnvironmentVariable && config.AutoAuth.Method.Namespace != "" {
ahClient.SetNamespace(config.AutoAuth.Method.Namespace)
}
if config.DisableIdleConnsAutoAuth {
ahClient.SetMaxIdleConnections(-1)
}

View File

@@ -77,6 +77,7 @@ type Vault struct {
ClientCert string `hcl:"client_cert"`
ClientKey string `hcl:"client_key"`
TLSServerName string `hcl:"tls_server_name"`
Namespace string `hcl:"namespace"`
Retry *Retry `hcl:"retry"`
}
@@ -92,11 +93,12 @@ type transportDialer interface {
// APIProxy contains any configuration needed for proxy mode
type APIProxy struct {
UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"`
UseAutoAuthToken bool `hcl:"-"`
ForceAutoAuthToken bool `hcl:"-"`
EnforceConsistency string `hcl:"enforce_consistency"`
WhenInconsistent string `hcl:"when_inconsistent"`
UseAutoAuthTokenRaw interface{} `hcl:"use_auto_auth_token"`
UseAutoAuthToken bool `hcl:"-"`
ForceAutoAuthToken bool `hcl:"-"`
EnforceConsistency string `hcl:"enforce_consistency"`
WhenInconsistent string `hcl:"when_inconsistent"`
PrependConfiguredNamespace bool `hcl:"prepend_configured_namespace"`
}
// Cache contains any configuration needed for Cache mode

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
// SPDX-License-Identifier: BUSL-1.1
//go:build !enterprise

View File

@@ -226,6 +226,13 @@ module "vault_verify_undo_logs" {
vault_instance_count = var.vault_instance_count
}
module "vault_verify_default_lcq" {
source = "./modules/vault_verify_default_lcq"
vault_autopilot_default_max_leases = "300000"
vault_instance_count = var.vault_instance_count
}
module "vault_verify_replication" {
source = "./modules/vault_verify_replication"

View File

@@ -50,8 +50,9 @@ scenario "autopilot" {
rhel = provider.enos.rhel
ubuntu = provider.enos.ubuntu
}
manage_service = matrix.artifact_type == "bundle"
vault_install_dir = matrix.artifact_type == "bundle" ? var.vault_install_dir : global.vault_install_dir_packages[matrix.distro]
manage_service = matrix.artifact_type == "bundle"
vault_install_dir = matrix.artifact_type == "bundle" ? var.vault_install_dir : global.vault_install_dir_packages[matrix.distro]
vault_autopilot_default_max_leases = semverconstraint(matrix.initial_version, ">=1.16.0-0") ? "300000" : ""
}
step "build_vault" {
@@ -524,6 +525,27 @@ scenario "autopilot" {
}
}
# Verify that upgrading from a version <1.16.0 does not introduce Default LCQ
step "verify_default_lcq" {
module = module.vault_verify_default_lcq
depends_on = [
step.create_vault_cluster_upgrade_targets,
step.remove_old_nodes,
step.upgrade_vault_cluster_with_autopilot,
step.verify_autopilot_idle_state
]
providers = {
enos = local.enos_provider[matrix.distro]
}
variables {
vault_instances = step.upgrade_vault_cluster_with_autopilot.target_hosts
vault_root_token = step.create_vault_cluster.root_token
vault_autopilot_default_max_leases = local.vault_autopilot_default_max_leases
}
}
output "audit_device_file_path" {
description = "The file path for the file audit device, if enabled"
value = step.create_vault_cluster.audit_device_file_path

View File

@@ -0,0 +1,74 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
terraform {
required_providers {
enos = {
source = "app.terraform.io/hashicorp-qti/enos"
}
}
}
variable "vault_instance_count" {
type = number
description = "How many vault instances are in the cluster"
}
variable "vault_instances" {
type = map(object({
private_ip = string
public_ip = string
}))
description = "The vault cluster instances that were created"
}
variable "vault_root_token" {
type = string
description = "The vault root token"
}
variable "vault_autopilot_default_max_leases" {
type = string
description = "The autopilot upgrade expected max_leases"
}
variable "timeout" {
type = number
description = "The max number of seconds to wait before timing out"
default = 60
}
variable "retry_interval" {
type = number
description = "How many seconds to wait between each retry"
default = 2
}
locals {
public_ips = {
for idx in range(var.vault_instance_count) : idx => {
public_ip = values(var.vault_instances)[idx].public_ip
private_ip = values(var.vault_instances)[idx].private_ip
}
}
}
resource "enos_remote_exec" "smoke_verify_default_lcq" {
for_each = local.public_ips
environment = {
RETRY_INTERVAL = var.retry_interval
TIMEOUT_SECONDS = var.timeout
VAULT_ADDR = "http://localhost:8200"
VAULT_TOKEN = var.vault_root_token
DEFAULT_LCQ = var.vault_autopilot_default_max_leases
}
scripts = [abspath("${path.module}/scripts/smoke-verify-default-lcq.sh")]
transport = {
ssh = {
host = each.value.public_ip
}
}
}

View File

@@ -0,0 +1,46 @@
#!/bin/bash
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: BUSL-1.1
function fail() {
echo "$1" 1>&2
exit 1
}
[[ -z "$RETRY_INTERVAL" ]] && fail "RETRY_INTERVAL env variable has not been set"
[[ -z "$TIMEOUT_SECONDS" ]] && fail "TIMEOUT_SECONDS env variable has not been set"
[[ -z "$VAULT_ADDR" ]] && fail "VAULT_ADDR env variable has not been set"
[[ -z "$VAULT_TOKEN" ]] && fail "VAULT_TOKEN env variable has not been set"
getMaxLeases() {
curl --request GET --header "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/sys/quotas/lease-count/default" | jq '.data.max_leases // empty'
}
waitForMaxLeases() {
local max_leases
if ! max_leases=$(getMaxLeases); then
echo "failed getting /v1/sys/quotas/lease-count/default data" 1>&2
return 1
fi
if [[ "$max_leases" == "$DEFAULT_LCQ" ]]; then
echo "$max_leases"
return 0
else
echo "Expected Default LCQ $DEFAULT_LCQ but got $max_leases"
return 1
fi
}
begin_time=$(date +%s)
end_time=$((begin_time + TIMEOUT_SECONDS))
while [ "$(date +%s)" -lt "$end_time" ]; do
if waitForMaxLeases; then
exit 0
fi
sleep "$RETRY_INTERVAL"
done
fail "Timed out waiting for Default LCQ verification to complete. Data:\n\t$(getMaxLeases)"

40
go.mod
View File

@@ -53,6 +53,7 @@ require (
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/denisenkom/go-mssqldb v0.12.3
github.com/docker/docker v24.0.7+incompatible
github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74
github.com/dustin/go-humanize v1.0.1
github.com/fatih/color v1.16.0
@@ -79,8 +80,8 @@ require (
github.com/hashicorp/cap v0.3.4
github.com/hashicorp/cap/ldap v0.0.0-20230914221201-c4eecc7e31f7
github.com/hashicorp/cli v1.1.6
github.com/hashicorp/consul-template v0.33.0
github.com/hashicorp/consul/api v1.23.0
github.com/hashicorp/consul-template v0.36.0
github.com/hashicorp/consul/api v1.26.1
github.com/hashicorp/errwrap v1.1.0
github.com/hashicorp/eventlogger v0.2.8
github.com/hashicorp/go-bexpr v0.1.12
@@ -211,20 +212,20 @@ require (
go.etcd.io/etcd/client/v3 v3.5.7
go.mongodb.org/atlas v0.33.0
go.mongodb.org/mongo-driver v1.12.1
go.opentelemetry.io/otel v1.16.0
go.opentelemetry.io/otel/sdk v1.14.0
go.opentelemetry.io/otel/trace v1.16.0
go.opentelemetry.io/otel v1.19.0
go.opentelemetry.io/otel/sdk v1.19.0
go.opentelemetry.io/otel/trace v1.19.0
go.uber.org/atomic v1.11.0
go.uber.org/goleak v1.2.1
golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1
golang.org/x/crypto v0.17.0
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/net v0.17.0
golang.org/x/oauth2 v0.11.0
golang.org/x/sync v0.3.0
golang.org/x/sys v0.14.0
golang.org/x/term v0.13.0
golang.org/x/text v0.13.0
golang.org/x/tools v0.10.0
golang.org/x/sys v0.15.0
golang.org/x/term v0.15.0
golang.org/x/text v0.14.0
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846
google.golang.org/api v0.139.0
google.golang.org/grpc v1.58.3
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0
@@ -234,7 +235,7 @@ require (
honnef.co/go/tools v0.4.3
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
layeh.com/radius v0.0.0-20190322222518-890bc1058917
mvdan.cc/gofumpt v0.3.1
mvdan.cc/gofumpt v0.5.0
nhooyr.io/websocket v1.8.7
)
@@ -305,7 +306,7 @@ require (
github.com/boltdb/bolt v1.3.1 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
@@ -316,8 +317,8 @@ require (
github.com/cloudfoundry-community/go-cfclient v0.0.0-20220930021109-9c4e6c59ccf1 // indirect
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect
github.com/containerd/containerd v1.7.0 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/containerd v1.7.11 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/coreos/etcd v3.3.27+incompatible // indirect
github.com/coreos/go-oidc v2.2.1+incompatible // indirect
github.com/coreos/go-oidc/v3 v3.5.0 // indirect
@@ -333,9 +334,8 @@ require (
github.com/digitalocean/godo v1.7.5 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/dnephin/pflag v1.0.7 // indirect
github.com/docker/cli v20.10.20+incompatible // indirect
github.com/docker/cli v23.0.3+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v24.0.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
@@ -403,7 +403,7 @@ require (
github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect
github.com/hashicorp/raft-boltdb v0.0.0-20230125174641-2a8082862702 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/hashicorp/vault/api/auth/kubernetes v0.4.1 // indirect
github.com/hashicorp/vault/api/auth/kubernetes v0.5.0 // indirect
github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/huandu/xstrings v1.4.0 // indirect
@@ -486,7 +486,7 @@ require (
github.com/segmentio/fasthash v1.0.3 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.1.1 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/snowflakedb/gosnowflake v1.6.24 // indirect
@@ -518,7 +518,7 @@ require (
github.com/zeebo/xxh3 v1.0.2 // indirect
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.19.1 // indirect
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect

73
go.sum
View File

@@ -923,8 +923,9 @@ github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XB
github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20221206110420-d395f97c4830/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20221215162035-5330a85ea652/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
@@ -1075,8 +1076,9 @@ github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy
github.com/Microsoft/hcsshim v0.9.3/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim v0.10.0-rc.7 h1:HBytQPxcv8Oy4244zbQbe6hnOnx544eL5QPUqhJldz8=
github.com/Microsoft/hcsshim v0.10.0-rc.7/go.mod h1:ILuwjA+kNW+MrN/w5un7n3mTqkwsFu4Bp05/okFUZlE=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -1258,8 +1260,9 @@ github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4r
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
@@ -1372,8 +1375,9 @@ github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0Npu
github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0=
github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0=
github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ=
github.com/containerd/containerd v1.7.0 h1:G/ZQr3gMZs6ZT0qPUZ15znx5QSdQdASW11nXTLTM2Pg=
github.com/containerd/containerd v1.7.0/go.mod h1:QfR7Efgb/6X2BDpTPJRvPTYDE9rsF0FsXX9J8sIs/sc=
github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
@@ -1382,8 +1386,9 @@ github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
@@ -1500,7 +1505,6 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
@@ -1543,8 +1547,9 @@ github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk=
github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4=
github.com/docker/cli v20.10.20+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v23.0.3+incompatible h1:Zcse1DuDqBdgI7OQDV8Go7b83xLgfhW1eza4HfEdxpY=
github.com/docker/cli v23.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@@ -2140,14 +2145,14 @@ github.com/hashicorp/cap/ldap v0.0.0-20230914221201-c4eecc7e31f7 h1:jgVdtp5YMn++
github.com/hashicorp/cap/ldap v0.0.0-20230914221201-c4eecc7e31f7/go.mod h1:q+c9XV1VqloZFZMu+zdvfb0cm7UrvKbvtmTF5wX5Q9o=
github.com/hashicorp/cli v1.1.6 h1:CMOV+/LJfL1tXCOKrgAX0uRKnzjj/mpmqNXloRSy2K8=
github.com/hashicorp/cli v1.1.6/go.mod h1:MPon5QYlgjjo0BSoAiN0ESeT5fRzDjVRp+uioJ0piz4=
github.com/hashicorp/consul-template v0.33.0 h1:UNyf7V/nFeh8edh5X6pP8f+9LZVn+DG9uNLLcTpLsFc=
github.com/hashicorp/consul-template v0.33.0/go.mod h1:3RayddSLvOGQwdifbbe4doVwamgJU4QvxTtf5DNeclw=
github.com/hashicorp/consul-template v0.36.0 h1:elo9xh+rERrLVKMbEKbXoRagFvSTBG1S4GOXeH9/x8o=
github.com/hashicorp/consul-template v0.36.0/go.mod h1:bvidXKwpfXzJ1X4wDw68OXnVxy5k7HLOHhOf5gnQr3M=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.23.0 h1:L6e4v1AfoumqAHq/Rrsmuulev+nd7vltM3k8H329tyI=
github.com/hashicorp/consul/api v1.23.0/go.mod h1:SfvUIT74b0EplDuNgAJQ/FVqSO6KyK2ia80UI39/Ye8=
github.com/hashicorp/consul/api v1.26.1 h1:5oSXOO5fboPZeW5SN+TdGFP/BILDgBm19OrPZ/pICIM=
github.com/hashicorp/consul/api v1.26.1/go.mod h1:B4sQTeaSO16NtynqrAdwOlahJ7IUDZM9cj2420xYL8A=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/consul/sdk v0.14.0 h1:Hly+BMNMssVzoWddbBnBFi3W+Fzytvm0haSkihhj3GU=
github.com/hashicorp/consul/sdk v0.14.0/go.mod h1:gHYeuDa0+0qRAD6Wwr6yznMBvBwHKoxSBoW5l73+saE=
github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU=
github.com/hashicorp/consul/sdk v0.15.0/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo=
github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c=
github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -3103,8 +3108,9 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
@@ -3356,8 +3362,8 @@ go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+n
go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4=
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04=
@@ -3379,16 +3385,17 @@ go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9deb
go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU=
go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A=
go.opentelemetry.io/otel/metric v0.37.0/go.mod h1:DmdaHfGt54iV6UKxsV9slj2bBRJcKC1B1uvDLIioc1s=
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI=
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
@@ -3398,8 +3405,8 @@ go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48
go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
@@ -3489,8 +3496,9 @@ golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -3507,8 +3515,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE=
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
@@ -3882,8 +3890,8 @@ golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -3902,8 +3910,9 @@ golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -3924,8 +3933,9 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -4037,8 +4047,9 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -4617,8 +4628,8 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
mvdan.cc/gofumpt v0.2.1/go.mod h1:a/rvZPhsNaedOJBzqRD9omnwVwHZsBdJirXHa9Gh9Ig=
mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=
mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE=
mvdan.cc/gofumpt v0.5.0 h1:0EQ+Z56k8tXjj/6TQD25BFNKQXpCvT0rnansIc7Ug5E=
mvdan.cc/gofumpt v0.5.0/go.mod h1:HBeVDtMKRZpXyxFciAirzdKklDlGu8aAy1wEbH5Y9js=
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
oras.land/oras-go v1.2.0/go.mod h1:pFNs7oHp2dYsYMSS82HaX5l4mpnGO7hbpPN6EWH2ltc=

View File

@@ -143,7 +143,12 @@ func (j *JobManager) GetPendingJobCount() int {
func (j *JobManager) GetWorkerCounts() map[string]int {
j.l.RLock()
defer j.l.RUnlock()
return j.workerCount
workerCounts := make(map[string]int, len(j.workerCount))
for k, v := range j.workerCount {
workerCounts[k] = v
}
return workerCounts
}
// GetWorkQueueLengths() returns a map of queue ID to number of jobs in the queue

View File

@@ -747,3 +747,23 @@ func TestFairshare_queueWorkersSaturated(t *testing.T) {
j.l.RUnlock()
}
}
func TestJobManager_GetWorkerCounts_RaceCondition(t *testing.T) {
j := NewJobManager("test-job-mgr", 20, nil, nil)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
for i := 0; i < 10; i++ {
j.incrementWorkerCount("a")
}
}()
wcs := j.GetWorkerCounts()
wcs["foo"] = 10
for worker, count := range wcs {
_ = worker
_ = count
}
wg.Wait()
}

View File

@@ -104,6 +104,7 @@ func NewCassandraBackend(conf map[string]string, logger log.Logger) (physical.Ba
cluster := gocql.NewCluster(hosts...)
cluster.Port = port
cluster.Keyspace = keyspace
cluster.Consistency = consistency
if retryCountStr, ok := conf["simple_retry_policy_retries"]; ok {
retryCount, err := strconv.Atoi(retryCountStr)

View File

@@ -21,8 +21,10 @@ import (
)
// Verify MSSQLBackend satisfies the correct interfaces
var _ physical.Backend = (*MSSQLBackend)(nil)
var identifierRegex = regexp.MustCompile(`^[\p{L}_][\p{L}\p{Nd}@#$_]*$`)
var (
_ physical.Backend = (*MSSQLBackend)(nil)
identifierRegex = regexp.MustCompile(`^[\p{L}_][\p{L}\p{Nd}@#$_]*$`)
)
type MSSQLBackend struct {
dbTable string

View File

@@ -6,8 +6,8 @@
find . -type f -name '*.go' | while read line; do
if grep "SPDX-License-Identifier: BUSL-1.1" $line; then
sed -i '' '/SPDX-License-Identifier: BUSL-1.1/d' $line
sed -i '' '/Copyright (c) HashiCorp, Inc./d' $line
sed -i '/SPDX-License-Identifier: BUSL-1.1/d' $line
sed -i '/Copyright (c) HashiCorp, Inc./d' $line
fi
done

View File

@@ -2,7 +2,7 @@ schema_version = 1
project {
license = "MPL-2.0"
copyright_year = 2023
copyright_year = 2024
header_ignore = []
}

View File

@@ -0,0 +1,90 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package backoff
import (
"errors"
"math"
"math/rand"
"time"
)
var ErrMaxRetry = errors.New("exceeded maximum number of retries")
const maxJitter = 0.25
// Backoff is used to do capped exponential backoff with jitter, with a maximum number of retries.
// Generally, use this struct by calling Next() or NextSleep() after a failure.
// If configured for N max retries, Next() and NextSleep() will return an error on the call N+1.
// The jitter is set to 25%, so values returned will have up to 25% less than twice the previous value.
// The min value will also include jitter, so the first call will almost always be less than the requested minimum value.
// Backoff is not thread-safe.
type Backoff struct {
currentAttempt int
maxRetries int
min time.Duration
max time.Duration
current time.Duration
}
// NewBackoff creates a new exponential backoff with the given number of maximum retries and min/max durations.
func NewBackoff(maxRetries int, min, max time.Duration) *Backoff {
b := &Backoff{
maxRetries: maxRetries,
max: max,
min: min,
}
b.Reset()
return b
}
// Current returns the next time that will be returned by Next() (or slept in NextSleep()).
func (b *Backoff) Current() time.Duration {
return b.current
}
// Next determines the next backoff duration that is roughly twice
// the current value, capped to a max value, with a measure of randomness.
// It returns an error if there are no more retries left.
func (b *Backoff) Next() (time.Duration, error) {
if b.currentAttempt >= b.maxRetries {
return time.Duration(-1), ErrMaxRetry
}
defer func() {
b.currentAttempt += 1
}()
if b.currentAttempt == 0 {
return b.current, nil
}
next := 2 * b.current
if next > b.max {
next = b.max
}
next = jitter(next)
b.current = next
return next, nil
}
// NextSleep will synchronously sleep the next backoff amount (see Next()).
// It returns an error if there are no more retries left.
func (b *Backoff) NextSleep() error {
next, err := b.Next()
if err != nil {
return err
}
time.Sleep(next)
return nil
}
// Reset resets the state to the initial backoff amount and 0 retries.
func (b *Backoff) Reset() {
b.current = b.min
b.current = jitter(b.current)
b.currentAttempt = 0
}
func jitter(t time.Duration) time.Duration {
f := float64(t) * (1.0 - maxJitter*rand.Float64())
return time.Duration(math.Floor(f))
}

View File

@@ -0,0 +1,52 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package backoff
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// TestBackoff_Basic tests that basic exponential backoff works as expected up to a max of 3 times.
func TestBackoff_Basic(t *testing.T) {
for i := 0; i < 100; i++ {
b := NewBackoff(3, 1*time.Millisecond, 10*time.Millisecond)
x, err := b.Next()
assert.Nil(t, err)
assert.LessOrEqual(t, x, 1*time.Millisecond)
assert.GreaterOrEqual(t, x, 750*time.Microsecond)
x2, err := b.Next()
assert.Nil(t, err)
assert.LessOrEqual(t, x2, x*2)
assert.GreaterOrEqual(t, x2, x*3/4)
x3, err := b.Next()
assert.Nil(t, err)
assert.LessOrEqual(t, x3, x2*2)
assert.GreaterOrEqual(t, x3, x2*3/4)
_, err = b.Next()
assert.NotNil(t, err)
}
}
// TestBackoff_ZeroRetriesAlwaysFails checks that if retries is set to zero, then an error is returned immediately.
func TestBackoff_ZeroRetriesAlwaysFails(t *testing.T) {
b := NewBackoff(0, 1*time.Millisecond, 10*time.Millisecond)
_, err := b.Next()
assert.NotNil(t, err)
}
// TestBackoff_MaxIsEnforced checks that the maximum backoff is enforced.
func TestBackoff_MaxIsEnforced(t *testing.T) {
b := NewBackoff(1001, 1*time.Millisecond, 2*time.Millisecond)
for i := 0; i < 1000; i++ {
x, err := b.Next()
assert.LessOrEqual(t, x, 2*time.Millisecond)
assert.Nil(t, err)
}
}

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: MPL-2.0
package logical

View File

@@ -1,5 +1,5 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
// SPDX-License-Identifier: MPL-2.0
package logical

View File

@@ -2,7 +2,7 @@ schema_version = 1
project {
license = "MPL-2.0"
copyright_year = 2023
copyright_year = 2024
header_ignore = []
}

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationAdapter from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationAdapter from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationAdapter from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import SecretsEnginePathAdapter from 'vault/adapters/secrets-engine-path';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import NamedPathAdapter from 'vault/adapters/named-path';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import NamedPathAdapter from 'vault/adapters/named-path';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
/**

View File

@@ -29,7 +29,8 @@ export default class SyncAssociationAdapter extends ApplicationAdapter {
// typically associations are queried for a specific destination which is what the standard query method does
// in specific cases we can query all associations to access total_associations and total_secrets values
queryAll() {
return this.query(this.store, { modelName: 'sync/association' }).then((response) => {
const url = `${this.buildURL('sync/association')}`;
return this.ajax(url, 'GET', { data: { list: true } }).then((response) => {
const { total_associations, total_secrets } = response.data;
return { total_associations, total_secrets };
});
@@ -49,8 +50,8 @@ export default class SyncAssociationAdapter extends ApplicationAdapter {
// array of association data for each destination a secret is synced to
fetchSyncStatus({ mount, secretName }) {
const url = `${this.buildURL()}/${mount}/${secretName}`;
return this.ajax(url, 'GET').then((resp) => {
const url = `${this.buildURL()}/destinations`;
return this.ajax(url, 'GET', { data: { mount, secret_name: secretName } }).then((resp) => {
const { associated_destinations } = resp.data;
const syncData = [];
for (const key in associated_destinations) {

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';

View File

@@ -47,7 +47,7 @@ export default Component.extend({
this.set('canList', true);
} catch (e) {
// If error out on findRecord call it's because you don't have permissions
// and therefor don't have permission to manage namespaces
// and therefore don't have permission to manage namespaces
this.set('canList', false);
}
}),

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Model, { attr } from '@ember-data/model';

View File

@@ -8,8 +8,8 @@ import { attr } from '@ember-data/model';
import { withFormFields } from 'vault/decorators/model-form-fields';
const displayFields = ['name', 'keyVaultUri', 'tenantId', 'cloud', 'clientId', 'clientSecret'];
const formFieldGroups = [
{ default: ['name', 'keyVaultUri', 'tenantId', 'cloud', 'clientId'] },
{ Credentials: ['clientSecret'] },
{ default: ['name', 'tenantId', 'cloud', 'clientId'] },
{ Credentials: ['keyVaultUri', 'clientSecret'] },
];
@withFormFields(displayFields, formFieldGroups)
export default class SyncDestinationsAzureKeyVaultModel extends SyncDestinationModel {
@@ -19,7 +19,7 @@ export default class SyncDestinationsAzureKeyVaultModel extends SyncDestinationM
'URI of an existing Azure Key Vault instance. If empty, Vault will use the KEY_VAULT_URI environment variable if configured.',
editDisabled: true,
})
keyVaultUri;
keyVaultUri; // obfuscated, never returned by API
@attr('string', {
label: 'Client ID',
@@ -44,7 +44,6 @@ export default class SyncDestinationsAzureKeyVaultModel extends SyncDestinationM
@attr('string', {
subText: 'Specifies a cloud for the client. The default is Azure Public Cloud.',
defaultValue: 'cloud',
editDisabled: true,
})
cloud;

View File

@@ -47,8 +47,9 @@ export default class SyncDestinationsVercelProjectModel extends SyncDestinationM
})
teamId;
// comma separated string, updated as array using deploymentEnvironmentsArray
@attr({
// commaString transforms param from the server's array type
// to a comma string so changedAttributes() will track changes
@attr('commaString', {
subText: 'Deployment environments where the environment variables are available.',
editType: 'checkboxList',
possibleValues: ['development', 'preview', 'production'],
@@ -56,9 +57,8 @@ export default class SyncDestinationsVercelProjectModel extends SyncDestinationM
})
deploymentEnvironments;
// Instead of using the 'array' attr transform, we keep deploymentEnvironments a string to leverage Ember's changedAttributes()
// which only tracks updates to string types. However, arrays are easier for managing multi-option selection so
// the fieldValue is used to get/set the deploymentEnvironments attribute to/from an array
// Arrays are easier for managing multi-option selection
// these get/set the deploymentEnvironments attribute via arrays
get deploymentEnvironmentsArray() {
// if undefined or an empty string, return empty array
return !this.deploymentEnvironments ? [] : this.deploymentEnvironments.split(',');

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import Route from '@ember/routing/route';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationSerializer from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import { assert } from '@ember/debug';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationSerializer from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationSerializer from '../application';

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
import ApplicationSerializer from '../application';

View File

@@ -12,17 +12,15 @@ export default class SyncDestinationSerializer extends ApplicationSerializer {
};
serialize(snapshot) {
// special serialization only for PATCH requests
if (snapshot.isNew) return super.serialize(snapshot);
const data = super.serialize(snapshot);
if (snapshot.isNew) return data;
// only send changed values
const data = {};
for (const attr in snapshot.changedAttributes()) {
// first array element is the old value
const [, newValue] = snapshot.changedAttributes()[attr];
data[decamelize(attr)] = newValue;
}
return data;
// only send changed parameters for PATCH requests
const changedKeys = Object.keys(snapshot.changedAttributes()).map((key) => decamelize(key));
return changedKeys.reduce((payload, key) => {
payload[key] = data[key];
return payload;
}, {});
}
// interrupt application's normalizeItems, which is called in normalizeResponse by application serializer

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
// used in KV version diff view. https://github.com/benjamine/jsondiffpatch/tree/master

View File

@@ -16,11 +16,15 @@ Commands:
delete Delete secrets and configuration
list List data or secrets
Web CLI Commands:
Web REPL Commands:
api Navigate to the Vault API explorer. Use 'api [filter]' to prefilter the list.
clear Clear output from the log
clearall Clear output and command history
fullscreen Toggle fullscreen display
refresh Refresh the data on the current screen under the CLI window
</pre>
<p class="console-ui-panel-intro is-font-mono has-bottom-margin-s">
For more detailed documentation, see the <Hds::Link::Inline @href={{doc-link "/vault/docs/command/web"}}>HashiCorp Developer site</Hds::Link::Inline>.
</p>
</div>

View File

@@ -16,8 +16,10 @@
<div class="console-ui-panel-content">
<div class="content has-bottom-margin-l">
<p class="console-ui-panel-intro is-font-mono has-bottom-margin-s">
The Vault Browser CLI provides an easy way to execute common Vault CLI commands, such as write, read, delete, and list.
It does not include kv v2 write or put commands. For guidance, type `help`.
The Vault Web REPL provides an easy way to execute common Vault CLI commands, such as write, read, delete, and list. It
does not include KV version 2 write or put commands. For guidance, type `help`. For more detailed documentation, see
the
<Hds::Link::Inline @href={{doc-link "/vault/docs/command/web"}}>HashiCorp Developer site</Hds::Link::Inline>.
</p>
<p class="console-ui-panel-intro is-font-mono has-bottom-margin-s">Examples:</p>
<p class="console-ui-panel-intro is-font-mono">→ Write secrets to kv v1: write &lt;mount&gt;/my-secret foo=bar</p>

View File

@@ -9,7 +9,7 @@
@instructions='Find the engine in the list and click on "View configuration" in the menu on the right.'
>
<p>
This engine isn't fully supported in the Vault UI yet, but you can view and edit the configuration and use the Vault
Browser CLI to interact with the engine just like you would on the command-line.
This engine isn't fully supported in the Vault UI yet, but you can view and edit the configuration and use the Vault Web
REPL to interact with the engine just like you would on the command-line.
</p>
</WizardSection>

View File

@@ -0,0 +1,27 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Transform from '@ember-data/serializer/transform';
/**
* transforms array types from the server to a comma separated string
* useful when using changedAttributes() in the serializer to track attribute changes for PATCH requests
* because arrays are not trackable and strings are!
*/
export default class CommaString extends Transform {
deserialize(serialized) {
if (Array.isArray(serialized)) {
return serialized.join(',');
}
return serialized;
}
serialize(deserialized) {
if (typeof deserialized === 'string') {
return deserialized.split(',');
}
return deserialized;
}
}

View File

@@ -1,6 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
* SPDX-License-Identifier: BUSL-1.1
*/
/**

Some files were not shown because too many files have changed in this diff Show More