mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-08 07:37:01 +02:00
Port: Telemetry For Lease Expiration Times (#10375)
* port lease metrics * go mod vendor * caught a bug
This commit is contained in:
parent
d9fb082c24
commit
0767980550
@ -30,6 +30,10 @@ func TestLoadConfigFileIntegerAndBooleanValuesJson(t *testing.T) {
|
|||||||
testLoadConfigFileIntegerAndBooleanValuesJson(t)
|
testLoadConfigFileIntegerAndBooleanValuesJson(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadConfigFileWithLeaseMetricTelemetry(t *testing.T) {
|
||||||
|
testLoadConfigFileLeaseMetrics(t)
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadConfigDir(t *testing.T) {
|
func TestLoadConfigDir(t *testing.T) {
|
||||||
testLoadConfigDir(t)
|
testLoadConfigDir(t)
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,9 @@ func testLoadConfigFile_topLevel(t *testing.T, entropy *configutil.Entropy) {
|
|||||||
PrometheusRetentionTime: 30 * time.Second,
|
PrometheusRetentionTime: 30 * time.Second,
|
||||||
UsageGaugePeriod: 5 * time.Minute,
|
UsageGaugePeriod: 5 * time.Minute,
|
||||||
MaximumGaugeCardinality: 125,
|
MaximumGaugeCardinality: 125,
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 168,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
DisableMlock: true,
|
DisableMlock: true,
|
||||||
@ -192,6 +195,9 @@ func testLoadConfigFile_json2(t *testing.T, entropy *configutil.Entropy) {
|
|||||||
CirconusBrokerID: "0",
|
CirconusBrokerID: "0",
|
||||||
CirconusBrokerSelectTag: "dc:sfo",
|
CirconusBrokerSelectTag: "dc:sfo",
|
||||||
PrometheusRetentionTime: 30 * time.Second,
|
PrometheusRetentionTime: 30 * time.Second,
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 168,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -380,6 +386,9 @@ func testLoadConfigFile(t *testing.T) {
|
|||||||
DogStatsDTags: []string{"tag_1:val_1", "tag_2:val_2"},
|
DogStatsDTags: []string{"tag_1:val_1", "tag_2:val_2"},
|
||||||
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
||||||
MetricsPrefix: "myprefix",
|
MetricsPrefix: "myprefix",
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 168,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
DisableMlock: true,
|
DisableMlock: true,
|
||||||
@ -477,6 +486,9 @@ func testLoadConfigFile_json(t *testing.T) {
|
|||||||
CirconusBrokerID: "",
|
CirconusBrokerID: "",
|
||||||
CirconusBrokerSelectTag: "",
|
CirconusBrokerSelectTag: "",
|
||||||
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 168,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
PidFile: "./pidfile",
|
PidFile: "./pidfile",
|
||||||
@ -546,6 +558,9 @@ func testLoadConfigDir(t *testing.T) {
|
|||||||
UsageGaugePeriod: 5 * time.Minute,
|
UsageGaugePeriod: 5 * time.Minute,
|
||||||
MaximumGaugeCardinality: 100,
|
MaximumGaugeCardinality: 100,
|
||||||
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 168,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
},
|
},
|
||||||
ClusterName: "testcluster",
|
ClusterName: "testcluster",
|
||||||
},
|
},
|
||||||
@ -668,6 +683,9 @@ func testConfig_Sanitized(t *testing.T) {
|
|||||||
"stackdriver_debug_logs": false,
|
"stackdriver_debug_logs": false,
|
||||||
"statsd_address": "bar",
|
"statsd_address": "bar",
|
||||||
"statsite_address": "",
|
"statsite_address": "",
|
||||||
|
"lease_metrics_epsilon": time.Hour,
|
||||||
|
"num_lease_metrics_buckets": 168,
|
||||||
|
"add_lease_metrics_namespace_labels": false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,3 +805,93 @@ func testParseSeals(t *testing.T) {
|
|||||||
}
|
}
|
||||||
require.Equal(t, config, expected)
|
require.Equal(t, config, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testLoadConfigFileLeaseMetrics(t *testing.T) {
|
||||||
|
config, err := LoadConfigFile("./test-fixtures/config5.hcl")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := &Config{
|
||||||
|
SharedConfig: &configutil.SharedConfig{
|
||||||
|
Listeners: []*configutil.Listener{
|
||||||
|
{
|
||||||
|
Type: "tcp",
|
||||||
|
Address: "127.0.0.1:443",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
Telemetry: &configutil.Telemetry{
|
||||||
|
StatsdAddr: "bar",
|
||||||
|
StatsiteAddr: "foo",
|
||||||
|
DisableHostname: false,
|
||||||
|
UsageGaugePeriod: 5 * time.Minute,
|
||||||
|
MaximumGaugeCardinality: 100,
|
||||||
|
DogStatsDAddr: "127.0.0.1:7254",
|
||||||
|
DogStatsDTags: []string{"tag_1:val_1", "tag_2:val_2"},
|
||||||
|
PrometheusRetentionTime: configutil.PrometheusDefaultRetentionTime,
|
||||||
|
MetricsPrefix: "myprefix",
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 2,
|
||||||
|
LeaseMetricsNameSpaceLabels: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
DisableMlock: true,
|
||||||
|
|
||||||
|
Entropy: nil,
|
||||||
|
|
||||||
|
PidFile: "./pidfile",
|
||||||
|
|
||||||
|
ClusterName: "testcluster",
|
||||||
|
},
|
||||||
|
|
||||||
|
Storage: &Storage{
|
||||||
|
Type: "consul",
|
||||||
|
RedirectAddr: "foo",
|
||||||
|
Config: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
HAStorage: &Storage{
|
||||||
|
Type: "consul",
|
||||||
|
RedirectAddr: "snafu",
|
||||||
|
Config: map[string]string{
|
||||||
|
"bar": "baz",
|
||||||
|
},
|
||||||
|
DisableClustering: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
ServiceRegistration: &ServiceRegistration{
|
||||||
|
Type: "consul",
|
||||||
|
Config: map[string]string{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
DisableCache: true,
|
||||||
|
DisableCacheRaw: true,
|
||||||
|
DisablePrintableCheckRaw: true,
|
||||||
|
DisablePrintableCheck: true,
|
||||||
|
EnableUI: true,
|
||||||
|
EnableUIRaw: true,
|
||||||
|
|
||||||
|
EnableRawEndpoint: true,
|
||||||
|
EnableRawEndpointRaw: true,
|
||||||
|
|
||||||
|
DisableSealWrap: true,
|
||||||
|
DisableSealWrapRaw: true,
|
||||||
|
|
||||||
|
MaxLeaseTTL: 10 * time.Hour,
|
||||||
|
MaxLeaseTTLRaw: "10h",
|
||||||
|
DefaultLeaseTTL: 10 * time.Hour,
|
||||||
|
DefaultLeaseTTLRaw: "10h",
|
||||||
|
}
|
||||||
|
|
||||||
|
addExpectedEntConfig(expected, []string{})
|
||||||
|
|
||||||
|
config.Listeners[0].RawConfig = nil
|
||||||
|
if diff := deep.Equal(config, expected); diff != nil {
|
||||||
|
t.Fatal(diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
51
command/server/test-fixtures/config5.hcl
Normal file
51
command/server/test-fixtures/config5.hcl
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
disable_cache = true
|
||||||
|
disable_mlock = true
|
||||||
|
|
||||||
|
ui = true
|
||||||
|
|
||||||
|
listener "tcp" {
|
||||||
|
address = "127.0.0.1:443"
|
||||||
|
allow_stuff = true
|
||||||
|
}
|
||||||
|
|
||||||
|
backend "consul" {
|
||||||
|
foo = "bar"
|
||||||
|
advertise_addr = "foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
ha_backend "consul" {
|
||||||
|
bar = "baz"
|
||||||
|
advertise_addr = "snafu"
|
||||||
|
disable_clustering = "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
service_registration "consul" {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
|
||||||
|
telemetry {
|
||||||
|
statsd_address = "bar"
|
||||||
|
usage_gauge_period = "5m"
|
||||||
|
maximum_gauge_cardinality = 100
|
||||||
|
|
||||||
|
statsite_address = "foo"
|
||||||
|
dogstatsd_addr = "127.0.0.1:7254"
|
||||||
|
dogstatsd_tags = ["tag_1:val_1", "tag_2:val_2"]
|
||||||
|
metrics_prefix = "myprefix"
|
||||||
|
|
||||||
|
lease_metrics_epsilon = "1h"
|
||||||
|
num_lease_metrics_buckets = 2
|
||||||
|
add_lease_metrics_namespace_labels = true
|
||||||
|
}
|
||||||
|
|
||||||
|
sentinel {
|
||||||
|
additional_enabled_modules = []
|
||||||
|
}
|
||||||
|
|
||||||
|
max_lease_ttl = "10h"
|
||||||
|
default_lease_ttl = "10h"
|
||||||
|
cluster_name = "testcluster"
|
||||||
|
pid_file = "./pidfile"
|
||||||
|
raw_storage_endpoint = true
|
||||||
|
disable_sealwrap = true
|
||||||
|
disable_printable_check = true
|
@ -37,3 +37,22 @@ func TTLBucket(ttl time.Duration) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ExpiryBucket(expiryTime time.Time, leaseEpsilon time.Duration, rollingWindow time.Time, labelNS string, useNS bool) *LeaseExpiryLabel {
|
||||||
|
if !useNS {
|
||||||
|
labelNS = ""
|
||||||
|
}
|
||||||
|
leaseExpiryLabel := LeaseExpiryLabel{LabelNS: labelNS}
|
||||||
|
|
||||||
|
// calculate rolling window
|
||||||
|
if expiryTime.Before(rollingWindow) {
|
||||||
|
leaseExpiryLabel.LabelName = expiryTime.Round(leaseEpsilon).String()
|
||||||
|
return &leaseExpiryLabel
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type LeaseExpiryLabel = struct {
|
||||||
|
LabelName string
|
||||||
|
LabelNS string
|
||||||
|
}
|
||||||
|
@ -28,6 +28,15 @@ type ClusterMetricSink struct {
|
|||||||
|
|
||||||
// Sink is the go-metrics instance to send to.
|
// Sink is the go-metrics instance to send to.
|
||||||
Sink metrics.MetricSink
|
Sink metrics.MetricSink
|
||||||
|
|
||||||
|
// Constants that are helpful for metrics within the metrics sink
|
||||||
|
TelemetryConsts TelemetryConstConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type TelemetryConstConfig struct {
|
||||||
|
LeaseMetricsEpsilon time.Duration
|
||||||
|
NumLeaseMetricsTimeBuckets int
|
||||||
|
LeaseMetricsNameSpaceLabels bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Metrics interface {
|
type Metrics interface {
|
||||||
@ -85,6 +94,7 @@ func NewClusterMetricSink(clusterName string, sink metrics.MetricSink) *ClusterM
|
|||||||
cms := &ClusterMetricSink{
|
cms := &ClusterMetricSink{
|
||||||
ClusterName: atomic.Value{},
|
ClusterName: atomic.Value{},
|
||||||
Sink: sink,
|
Sink: sink,
|
||||||
|
TelemetryConsts: TelemetryConstConfig{},
|
||||||
}
|
}
|
||||||
cms.ClusterName.Store(clusterName)
|
cms.ClusterName.Store(clusterName)
|
||||||
return cms
|
return cms
|
||||||
|
@ -214,6 +214,9 @@ func (c *SharedConfig) Sanitized() map[string]interface{} {
|
|||||||
"stackdriver_location": c.Telemetry.StackdriverLocation,
|
"stackdriver_location": c.Telemetry.StackdriverLocation,
|
||||||
"stackdriver_namespace": c.Telemetry.StackdriverNamespace,
|
"stackdriver_namespace": c.Telemetry.StackdriverNamespace,
|
||||||
"stackdriver_debug_logs": c.Telemetry.StackdriverDebugLogs,
|
"stackdriver_debug_logs": c.Telemetry.StackdriverDebugLogs,
|
||||||
|
"lease_metrics_epsilon": c.Telemetry.LeaseMetricsEpsilon,
|
||||||
|
"num_lease_metrics_buckets": c.Telemetry.NumLeaseMetricsTimeBuckets,
|
||||||
|
"add_lease_metrics_namespace_labels": c.Telemetry.LeaseMetricsNameSpaceLabels,
|
||||||
}
|
}
|
||||||
result["telemetry"] = sanitizedTelemetry
|
result["telemetry"] = sanitizedTelemetry
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ const (
|
|||||||
PrometheusDefaultRetentionTime = 24 * time.Hour
|
PrometheusDefaultRetentionTime = 24 * time.Hour
|
||||||
UsageGaugeDefaultPeriod = 10 * time.Minute
|
UsageGaugeDefaultPeriod = 10 * time.Minute
|
||||||
MaximumGaugeCardinalityDefault = 500
|
MaximumGaugeCardinalityDefault = 500
|
||||||
|
LeaseMetricsEpsilonDefault = time.Hour
|
||||||
|
NumLeaseMetricsTimeBucketsDefault = 168
|
||||||
)
|
)
|
||||||
|
|
||||||
// Telemetry is the telemetry configuration for the server
|
// Telemetry is the telemetry configuration for the server
|
||||||
@ -137,6 +139,16 @@ type Telemetry struct {
|
|||||||
StackdriverNamespace string `hcl:"stackdriver_namespace"`
|
StackdriverNamespace string `hcl:"stackdriver_namespace"`
|
||||||
// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr.
|
// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr.
|
||||||
StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"`
|
StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"`
|
||||||
|
|
||||||
|
// How often metrics for lease expiry will be aggregated
|
||||||
|
LeaseMetricsEpsilon time.Duration
|
||||||
|
LeaseMetricsEpsilonRaw interface{} `hcl:"lease_metrics_epsilon"`
|
||||||
|
|
||||||
|
// Number of buckets by time that will be used in lease aggregation
|
||||||
|
NumLeaseMetricsTimeBuckets int `hcl:"num_lease_metrics_buckets"`
|
||||||
|
|
||||||
|
// Whether or not telemetry should add labels for namespaces
|
||||||
|
LeaseMetricsNameSpaceLabels bool `hcl:"add_lease_metrics_namespace_labels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Telemetry) GoString() string {
|
func (t *Telemetry) GoString() string {
|
||||||
@ -151,11 +163,6 @@ func parseTelemetry(result *SharedConfig, list *ast.ObjectList) error {
|
|||||||
// Get our one item
|
// Get our one item
|
||||||
item := list.Items[0]
|
item := list.Items[0]
|
||||||
|
|
||||||
var t Telemetry
|
|
||||||
if err := hcl.DecodeObject(&t, item.Val); err != nil {
|
|
||||||
return multierror.Prefix(err, "telemetry:")
|
|
||||||
}
|
|
||||||
|
|
||||||
if result.Telemetry == nil {
|
if result.Telemetry == nil {
|
||||||
result.Telemetry = &Telemetry{}
|
result.Telemetry = &Telemetry{}
|
||||||
}
|
}
|
||||||
@ -192,6 +199,24 @@ func parseTelemetry(result *SharedConfig, list *ast.ObjectList) error {
|
|||||||
result.Telemetry.MaximumGaugeCardinality = MaximumGaugeCardinalityDefault
|
result.Telemetry.MaximumGaugeCardinality = MaximumGaugeCardinalityDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if result.Telemetry.LeaseMetricsEpsilonRaw != nil {
|
||||||
|
if result.Telemetry.LeaseMetricsEpsilonRaw == "none" {
|
||||||
|
result.Telemetry.LeaseMetricsEpsilonRaw = 0
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
if result.Telemetry.LeaseMetricsEpsilon, err = parseutil.ParseDurationSecond(result.Telemetry.LeaseMetricsEpsilonRaw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
result.Telemetry.LeaseMetricsEpsilonRaw = nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.Telemetry.LeaseMetricsEpsilon = LeaseMetricsEpsilonDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.Telemetry.NumLeaseMetricsTimeBuckets == 0 {
|
||||||
|
result.Telemetry.NumLeaseMetricsTimeBuckets = NumLeaseMetricsTimeBucketsDefault
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,6 +380,9 @@ func SetupTelemetry(opts *SetupTelemetryOpts) (*metrics.InmemSink, *metricsutil.
|
|||||||
wrapper := metricsutil.NewClusterMetricSink(opts.ClusterName, globalMetrics)
|
wrapper := metricsutil.NewClusterMetricSink(opts.ClusterName, globalMetrics)
|
||||||
wrapper.MaxGaugeCardinality = opts.Config.MaximumGaugeCardinality
|
wrapper.MaxGaugeCardinality = opts.Config.MaximumGaugeCardinality
|
||||||
wrapper.GaugeInterval = opts.Config.UsageGaugePeriod
|
wrapper.GaugeInterval = opts.Config.UsageGaugePeriod
|
||||||
|
wrapper.TelemetryConsts.LeaseMetricsEpsilon = opts.Config.LeaseMetricsEpsilon
|
||||||
|
wrapper.TelemetryConsts.LeaseMetricsNameSpaceLabels = opts.Config.LeaseMetricsNameSpaceLabels
|
||||||
|
wrapper.TelemetryConsts.NumLeaseMetricsTimeBuckets = opts.Config.NumLeaseMetricsTimeBuckets
|
||||||
|
|
||||||
return inm, wrapper, prometheusEnabled, nil
|
return inm, wrapper, prometheusEnabled, nil
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,17 @@ func (c *Core) tokenGaugePolicyCollector(ctx context.Context) ([]metricsutil.Gau
|
|||||||
return ts.gaugeCollectorByPolicy(ctx)
|
return ts.gaugeCollectorByPolicy(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Core) leaseExpiryGaugeCollector(ctx context.Context) ([]metricsutil.GaugeLabelValues, error) {
|
||||||
|
c.stateLock.RLock()
|
||||||
|
e := c.expiration
|
||||||
|
metricsConsts := c.MetricSink().TelemetryConsts
|
||||||
|
c.stateLock.RUnlock()
|
||||||
|
if e == nil {
|
||||||
|
return []metricsutil.GaugeLabelValues{}, errors.New("nil expiration manager")
|
||||||
|
}
|
||||||
|
return e.leaseAggregationMetrics(ctx, metricsConsts)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Core) tokenGaugeMethodCollector(ctx context.Context) ([]metricsutil.GaugeLabelValues, error) {
|
func (c *Core) tokenGaugeMethodCollector(ctx context.Context) ([]metricsutil.GaugeLabelValues, error) {
|
||||||
c.stateLock.RLock()
|
c.stateLock.RLock()
|
||||||
ts := c.tokenStore
|
ts := c.tokenStore
|
||||||
@ -164,6 +175,12 @@ func (c *Core) emitMetrics(stopCh chan struct{}) {
|
|||||||
c.tokenGaugePolicyCollector,
|
c.tokenGaugePolicyCollector,
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
[]string{"expire", "leases", "by_expiration"},
|
||||||
|
[]metrics.Label{{"gauge", "leases_by_expiration"}},
|
||||||
|
c.leaseExpiryGaugeCollector,
|
||||||
|
"",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
[]string{"token", "count", "by_auth"},
|
[]string{"token", "count", "by_auth"},
|
||||||
[]metrics.Label{{"gauge", "token_by_auth"}},
|
[]metrics.Label{{"gauge", "token_by_auth"}},
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/hashicorp/errwrap"
|
"github.com/hashicorp/errwrap"
|
||||||
log "github.com/hashicorp/go-hclog"
|
log "github.com/hashicorp/go-hclog"
|
||||||
multierror "github.com/hashicorp/go-multierror"
|
multierror "github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/hashicorp/vault/helper/metricsutil"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/framework"
|
"github.com/hashicorp/vault/sdk/framework"
|
||||||
"github.com/hashicorp/vault/sdk/helper/base62"
|
"github.com/hashicorp/vault/sdk/helper/base62"
|
||||||
@ -1997,6 +1998,66 @@ func (m *ExpirationManager) emitMetrics() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *ExpirationManager) leaseAggregationMetrics(ctx context.Context, consts metricsutil.TelemetryConstConfig) ([]metricsutil.GaugeLabelValues, error) {
|
||||||
|
expiryTimes := make(map[metricsutil.LeaseExpiryLabel]int)
|
||||||
|
leaseEpsilon := consts.LeaseMetricsEpsilon
|
||||||
|
nsLabel := consts.LeaseMetricsNameSpaceLabels
|
||||||
|
|
||||||
|
rollingWindow := time.Now().Add(time.Duration(consts.NumLeaseMetricsTimeBuckets) * leaseEpsilon)
|
||||||
|
|
||||||
|
err := m.walkLeases(func(entryID string, expireTime time.Time) bool {
|
||||||
|
select {
|
||||||
|
// Abort and return empty collection if it's taking too much time, nonblocking check.
|
||||||
|
case <-ctx.Done():
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
if entryID == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, nsID := namespace.SplitIDFromString(entryID)
|
||||||
|
if nsID == "" {
|
||||||
|
nsID = "root" // this is what metricsutil.NamespaceLabel does
|
||||||
|
}
|
||||||
|
label := metricsutil.ExpiryBucket(expireTime, leaseEpsilon, rollingWindow, nsID, nsLabel)
|
||||||
|
if label != nil {
|
||||||
|
expiryTimes[*label] += 1
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []metricsutil.GaugeLabelValues{}, suppressRestoreModeError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If collection was cancelled, return an empty array.
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return []metricsutil.GaugeLabelValues{}, nil
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedResults := make([]metricsutil.GaugeLabelValues, 0, len(expiryTimes))
|
||||||
|
|
||||||
|
for bucket, count := range expiryTimes {
|
||||||
|
if nsLabel {
|
||||||
|
flattenedResults = append(flattenedResults,
|
||||||
|
metricsutil.GaugeLabelValues{
|
||||||
|
Labels: []metrics.Label{{"expiring", bucket.LabelName}, {"namespace", bucket.LabelNS}},
|
||||||
|
Value: float32(count),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
flattenedResults = append(flattenedResults,
|
||||||
|
metricsutil.GaugeLabelValues{
|
||||||
|
Labels: []metrics.Label{{"expiring", bucket.LabelName}},
|
||||||
|
Value: float32(count),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flattenedResults, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Callback function type to walk tokens referenced in the expiration
|
// Callback function type to walk tokens referenced in the expiration
|
||||||
// manager. Don't want to use leaseEntry here because it's an unexported
|
// manager. Don't want to use leaseEntry here because it's an unexported
|
||||||
// type (though most likely we would only call this from within the "vault" core package.)
|
// type (though most likely we would only call this from within the "vault" core package.)
|
||||||
@ -2031,6 +2092,30 @@ func (m *ExpirationManager) WalkTokens(walkFn ExpirationWalkFunction) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// leaseWalkFunction can only be used by the core package.
|
||||||
|
type leaseWalkFunction = func(leaseID string, expireTime time.Time) bool
|
||||||
|
|
||||||
|
func (m *ExpirationManager) walkLeases(walkFn leaseWalkFunction) error {
|
||||||
|
if m.inRestoreMode() {
|
||||||
|
return ErrInRestoreMode
|
||||||
|
}
|
||||||
|
|
||||||
|
callback := func(key, value interface{}) bool {
|
||||||
|
p := value.(pendingInfo)
|
||||||
|
if p.cachedLeaseInfo == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
lease := p.cachedLeaseInfo
|
||||||
|
expireTime := lease.ExpireTime
|
||||||
|
return walkFn(key.(string), expireTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.pending.Range(callback)
|
||||||
|
m.nonexpiring.Range(callback)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// leaseEntry is used to structure the values the expiration
|
// leaseEntry is used to structure the values the expiration
|
||||||
// manager stores. This is used to handle renew and revocation.
|
// manager stores. This is used to handle renew and revocation.
|
||||||
type leaseEntry struct {
|
type leaseEntry struct {
|
||||||
|
@ -13,8 +13,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
metrics "github.com/armon/go-metrics"
|
||||||
log "github.com/hashicorp/go-hclog"
|
log "github.com/hashicorp/go-hclog"
|
||||||
uuid "github.com/hashicorp/go-uuid"
|
uuid "github.com/hashicorp/go-uuid"
|
||||||
|
"github.com/hashicorp/vault/helper/metricsutil"
|
||||||
"github.com/hashicorp/vault/helper/namespace"
|
"github.com/hashicorp/vault/helper/namespace"
|
||||||
"github.com/hashicorp/vault/sdk/framework"
|
"github.com/hashicorp/vault/sdk/framework"
|
||||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||||
@ -38,6 +40,186 @@ func mockBackendExpiration(t testing.TB, backend physical.Backend) (*Core, *Expi
|
|||||||
return c, c.expiration
|
return c, c.expiration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExpiration_Metrics(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
testCore := TestCore(t)
|
||||||
|
testCore.baseLogger = logger
|
||||||
|
testCore.logger = logger.Named("core")
|
||||||
|
testCoreUnsealed(t, testCore)
|
||||||
|
|
||||||
|
exp := testCore.expiration
|
||||||
|
|
||||||
|
if err := exp.Restore(nil); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a count function to calculate number of leases
|
||||||
|
count := 0
|
||||||
|
countFunc := func(leaseID string) {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan the storage with the count func set
|
||||||
|
if err = logical.ScanView(namespace.RootContext(nil), exp.idView, countFunc); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that there are no leases to begin with
|
||||||
|
if count != 0 {
|
||||||
|
t.Fatalf("bad: lease count; expected:0 actual:%d", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 50; i++ {
|
||||||
|
le := &leaseEntry{
|
||||||
|
LeaseID: "lease" + fmt.Sprintf("%d", i),
|
||||||
|
Path: "foo/bar/" + fmt.Sprintf("%d", i),
|
||||||
|
namespace: namespace.RootNamespace,
|
||||||
|
IssueTime: time.Now(),
|
||||||
|
ExpireTime: time.Now().Add(time.Hour),
|
||||||
|
}
|
||||||
|
|
||||||
|
otherNS := &namespace.Namespace{
|
||||||
|
ID: "nsid",
|
||||||
|
Path: "foo/bar",
|
||||||
|
}
|
||||||
|
|
||||||
|
otherNSle := &leaseEntry{
|
||||||
|
LeaseID: "lease" + fmt.Sprintf("%d", i) + "/blah.nsid",
|
||||||
|
Path: "foo/bar/" + fmt.Sprintf("%d", i) + "/blah.nsid",
|
||||||
|
namespace: otherNS,
|
||||||
|
IssueTime: time.Now(),
|
||||||
|
ExpireTime: time.Now().Add(time.Hour),
|
||||||
|
}
|
||||||
|
|
||||||
|
exp.pendingLock.Lock()
|
||||||
|
if err := exp.persistEntry(namespace.RootContext(nil), le); err != nil {
|
||||||
|
exp.pendingLock.Unlock()
|
||||||
|
t.Fatalf("error persisting entry: %v", err)
|
||||||
|
}
|
||||||
|
exp.updatePendingInternal(le)
|
||||||
|
|
||||||
|
if err := exp.persistEntry(namespace.RootContext(nil), otherNSle); err != nil {
|
||||||
|
exp.pendingLock.Unlock()
|
||||||
|
t.Fatalf("error persisting entry: %v", err)
|
||||||
|
}
|
||||||
|
exp.updatePendingInternal(otherNSle)
|
||||||
|
exp.pendingLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 50; i < 250; i++ {
|
||||||
|
le := &leaseEntry{
|
||||||
|
LeaseID: "lease" + fmt.Sprintf("%d", i+1),
|
||||||
|
Path: "foo/bar/" + fmt.Sprintf("%d", i+1),
|
||||||
|
namespace: namespace.RootNamespace,
|
||||||
|
IssueTime: time.Now(),
|
||||||
|
ExpireTime: time.Now().Add(2 * time.Hour),
|
||||||
|
}
|
||||||
|
|
||||||
|
exp.pendingLock.Lock()
|
||||||
|
if err := exp.persistEntry(namespace.RootContext(nil), le); err != nil {
|
||||||
|
exp.pendingLock.Unlock()
|
||||||
|
t.Fatalf("error persisting entry: %v", err)
|
||||||
|
}
|
||||||
|
exp.updatePendingInternal(le)
|
||||||
|
exp.pendingLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
if err = logical.ScanView(context.Background(), exp.idView, countFunc); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var conf metricsutil.TelemetryConstConfig = metricsutil.TelemetryConstConfig{
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 2,
|
||||||
|
LeaseMetricsNameSpaceLabels: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedResults, err := exp.leaseAggregationMetrics(context.Background(), conf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if flattenedResults == nil {
|
||||||
|
t.Fatal("lease aggregation returns nil metrics")
|
||||||
|
}
|
||||||
|
|
||||||
|
labelOneHour := metrics.Label{"expiring", time.Now().Add(time.Hour).Round(time.Hour).String()}
|
||||||
|
labelTwoHours := metrics.Label{"expiring", time.Now().Add(2 * time.Hour).Round(time.Hour).String()}
|
||||||
|
nsLabel := metrics.Label{"namespace", "root"}
|
||||||
|
nsLabelNonRoot := metrics.Label{"namespace", "nsid"}
|
||||||
|
|
||||||
|
foundLabelOne := false
|
||||||
|
foundLabelTwo := false
|
||||||
|
foundLabelThree := false
|
||||||
|
|
||||||
|
for _, labelVal := range flattenedResults {
|
||||||
|
retNsLabel := labelVal.Labels[1]
|
||||||
|
retTimeLabel := labelVal.Labels[0]
|
||||||
|
if nsLabel == retNsLabel {
|
||||||
|
if labelVal.Value == 50 {
|
||||||
|
if retTimeLabel == labelOneHour {
|
||||||
|
foundLabelOne = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if labelVal.Value == 200 {
|
||||||
|
if retTimeLabel == labelTwoHours {
|
||||||
|
foundLabelTwo = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if retNsLabel == nsLabelNonRoot {
|
||||||
|
if labelVal.Value == 50 {
|
||||||
|
if retTimeLabel == labelOneHour {
|
||||||
|
foundLabelThree = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !foundLabelOne || !foundLabelTwo || !foundLabelThree {
|
||||||
|
t.Errorf("One of the labels is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test the same leases while ignoring namespaces so the 2 different namespaces get aggregated
|
||||||
|
conf = metricsutil.TelemetryConstConfig{
|
||||||
|
LeaseMetricsEpsilon: time.Hour,
|
||||||
|
NumLeaseMetricsTimeBuckets: 2,
|
||||||
|
LeaseMetricsNameSpaceLabels: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedResults, err = exp.leaseAggregationMetrics(context.Background(), conf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if flattenedResults == nil {
|
||||||
|
t.Fatal("lease aggregation returns nil metrics")
|
||||||
|
}
|
||||||
|
|
||||||
|
foundLabelOne = false
|
||||||
|
foundLabelTwo = false
|
||||||
|
|
||||||
|
for _, labelVal := range flattenedResults {
|
||||||
|
if len(labelVal.Labels) != 1 {
|
||||||
|
t.Errorf("Namespace label is returned when explicitly not requested.")
|
||||||
|
}
|
||||||
|
retTimeLabel := labelVal.Labels[0]
|
||||||
|
if labelVal.Value == 100 {
|
||||||
|
if retTimeLabel == labelOneHour {
|
||||||
|
foundLabelOne = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if labelVal.Value == 200 {
|
||||||
|
if retTimeLabel == labelTwoHours {
|
||||||
|
foundLabelTwo = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundLabelOne || !foundLabelTwo {
|
||||||
|
t.Errorf("One of the labels is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func TestExpiration_Tidy(t *testing.T) {
|
func TestExpiration_Tidy(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
96
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
96
vendor/github.com/hashicorp/vault/api/client.go
generated
vendored
@ -475,6 +475,9 @@ func (c *Client) SetAddress(addr string) error {
|
|||||||
return errwrap.Wrapf("failed to set address: {{err}}", err)
|
return errwrap.Wrapf("failed to set address: {{err}}", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.config.modifyLock.Lock()
|
||||||
|
c.config.Address = addr
|
||||||
|
c.config.modifyLock.Unlock()
|
||||||
c.addr = parsedAddr
|
c.addr = parsedAddr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -492,57 +495,111 @@ func (c *Client) Address() string {
|
|||||||
// rateLimit and burst are specified according to https://godoc.org/golang.org/x/time/rate#NewLimiter
|
// rateLimit and burst are specified according to https://godoc.org/golang.org/x/time/rate#NewLimiter
|
||||||
func (c *Client) SetLimiter(rateLimit float64, burst int) {
|
func (c *Client) SetLimiter(rateLimit float64, burst int) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.Limiter = rate.NewLimiter(rate.Limit(rateLimit), burst)
|
c.config.Limiter = rate.NewLimiter(rate.Limit(rateLimit), burst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) Limiter() *rate.Limiter {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.RLock()
|
||||||
|
defer c.config.modifyLock.RUnlock()
|
||||||
|
|
||||||
|
return c.config.Limiter
|
||||||
|
}
|
||||||
|
|
||||||
// SetMaxRetries sets the number of retries that will be used in the case of certain errors
|
// SetMaxRetries sets the number of retries that will be used in the case of certain errors
|
||||||
func (c *Client) SetMaxRetries(retries int) {
|
func (c *Client) SetMaxRetries(retries int) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.MaxRetries = retries
|
c.config.MaxRetries = retries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) MaxRetries() int {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.RLock()
|
||||||
|
defer c.config.modifyLock.RUnlock()
|
||||||
|
|
||||||
|
return c.config.MaxRetries
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) SetSRVLookup(srv bool) {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.Lock()
|
||||||
|
defer c.config.modifyLock.Unlock()
|
||||||
|
|
||||||
|
c.config.SRVLookup = srv
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) SRVLookup() bool {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.RLock()
|
||||||
|
defer c.config.modifyLock.RUnlock()
|
||||||
|
|
||||||
|
return c.config.SRVLookup
|
||||||
|
}
|
||||||
|
|
||||||
// SetCheckRetry sets the CheckRetry function to be used for future requests.
|
// SetCheckRetry sets the CheckRetry function to be used for future requests.
|
||||||
func (c *Client) SetCheckRetry(checkRetry retryablehttp.CheckRetry) {
|
func (c *Client) SetCheckRetry(checkRetry retryablehttp.CheckRetry) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.CheckRetry = checkRetry
|
c.config.CheckRetry = checkRetry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) CheckRetry() retryablehttp.CheckRetry {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.RLock()
|
||||||
|
defer c.config.modifyLock.RUnlock()
|
||||||
|
|
||||||
|
return c.config.CheckRetry
|
||||||
|
}
|
||||||
|
|
||||||
// SetClientTimeout sets the client request timeout
|
// SetClientTimeout sets the client request timeout
|
||||||
func (c *Client) SetClientTimeout(timeout time.Duration) {
|
func (c *Client) SetClientTimeout(timeout time.Duration) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.Timeout = timeout
|
c.config.Timeout = timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) OutputCurlString() bool {
|
func (c *Client) ClientTimeout() time.Duration {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
|
c.config.modifyLock.RLock()
|
||||||
|
defer c.config.modifyLock.RUnlock()
|
||||||
|
|
||||||
|
return c.config.Timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) OutputCurlString() bool {
|
||||||
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.RLock()
|
c.config.modifyLock.RLock()
|
||||||
defer c.config.modifyLock.RUnlock()
|
defer c.config.modifyLock.RUnlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
return c.config.OutputCurlString
|
return c.config.OutputCurlString
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) SetOutputCurlString(curl bool) {
|
func (c *Client) SetOutputCurlString(curl bool) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.OutputCurlString = curl
|
c.config.OutputCurlString = curl
|
||||||
}
|
}
|
||||||
@ -552,7 +609,6 @@ func (c *Client) SetOutputCurlString(curl bool) {
|
|||||||
func (c *Client) CurrentWrappingLookupFunc() WrappingLookupFunc {
|
func (c *Client) CurrentWrappingLookupFunc() WrappingLookupFunc {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
defer c.modifyLock.RUnlock()
|
defer c.modifyLock.RUnlock()
|
||||||
|
|
||||||
return c.wrappingLookupFunc
|
return c.wrappingLookupFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,7 +617,6 @@ func (c *Client) CurrentWrappingLookupFunc() WrappingLookupFunc {
|
|||||||
func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) {
|
func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) {
|
||||||
c.modifyLock.Lock()
|
c.modifyLock.Lock()
|
||||||
defer c.modifyLock.Unlock()
|
defer c.modifyLock.Unlock()
|
||||||
|
|
||||||
c.wrappingLookupFunc = lookupFunc
|
c.wrappingLookupFunc = lookupFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,7 +625,6 @@ func (c *Client) SetWrappingLookupFunc(lookupFunc WrappingLookupFunc) {
|
|||||||
func (c *Client) SetMFACreds(creds []string) {
|
func (c *Client) SetMFACreds(creds []string) {
|
||||||
c.modifyLock.Lock()
|
c.modifyLock.Lock()
|
||||||
defer c.modifyLock.Unlock()
|
defer c.modifyLock.Unlock()
|
||||||
|
|
||||||
c.mfaCreds = creds
|
c.mfaCreds = creds
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +649,6 @@ func (c *Client) setNamespace(namespace string) {
|
|||||||
func (c *Client) Token() string {
|
func (c *Client) Token() string {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
defer c.modifyLock.RUnlock()
|
defer c.modifyLock.RUnlock()
|
||||||
|
|
||||||
return c.token
|
return c.token
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +657,6 @@ func (c *Client) Token() string {
|
|||||||
func (c *Client) SetToken(v string) {
|
func (c *Client) SetToken(v string) {
|
||||||
c.modifyLock.Lock()
|
c.modifyLock.Lock()
|
||||||
defer c.modifyLock.Unlock()
|
defer c.modifyLock.Unlock()
|
||||||
|
|
||||||
c.token = v
|
c.token = v
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,7 +664,6 @@ func (c *Client) SetToken(v string) {
|
|||||||
func (c *Client) ClearToken() {
|
func (c *Client) ClearToken() {
|
||||||
c.modifyLock.Lock()
|
c.modifyLock.Lock()
|
||||||
defer c.modifyLock.Unlock()
|
defer c.modifyLock.Unlock()
|
||||||
|
|
||||||
c.token = ""
|
c.token = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,9 +706,9 @@ func (c *Client) SetHeaders(headers http.Header) {
|
|||||||
// SetBackoff sets the backoff function to be used for future requests.
|
// SetBackoff sets the backoff function to be used for future requests.
|
||||||
func (c *Client) SetBackoff(backoff retryablehttp.Backoff) {
|
func (c *Client) SetBackoff(backoff retryablehttp.Backoff) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
|
defer c.modifyLock.RUnlock()
|
||||||
c.config.modifyLock.Lock()
|
c.config.modifyLock.Lock()
|
||||||
defer c.config.modifyLock.Unlock()
|
defer c.config.modifyLock.Unlock()
|
||||||
c.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
c.config.Backoff = backoff
|
c.config.Backoff = backoff
|
||||||
}
|
}
|
||||||
@ -672,9 +723,11 @@ func (c *Client) SetBackoff(backoff retryablehttp.Backoff) {
|
|||||||
// behavior, must currently then be set as desired on the new client.
|
// behavior, must currently then be set as desired on the new client.
|
||||||
func (c *Client) Clone() (*Client, error) {
|
func (c *Client) Clone() (*Client, error) {
|
||||||
c.modifyLock.RLock()
|
c.modifyLock.RLock()
|
||||||
c.config.modifyLock.RLock()
|
defer c.modifyLock.RUnlock()
|
||||||
|
|
||||||
config := c.config
|
config := c.config
|
||||||
c.modifyLock.RUnlock()
|
config.modifyLock.RLock()
|
||||||
|
defer config.modifyLock.RUnlock()
|
||||||
|
|
||||||
newConfig := &Config{
|
newConfig := &Config{
|
||||||
Address: config.Address,
|
Address: config.Address,
|
||||||
@ -684,10 +737,16 @@ func (c *Client) Clone() (*Client, error) {
|
|||||||
Backoff: config.Backoff,
|
Backoff: config.Backoff,
|
||||||
CheckRetry: config.CheckRetry,
|
CheckRetry: config.CheckRetry,
|
||||||
Limiter: config.Limiter,
|
Limiter: config.Limiter,
|
||||||
|
OutputCurlString: config.OutputCurlString,
|
||||||
|
AgentAddress: config.AgentAddress,
|
||||||
|
SRVLookup: config.SRVLookup,
|
||||||
|
}
|
||||||
|
client, err := NewClient(newConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
config.modifyLock.RUnlock()
|
|
||||||
|
|
||||||
return NewClient(newConfig)
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPolicyOverride sets whether requests should be sent with the policy
|
// SetPolicyOverride sets whether requests should be sent with the policy
|
||||||
@ -696,7 +755,6 @@ func (c *Client) Clone() (*Client, error) {
|
|||||||
func (c *Client) SetPolicyOverride(override bool) {
|
func (c *Client) SetPolicyOverride(override bool) {
|
||||||
c.modifyLock.Lock()
|
c.modifyLock.Lock()
|
||||||
defer c.modifyLock.Unlock()
|
defer c.modifyLock.Unlock()
|
||||||
|
|
||||||
c.policyOverride = override
|
c.policyOverride = override
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user