github.com/crowdsecurity/crowdsec@v1.6.1/pkg/leakybucket/conditional.go (about) 1 package leakybucket 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/antonmedv/expr" 8 "github.com/antonmedv/expr/vm" 9 "github.com/crowdsecurity/crowdsec/pkg/exprhelpers" 10 "github.com/crowdsecurity/crowdsec/pkg/types" 11 ) 12 13 var conditionalExprCache map[string]vm.Program 14 var conditionalExprCacheLock sync.Mutex 15 16 type ConditionalOverflow struct { 17 ConditionalFilter string 18 ConditionalFilterRuntime *vm.Program 19 DumbProcessor 20 } 21 22 func (c *ConditionalOverflow) OnBucketInit(g *BucketFactory) error { 23 var err error 24 var compiledExpr *vm.Program 25 26 if conditionalExprCache == nil { 27 conditionalExprCache = make(map[string]vm.Program) 28 } 29 conditionalExprCacheLock.Lock() 30 if compiled, ok := conditionalExprCache[g.ConditionalOverflow]; ok { 31 conditionalExprCacheLock.Unlock() 32 c.ConditionalFilterRuntime = &compiled 33 } else { 34 conditionalExprCacheLock.Unlock() 35 //release the lock during compile 36 compiledExpr, err = expr.Compile(g.ConditionalOverflow, exprhelpers.GetExprOptions(map[string]interface{}{"queue": &types.Queue{}, "leaky": &Leaky{}, "evt": &types.Event{}})...) 37 if err != nil { 38 return fmt.Errorf("conditional compile error : %w", err) 39 } 40 c.ConditionalFilterRuntime = compiledExpr 41 conditionalExprCacheLock.Lock() 42 conditionalExprCache[g.ConditionalOverflow] = *compiledExpr 43 conditionalExprCacheLock.Unlock() 44 } 45 return err 46 } 47 48 func (c *ConditionalOverflow) AfterBucketPour(b *BucketFactory) func(types.Event, *Leaky) *types.Event { 49 return func(msg types.Event, l *Leaky) *types.Event { 50 var condition, ok bool 51 if c.ConditionalFilterRuntime != nil { 52 l.logger.Debugf("Running condition expression : %s", c.ConditionalFilter) 53 54 ret, err := exprhelpers.Run(c.ConditionalFilterRuntime, 55 map[string]interface{}{"evt": &msg, "queue": l.Queue, "leaky": l}, 56 l.logger, b.Debug) 57 if err != nil { 58 l.logger.Errorf("unable to run conditional filter : %s", err) 59 return &msg 60 } 61 l.logger.Debugf("Conditional bucket expression returned : %v", ret) 62 63 if condition, ok = ret.(bool); !ok { 64 l.logger.Warningf("overflow condition, unexpected non-bool return : %T", ret) 65 return &msg 66 } 67 68 if condition { 69 l.logger.Debugf("Conditional bucket overflow") 70 l.Ovflw_ts = l.Last_ts 71 l.Out <- l.Queue 72 return nil 73 } 74 } 75 76 return &msg 77 } 78 }