github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/graveler/branch/protection_manager.go (about) 1 package branch 2 3 import ( 4 "context" 5 "errors" 6 "time" 7 8 "github.com/gobwas/glob" 9 "github.com/treeverse/lakefs/pkg/cache" 10 "github.com/treeverse/lakefs/pkg/graveler" 11 "github.com/treeverse/lakefs/pkg/graveler/settings" 12 ) 13 14 const ProtectionSettingKey = "protected_branches" 15 16 const ( 17 matcherCacheSize = 100_000 18 matcherCacheExpiry = 1 * time.Hour 19 matcherCacheJitter = 1 * time.Minute 20 ) 21 22 type ProtectionManager struct { 23 settingManager *settings.Manager 24 matchers cache.Cache 25 } 26 27 func NewProtectionManager(settingManager *settings.Manager) *ProtectionManager { 28 return &ProtectionManager{settingManager: settingManager, matchers: cache.NewCache(matcherCacheSize, matcherCacheExpiry, cache.NewJitterFn(matcherCacheJitter))} 29 } 30 31 func (m *ProtectionManager) GetRules(ctx context.Context, repository *graveler.RepositoryRecord) (*graveler.BranchProtectionRules, *string, error) { 32 rulesMsg := &graveler.BranchProtectionRules{} 33 checksum, err := m.settingManager.GetLatest(ctx, repository, ProtectionSettingKey, rulesMsg) 34 if err != nil { 35 return nil, nil, err 36 } 37 return rulesMsg, checksum, nil 38 } 39 40 func (m *ProtectionManager) SetRules(ctx context.Context, repository *graveler.RepositoryRecord, rules *graveler.BranchProtectionRules, lastKnownChecksum *string) error { 41 return m.settingManager.Save(ctx, repository, ProtectionSettingKey, rules, lastKnownChecksum) 42 } 43 44 func (m *ProtectionManager) IsBlocked(ctx context.Context, repository *graveler.RepositoryRecord, branchID graveler.BranchID, action graveler.BranchProtectionBlockedAction) (bool, error) { 45 rules := &graveler.BranchProtectionRules{} 46 err := m.settingManager.Get(ctx, repository, ProtectionSettingKey, rules) 47 if errors.Is(err, graveler.ErrNotFound) { 48 return false, nil 49 } 50 if err != nil { 51 return false, err 52 } 53 for pattern, blockedActions := range rules.BranchPatternToBlockedActions { 54 pattern := pattern 55 matcher, err := m.matchers.GetOrSet(pattern, func() (v interface{}, err error) { 56 return glob.Compile(pattern) 57 }) 58 if err != nil { 59 return false, err 60 } 61 if !matcher.(glob.Glob).Match(string(branchID)) { 62 continue 63 } 64 for _, c := range blockedActions.GetValue() { 65 if c == action { 66 return true, nil 67 } 68 } 69 } 70 return false, nil 71 }