Add config value that gives users options to skip calculating role for each lease (#22651) (#22730)

* Add config value that gives users options to skip calculating role for each lease

* add changelog

* change name

* add config for testing

* Update changelog/22651.txt



* update tests, docs and reorder logic in conditional

* fix comment

* update comment

* fix comment again

* Update comments and change if order

* change comment again

* add other comment

* fix tests

* add documentation

* edit docs

* Update http/util.go



* Update vault/core.go

* Update vault/core.go

* update var name

* udpate docs

* Update vault/request_handling.go



* 1 more docs change

---------

Co-authored-by: Ellie <ellie.sterner@hashicorp.com>
Co-authored-by: Violet Hynes <violet.hynes@hashicorp.com>
Co-authored-by: Mike Palmiotto <mike.palmiotto@hashicorp.com>
This commit is contained in:
hc-github-team-secure-vault-core 2023-09-01 09:07:47 -04:00 committed by GitHub
parent 4c02eb4d71
commit cb0784b87f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 40 additions and 4 deletions

3
changelog/22651.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
core/quotas: Add configuration to allow skipping of expensive role calculations
```

View File

@ -2769,6 +2769,7 @@ func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.
LogicalBackends: c.LogicalBackends, LogicalBackends: c.LogicalBackends,
Logger: c.logger, Logger: c.logger,
DetectDeadlocks: config.DetectDeadlocks, DetectDeadlocks: config.DetectDeadlocks,
ImpreciseLeaseRoleTracking: config.ImpreciseLeaseRoleTracking,
DisableSentinelTrace: config.DisableSentinelTrace, DisableSentinelTrace: config.DisableSentinelTrace,
DisableCache: config.DisableCache, DisableCache: config.DisableCache,
DisableMlock: config.DisableMlock, DisableMlock: config.DisableMlock,

View File

@ -112,6 +112,8 @@ type Config struct {
DetectDeadlocks string `hcl:"detect_deadlocks"` DetectDeadlocks string `hcl:"detect_deadlocks"`
ImpreciseLeaseRoleTracking bool `hcl:"imprecise_lease_role_tracking"`
EnableResponseHeaderRaftNodeID bool `hcl:"-"` EnableResponseHeaderRaftNodeID bool `hcl:"-"`
EnableResponseHeaderRaftNodeIDRaw interface{} `hcl:"enable_response_header_raft_node_id"` EnableResponseHeaderRaftNodeIDRaw interface{} `hcl:"enable_response_header_raft_node_id"`
@ -412,6 +414,11 @@ func (c *Config) Merge(c2 *Config) *Config {
result.DetectDeadlocks = c2.DetectDeadlocks result.DetectDeadlocks = c2.DetectDeadlocks
} }
result.ImpreciseLeaseRoleTracking = c.ImpreciseLeaseRoleTracking
if c2.ImpreciseLeaseRoleTracking {
result.ImpreciseLeaseRoleTracking = c2.ImpreciseLeaseRoleTracking
}
result.EnableResponseHeaderRaftNodeID = c.EnableResponseHeaderRaftNodeID result.EnableResponseHeaderRaftNodeID = c.EnableResponseHeaderRaftNodeID
if c2.EnableResponseHeaderRaftNodeID { if c2.EnableResponseHeaderRaftNodeID {
result.EnableResponseHeaderRaftNodeID = c2.EnableResponseHeaderRaftNodeID result.EnableResponseHeaderRaftNodeID = c2.EnableResponseHeaderRaftNodeID
@ -1136,6 +1143,8 @@ func (c *Config) Sanitized() map[string]interface{} {
"experiments": c.Experiments, "experiments": c.Experiments,
"detect_deadlocks": c.DetectDeadlocks, "detect_deadlocks": c.DetectDeadlocks,
"imprecise_lease_role_tracking": c.ImpreciseLeaseRoleTracking,
} }
for k, v := range sharedResult { for k, v := range sharedResult {
result[k] = v result[k] = v

View File

@ -842,6 +842,7 @@ func testConfig_Sanitized(t *testing.T) {
"add_lease_metrics_namespace_labels": false, "add_lease_metrics_namespace_labels": false,
}, },
"administrative_namespace_path": "admin/", "administrative_namespace_path": "admin/",
"imprecise_lease_role_tracking": false,
} }
addExpectedEntSanitizedConfig(expected, []string{"http"}) addExpectedEntSanitizedConfig(expected, []string{"http"})

View File

@ -175,6 +175,7 @@ func TestSysConfigState_Sanitized(t *testing.T) {
}, },
"storage": tc.expectedStorageOutput, "storage": tc.expectedStorageOutput,
"administrative_namespace_path": "", "administrative_namespace_path": "",
"imprecise_lease_role_tracking": false,
} }
if tc.expectedHAStorageOutput != nil { if tc.expectedHAStorageOutput != nil {

View File

@ -71,6 +71,8 @@ func rateLimitQuotaWrapping(handler http.Handler, core *vault.Core) http.Handler
NamespacePath: ns.Path, NamespacePath: ns.Path,
ClientAddress: parseRemoteIPAddress(r), ClientAddress: parseRemoteIPAddress(r),
} }
// This checks if any role based quota is required (LCQ or RLQ).
requiresResolveRole, err := core.ResolveRoleForQuotas(r.Context(), quotaReq) requiresResolveRole, err := core.ResolveRoleForQuotas(r.Context(), quotaReq)
if err != nil { if err != nil {
core.Logger().Error("failed to lookup quotas", "path", path, "error", err) core.Logger().Error("failed to lookup quotas", "path", path, "error", err)

View File

@ -693,6 +693,9 @@ type Core struct {
// if populated, the callback is called for every request // if populated, the callback is called for every request
// for testing purposes // for testing purposes
requestResponseCallback func(logical.Backend, *logical.Request, *logical.Response) requestResponseCallback func(logical.Backend, *logical.Request, *logical.Response)
// If any role based quota (LCQ or RLQ) is enabled, don't track lease counts by role
impreciseLeaseRoleTracking bool
} }
// c.stateLock needs to be held in read mode before calling this function. // c.stateLock needs to be held in read mode before calling this function.
@ -754,6 +757,9 @@ type CoreConfig struct {
// Use the deadlocks library to detect deadlocks // Use the deadlocks library to detect deadlocks
DetectDeadlocks string DetectDeadlocks string
// If any role based quota (LCQ or RLQ) is enabled, don't track lease counts by role
ImpreciseLeaseRoleTracking bool
// Disables the trace display for Sentinel checks // Disables the trace display for Sentinel checks
DisableSentinelTrace bool DisableSentinelTrace bool
@ -1018,6 +1024,7 @@ func CreateCore(conf *CoreConfig) (*Core, error) {
experiments: conf.Experiments, experiments: conf.Experiments,
pendingRemovalMountsAllowed: conf.PendingRemovalMountsAllowed, pendingRemovalMountsAllowed: conf.PendingRemovalMountsAllowed,
expirationRevokeRetryBase: conf.ExpirationRevokeRetryBase, expirationRevokeRetryBase: conf.ExpirationRevokeRetryBase,
impreciseLeaseRoleTracking: conf.ImpreciseLeaseRoleTracking,
} }
c.standbyStopCh.Store(make(chan struct{})) c.standbyStopCh.Store(make(chan struct{}))

View File

@ -1687,10 +1687,16 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
// Attach the display name, might be used by audit backends // Attach the display name, might be used by audit backends
req.DisplayName = auth.DisplayName req.DisplayName = auth.DisplayName
// If this is not a role-based quota, we still need to associate the requiresLease := resp.Auth.TokenType != logical.TokenTypeBatch
// login role with this lease for later lease-count quotas to be
// accurate. // If role was not already determined by http.rateLimitQuotaWrapping
if reqRole == nil && resp.Auth.TokenType != logical.TokenTypeBatch { // and a lease will be generated, calculate a role for the leaseEntry.
// We can skip this step if there are no pre-existing role-based quotas
// for this mount and Vault is configured to skip lease role-based lease counting
// until after they're created. This effectively zeroes out the lease count
// for new role-based quotas upon creation, rather than counting old leases toward
// the total.
if reqRole == nil && requiresLease && !c.impreciseLeaseRoleTracking {
role = c.DetermineRoleFromLoginRequest(ctx, req.MountPoint, req.Data) role = c.DetermineRoleFromLoginRequest(ctx, req.MountPoint, req.Data)
} }

View File

@ -220,6 +220,7 @@ func TestCoreWithSealAndUINoCleanup(t testing.T, opts *CoreConfig) *Core {
conf.Experiments = []string{experiments.VaultExperimentEventsAlpha1} conf.Experiments = []string{experiments.VaultExperimentEventsAlpha1}
conf.CensusAgent = opts.CensusAgent conf.CensusAgent = opts.CensusAgent
conf.AdministrativeNamespacePath = opts.AdministrativeNamespacePath conf.AdministrativeNamespacePath = opts.AdministrativeNamespacePath
conf.ImpreciseLeaseRoleTracking = opts.ImpreciseLeaseRoleTracking
if opts.Logger != nil { if opts.Logger != nil {
conf.Logger = opts.Logger conf.Logger = opts.Logger
@ -1533,6 +1534,7 @@ func NewTestCluster(t testing.T, base *CoreConfig, opts *TestClusterOptions) *Te
coreConfig.DisableAutopilot = base.DisableAutopilot coreConfig.DisableAutopilot = base.DisableAutopilot
coreConfig.AdministrativeNamespacePath = base.AdministrativeNamespacePath coreConfig.AdministrativeNamespacePath = base.AdministrativeNamespacePath
coreConfig.ServiceRegistration = base.ServiceRegistration coreConfig.ServiceRegistration = base.ServiceRegistration
coreConfig.ImpreciseLeaseRoleTracking = base.ImpreciseLeaseRoleTracking
if base.BuiltinRegistry != nil { if base.BuiltinRegistry != nil {
coreConfig.BuiltinRegistry = base.BuiltinRegistry coreConfig.BuiltinRegistry = base.BuiltinRegistry

View File

@ -221,6 +221,10 @@ a negative effect on performance due to the tracking of each lock attempt.
the `VAULT_EXPERIMENTS` environment variable as a comma-separated list, or via the the `VAULT_EXPERIMENTS` environment variable as a comma-separated list, or via the
[`-experiment`](/vault/docs/commands/server#experiment) flag. [`-experiment`](/vault/docs/commands/server#experiment) flag.
- `imprecise_lease_role_tracking` `(bool: "false")` - Skip lease counting by role if there are no role based quotas enabled.
When `imprecise_lease_role_tracking` is set to true and a new role-based quota is enabled, subsequent lease counts start from 0.
`imprecise_lease_role_tracking` affects role-based lease count quotas, but reduces latencies when not using role based quotas.
### High availability parameters ### High availability parameters
The following parameters are used on backends that support [high availability][high-availability]. The following parameters are used on backends that support [high availability][high-availability].