Skip to content

Commit 7913f6d

Browse files
committed
fix tenant glob match bug
Signed-off-by: Yi Jin <[email protected]>
1 parent 034daed commit 7913f6d

File tree

2 files changed

+90
-22
lines changed

2 files changed

+90
-22
lines changed

pkg/receive/hashring.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,42 @@ func (c ketamaHashring) GetN(tenant string, ts *prompb.TimeSeries, n uint64) (En
244244
return c.endpoints[endpointIndex], nil
245245
}
246246

247+
type tenantSet map[string]tenantMatcher
248+
249+
func (t tenantSet) match(tenant string) (bool, error) {
250+
// Fast path for the common case of direct match.
251+
if mt, ok := t[tenant]; ok && isExactMatcher(mt) {
252+
return true, nil
253+
} else {
254+
for tenantPattern, matcherType := range t {
255+
switch matcherType {
256+
case TenantMatcherGlob:
257+
matches, err := filepath.Match(tenantPattern, tenant)
258+
if err != nil {
259+
return false, fmt.Errorf("error matching tenant pattern %s (tenant %s): %w", tenantPattern, tenant, err)
260+
}
261+
if matches {
262+
return true, nil
263+
}
264+
case TenantMatcherTypeExact:
265+
// Already checked above, skipping.
266+
fallthrough
267+
default:
268+
continue
269+
}
270+
271+
}
272+
}
273+
return false, nil
274+
}
275+
247276
// multiHashring represents a set of hashrings.
248277
// Which hashring to use for a tenant is determined
249278
// by the tenants field of the hashring configuration.
250279
type multiHashring struct {
251280
cache map[string]Hashring
252281
hashrings []Hashring
253-
tenantSets []map[string]tenantMatcher
282+
tenantSets []tenantSet
254283

255284
// We need a mutex to guard concurrent access
256285
// to the cache map, as this is both written to
@@ -283,28 +312,10 @@ func (m *multiHashring) GetN(tenant string, ts *prompb.TimeSeries, n uint64) (En
283312
if t == nil {
284313
found = true
285314
} else {
286-
// Fast path for the common case of direct match.
287-
if mt, ok := t[tenant]; ok && isExactMatcher(mt) {
288-
found = true
289-
} else {
290-
for tenantPattern, matcherType := range t {
291-
switch matcherType {
292-
case TenantMatcherGlob:
293-
matches, err := filepath.Match(tenantPattern, tenant)
294-
if err != nil {
295-
return Endpoint{}, fmt.Errorf("error matching tenant pattern %s (tenant %s): %w", tenantPattern, tenant, err)
296-
}
297-
found = matches
298-
case TenantMatcherTypeExact:
299-
// Already checked above, skipping.
300-
fallthrough
301-
default:
302-
continue
303-
}
304-
305-
}
315+
var err error
316+
if found, err = t.match(tenant); err != nil {
317+
return Endpoint{}, err
306318
}
307-
308319
}
309320
if found {
310321
m.mu.Lock()

pkg/receive/hashring_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,63 @@ func TestHashringGet(t *testing.T) {
140140
"node6": {},
141141
},
142142
},
143+
{
144+
name: "glob hashring match",
145+
cfg: []HashringConfig{
146+
{
147+
Endpoints: []Endpoint{{Address: "node1"}, {Address: "node2"}, {Address: "node3"}},
148+
Tenants: []string{"prefix*"},
149+
TenantMatcherType: TenantMatcherGlob,
150+
},
151+
{
152+
Endpoints: []Endpoint{{Address: "node4"}, {Address: "node5"}, {Address: "node6"}},
153+
},
154+
},
155+
nodes: map[string]struct{}{
156+
"node1": {},
157+
"node2": {},
158+
"node3": {},
159+
},
160+
tenant: "prefix-1",
161+
},
162+
{
163+
name: "glob hashring not match",
164+
cfg: []HashringConfig{
165+
{
166+
Endpoints: []Endpoint{{Address: "node1"}, {Address: "node2"}, {Address: "node3"}},
167+
Tenants: []string{"prefix*"},
168+
TenantMatcherType: TenantMatcherGlob,
169+
},
170+
{
171+
Endpoints: []Endpoint{{Address: "node4"}, {Address: "node5"}, {Address: "node6"}},
172+
},
173+
},
174+
nodes: map[string]struct{}{
175+
"node4": {},
176+
"node5": {},
177+
"node6": {},
178+
},
179+
tenant: "suffix-1",
180+
},
181+
{
182+
name: "glob hashring multiple matches",
183+
cfg: []HashringConfig{
184+
{
185+
Endpoints: []Endpoint{{Address: "node1"}, {Address: "node2"}, {Address: "node3"}},
186+
Tenants: []string{"t1-*", "t2", "t3-*"},
187+
TenantMatcherType: TenantMatcherGlob,
188+
},
189+
{
190+
Endpoints: []Endpoint{{Address: "node4"}, {Address: "node5"}, {Address: "node6"}},
191+
},
192+
},
193+
nodes: map[string]struct{}{
194+
"node1": {},
195+
"node2": {},
196+
"node3": {},
197+
},
198+
tenant: "t2",
199+
},
143200
} {
144201
hs, err := NewMultiHashring(AlgorithmHashmod, 3, tc.cfg)
145202
require.NoError(t, err)

0 commit comments

Comments
 (0)