csprofiles: fix default decision duration, lint (#2703)
* return nil with errors * errors.Wrap -> fmt.Errorf * var -> const * fix default decision duration * lint (whitespace)
This commit is contained in:
parent
0ef5f20aa7
commit
733f5e165b
1 changed files with 36 additions and 24 deletions
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/antonmedv/expr"
|
||||
"github.com/antonmedv/expr/vm"
|
||||
"github.com/pkg/errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
|
||||
|
@ -22,19 +21,23 @@ type Runtime struct {
|
|||
Logger *log.Entry `json:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
var defaultDuration = "4h"
|
||||
const defaultDuration = "4h"
|
||||
|
||||
func NewProfile(profilesCfg []*csconfig.ProfileCfg) ([]*Runtime, error) {
|
||||
var err error
|
||||
|
||||
profilesRuntime := make([]*Runtime, 0)
|
||||
|
||||
for _, profile := range profilesCfg {
|
||||
var runtimeFilter, runtimeDurationExpr *vm.Program
|
||||
|
||||
runtime := &Runtime{}
|
||||
|
||||
xlog := log.New()
|
||||
if err := types.ConfigureLogger(xlog); err != nil {
|
||||
log.Fatalf("While creating profiles-specific logger : %s", err)
|
||||
}
|
||||
|
||||
xlog.SetLevel(log.InfoLevel)
|
||||
runtime.Logger = xlog.WithFields(log.Fields{
|
||||
"type": "profile",
|
||||
|
@ -43,17 +46,20 @@ func NewProfile(profilesCfg []*csconfig.ProfileCfg) ([]*Runtime, error) {
|
|||
|
||||
runtime.RuntimeFilters = make([]*vm.Program, len(profile.Filters))
|
||||
runtime.Cfg = profile
|
||||
if runtime.Cfg.OnSuccess != "" && runtime.Cfg.OnSuccess != "continue" && runtime.Cfg.OnSuccess != "break" {
|
||||
return []*Runtime{}, fmt.Errorf("invalid 'on_success' for '%s': %s", profile.Name, runtime.Cfg.OnSuccess)
|
||||
}
|
||||
if runtime.Cfg.OnFailure != "" && runtime.Cfg.OnFailure != "continue" && runtime.Cfg.OnFailure != "break" && runtime.Cfg.OnFailure != "apply" {
|
||||
return []*Runtime{}, fmt.Errorf("invalid 'on_failure' for '%s' : %s", profile.Name, runtime.Cfg.OnFailure)
|
||||
}
|
||||
for fIdx, filter := range profile.Filters {
|
||||
|
||||
if runtime.Cfg.OnSuccess != "" && runtime.Cfg.OnSuccess != "continue" && runtime.Cfg.OnSuccess != "break" {
|
||||
return nil, fmt.Errorf("invalid 'on_success' for '%s': %s", profile.Name, runtime.Cfg.OnSuccess)
|
||||
}
|
||||
|
||||
if runtime.Cfg.OnFailure != "" && runtime.Cfg.OnFailure != "continue" && runtime.Cfg.OnFailure != "break" && runtime.Cfg.OnFailure != "apply" {
|
||||
return nil, fmt.Errorf("invalid 'on_failure' for '%s' : %s", profile.Name, runtime.Cfg.OnFailure)
|
||||
}
|
||||
|
||||
for fIdx, filter := range profile.Filters {
|
||||
if runtimeFilter, err = expr.Compile(filter, exprhelpers.GetExprOptions(map[string]interface{}{"Alert": &models.Alert{}})...); err != nil {
|
||||
return []*Runtime{}, errors.Wrapf(err, "error compiling filter of '%s'", profile.Name)
|
||||
return nil, fmt.Errorf("error compiling filter of '%s': %w", profile.Name, err)
|
||||
}
|
||||
|
||||
runtime.RuntimeFilters[fIdx] = runtimeFilter
|
||||
if profile.Debug != nil && *profile.Debug {
|
||||
runtime.Logger.Logger.SetLevel(log.DebugLevel)
|
||||
|
@ -62,8 +68,9 @@ func NewProfile(profilesCfg []*csconfig.ProfileCfg) ([]*Runtime, error) {
|
|||
|
||||
if profile.DurationExpr != "" {
|
||||
if runtimeDurationExpr, err = expr.Compile(profile.DurationExpr, exprhelpers.GetExprOptions(map[string]interface{}{"Alert": &models.Alert{}})...); err != nil {
|
||||
return []*Runtime{}, errors.Wrapf(err, "error compiling duration_expr of %s", profile.Name)
|
||||
return nil, fmt.Errorf("error compiling duration_expr of %s: %w", profile.Name, err)
|
||||
}
|
||||
|
||||
runtime.RuntimeDurationExpr = runtimeDurationExpr
|
||||
}
|
||||
|
||||
|
@ -76,14 +83,16 @@ func NewProfile(profilesCfg []*csconfig.ProfileCfg) ([]*Runtime, error) {
|
|||
runtime.Logger.Warningf("No duration specified for %s, using default duration %s", profile.Name, defaultDuration)
|
||||
duration = defaultDuration
|
||||
}
|
||||
|
||||
if _, err := time.ParseDuration(duration); err != nil {
|
||||
return []*Runtime{}, errors.Wrapf(err, "error parsing duration '%s' of %s", duration, profile.Name)
|
||||
return nil, fmt.Errorf("error parsing duration '%s' of %s: %w", duration, profile.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
profilesRuntime = append(profilesRuntime, runtime)
|
||||
}
|
||||
|
||||
return profilesRuntime, nil
|
||||
}
|
||||
|
||||
|
@ -110,30 +119,29 @@ func (Profile *Runtime) GenerateDecisionFromProfile(Alert *models.Alert) ([]*mod
|
|||
*decision.Scope = *Alert.Source.Scope
|
||||
}
|
||||
/*some fields are populated from the reference object : duration, scope, type*/
|
||||
|
||||
decision.Duration = new(string)
|
||||
if refDecision.Duration != nil {
|
||||
*decision.Duration = *refDecision.Duration
|
||||
}
|
||||
|
||||
if Profile.Cfg.DurationExpr != "" && Profile.RuntimeDurationExpr != nil {
|
||||
profileDebug := false
|
||||
if Profile.Cfg.Debug != nil && *Profile.Cfg.Debug {
|
||||
profileDebug = true
|
||||
}
|
||||
|
||||
duration, err := exprhelpers.Run(Profile.RuntimeDurationExpr, map[string]interface{}{"Alert": Alert}, Profile.Logger, profileDebug)
|
||||
if err != nil {
|
||||
Profile.Logger.Warningf("Failed to run duration_expr : %v", err)
|
||||
*decision.Duration = *refDecision.Duration
|
||||
} else {
|
||||
durationStr := fmt.Sprint(duration)
|
||||
if _, err := time.ParseDuration(durationStr); err != nil {
|
||||
Profile.Logger.Warningf("Failed to parse expr duration result '%s'", duration)
|
||||
*decision.Duration = *refDecision.Duration
|
||||
} else {
|
||||
*decision.Duration = durationStr
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if refDecision.Duration == nil {
|
||||
*decision.Duration = defaultDuration
|
||||
}
|
||||
*decision.Duration = *refDecision.Duration
|
||||
}
|
||||
|
||||
decision.Type = new(string)
|
||||
|
@ -144,13 +152,16 @@ func (Profile *Runtime) GenerateDecisionFromProfile(Alert *models.Alert) ([]*mod
|
|||
*decision.Value = *Alert.Source.Value
|
||||
decision.Origin = new(string)
|
||||
*decision.Origin = types.CrowdSecOrigin
|
||||
|
||||
if refDecision.Origin != nil {
|
||||
*decision.Origin = fmt.Sprintf("%s/%s", *decision.Origin, *refDecision.Origin)
|
||||
}
|
||||
|
||||
decision.Scenario = new(string)
|
||||
*decision.Scenario = *Alert.Scenario
|
||||
decisions = append(decisions, &decision)
|
||||
}
|
||||
|
||||
return decisions, nil
|
||||
}
|
||||
|
||||
|
@ -159,16 +170,19 @@ func (Profile *Runtime) EvaluateProfile(Alert *models.Alert) ([]*models.Decision
|
|||
var decisions []*models.Decision
|
||||
|
||||
matched := false
|
||||
|
||||
for eIdx, expression := range Profile.RuntimeFilters {
|
||||
debugProfile := false
|
||||
if Profile.Cfg.Debug != nil && *Profile.Cfg.Debug {
|
||||
debugProfile = true
|
||||
}
|
||||
|
||||
output, err := exprhelpers.Run(expression, map[string]interface{}{"Alert": Alert}, Profile.Logger, debugProfile)
|
||||
if err != nil {
|
||||
Profile.Logger.Warningf("failed to run profile expr for %s : %v", Profile.Cfg.Name, err)
|
||||
return nil, matched, errors.Wrapf(err, "while running expression %s", Profile.Cfg.Filters[eIdx])
|
||||
Profile.Logger.Warningf("failed to run profile expr for %s: %v", Profile.Cfg.Name, err)
|
||||
return nil, matched, fmt.Errorf("while running expression %s: %w", Profile.Cfg.Filters[eIdx], err)
|
||||
}
|
||||
|
||||
switch out := output.(type) {
|
||||
case bool:
|
||||
if out {
|
||||
|
@ -176,7 +190,7 @@ func (Profile *Runtime) EvaluateProfile(Alert *models.Alert) ([]*models.Decision
|
|||
/*the expression matched, create the associated decision*/
|
||||
subdecisions, err := Profile.GenerateDecisionFromProfile(Alert)
|
||||
if err != nil {
|
||||
return nil, matched, errors.Wrapf(err, "while generating decision from profile %s", Profile.Cfg.Name)
|
||||
return nil, matched, fmt.Errorf("while generating decision from profile %s: %w", Profile.Cfg.Name, err)
|
||||
}
|
||||
|
||||
decisions = append(decisions, subdecisions...)
|
||||
|
@ -189,9 +203,7 @@ func (Profile *Runtime) EvaluateProfile(Alert *models.Alert) ([]*models.Decision
|
|||
|
||||
default:
|
||||
return nil, matched, fmt.Errorf("unexpected type %t (%v) while running '%s'", output, output, Profile.Cfg.Filters[eIdx])
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return decisions, matched, nil
|
||||
|
|
Loading…
Reference in a new issue