feat(config): custom weight thresholds via CEL (#688)
* feat(config): add Thresholds to the top level config file Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(config): make String() on ExpressionOrList join the component expressions Signed-off-by: Xe Iaso <me@xeiaso.net> * test(config): ensure unparseable json fails Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(config): if no thresholds are set, use the default thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(policy): half implement thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(policy): continue wiring things up Signed-off-by: Xe Iaso <me@xeiaso.net> * feat(lib): wire up thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * test(lib): handle behavior from legacy configurations Signed-off-by: Xe Iaso <me@xeiaso.net> * docs: document thresholds Signed-off-by: Xe Iaso <me@xeiaso.net> * docs: update CHANGELOG, refer to threshold configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * fix(lib): fix build Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(lib): fix U1000 Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Signed-off-by: Jason Cameron <git@jasoncameron.dev> Co-authored-by: Jason Cameron <git@jasoncameron.dev>
This commit is contained in:
parent
1d5fa49eb0
commit
226cf36bf7
22 changed files with 683 additions and 305 deletions
80
lib/policy/config/threshold.go
Normal file
80
lib/policy/config/threshold.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/TecharoHQ/anubis"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoThresholdRulesDefined = errors.New("config: no thresholds defined")
|
||||
ErrThresholdMustHaveName = errors.New("config.Threshold: must set name")
|
||||
ErrThresholdMustHaveExpression = errors.New("config.Threshold: must set expression")
|
||||
ErrThresholdChallengeMustHaveChallenge = errors.New("config.Threshold: a threshold with the CHALLENGE action must have challenge set")
|
||||
ErrThresholdCannotHaveWeighAction = errors.New("config.Threshold: a threshold cannot have the WEIGH action")
|
||||
|
||||
DefaultThresholds = []Threshold{
|
||||
{
|
||||
Name: "legacy-anubis-behaviour",
|
||||
Expression: &ExpressionOrList{
|
||||
Expression: "weight > 0",
|
||||
},
|
||||
Action: RuleChallenge,
|
||||
Challenge: &ChallengeRules{
|
||||
Algorithm: "fast",
|
||||
Difficulty: anubis.DefaultDifficulty,
|
||||
ReportAs: anubis.DefaultDifficulty,
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type Threshold struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Expression *ExpressionOrList `json:"expression" yaml:"expression"`
|
||||
Action Rule `json:"action" yaml:"action"`
|
||||
Challenge *ChallengeRules `json:"challenge" yaml:"challenge"`
|
||||
}
|
||||
|
||||
func (t Threshold) Valid() error {
|
||||
var errs []error
|
||||
|
||||
if len(t.Name) == 0 {
|
||||
errs = append(errs, ErrThresholdMustHaveName)
|
||||
}
|
||||
|
||||
if t.Expression == nil {
|
||||
errs = append(errs, ErrThresholdMustHaveExpression)
|
||||
}
|
||||
|
||||
if t.Expression != nil {
|
||||
if err := t.Expression.Valid(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := t.Action.Valid(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if t.Action == RuleWeigh {
|
||||
errs = append(errs, ErrThresholdCannotHaveWeighAction)
|
||||
}
|
||||
|
||||
if t.Action == RuleChallenge && t.Challenge == nil {
|
||||
errs = append(errs, ErrThresholdChallengeMustHaveChallenge)
|
||||
}
|
||||
|
||||
if t.Challenge != nil {
|
||||
if err := t.Challenge.Valid(); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(errs) != 0 {
|
||||
return fmt.Errorf("config: threshold entry for %q is not valid:\n%w", t.Name, errors.Join(errs...))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue