123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package expressions
- import (
- "math/rand/v2"
- "github.com/google/cel-go/cel"
- "github.com/google/cel-go/common/types"
- "github.com/google/cel-go/common/types/ref"
- "github.com/google/cel-go/ext"
- )
- // BotEnvironment creates a new CEL environment, this is the set of
- // variables and functions that are passed into the CEL scope so that
- // Anubis can fail loudly and early when something is invalid instead
- // of blowing up at runtime.
- func BotEnvironment() (*cel.Env, error) {
- return New(
- // Variables exposed to CEL programs:
- cel.Variable("remoteAddress", cel.StringType),
- cel.Variable("host", cel.StringType),
- cel.Variable("method", cel.StringType),
- cel.Variable("userAgent", cel.StringType),
- cel.Variable("path", cel.StringType),
- cel.Variable("query", cel.MapType(cel.StringType, cel.StringType)),
- cel.Variable("headers", cel.MapType(cel.StringType, cel.StringType)),
- )
- }
- // NewThreshold creates a new CEL environment for threshold checking.
- func ThresholdEnvironment() (*cel.Env, error) {
- return New(
- cel.Variable("weight", cel.IntType),
- )
- }
- func New(opts ...cel.EnvOption) (*cel.Env, error) {
- args := []cel.EnvOption{
- ext.Strings(
- ext.StringsLocale("en_US"),
- ext.StringsValidateFormatCalls(true),
- ),
- // default all timestamps to UTC
- cel.DefaultUTCTimeZone(true),
- // Functions exposed to all CEL programs:
- cel.Function("randInt",
- cel.Overload("randInt_int",
- []*cel.Type{cel.IntType},
- cel.IntType,
- cel.UnaryBinding(func(val ref.Val) ref.Val {
- n, ok := val.(types.Int)
- if !ok {
- return types.ValOrErr(val, "value is not an integer, but is %T", val)
- }
- return types.Int(rand.IntN(int(n)))
- }),
- ),
- ),
- }
- args = append(args, opts...)
- return cel.NewEnv(args...)
- }
- // Compile takes CEL environment and syntax tree then emits an optimized
- // Program for execution.
- func Compile(env *cel.Env, src string) (cel.Program, error) {
- intermediate, iss := env.Compile(src)
- if iss != nil {
- return nil, iss.Err()
- }
- ast, iss := env.Check(intermediate)
- if iss != nil {
- return nil, iss.Err()
- }
- return env.Program(
- ast,
- cel.EvalOptions(
- // optimize regular expressions right now instead of on the fly
- cel.OptOptimize,
- ),
- )
- }
|