github.com/DataDog/datadog-agent/pkg/security/secl@v0.55.0-devel.0.20240517055856-10c4965fea94/compiler/eval/evaluators.go (about) 1 // Unless explicitly stated otherwise all files in this repository are licensed 2 // under the Apache License Version 2.0. 3 // This product includes software developed at Datadog (https://www.datadoghq.com/). 4 // Copyright 2016-present Datadog, Inc. 5 6 // Package eval holds eval related files 7 package eval 8 9 import ( 10 "net" 11 12 "github.com/DataDog/datadog-agent/pkg/security/secl/compiler/ast" 13 ) 14 15 // Evaluator is the interface of an evaluator 16 type Evaluator interface { 17 Eval(ctx *Context) interface{} 18 IsDeterministicFor(field Field) bool 19 GetField() string 20 IsStatic() bool 21 } 22 23 // BoolEvaluator returns a bool as result of the evaluation 24 type BoolEvaluator struct { 25 EvalFnc BoolEvalFnc 26 Field Field 27 Value bool 28 Weight int 29 OpOverrides *OpOverrides 30 31 // used during compilation of partial 32 isDeterministic bool 33 } 34 35 // Eval returns the result of the evaluation 36 func (b *BoolEvaluator) Eval(ctx *Context) interface{} { 37 return b.EvalFnc(ctx) 38 } 39 40 // IsDeterministicFor returns whether the evaluator is partial 41 func (b *BoolEvaluator) IsDeterministicFor(field Field) bool { 42 return b.isDeterministic || (b.Field != "" && b.Field == field) 43 } 44 45 // GetField returns field name used by this evaluator 46 func (b *BoolEvaluator) GetField() string { 47 return b.Field 48 } 49 50 // IsStatic returns whether the evaluator is a scalar 51 func (b *BoolEvaluator) IsStatic() bool { 52 return b.EvalFnc == nil 53 } 54 55 // IntEvaluator returns an int as result of the evaluation 56 type IntEvaluator struct { 57 EvalFnc func(ctx *Context) int 58 Field Field 59 Value int 60 Weight int 61 OpOverrides *OpOverrides 62 63 // used during compilation of partial 64 isDeterministic bool 65 isDuration bool 66 isFromArithmeticOperation bool 67 } 68 69 // Eval returns the result of the evaluation 70 func (i *IntEvaluator) Eval(ctx *Context) interface{} { 71 return i.EvalFnc(ctx) 72 } 73 74 // IsDeterministicFor returns whether the evaluator is partial 75 func (i *IntEvaluator) IsDeterministicFor(field Field) bool { 76 return i.isDeterministic || (i.Field != "" && i.Field == field) 77 } 78 79 // GetField returns field name used by this evaluator 80 func (i *IntEvaluator) GetField() string { 81 return i.Field 82 } 83 84 // IsStatic returns whether the evaluator is a scalar 85 func (i *IntEvaluator) IsStatic() bool { 86 return i.EvalFnc == nil 87 } 88 89 // StringEvaluator returns a string as result of the evaluation 90 type StringEvaluator struct { 91 EvalFnc func(ctx *Context) string 92 Field Field 93 Value string 94 Weight int 95 OpOverrides *OpOverrides 96 ValueType FieldValueType 97 StringCmpOpts StringCmpOpts // only Field evaluator can set this value 98 99 // used during compilation of partial 100 isDeterministic bool 101 } 102 103 // Eval returns the result of the evaluation 104 func (s *StringEvaluator) Eval(ctx *Context) interface{} { 105 return s.EvalFnc(ctx) 106 } 107 108 // IsDeterministicFor returns whether the evaluator is partial 109 func (s *StringEvaluator) IsDeterministicFor(field Field) bool { 110 return s.isDeterministic || (s.Field != "" && s.Field == field) 111 } 112 113 // GetField returns field name used by this evaluator 114 func (s *StringEvaluator) GetField() string { 115 return s.Field 116 } 117 118 // IsStatic returns whether the evaluator is a scalar 119 func (s *StringEvaluator) IsStatic() bool { 120 return s.EvalFnc == nil 121 } 122 123 // GetValue returns the evaluator value 124 func (s *StringEvaluator) GetValue(ctx *Context) string { 125 if s.EvalFnc == nil { 126 return s.Value 127 } 128 return s.EvalFnc(ctx) 129 } 130 131 // ToStringMatcher returns a StringMatcher of the evaluator 132 func (s *StringEvaluator) ToStringMatcher(opts StringCmpOpts) (StringMatcher, error) { 133 if s.IsStatic() { 134 matcher, err := NewStringMatcher(s.ValueType, s.Value, opts) 135 if err != nil { 136 return nil, err 137 } 138 return matcher, nil 139 } 140 141 return nil, nil 142 } 143 144 // StringArrayEvaluator returns an array of strings 145 type StringArrayEvaluator struct { 146 EvalFnc func(ctx *Context) []string 147 Values []string 148 Field Field 149 Weight int 150 OpOverrides *OpOverrides 151 StringCmpOpts StringCmpOpts // only Field evaluator can set this value 152 153 // used during compilation of partial 154 isDeterministic bool 155 } 156 157 // Eval returns the result of the evaluation 158 func (s *StringArrayEvaluator) Eval(ctx *Context) interface{} { 159 return s.EvalFnc(ctx) 160 } 161 162 // IsDeterministicFor returns whether the evaluator is partial 163 func (s *StringArrayEvaluator) IsDeterministicFor(field Field) bool { 164 return s.isDeterministic || (s.Field != "" && s.Field == field) 165 } 166 167 // GetField returns field name used by this evaluator 168 func (s *StringArrayEvaluator) GetField() string { 169 return s.Field 170 } 171 172 // IsStatic returns whether the evaluator is a scalar 173 func (s *StringArrayEvaluator) IsStatic() bool { 174 return s.EvalFnc == nil 175 } 176 177 // AppendValue append the given value 178 func (s *StringArrayEvaluator) AppendValue(value string) { 179 s.Values = append(s.Values, value) 180 } 181 182 // StringValuesEvaluator returns an array of strings 183 type StringValuesEvaluator struct { 184 EvalFnc func(ctx *Context) *StringValues 185 Values StringValues 186 Weight int 187 188 // used during compilation of partial 189 isDeterministic bool 190 } 191 192 // Eval returns the result of the evaluation 193 func (s *StringValuesEvaluator) Eval(ctx *Context) interface{} { 194 return s.EvalFnc(ctx) 195 } 196 197 // IsDeterministicFor returns whether the evaluator is partial 198 func (s *StringValuesEvaluator) IsDeterministicFor(_ Field) bool { 199 return s.isDeterministic 200 } 201 202 // GetField returns field name used by this evaluator 203 func (s *StringValuesEvaluator) GetField() string { 204 return "" 205 } 206 207 // IsStatic returns whether the evaluator is a scalar 208 func (s *StringValuesEvaluator) IsStatic() bool { 209 return s.EvalFnc == nil 210 } 211 212 // Compile the underlying StringValues 213 func (s *StringValuesEvaluator) Compile(opts StringCmpOpts) error { 214 return s.Values.Compile(opts) 215 } 216 217 // SetFieldValues apply field values 218 func (s *StringValuesEvaluator) SetFieldValues(values ...FieldValue) error { 219 return s.Values.SetFieldValues(values...) 220 } 221 222 // AppendMembers add members to the evaluator 223 func (s *StringValuesEvaluator) AppendMembers(members ...ast.StringMember) { 224 for _, member := range members { 225 var value FieldValue 226 if member.Pattern != nil { 227 value = FieldValue{ 228 Value: *member.Pattern, 229 Type: PatternValueType, 230 } 231 } else if member.Regexp != nil { 232 value = FieldValue{ 233 Value: *member.Regexp, 234 Type: RegexpValueType, 235 } 236 } else { 237 value = FieldValue{ 238 Value: *member.String, 239 Type: ScalarValueType, 240 } 241 } 242 s.Values.AppendFieldValue(value) 243 } 244 } 245 246 // IntArrayEvaluator returns an array of int 247 type IntArrayEvaluator struct { 248 EvalFnc func(ctx *Context) []int 249 Field Field 250 Values []int 251 Weight int 252 OpOverrides *OpOverrides 253 254 // used during compilation of partial 255 isDeterministic bool 256 } 257 258 // Eval returns the result of the evaluation 259 func (i *IntArrayEvaluator) Eval(ctx *Context) interface{} { 260 return i.EvalFnc(ctx) 261 } 262 263 // IsDeterministicFor returns whether the evaluator is partial 264 func (i *IntArrayEvaluator) IsDeterministicFor(field Field) bool { 265 return i.isDeterministic || (i.Field != "" && i.Field == field) 266 } 267 268 // GetField returns field name used by this evaluator 269 func (i *IntArrayEvaluator) GetField() string { 270 return i.Field 271 } 272 273 // IsStatic returns whether the evaluator is a scalar 274 func (i *IntArrayEvaluator) IsStatic() bool { 275 return i.EvalFnc == nil 276 } 277 278 // AppendValues to the array evaluator 279 func (i *IntArrayEvaluator) AppendValues(values ...int) { 280 i.Values = append(i.Values, values...) 281 } 282 283 // BoolArrayEvaluator returns an array of bool 284 type BoolArrayEvaluator struct { 285 EvalFnc func(ctx *Context) []bool 286 Field Field 287 Values []bool 288 Weight int 289 OpOverrides *OpOverrides 290 291 // used during compilation of partial 292 isDeterministic bool 293 } 294 295 // Eval returns the result of the evaluation 296 func (b *BoolArrayEvaluator) Eval(ctx *Context) interface{} { 297 return b.EvalFnc(ctx) 298 } 299 300 // IsDeterministicFor returns whether the evaluator is partial 301 func (b *BoolArrayEvaluator) IsDeterministicFor(field Field) bool { 302 return b.isDeterministic || (b.Field != "" && b.Field == field) 303 } 304 305 // GetField returns field name used by this evaluator 306 func (b *BoolArrayEvaluator) GetField() string { 307 return b.Field 308 } 309 310 // IsStatic returns whether the evaluator is a scalar 311 func (b *BoolArrayEvaluator) IsStatic() bool { 312 return b.EvalFnc == nil 313 } 314 315 // CIDREvaluator returns a net.IP 316 type CIDREvaluator struct { 317 EvalFnc func(ctx *Context) net.IPNet 318 Field Field 319 Value net.IPNet 320 Weight int 321 OpOverrides *OpOverrides 322 ValueType FieldValueType 323 324 // used during compilation of partial 325 isDeterministic bool 326 } 327 328 // Eval returns the result of the evaluation 329 func (s *CIDREvaluator) Eval(ctx *Context) interface{} { 330 return s.EvalFnc(ctx) 331 } 332 333 // IsDeterministicFor returns whether the evaluator is partial 334 func (s *CIDREvaluator) IsDeterministicFor(field Field) bool { 335 return s.isDeterministic || (s.Field != "" && s.Field == field) 336 } 337 338 // GetField returns field name used by this evaluator 339 func (s *CIDREvaluator) GetField() string { 340 return s.Field 341 } 342 343 // IsStatic returns whether the evaluator is a scalar 344 func (s *CIDREvaluator) IsStatic() bool { 345 return s.EvalFnc == nil 346 } 347 348 // CIDRValuesEvaluator returns a net.IP 349 type CIDRValuesEvaluator struct { 350 EvalFnc func(ctx *Context) *CIDRValues 351 Value CIDRValues 352 Weight int 353 ValueType FieldValueType 354 355 // used during compilation of partial 356 isDeterministic bool 357 } 358 359 // Eval returns the result of the evaluation 360 func (s *CIDRValuesEvaluator) Eval(ctx *Context) interface{} { 361 return s.EvalFnc(ctx) 362 } 363 364 // IsDeterministicFor returns whether the evaluator is partial 365 func (s *CIDRValuesEvaluator) IsDeterministicFor(_ Field) bool { 366 return s.isDeterministic 367 } 368 369 // GetField returns field name used by this evaluator 370 func (s *CIDRValuesEvaluator) GetField() string { 371 return "" 372 } 373 374 // IsStatic returns whether the evaluator is a scalar 375 func (s *CIDRValuesEvaluator) IsStatic() bool { 376 return s.EvalFnc == nil 377 } 378 379 // CIDRArrayEvaluator returns an array of net.IPNet 380 type CIDRArrayEvaluator struct { 381 EvalFnc func(ctx *Context) []net.IPNet 382 Field Field 383 Value []net.IPNet 384 Weight int 385 OpOverrides *OpOverrides 386 ValueType FieldValueType 387 388 // used during compilation of partial 389 isDeterministic bool 390 } 391 392 // Eval returns the result of the evaluation 393 func (s *CIDRArrayEvaluator) Eval(ctx *Context) interface{} { 394 return s.EvalFnc(ctx) 395 } 396 397 // IsDeterministicFor returns whether the evaluator is partial 398 func (s *CIDRArrayEvaluator) IsDeterministicFor(field Field) bool { 399 return s.isDeterministic || (s.Field != "" && s.Field == field) 400 } 401 402 // GetField returns field name used by this evaluator 403 func (s *CIDRArrayEvaluator) GetField() string { 404 return s.Field 405 } 406 407 // IsStatic returns whether the evaluator is a scalar 408 func (s *CIDRArrayEvaluator) IsStatic() bool { 409 return s.EvalFnc == nil 410 }