Line 0
Link Here
|
|
|
1 |
This is a combination of upstream commits: |
2 |
b368a675955707db4e940da29a1043871a3781b6 |
3 |
21ea03e0f874991086d2f1bcdc285216878bd566 |
4 |
|
5 |
Fixes https://bugs.gentoo.org/808791 |
6 |
Fixes https://bugs.gentoo.org/810317 |
7 |
|
8 |
diff --git a/go.mod b/go.mod |
9 |
index 548c0590f..22a8833e2 100644 |
10 |
--- a/go.mod |
11 |
+++ b/go.mod |
12 |
@@ -150,7 +150,7 @@ require ( |
13 |
github.com/ryanuber/go-glob v1.0.0 |
14 |
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da |
15 |
github.com/sasha-s/go-deadlock v0.2.0 |
16 |
- github.com/sethvargo/go-limiter v0.3.0 |
17 |
+ github.com/sethvargo/go-limiter v0.7.1 |
18 |
github.com/shirou/gopsutil v3.21.5+incompatible |
19 |
github.com/stretchr/testify v1.7.0 |
20 |
github.com/tidwall/pretty v1.0.1 // indirect |
21 |
diff --git a/go.sum b/go.sum |
22 |
index c5b3b410d..98a5dd0a8 100644 |
23 |
--- a/go.sum |
24 |
+++ b/go.sum |
25 |
@@ -1120,8 +1120,8 @@ github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627/go.mod h1:7zjs06q |
26 |
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6qbIiqJ6/Bqeq25bCLbL7YFmpaFfJDuM= |
27 |
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= |
28 |
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= |
29 |
-github.com/sethvargo/go-limiter v0.3.0 h1:yRMc+Qs2yqw6YJp6UxrO2iUs6DOSq4zcnljbB7/rMns= |
30 |
-github.com/sethvargo/go-limiter v0.3.0/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU= |
31 |
+github.com/sethvargo/go-limiter v0.7.1 h1:wWNhTj0pxjyJ7wuJHpRJpYwJn+bUnjYfw2a85eu5w9U= |
32 |
+github.com/sethvargo/go-limiter v0.7.1/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU= |
33 |
github.com/shirou/gopsutil v3.21.5+incompatible h1:OloQyEerMi7JUrXiNzy8wQ5XN+baemxSl12QgIzt0jc= |
34 |
github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= |
35 |
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE= |
36 |
diff --git a/http/util.go b/http/util.go |
37 |
index 0550a93c7..cbb364843 100644 |
38 |
--- a/http/util.go |
39 |
+++ b/http/util.go |
40 |
@@ -48,7 +48,7 @@ func rateLimitQuotaWrapping(handler http.Handler, core *vault.Core) http.Handler |
41 |
return |
42 |
} |
43 |
|
44 |
- quotaResp, err := core.ApplyRateLimitQuota("as.Request{ |
45 |
+ quotaResp, err := core.ApplyRateLimitQuota(r.Context(), "as.Request{ |
46 |
Type: quotas.TypeRateLimit, |
47 |
Path: path, |
48 |
MountPath: strings.TrimPrefix(core.MatchingMount(r.Context(), path), ns.Path), |
49 |
diff --git a/vault/core.go b/vault/core.go |
50 |
index 3b6e461fd..27741e8c6 100644 |
51 |
--- a/vault/core.go |
52 |
+++ b/vault/core.go |
53 |
@@ -2744,7 +2744,7 @@ func (c *Core) setupQuotas(ctx context.Context, isPerfStandby bool) error { |
54 |
|
55 |
// ApplyRateLimitQuota checks the request against all the applicable quota rules. |
56 |
// If the given request's path is exempt, no rate limiting will be applied. |
57 |
-func (c *Core) ApplyRateLimitQuota(req *quotas.Request) (quotas.Response, error) { |
58 |
+func (c *Core) ApplyRateLimitQuota(ctx context.Context, req *quotas.Request) (quotas.Response, error) { |
59 |
req.Type = quotas.TypeRateLimit |
60 |
|
61 |
resp := quotas.Response{ |
62 |
@@ -2758,7 +2758,7 @@ func (c *Core) ApplyRateLimitQuota(req *quotas.Request) (quotas.Response, error) |
63 |
return resp, nil |
64 |
} |
65 |
|
66 |
- return c.quotaManager.ApplyQuota(req) |
67 |
+ return c.quotaManager.ApplyQuota(ctx, req) |
68 |
} |
69 |
|
70 |
return resp, nil |
71 |
diff --git a/vault/quotas/quotas.go b/vault/quotas/quotas.go |
72 |
index 68cc72f9f..80ee59521 100644 |
73 |
--- a/vault/quotas/quotas.go |
74 |
+++ b/vault/quotas/quotas.go |
75 |
@@ -168,7 +168,7 @@ type Manager struct { |
76 |
// Quota represents the common properties of every quota type |
77 |
type Quota interface { |
78 |
// allow checks the if the request is allowed by the quota type implementation. |
79 |
- allow(*Request) (Response, error) |
80 |
+ allow(context.Context, *Request) (Response, error) |
81 |
|
82 |
// quotaID is the identifier of the quota rule |
83 |
quotaID() string |
84 |
@@ -181,7 +181,7 @@ type Quota interface { |
85 |
|
86 |
// close defines any cleanup behavior that needs to be executed when a quota |
87 |
// rule is deleted. |
88 |
- close() error |
89 |
+ close(context.Context) error |
90 |
|
91 |
// handleRemount takes in the new mount path in the quota |
92 |
handleRemount(string) |
93 |
@@ -287,7 +287,7 @@ func (m *Manager) setQuotaLocked(ctx context.Context, qType string, quota Quota, |
94 |
// If there already exists an entry in the db, remove that first. |
95 |
if raw != nil { |
96 |
quota := raw.(Quota) |
97 |
- if err := quota.close(); err != nil { |
98 |
+ if err := quota.close(ctx); err != nil { |
99 |
return err |
100 |
} |
101 |
err = txn.Delete(qType, raw) |
102 |
@@ -518,7 +518,7 @@ func (m *Manager) DeleteQuota(ctx context.Context, qType string, name string) er |
103 |
} |
104 |
|
105 |
quota := raw.(Quota) |
106 |
- if err := quota.close(); err != nil { |
107 |
+ if err := quota.close(ctx); err != nil { |
108 |
return err |
109 |
} |
110 |
|
111 |
@@ -541,7 +541,7 @@ func (m *Manager) DeleteQuota(ctx context.Context, qType string, name string) er |
112 |
// ApplyQuota runs the request against any quota rule that is applicable to it. If |
113 |
// there are multiple quota rule that matches the request parameters, rule that |
114 |
// takes precedence will be used to allow/reject the request. |
115 |
-func (m *Manager) ApplyQuota(req *Request) (Response, error) { |
116 |
+func (m *Manager) ApplyQuota(ctx context.Context, req *Request) (Response, error) { |
117 |
var resp Response |
118 |
|
119 |
quota, err := m.QueryQuota(req) |
120 |
@@ -562,7 +562,7 @@ func (m *Manager) ApplyQuota(req *Request) (Response, error) { |
121 |
return resp, nil |
122 |
} |
123 |
|
124 |
- return quota.allow(req) |
125 |
+ return quota.allow(ctx, req) |
126 |
} |
127 |
|
128 |
// SetEnableRateLimitAuditLogging updates the operator preference regarding the |
129 |
diff --git a/vault/quotas/quotas_rate_limit.go b/vault/quotas/quotas_rate_limit.go |
130 |
index 64117b002..ad58b2af3 100644 |
131 |
--- a/vault/quotas/quotas_rate_limit.go |
132 |
+++ b/vault/quotas/quotas_rate_limit.go |
133 |
@@ -1,6 +1,7 @@ |
134 |
package quotas |
135 |
|
136 |
import ( |
137 |
+ "context" |
138 |
"encoding/hex" |
139 |
"fmt" |
140 |
"math" |
141 |
@@ -264,7 +265,7 @@ func (rlq *RateLimitQuota) QuotaName() string { |
142 |
// returned if the request ID or address is empty. If the path is exempt, the |
143 |
// quota will not be evaluated. Otherwise, the client rate limiter is retrieved |
144 |
// by address and the rate limit quota is checked against that limiter. |
145 |
-func (rlq *RateLimitQuota) allow(req *Request) (Response, error) { |
146 |
+func (rlq *RateLimitQuota) allow(ctx context.Context, req *Request) (Response, error) { |
147 |
resp := Response{ |
148 |
Headers: make(map[string]string), |
149 |
} |
150 |
@@ -300,7 +301,11 @@ func (rlq *RateLimitQuota) allow(req *Request) (Response, error) { |
151 |
} |
152 |
} |
153 |
|
154 |
- limit, remaining, reset, allow := rlq.store.Take(req.ClientAddress) |
155 |
+ limit, remaining, reset, allow, err := rlq.store.Take(ctx, req.ClientAddress) |
156 |
+ if err != nil { |
157 |
+ return resp, err |
158 |
+ } |
159 |
+ |
160 |
resp.Allowed = allow |
161 |
resp.Headers[httplimit.HeaderRateLimitLimit] = strconv.FormatUint(limit, 10) |
162 |
resp.Headers[httplimit.HeaderRateLimitRemaining] = strconv.FormatUint(remaining, 10) |
163 |
@@ -320,13 +325,13 @@ func (rlq *RateLimitQuota) allow(req *Request) (Response, error) { |
164 |
|
165 |
// close stops the current running client purge loop. |
166 |
// It should be called with the write lock held. |
167 |
-func (rlq *RateLimitQuota) close() error { |
168 |
+func (rlq *RateLimitQuota) close(ctx context.Context) error { |
169 |
if rlq.purgeBlocked { |
170 |
close(rlq.closePurgeBlockedCh) |
171 |
} |
172 |
|
173 |
if rlq.store != nil { |
174 |
- return rlq.store.Close() |
175 |
+ return rlq.store.Close(ctx) |
176 |
} |
177 |
|
178 |
return nil |
179 |
diff --git a/vault/quotas/quotas_rate_limit_test.go b/vault/quotas/quotas_rate_limit_test.go |
180 |
index 27225e338..21f35dac3 100644 |
181 |
--- a/vault/quotas/quotas_rate_limit_test.go |
182 |
+++ b/vault/quotas/quotas_rate_limit_test.go |
183 |
@@ -37,7 +37,7 @@ func TestNewRateLimitQuota(t *testing.T) { |
184 |
err := tc.rlq.initialize(logging.NewVaultLogger(log.Trace), metricsutil.BlackholeSink()) |
185 |
require.Equal(t, tc.expectErr, err != nil, err) |
186 |
if err == nil { |
187 |
- require.Nil(t, tc.rlq.close()) |
188 |
+ require.Nil(t, tc.rlq.close(context.Background())) |
189 |
} |
190 |
}) |
191 |
} |
192 |
@@ -46,7 +46,7 @@ func TestNewRateLimitQuota(t *testing.T) { |
193 |
func TestRateLimitQuota_Close(t *testing.T) { |
194 |
rlq := NewRateLimitQuota("test-rate-limiter", "qa", "/foo/bar", 16.7, time.Second, time.Minute) |
195 |
require.NoError(t, rlq.initialize(logging.NewVaultLogger(log.Trace), metricsutil.BlackholeSink())) |
196 |
- require.NoError(t, rlq.close()) |
197 |
+ require.NoError(t, rlq.close(context.Background())) |
198 |
|
199 |
time.Sleep(time.Second) // allow enough time for purgeClientsLoop to receive on closeCh |
200 |
require.False(t, rlq.getPurgeBlocked(), "expected blocked client purging to be disabled after explicit close") |
201 |
@@ -66,14 +66,14 @@ func TestRateLimitQuota_Allow(t *testing.T) { |
202 |
} |
203 |
|
204 |
require.NoError(t, rlq.initialize(logging.NewVaultLogger(log.Trace), metricsutil.BlackholeSink())) |
205 |
- defer rlq.close() |
206 |
+ defer rlq.close(context.Background()) |
207 |
|
208 |
var wg sync.WaitGroup |
209 |
|
210 |
reqFunc := func(addr string, atomicNumAllow, atomicNumFail *atomic.Int32) { |
211 |
defer wg.Done() |
212 |
|
213 |
- resp, err := rlq.allow(&Request{ClientAddress: addr}) |
214 |
+ resp, err := rlq.allow(context.Background(), &Request{ClientAddress: addr}) |
215 |
if err != nil { |
216 |
return |
217 |
} |
218 |
@@ -141,7 +141,7 @@ func TestRateLimitQuota_Allow_WithBlock(t *testing.T) { |
219 |
} |
220 |
|
221 |
require.NoError(t, rlq.initialize(logging.NewVaultLogger(log.Trace), metricsutil.BlackholeSink())) |
222 |
- defer rlq.close() |
223 |
+ defer rlq.close(context.Background()) |
224 |
require.True(t, rlq.getPurgeBlocked()) |
225 |
|
226 |
var wg sync.WaitGroup |
227 |
@@ -149,7 +149,7 @@ func TestRateLimitQuota_Allow_WithBlock(t *testing.T) { |
228 |
reqFunc := func(addr string, atomicNumAllow, atomicNumFail *atomic.Int32) { |
229 |
defer wg.Done() |
230 |
|
231 |
- resp, err := rlq.allow(&Request{ClientAddress: addr}) |
232 |
+ resp, err := rlq.allow(context.Background(), &Request{ClientAddress: addr}) |
233 |
if err != nil { |
234 |
return |
235 |
} |
236 |
@@ -221,5 +221,5 @@ func TestRateLimitQuota_Update(t *testing.T) { |
237 |
require.NoError(t, qm.SetQuota(context.Background(), TypeRateLimit.String(), quota, true)) |
238 |
require.NoError(t, qm.SetQuota(context.Background(), TypeRateLimit.String(), quota, true)) |
239 |
|
240 |
- require.Nil(t, quota.close()) |
241 |
+ require.Nil(t, quota.close(context.Background())) |
242 |
} |
243 |
diff --git a/vault/quotas/quotas_util.go b/vault/quotas/quotas_util.go |
244 |
index dc2fcdfac..7c0732f67 100644 |
245 |
--- a/vault/quotas/quotas_util.go |
246 |
+++ b/vault/quotas/quotas_util.go |
247 |
@@ -40,7 +40,7 @@ func (*entManager) Reset() error { |
248 |
|
249 |
type LeaseCountQuota struct{} |
250 |
|
251 |
-func (l LeaseCountQuota) allow(request *Request) (Response, error) { |
252 |
+func (l LeaseCountQuota) allow(_ context.Context, _ *Request) (Response, error) { |
253 |
panic("implement me") |
254 |
} |
255 |
|
256 |
@@ -56,7 +56,7 @@ func (l LeaseCountQuota) initialize(logger log.Logger, sink *metricsutil.Cluster |
257 |
panic("implement me") |
258 |
} |
259 |
|
260 |
-func (l LeaseCountQuota) close() error { |
261 |
+func (l LeaseCountQuota) close(_ context.Context) error { |
262 |
panic("implement me") |
263 |
} |
264 |
|