/
globs.go
74 lines (58 loc) · 1.56 KB
/
globs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2021-2024 Zenauth Ltd.
// SPDX-License-Identifier: Apache-2.0
package util
import (
"github.com/cerbos/cerbos/internal/cache"
"github.com/gobwas/glob"
"go.uber.org/zap"
)
var globs = &globCache{cache: cache.New[string, glob.Glob]("glob", 1024)} //nolint:gomnd
type globCache struct {
cache *cache.Cache[string, glob.Glob]
}
func (gc *globCache) matches(globExpr, val string) bool {
cachedGlob, ok := gc.cache.Get(globExpr)
if ok {
return cachedGlob.Match(val)
}
g, err := glob.Compile(globExpr, ':')
if err != nil {
zap.L().Named("glob-cache").Warn("Invalid glob expression", zap.String("glob", globExpr), zap.Error(err))
return false
}
gc.cache.Set(globExpr, g)
return g.Match(val)
}
// MatchesGlob returns true if the given glob expression matches the given string.
func MatchesGlob(globExpr, val string) bool {
return globs.matches(globExpr, val)
}
// FilterGlob returns the set of values that match the given glob.
func FilterGlob(g string, values []string) []string {
globExp := fixGlob(g)
var out []string
for _, v := range values {
if globs.matches(globExp, v) {
out = append(out, v)
}
}
return out
}
// FilterGlobNotMatches returns the set of values that do not match the given glob.
func FilterGlobNotMatches(g string, values []string) []string {
globExp := fixGlob(g)
var out []string
for _, v := range values {
if !globs.matches(globExp, v) {
out = append(out, v)
}
}
return out
}
func fixGlob(g string) string {
// for backward compatibility, consider single * as **
if g == "*" {
return "**"
}
return g
}