VAULT-7707 OSS portion of changes (#18019)
* VAULT-7707 OSS portion of changes * Revert "VAULT-7707 OSS portion of changes" This reverts commit 5b8cf3882fb7e2427593d59e1439d46b3a5c20a7. * VAULT-7707 smarter locking behaviour * VAULT-7707 typo * VAULT-7707 typo
This commit is contained in:
parent
5c4e148ce2
commit
bfeae1fe8e
|
@ -165,7 +165,15 @@ type Manager struct {
|
|||
|
||||
logger log.Logger
|
||||
metricSink *metricsutil.ClusterMetricSink
|
||||
lock *sync.RWMutex
|
||||
|
||||
// quotaLock is a lock for manipulating quotas and anything not covered by a more specific lock
|
||||
quotaLock *sync.RWMutex
|
||||
|
||||
// quotaConfigLock is a lock for accessing config items, such as RateLimitExemptPaths
|
||||
quotaConfigLock *sync.RWMutex
|
||||
|
||||
// dbAndCacheLock is a lock for db and path caches that need to be reset during Reset()
|
||||
dbAndCacheLock *sync.RWMutex
|
||||
}
|
||||
|
||||
// QuotaLeaseInformation contains all of the information lease-count quotas require
|
||||
|
@ -273,7 +281,9 @@ func NewManager(logger log.Logger, walkFunc leaseWalkFunc, ms *metricsutil.Clust
|
|||
metricSink: ms,
|
||||
rateLimitPathManager: pathmanager.New(),
|
||||
config: new(Config),
|
||||
lock: new(sync.RWMutex),
|
||||
quotaLock: new(sync.RWMutex),
|
||||
quotaConfigLock: new(sync.RWMutex),
|
||||
dbAndCacheLock: new(sync.RWMutex),
|
||||
}
|
||||
|
||||
manager.init(walkFunc)
|
||||
|
@ -283,8 +293,10 @@ func NewManager(logger log.Logger, walkFunc leaseWalkFunc, ms *metricsutil.Clust
|
|||
|
||||
// SetQuota adds or updates a quota rule.
|
||||
func (m *Manager) SetQuota(ctx context.Context, qType string, quota Quota, loading bool) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.quotaLock.Unlock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
return m.setQuotaLocked(ctx, qType, quota, loading)
|
||||
}
|
||||
|
||||
|
@ -355,8 +367,8 @@ func (m *Manager) setQuotaLockedWithTxn(ctx context.Context, qType string, quota
|
|||
|
||||
// QuotaNames returns the names of all the quota rules for a given type
|
||||
func (m *Manager) QuotaNames(qType Type) ([]string, error) {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
return m.quotaNamesLocked(qType)
|
||||
}
|
||||
|
@ -377,8 +389,8 @@ func (m *Manager) quotaNamesLocked(qType Type) ([]string, error) {
|
|||
|
||||
// QuotaByID queries for a quota rule in the db for a given quota ID
|
||||
func (m *Manager) QuotaByID(qType string, id string) (Quota, error) {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
txn := m.db.Txn(false)
|
||||
|
||||
|
@ -395,8 +407,8 @@ func (m *Manager) QuotaByID(qType string, id string) (Quota, error) {
|
|||
|
||||
// QuotaByName queries for a quota rule in the db for a given quota name
|
||||
func (m *Manager) QuotaByName(qType string, name string) (Quota, error) {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
return m.quotaByNameLocked(qType, name)
|
||||
}
|
||||
|
@ -418,8 +430,8 @@ func (m *Manager) quotaByNameLocked(qType string, name string) (Quota, error) {
|
|||
|
||||
// QuotaByFactors returns the quota rule that matches the provided factors
|
||||
func (m *Manager) QuotaByFactors(ctx context.Context, qType, nsPath, mountPath, pathSuffix, role string) (Quota, error) {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
// nsPath would have been made non-empty during insertion. Use non-empty value
|
||||
// during query as well.
|
||||
|
@ -464,8 +476,8 @@ func (m *Manager) QuotaByFactors(ctx context.Context, qType, nsPath, mountPath,
|
|||
|
||||
// QueryQuota returns the most specific applicable quota for a given request.
|
||||
func (m *Manager) QueryQuota(req *Request) (Quota, error) {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
return m.queryQuota(nil, req)
|
||||
}
|
||||
|
@ -587,8 +599,10 @@ func (m *Manager) queryQuota(txn *memdb.Txn, req *Request) (Quota, error) {
|
|||
|
||||
// DeleteQuota removes a quota rule from the db for a given name
|
||||
func (m *Manager) DeleteQuota(ctx context.Context, qType string, name string) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.quotaLock.Unlock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
txn := m.db.Txn(true)
|
||||
defer txn.Abort()
|
||||
|
@ -652,8 +666,8 @@ func (m *Manager) ApplyQuota(ctx context.Context, req *Request) (Response, error
|
|||
// SetEnableRateLimitAuditLogging updates the operator preference regarding the
|
||||
// audit logging behavior.
|
||||
func (m *Manager) SetEnableRateLimitAuditLogging(val bool) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
defer m.quotaLock.Unlock()
|
||||
m.setEnableRateLimitAuditLoggingLocked(val)
|
||||
}
|
||||
|
||||
|
@ -664,8 +678,8 @@ func (m *Manager) setEnableRateLimitAuditLoggingLocked(val bool) {
|
|||
// SetEnableRateLimitResponseHeaders updates the operator preference regarding
|
||||
// the rate limit quota HTTP header behavior.
|
||||
func (m *Manager) SetEnableRateLimitResponseHeaders(val bool) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaConfigLock.Lock()
|
||||
defer m.quotaConfigLock.Unlock()
|
||||
m.setEnableRateLimitResponseHeadersLocked(val)
|
||||
}
|
||||
|
||||
|
@ -678,8 +692,8 @@ func (m *Manager) setEnableRateLimitResponseHeadersLocked(val bool) {
|
|||
// SetRateLimitExemptPaths will wipe out the existing path manager and set the
|
||||
// paths based on the provided argument.
|
||||
func (m *Manager) SetRateLimitExemptPaths(vals []string) {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaConfigLock.Lock()
|
||||
defer m.quotaConfigLock.Unlock()
|
||||
m.setRateLimitExemptPathsLocked(vals)
|
||||
}
|
||||
|
||||
|
@ -695,8 +709,8 @@ func (m *Manager) setRateLimitExemptPathsLocked(vals []string) {
|
|||
// RateLimitAuditLoggingEnabled returns if the quota configuration allows audit
|
||||
// logging of request rejections due to rate limiting quota rule violations.
|
||||
func (m *Manager) RateLimitAuditLoggingEnabled() bool {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.quotaConfigLock.RLock()
|
||||
defer m.quotaConfigLock.RUnlock()
|
||||
|
||||
return m.config.EnableRateLimitAuditLogging
|
||||
}
|
||||
|
@ -704,8 +718,8 @@ func (m *Manager) RateLimitAuditLoggingEnabled() bool {
|
|||
// RateLimitResponseHeadersEnabled returns if the quota configuration allows for
|
||||
// rate limit quota HTTP headers to be added to responses.
|
||||
func (m *Manager) RateLimitResponseHeadersEnabled() bool {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.quotaConfigLock.RLock()
|
||||
defer m.quotaConfigLock.RUnlock()
|
||||
|
||||
return m.config.EnableRateLimitResponseHeaders
|
||||
}
|
||||
|
@ -713,8 +727,8 @@ func (m *Manager) RateLimitResponseHeadersEnabled() bool {
|
|||
// RateLimitExemptPaths returns the list of exempt paths from all rate limit
|
||||
// resource quotas from the Manager's configuration.
|
||||
func (m *Manager) RateLimitExemptPaths() []string {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.quotaConfigLock.RLock()
|
||||
defer m.quotaConfigLock.RUnlock()
|
||||
|
||||
return m.config.RateLimitExemptPaths
|
||||
}
|
||||
|
@ -723,8 +737,8 @@ func (m *Manager) RateLimitExemptPaths() []string {
|
|||
// any rate limit quota. If not rate limit path manager is defined, false is
|
||||
// returned.
|
||||
func (m *Manager) RateLimitPathExempt(path string) bool {
|
||||
m.lock.RLock()
|
||||
defer m.lock.RUnlock()
|
||||
m.quotaConfigLock.RLock()
|
||||
defer m.quotaConfigLock.RUnlock()
|
||||
|
||||
if m.rateLimitPathManager == nil {
|
||||
return false
|
||||
|
@ -740,8 +754,10 @@ func (m *Manager) Config() *Config {
|
|||
|
||||
// Reset will clear all the quotas from the db and clear the lease path cache.
|
||||
func (m *Manager) Reset() error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
defer m.quotaLock.Unlock()
|
||||
m.dbAndCacheLock.Lock()
|
||||
defer m.dbAndCacheLock.Unlock()
|
||||
|
||||
err := m.resetCache()
|
||||
if err != nil {
|
||||
|
@ -1015,8 +1031,12 @@ func Load(ctx context.Context, storage logical.Storage, qType, name string) (Quo
|
|||
// Setup loads the quota configuration and all the quota rules into the
|
||||
// quota manager.
|
||||
func (m *Manager) Setup(ctx context.Context, storage logical.Storage, isPerfStandby, isDRSecondary bool) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
m.quotaConfigLock.Lock()
|
||||
m.dbAndCacheLock.Lock()
|
||||
defer m.quotaLock.Unlock()
|
||||
defer m.quotaConfigLock.Unlock()
|
||||
defer m.dbAndCacheLock.Unlock()
|
||||
|
||||
m.storage = storage
|
||||
m.ctx = ctx
|
||||
|
@ -1104,8 +1124,10 @@ func QuotaStoragePath(quotaType, name string) string {
|
|||
// took place. Quota manager will trigger the quota specific updates including
|
||||
// the mount path update and the namespace update
|
||||
func (m *Manager) HandleRemount(ctx context.Context, from, to namespace.MountPathDetails) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.quotaLock.Unlock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
// Grab a write transaction, as we want to save the updated quota in memdb
|
||||
txn := m.db.Txn(true)
|
||||
|
@ -1189,8 +1211,10 @@ func (m *Manager) HandleRemount(ctx context.Context, from, to namespace.MountPat
|
|||
// or secret engine disabling. This should only be called on the primary cluster
|
||||
// node.
|
||||
func (m *Manager) HandleBackendDisabling(ctx context.Context, nsPath, mountPath string) error {
|
||||
m.lock.Lock()
|
||||
defer m.lock.Unlock()
|
||||
m.quotaLock.Lock()
|
||||
m.dbAndCacheLock.RLock()
|
||||
defer m.quotaLock.Unlock()
|
||||
defer m.dbAndCacheLock.RUnlock()
|
||||
|
||||
txn := m.db.Txn(true)
|
||||
defer txn.Abort()
|
||||
|
|
Loading…
Reference in New Issue