diff --git a/changelog/16386.txt b/changelog/16386.txt new file mode 100644 index 000000000..4fa6a6ca6 --- /dev/null +++ b/changelog/16386.txt @@ -0,0 +1,3 @@ +```release-note:bug +core/quotas: Added globbing functionality on the end of path suffix quota paths +``` diff --git a/vault/quotas/quotas.go b/vault/quotas/quotas.go index cac8ba589..038fe54d6 100644 --- a/vault/quotas/quotas.go +++ b/vault/quotas/quotas.go @@ -523,6 +523,20 @@ func (m *Manager) queryQuota(txn *memdb.Txn, req *Request) (Quota, error) { return quota, nil } + // Fetch path suffix quotas with globbing + // Request paths which match the resulting glob (i.e. share the same prefix prior to the glob) are in scope for the quota + for i := 0; i <= len(pathSuffix); i++ { + trimmedSuffixWithGlob := pathSuffix[:len(pathSuffix)-i] + "*" + // Check to see if a quota exists with this particular pattern + quota, err = quotaFetchFunc(indexNamespaceMountPath, req.NamespacePath, req.MountPath, trimmedSuffixWithGlob, false) + if err != nil { + return nil, err + } + if quota != nil { + return quota, nil + } + } + // Fetch mount quota quota, err = quotaFetchFunc(indexNamespaceMount, req.NamespacePath, req.MountPath, false, false) if err != nil { diff --git a/vault/quotas/quotas_test.go b/vault/quotas/quotas_test.go index f65f0a9cd..00299859f 100644 --- a/vault/quotas/quotas_test.go +++ b/vault/quotas/quotas_test.go @@ -87,7 +87,19 @@ func TestQuotas_Precedence(t *testing.T) { // Define a namespace mount specific quota and expect that to be returned. rateLimitNSMountQuota := setQuotaFunc(t, "rateLimitNSMountQuota", "testns/", "testmount/", "", "") - checkQuotaFunc(t, "testns/", "testmount/", "", "", rateLimitNSMountQuota) + checkQuotaFunc(t, "testns/", "testmount/", "testpath", "", rateLimitNSMountQuota) + + // Define a namespace mount + glob and expect that to be returned. + rateLimitNSMountGlob := setQuotaFunc(t, "rateLimitNSMountGlob", "testns/", "testmount/", "*", "") + checkQuotaFunc(t, "testns/", "testmount/", "testpath", "", rateLimitNSMountGlob) + + // Define a namespace mount + path specific quota with a glob and expect that to be returned. + rateLimitNSMountPathSuffixGlob := setQuotaFunc(t, "rateLimitNSMountPathSuffixGlob", "testns/", "testmount/", "test*", "") + checkQuotaFunc(t, "testns/", "testmount/", "testpath", "", rateLimitNSMountPathSuffixGlob) + + // Define a namespace mount + path specific quota with a glob at the end of the path and expect that to be returned. + rateLimitNSMountPathSuffixGlobAfterPath := setQuotaFunc(t, "rateLimitNSMountPathSuffixGlobAfterPath", "testns/", "testmount/", "testpath*", "") + checkQuotaFunc(t, "testns/", "testmount/", "testpath", "", rateLimitNSMountPathSuffixGlobAfterPath) // Define a namespace mount + path specific quota and expect that to be returned. rateLimitNSMountPathQuota := setQuotaFunc(t, "rateLimitNSMountPathQuota", "testns/", "testmount/", "testpath", "")