mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
Merge branch 'main' into raft-wal
This commit is contained in:
@@ -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/**",
|
||||
|
||||
2
.github/workflows/security-scan.yml
vendored
2
.github/workflows/security-scan.yml
vendored
@@ -83,8 +83,6 @@ jobs:
|
||||
|
||||
- name: SARIF Output
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cat results.sarif
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@ schema_version = 1
|
||||
|
||||
project {
|
||||
license = "MPL-2.0"
|
||||
copyright_year = 2023
|
||||
copyright_year = 2024
|
||||
|
||||
header_ignore = []
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
1000
api/auth/gcp/go.sum
1000
api/auth/gcp/go.sum
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
)
|
||||
|
||||
16
api/go.sum
16
api/go.sum
@@ -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=
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package transit
|
||||
|
||||
|
||||
@@ -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
3
changelog/24548.txt
Normal 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
3
changelog/24616.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:bug
|
||||
fairshare: fix a race condition in JobManager.GetWorkerCounts
|
||||
```
|
||||
3
changelog/24649.txt
Normal file
3
changelog/24649.txt
Normal 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
6
changelog/24667.txt
Normal 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.
|
||||
```
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ vault {
|
||||
template_config {
|
||||
exit_on_retry_failure = true
|
||||
static_secret_render_interval = 60
|
||||
max_connections_per_host = 100
|
||||
}
|
||||
|
||||
template {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 \{
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package ldap
|
||||
|
||||
|
||||
27
command/agentproxyshared/cache/api_proxy.go
vendored
27
command/agentproxyshared/cache/api_proxy.go
vendored
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
//go:build !enterprise
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
74
enos/modules/vault_verify_default_lcq/main.tf
Normal file
74
enos/modules/vault_verify_default_lcq/main.tf
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
46
enos/modules/vault_verify_default_lcq/scripts/smoke-verify-default-lcq.sh
Executable file
46
enos/modules/vault_verify_default_lcq/scripts/smoke-verify-default-lcq.sh
Executable 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
40
go.mod
@@ -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
73
go.sum
@@ -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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ schema_version = 1
|
||||
|
||||
project {
|
||||
license = "MPL-2.0"
|
||||
copyright_year = 2023
|
||||
copyright_year = 2024
|
||||
|
||||
header_ignore = []
|
||||
}
|
||||
|
||||
90
sdk/helper/backoff/backoff.go
Normal file
90
sdk/helper/backoff/backoff.go
Normal 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))
|
||||
}
|
||||
52
sdk/helper/backoff/backoff_test.go
Normal file
52
sdk/helper/backoff/backoff_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package logical
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package logical
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ schema_version = 1
|
||||
|
||||
project {
|
||||
license = "MPL-2.0"
|
||||
copyright_year = 2023
|
||||
copyright_year = 2024
|
||||
|
||||
header_ignore = []
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from '../application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from '../application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationAdapter from '../application';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(',');
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from '../application';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from '../application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from '../application';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from '../application';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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 <mount>/my-secret foo=bar</p>
|
||||
|
||||
@@ -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>
|
||||
27
ui/app/transforms/comma-string.js
Normal file
27
ui/app/transforms/comma-string.js
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user