Fill in missing lease ID deterministically. Generate a UUID on creation. (#10855)

This commit is contained in:
Mark Gritter 2021-02-08 13:46:59 -06:00 committed by GitHub
parent baf50061e9
commit d0994340fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 6 deletions

3
changelog/10855.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
core: Fix duplicate quotas on performance standby nodes.
```

View File

@ -1,6 +1,7 @@
package quotas package quotas
import ( import (
"encoding/hex"
"fmt" "fmt"
"math" "math"
"strconv" "strconv"
@ -11,6 +12,7 @@ import (
log "github.com/hashicorp/go-hclog" log "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/helper/metricsutil" "github.com/hashicorp/vault/helper/metricsutil"
"github.com/hashicorp/vault/sdk/helper/cryptoutil"
"github.com/sethvargo/go-limiter" "github.com/sethvargo/go-limiter"
"github.com/sethvargo/go-limiter/httplimit" "github.com/sethvargo/go-limiter/httplimit"
"github.com/sethvargo/go-limiter/memorystore" "github.com/sethvargo/go-limiter/memorystore"
@ -79,8 +81,14 @@ type RateLimitQuota struct {
// duration may be provided, where if set, when a client reaches the rate limit, // duration may be provided, where if set, when a client reaches the rate limit,
// subsequent requests will fail until the block duration has passed. // subsequent requests will fail until the block duration has passed.
func NewRateLimitQuota(name, nsPath, mountPath string, rate float64, interval, block time.Duration) *RateLimitQuota { func NewRateLimitQuota(name, nsPath, mountPath string, rate float64, interval, block time.Duration) *RateLimitQuota {
id, err := uuid.GenerateUUID()
if err != nil {
// Fall back to generating with a hash of the name, later in initialize
id = ""
}
return &RateLimitQuota{ return &RateLimitQuota{
Name: name, Name: name,
ID: id,
Type: TypeRateLimit, Type: TypeRateLimit,
NamespacePath: nsPath, NamespacePath: nsPath,
MountPath: mountPath, MountPath: mountPath,
@ -130,12 +138,13 @@ func (rlq *RateLimitQuota) initialize(logger log.Logger, ms *metricsutil.Cluster
} }
if rlq.ID == "" { if rlq.ID == "" {
id, err := uuid.GenerateUUID() // A lease which was created with a blank ID may have been persisted
if err != nil { // to storage already (this is the case up to release 1.6.2.)
return err // So, performance standby nodes could call initialize() on their copy
} // of the lease; for consistency we need to generate an ID that is
// deterministic. That ensures later invalidation removes the original
rlq.ID = id // lease from the memdb, instead of creating a duplicate.
rlq.ID = hex.EncodeToString(cryptoutil.Blake2b256Hash(rlq.Name))
} }
// Set purgeInterval if coming from a previous version where purgeInterval was // Set purgeInterval if coming from a previous version where purgeInterval was