Fix quota enforcing old path issue (#10689)

* Fix db indexing issue

* Add CL update
This commit is contained in:
Vishal Nayak 2021-02-09 05:46:09 -05:00 committed by GitHub
parent 5ce35d1c52
commit 8613ba88a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 2 deletions

3
changelog/10689.txt Normal file
View File

@ -0,0 +1,3 @@
```changelog:bug
quotas/rate: Fix quotas enforcing old rate limit quota paths
```

View File

@ -5,9 +5,10 @@ import (
"strings"
"time"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/vault/quotas"
)
@ -209,15 +210,18 @@ func (b *SystemBackend) handleRateLimitQuotasUpdate() framework.OperationFunc {
switch {
case quota == nil:
quota = quotas.NewRateLimitQuota(name, ns.Path, mountPath, rate, interval, blockInterval)
default:
rlq := quota.(*quotas.RateLimitQuota)
// Re-inserting the already indexed object in memdb might cause problems.
// So, clone the object. See https://github.com/hashicorp/go-memdb/issues/76.
rlq = rlq.Clone()
rlq.NamespacePath = ns.Path
rlq.MountPath = mountPath
rlq.Rate = rate
rlq.Interval = interval
rlq.BlockInterval = blockInterval
quota = rlq
}
entry, err := logical.StorageEntryJSON(quotas.QuotaStoragePath(qType, name), quota)

View File

@ -100,6 +100,20 @@ func NewRateLimitQuota(name, nsPath, mountPath string, rate float64, interval, b
}
}
func (q *RateLimitQuota) Clone() *RateLimitQuota {
rlq := &RateLimitQuota{
ID: q.ID,
Name: q.Name,
MountPath: q.MountPath,
Type: q.Type,
NamespacePath: q.NamespacePath,
BlockInterval: q.BlockInterval,
Rate: q.Rate,
Interval: q.Interval,
}
return rlq
}
// initialize ensures the namespace and max requests are initialized, sets the ID
// if it's currently empty, sets the purge interval and stale age to default
// values, and finally starts the client purge go routine if it has been started

View File

@ -12,6 +12,33 @@ import (
"github.com/stretchr/testify/require"
)
func TestQuotas_MountPathOverwrite(t *testing.T) {
qm, err := NewManager(logging.NewVaultLogger(log.Trace), nil, metricsutil.BlackholeSink())
require.NoError(t, err)
quota := NewRateLimitQuota("tq", "", "kv1/", 10, time.Second, 0)
require.NoError(t, qm.SetQuota(context.Background(), TypeRateLimit.String(), quota, false))
quota = quota.Clone()
quota.MountPath = "kv2/"
require.NoError(t, qm.SetQuota(context.Background(), TypeRateLimit.String(), quota, false))
q, err := qm.QueryQuota(&Request{
Type: TypeRateLimit,
MountPath: "kv1/",
})
require.NoError(t, err)
require.Nil(t, q)
require.NoError(t, qm.DeleteQuota(context.Background(), TypeRateLimit.String(), "tq"))
q, err = qm.QueryQuota(&Request{
Type: TypeRateLimit,
MountPath: "kv1/",
})
require.NoError(t, err)
require.Nil(t, q)
}
func TestQuotas_Precedence(t *testing.T) {
qm, err := NewManager(logging.NewVaultLogger(log.Trace), nil, metricsutil.BlackholeSink())
require.NoError(t, err)