crowdsec/pkg/leakybucket/conditional.go

79 lines
2.2 KiB
Go
Raw Normal View History

2023-01-06 08:26:16 +00:00
package leakybucket
import (
"fmt"
"sync"
2023-01-06 08:26:16 +00:00
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
"github.com/crowdsecurity/crowdsec/pkg/types"
)
var conditionalExprCache map[string]vm.Program
var conditionalExprCacheLock sync.Mutex
2023-01-06 08:26:16 +00:00
type ConditionalOverflow struct {
ConditionalFilter string
ConditionalFilterRuntime *vm.Program
DumbProcessor
}
func (c *ConditionalOverflow) OnBucketInit(g *BucketFactory) error {
2023-01-06 08:26:16 +00:00
var err error
var compiledExpr *vm.Program
2023-01-06 08:26:16 +00:00
if conditionalExprCache == nil {
conditionalExprCache = make(map[string]vm.Program)
}
conditionalExprCacheLock.Lock()
if compiled, ok := conditionalExprCache[g.ConditionalOverflow]; ok {
conditionalExprCacheLock.Unlock()
c.ConditionalFilterRuntime = &compiled
} else {
conditionalExprCacheLock.Unlock()
//release the lock during compile
compiledExpr, err = expr.Compile(g.ConditionalOverflow, exprhelpers.GetExprOptions(map[string]interface{}{"queue": &types.Queue{}, "leaky": &Leaky{}, "evt": &types.Event{}})...)
if err != nil {
return fmt.Errorf("conditional compile error : %w", err)
}
c.ConditionalFilterRuntime = compiledExpr
conditionalExprCacheLock.Lock()
conditionalExprCache[g.ConditionalOverflow] = *compiledExpr
conditionalExprCacheLock.Unlock()
2023-01-06 08:26:16 +00:00
}
return err
2023-01-06 08:26:16 +00:00
}
func (c *ConditionalOverflow) AfterBucketPour(b *BucketFactory) func(types.Event, *Leaky) *types.Event {
return func(msg types.Event, l *Leaky) *types.Event {
var condition, ok bool
if c.ConditionalFilterRuntime != nil {
l.logger.Debugf("Running condition expression : %s", c.ConditionalFilter)
ret, err := exprhelpers.Run(c.ConditionalFilterRuntime,
map[string]interface{}{"evt": &msg, "queue": l.Queue, "leaky": l},
l.logger, b.Debug)
2023-01-06 08:26:16 +00:00
if err != nil {
l.logger.Errorf("unable to run conditional filter : %s", err)
return &msg
}
l.logger.Debugf("Conditional bucket expression returned : %v", ret)
if condition, ok = ret.(bool); !ok {
l.logger.Warningf("overflow condition, unexpected non-bool return : %T", ret)
return &msg
}
if condition {
l.logger.Debugf("Conditional bucket overflow")
2023-04-28 14:32:46 +00:00
l.Ovflw_ts = l.Last_ts
2023-01-06 08:26:16 +00:00
l.Out <- l.Queue
return nil
}
}
return &msg
}
}