github.com/cloudwan/edgelq-sdk@v1.15.4/alerting/resources/v1/alert/alert.pb.filter.go (about) 1 // Code generated by protoc-gen-goten-resource 2 // Resource: Alert 3 // DO NOT EDIT!!! 4 5 package alert 6 7 import ( 8 "fmt" 9 "math" 10 "strings" 11 12 "google.golang.org/grpc/codes" 13 "google.golang.org/grpc/status" 14 "google.golang.org/protobuf/proto" 15 16 gotenobject "github.com/cloudwan/goten-sdk/runtime/object" 17 gotenresource "github.com/cloudwan/goten-sdk/runtime/resource" 18 filterParser "github.com/cloudwan/goten-sdk/runtime/resource/filter" 19 utils "github.com/cloudwan/goten-sdk/runtime/utils" 20 ) 21 22 // proto imports 23 import ( 24 rcommon "github.com/cloudwan/edgelq-sdk/alerting/resources/v1/common" 25 log_condition "github.com/cloudwan/edgelq-sdk/alerting/resources/v1/log_condition" 26 notification_channel "github.com/cloudwan/edgelq-sdk/alerting/resources/v1/notification_channel" 27 ts_condition "github.com/cloudwan/edgelq-sdk/alerting/resources/v1/ts_condition" 28 meta "github.com/cloudwan/goten-sdk/types/meta" 29 durationpb "google.golang.org/protobuf/types/known/durationpb" 30 timestamppb "google.golang.org/protobuf/types/known/timestamppb" 31 ) 32 33 var ( 34 _ = new(fmt.Stringer) 35 _ = strings.Builder{} 36 _ = math.IsNaN 37 38 _ = new(proto.Message) 39 40 _ = new(gotenobject.FieldPath) 41 _ = gotenresource.WildcardId 42 ) 43 44 // make sure we're using proto imports 45 var ( 46 _ = &log_condition.LogCondition{} 47 _ = ¬ification_channel.NotificationChannel{} 48 _ = &rcommon.LogCndSpec{} 49 _ = &ts_condition.TsCondition{} 50 _ = &durationpb.Duration{} 51 _ = ×tamppb.Timestamp{} 52 _ = &meta.Meta{} 53 ) 54 55 type FilterCondition interface { 56 gotenresource.FilterCondition 57 _IsFilterCondition() 58 _IsAlertFilterBuilderOrCondition() 59 And(...FilterCondition) FilterCondition 60 Evaluate(res *Alert) bool 61 62 // Whether this condition is at least as specific as other. 63 // When true, any Alert that passes this condition will also pass other condition. 64 Satisfies(other FilterCondition) bool 65 66 // Checks whether condition specifies given field path 67 // Useful for blacklisting protected paths in iam policy conditions 68 SpecifiesFieldPath(fp Alert_FieldPath) bool 69 } 70 71 func AndFilterConditions(conds ...FilterCondition) FilterCondition { 72 result := &FilterConditionComposite{ 73 Operator: filterParser.AND, 74 } 75 for _, condi := range conds { 76 switch cond := condi.(type) { 77 case *FilterConditionComposite: 78 if cond.Operator == filterParser.AND { 79 result.Conditions = append(result.Conditions, cond.Conditions...) 80 continue 81 } 82 default: 83 } 84 result.Conditions = append(result.Conditions, condi) 85 } 86 return result 87 } 88 89 type FilterConditionComposite struct { 90 Operator filterParser.CompositeOperator 91 Conditions []FilterCondition 92 } 93 94 func (cond *FilterConditionComposite) String() string { 95 substrs := make([]string, 0, len(cond.Conditions)) 96 for _, subcond := range cond.Conditions { 97 substrs = append(substrs, subcond.String()) 98 } 99 sep := fmt.Sprintf(" %s ", cond.Operator) 100 return "(" + strings.Join(substrs, sep) + ")" 101 } 102 103 func (cond *FilterConditionComposite) _IsFilterCondition() {} 104 105 func (cond *FilterConditionComposite) _IsAlertFilterBuilderOrCondition() {} 106 107 func (cond *FilterConditionComposite) And(conds ...FilterCondition) FilterCondition { 108 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 109 } 110 111 func (cond *FilterConditionComposite) Evaluate(res *Alert) bool { 112 switch cond.Operator { 113 case filterParser.OR: 114 for _, subCond := range cond.Conditions { 115 if subCond.Evaluate(res) { 116 return true 117 } 118 } 119 return false 120 case filterParser.AND: 121 for _, subCond := range cond.Conditions { 122 if !subCond.Evaluate(res) { 123 return false 124 } 125 } 126 return true 127 default: 128 panic(fmt.Sprintf("Unsupported composite condition operator: %s", cond.Operator)) 129 } 130 } 131 132 func (cond *FilterConditionComposite) EvaluateRaw(res gotenresource.Resource) bool { 133 if typedRes, ok := res.(*Alert); !ok { 134 return false 135 } else { 136 return cond.Evaluate(typedRes) 137 } 138 } 139 140 func (cond *FilterConditionComposite) flattenConditions() (results []FilterCondition) { 141 for _, subcnd := range cond.Conditions { 142 switch tsubcnd := subcnd.(type) { 143 case *FilterConditionComposite: 144 if tsubcnd.Operator == cond.Operator { 145 results = append(results, tsubcnd.flattenConditions()...) 146 } else { 147 results = append(results, subcnd) // take it as it is 148 } 149 default: 150 results = append(results, subcnd) 151 } 152 } 153 return 154 } 155 156 func (cond *FilterConditionComposite) Satisfies(other FilterCondition) bool { 157 flattened := cond.flattenConditions() 158 switch cond.Operator { 159 case filterParser.AND: 160 switch tother := other.(type) { 161 case *FilterConditionComposite: 162 switch tother.Operator { 163 case filterParser.AND: 164 otherFlattened := tother.flattenConditions() 165 OtherSubcnds: 166 for _, otherSubcnd := range otherFlattened { 167 for _, subcnd := range flattened { 168 if subcnd.Satisfies(otherSubcnd) { 169 continue OtherSubcnds 170 } 171 } 172 return false 173 } 174 return true 175 case filterParser.OR: 176 otherFlattened := tother.flattenConditions() 177 for _, otherSubcnd := range otherFlattened { 178 if cond.Satisfies(otherSubcnd) { 179 return true 180 } 181 } 182 return false 183 default: 184 return false 185 } 186 default: 187 for _, subcnd := range flattened { 188 if subcnd.Satisfies(other) { 189 return true 190 } 191 } 192 return false 193 } 194 default: 195 panic(fmt.Errorf("unsupported condition type %s", cond.Operator)) 196 } 197 return false 198 } 199 200 func (cond *FilterConditionComposite) SatisfiesRaw(other gotenresource.FilterCondition) bool { 201 if typedCond, ok := other.(FilterCondition); !ok { 202 return false 203 } else { 204 return cond.Satisfies(typedCond) 205 } 206 } 207 208 func (cond *FilterConditionComposite) SpecifiesFieldPath(fp Alert_FieldPath) bool { 209 for _, subcnd := range cond.Conditions { 210 if subcnd.SpecifiesFieldPath(fp) { 211 return true 212 } 213 } 214 return false 215 } 216 217 func (cond *FilterConditionComposite) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 218 if typedFp, ok := fp.(Alert_FieldPath); !ok { 219 return false 220 } else { 221 return cond.SpecifiesFieldPath(typedFp) 222 } 223 } 224 225 func (cond *FilterConditionComposite) GetOperator() filterParser.CompositeOperator { 226 return cond.Operator 227 } 228 229 func (cond *FilterConditionComposite) GetSubConditions() []gotenresource.FilterCondition { 230 subConds := make([]gotenresource.FilterCondition, len(cond.Conditions)) 231 for idx, subCond := range cond.Conditions { 232 subConds[idx] = subCond 233 } 234 return subConds 235 } 236 237 func (cond *FilterConditionComposite) ConditionComposite() {} 238 239 type FilterConditionNot struct { 240 FilterCondition 241 } 242 243 func (cond *FilterConditionNot) String() string { 244 return "NOT " + cond.FilterCondition.String() 245 } 246 247 func (cond *FilterConditionNot) _IsFilterCondition() {} 248 249 func (cond *FilterConditionNot) _IsAlertFilterBuilderOrCondition() {} 250 251 func (cond *FilterConditionNot) And(conds ...FilterCondition) FilterCondition { 252 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 253 } 254 255 func (cond *FilterConditionNot) Evaluate(res *Alert) bool { 256 return !cond.FilterCondition.Evaluate(res) 257 } 258 259 func (cond *FilterConditionNot) EvaluateRaw(res gotenresource.Resource) bool { 260 if typedRes, ok := res.(*Alert); !ok { 261 return false 262 } else { 263 return cond.Evaluate(typedRes) 264 } 265 } 266 267 func (cond *FilterConditionNot) Satisfies(other FilterCondition) bool { 268 switch tother := other.(type) { 269 case *FilterConditionNot: 270 return cond.FilterCondition.Satisfies(tother.FilterCondition) 271 default: 272 return !cond.FilterCondition.Satisfies(other) 273 } 274 } 275 276 func (cond *FilterConditionNot) SatisfiesRaw(other gotenresource.FilterCondition) bool { 277 if typedCond, ok := other.(FilterCondition); !ok { 278 return false 279 } else { 280 return cond.Satisfies(typedCond) 281 } 282 } 283 284 func (cond *FilterConditionNot) SpecifiesFieldPath(fp Alert_FieldPath) bool { 285 return cond.FilterCondition.SpecifiesFieldPath(fp) 286 } 287 288 func (cond *FilterConditionNot) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 289 if typedFp, ok := fp.(Alert_FieldPath); !ok { 290 return false 291 } else { 292 return cond.SpecifiesFieldPath(typedFp) 293 } 294 } 295 296 func (cond *FilterConditionNot) GetSubCondition() gotenresource.FilterCondition { 297 return cond.FilterCondition 298 } 299 300 func (cond *FilterConditionNot) ConditionNot() {} 301 302 type FilterConditionIsNull struct { 303 Not bool 304 FieldPath Alert_FieldPath 305 } 306 307 func (cond *FilterConditionIsNull) String() string { 308 if cond.Not { 309 return cond.FieldPath.String() + " IS NOT NULL" 310 } else { 311 return cond.FieldPath.String() + " IS NULL" 312 } 313 } 314 315 func (cond *FilterConditionIsNull) _IsFilterCondition() {} 316 317 func (cond *FilterConditionIsNull) _IsAlertFilterBuilderOrCondition() {} 318 319 func (cond *FilterConditionIsNull) And(conds ...FilterCondition) FilterCondition { 320 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 321 } 322 323 func (cond *FilterConditionIsNull) Evaluate(res *Alert) bool { 324 if v, ok := cond.FieldPath.GetSingleRaw(res); !ok { 325 return !cond.Not 326 } else { 327 return cond.Not != utils.IsNil(v) 328 } 329 } 330 331 func (cond *FilterConditionIsNull) EvaluateRaw(res gotenresource.Resource) bool { 332 if typedRes, ok := res.(*Alert); !ok { 333 return false 334 } else { 335 return cond.Evaluate(typedRes) 336 } 337 } 338 339 func (cond *FilterConditionIsNull) asCompare() FilterCondition { 340 res := &FilterConditionCompare{ 341 Operator: filterParser.Eq, 342 Alert_FieldPathValue: cond.FieldPath.WithIValue(nil), 343 } 344 if cond.Not { 345 res.Operator = filterParser.Neq 346 } 347 return res 348 } 349 350 func (cond *FilterConditionIsNull) Satisfies(other FilterCondition) bool { 351 switch tother := other.(type) { 352 case *FilterConditionIsNull: 353 return cond.FieldPath.String() == tother.FieldPath.String() && cond.Not == tother.Not 354 case *FilterConditionCompare: 355 return cond.asCompare().Satisfies(tother) 356 default: 357 return false 358 } 359 } 360 361 func (cond *FilterConditionIsNull) SatisfiesRaw(other gotenresource.FilterCondition) bool { 362 if typedCond, ok := other.(FilterCondition); !ok { 363 return false 364 } else { 365 return cond.Satisfies(typedCond) 366 } 367 } 368 369 func (cond *FilterConditionIsNull) SpecifiesFieldPath(fp Alert_FieldPath) bool { 370 return cond.FieldPath.String() == fp.String() 371 } 372 373 func (cond *FilterConditionIsNull) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 374 if typedFp, ok := fp.(Alert_FieldPath); !ok { 375 return false 376 } else { 377 return cond.SpecifiesFieldPath(typedFp) 378 } 379 } 380 381 func (cond *FilterConditionIsNull) NotNull() bool { 382 return cond.Not 383 } 384 385 func (cond *FilterConditionIsNull) GetRawFieldPath() gotenobject.FieldPath { 386 return cond.FieldPath 387 } 388 389 func (cond *FilterConditionIsNull) ConditionIsNull() {} 390 391 type FilterConditionIsNaN struct { 392 Not bool 393 FieldPath Alert_FieldPath 394 } 395 396 func (cond *FilterConditionIsNaN) String() string { 397 if cond.Not { 398 return cond.FieldPath.String() + " IS NOT NaN" 399 } else { 400 return cond.FieldPath.String() + " IS NaN" 401 } 402 } 403 404 func (cond *FilterConditionIsNaN) _IsFilterCondition() {} 405 406 func (cond *FilterConditionIsNaN) _IsAlertFilterBuilderOrCondition() {} 407 408 func (cond *FilterConditionIsNaN) And(conds ...FilterCondition) FilterCondition { 409 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 410 } 411 412 func (cond *FilterConditionIsNaN) Evaluate(res *Alert) bool { 413 v, ok := cond.FieldPath.GetSingleRaw(res) 414 if !ok { 415 return false 416 } 417 fv, ok := v.(float64) 418 if !ok { 419 return false 420 } 421 return math.IsNaN(fv) 422 } 423 424 func (cond *FilterConditionIsNaN) EvaluateRaw(res gotenresource.Resource) bool { 425 if typedRes, ok := res.(*Alert); !ok { 426 return false 427 } else { 428 return cond.Evaluate(typedRes) 429 } 430 } 431 432 func (cond *FilterConditionIsNaN) Satisfies(other FilterCondition) bool { 433 switch tother := other.(type) { 434 case *FilterConditionIsNaN: 435 return cond.FieldPath.String() == tother.FieldPath.String() && cond.Not == tother.Not 436 default: 437 return false 438 } 439 } 440 441 func (cond *FilterConditionIsNaN) SatisfiesRaw(other gotenresource.FilterCondition) bool { 442 if typedCond, ok := other.(FilterCondition); !ok { 443 return false 444 } else { 445 return cond.Satisfies(typedCond) 446 } 447 } 448 449 func (cond *FilterConditionIsNaN) SpecifiesFieldPath(fp Alert_FieldPath) bool { 450 return cond.FieldPath.String() == fp.String() 451 } 452 453 func (cond *FilterConditionIsNaN) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 454 if typedFp, ok := fp.(Alert_FieldPath); !ok { 455 return false 456 } else { 457 return cond.SpecifiesFieldPath(typedFp) 458 } 459 } 460 461 func (cond *FilterConditionIsNaN) GetRawFieldPath() gotenobject.FieldPath { 462 return cond.FieldPath 463 } 464 465 func (cond *FilterConditionIsNaN) ConditionIsNaN() {} 466 467 type FilterConditionCompare struct { 468 Operator filterParser.CompareOperator 469 Alert_FieldPathValue 470 } 471 472 func (cond *FilterConditionCompare) String() string { 473 jsonValue, err := utils.JsonMarshal(cond.Alert_FieldPathValue.GetRawValue()) 474 if err != nil { 475 panic(err) 476 } 477 return fmt.Sprintf("%s %s %s", cond.Alert_FieldPathValue, cond.Operator, jsonValue) 478 } 479 480 func (cond *FilterConditionCompare) _IsFilterCondition() {} 481 482 func (cond *FilterConditionCompare) _IsAlertFilterBuilderOrCondition() {} 483 484 func (cond *FilterConditionCompare) And(conds ...FilterCondition) FilterCondition { 485 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 486 } 487 488 func (cond *FilterConditionCompare) Evaluate(res *Alert) bool { 489 // Special evaluation for name or reference - may include wildcards 490 if nameOrRefFPV, ok := cond.Alert_FieldPathValue.GetRawValue().(gotenresource.Name); ok { 491 if otherObj, ok := cond.Alert_FieldPathValue.GetSingleRaw(res); ok { 492 match := nameOrRefFPV.Matches(otherObj) 493 switch cond.Operator { 494 case filterParser.Eq: 495 return match 496 case filterParser.Neq: 497 return !match 498 default: 499 return false 500 } 501 } 502 } 503 // special evaluation for objects 504 if objValue, ok := cond.Alert_FieldPathValue.GetRawValue().(proto.Message); ok { 505 if otherObj, ok := cond.Alert_FieldPathValue.GetSingleRaw(res); ok { 506 switch cond.Operator { 507 case filterParser.Eq: 508 return proto.Equal(objValue, otherObj.(proto.Message)) 509 case filterParser.Neq: 510 return !proto.Equal(objValue, otherObj.(proto.Message)) 511 default: 512 return false 513 } 514 } 515 } 516 cmpResult, comparable := cond.Alert_FieldPathValue.CompareWith(res) 517 if !comparable { 518 return false 519 } 520 return cond.Operator.MatchCompareResult(cmpResult) 521 } 522 523 func (cond *FilterConditionCompare) EvaluateRaw(res gotenresource.Resource) bool { 524 if typedRes, ok := res.(*Alert); !ok { 525 return false 526 } else { 527 return cond.Evaluate(typedRes) 528 } 529 } 530 531 func (cond *FilterConditionCompare) Satisfies(other FilterCondition) bool { 532 switch tother := other.(type) { 533 case *FilterConditionCompare: 534 if cond.Alert_FieldPathValue.String() != tother.Alert_FieldPathValue.String() { 535 return false 536 } 537 othertmp := new(Alert) 538 tother.SetTo(&othertmp) 539 if cmp, comparable := cond.CompareWith(othertmp); !comparable { 540 return false 541 } else { 542 return filterParser.CompareSatisfies(tother.Operator, cond.Operator, cmp) 543 } 544 case *FilterConditionIn: 545 if cond.Operator != filterParser.Eq { 546 return false 547 } 548 if cond.Alert_FieldPathValue.String() != tother.Alert_FieldPathArrayOfValues.String() { 549 return false 550 } 551 for _, inv := range tother.GetRawValues() { 552 othertmp := new(Alert) 553 tother.WithIValue(inv).SetTo(&othertmp) 554 if cmp, comparable := cond.Alert_FieldPathValue.CompareWith(othertmp); comparable && cmp == 0 { 555 return true 556 } 557 } 558 return false 559 case *FilterConditionComposite: 560 if tother.Operator == filterParser.AND { 561 for _, othersubcnd := range tother.flattenConditions() { 562 if !cond.Satisfies(othersubcnd) { 563 return false 564 } 565 } 566 return true 567 } else { // OR 568 for _, othersubcnd := range tother.flattenConditions() { 569 if cond.Satisfies(othersubcnd) { 570 return true 571 } 572 } 573 return false 574 } 575 default: 576 return false 577 } 578 } 579 580 func (cond *FilterConditionCompare) SatisfiesRaw(other gotenresource.FilterCondition) bool { 581 if typedCond, ok := other.(FilterCondition); !ok { 582 return false 583 } else { 584 return cond.Satisfies(typedCond) 585 } 586 } 587 588 func (cond *FilterConditionCompare) SpecifiesFieldPath(fp Alert_FieldPath) bool { 589 return cond.Alert_FieldPathValue.String() == fp.String() 590 } 591 592 func (cond *FilterConditionCompare) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 593 if typedFp, ok := fp.(Alert_FieldPath); !ok { 594 return false 595 } else { 596 return cond.SpecifiesFieldPath(typedFp) 597 } 598 } 599 600 func (cond *FilterConditionCompare) GetOperator() filterParser.CompareOperator { 601 return cond.Operator 602 } 603 604 func (cond *FilterConditionCompare) GetRawFieldPath() gotenobject.FieldPath { 605 return cond.Alert_FieldPathValue 606 } 607 608 func (cond *FilterConditionCompare) GetRawFieldPathValue() gotenobject.FieldPathValue { 609 return cond.Alert_FieldPathValue 610 } 611 612 func (cond *FilterConditionCompare) ConditionCompare() {} 613 614 type FilterConditionContains struct { 615 Type gotenresource.ConditionContainsType 616 FieldPath Alert_FieldPath 617 618 Value Alert_FieldPathArrayItemValue 619 Values []Alert_FieldPathArrayItemValue 620 } 621 622 func (cond *FilterConditionContains) String() string { 623 switch cond.ConditionContainsType() { 624 case gotenresource.ConditionContainsTypeValue: 625 jsonValue, err := utils.JsonMarshal(cond.Value.GetRawItemValue()) 626 if err != nil { 627 panic(err) 628 } 629 return fmt.Sprintf("%s CONTAINS %s", cond.FieldPath, string(jsonValue)) 630 case gotenresource.ConditionContainsTypeAny, gotenresource.ConditionContainsTypeAll: 631 jsonValues := make([]string, len(cond.Values)) 632 for i, v := range cond.Values { 633 if jsonValue, err := utils.JsonMarshal(v.GetRawItemValue()); err != nil { 634 panic(err) 635 } else { 636 jsonValues[i] = string(jsonValue) 637 } 638 } 639 return fmt.Sprintf("%s CONTAINS %s %s", cond.FieldPath, cond.ConditionContainsType(), fmt.Sprintf("(%s)", strings.Join(jsonValues, ", "))) 640 default: 641 panic(gotenresource.NewUnknownConditionContainsType(cond.ConditionContainsType())) 642 } 643 } 644 645 func (cond *FilterConditionContains) ConditionContainsType() gotenresource.ConditionContainsType { 646 return cond.Type 647 } 648 649 func (cond *FilterConditionContains) _IsFilterCondition() {} 650 651 func (cond *FilterConditionContains) _IsAlertFilterBuilderOrCondition() {} 652 653 func (cond *FilterConditionContains) And(conds ...FilterCondition) FilterCondition { 654 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 655 } 656 657 func (cond *FilterConditionContains) Evaluate(res *Alert) bool { 658 switch cond.ConditionContainsType() { 659 case gotenresource.ConditionContainsTypeValue: 660 return cond.Value.ContainsValue(res) 661 case gotenresource.ConditionContainsTypeAny: 662 for _, v := range cond.Values { 663 if v.ContainsValue(res) { 664 return true 665 } 666 } 667 return false 668 case gotenresource.ConditionContainsTypeAll: 669 for _, v := range cond.Values { 670 if !v.ContainsValue(res) { 671 return false 672 } 673 } 674 return true 675 default: 676 panic(gotenresource.NewUnknownConditionContainsType(cond.ConditionContainsType())) 677 } 678 } 679 680 func (cond *FilterConditionContains) EvaluateRaw(res gotenresource.Resource) bool { 681 if typedRes, ok := res.(*Alert); !ok { 682 return false 683 } else { 684 return cond.Evaluate(typedRes) 685 } 686 } 687 688 func (cond *FilterConditionContains) Satisfies(other FilterCondition) bool { 689 switch tother := other.(type) { 690 case *FilterConditionContains: 691 if cond.ConditionContainsType().IsValue() && tother.ConditionContainsType().IsValue() { 692 othertmp := new(Alert) 693 tother.Value.WithIValue(tother.GetRawFieldPathItemValue().GetRawItemValue()).SetTo(&othertmp) 694 return cond.Value.ContainsValue(othertmp) 695 } 696 return false 697 default: 698 return false 699 } 700 } 701 702 func (cond *FilterConditionContains) SatisfiesRaw(other gotenresource.FilterCondition) bool { 703 if typedCond, ok := other.(FilterCondition); !ok { 704 return false 705 } else { 706 return cond.Satisfies(typedCond) 707 } 708 } 709 710 func (cond *FilterConditionContains) SpecifiesFieldPath(fp Alert_FieldPath) bool { 711 return cond.FieldPath.String() == fp.String() 712 } 713 714 func (cond *FilterConditionContains) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 715 if typedFp, ok := fp.(Alert_FieldPath); !ok { 716 return false 717 } else { 718 return cond.SpecifiesFieldPath(typedFp) 719 } 720 } 721 722 func (cond *FilterConditionContains) GetFieldPath() Alert_FieldPath { 723 return cond.FieldPath 724 } 725 726 func (cond *FilterConditionContains) GetRawFieldPath() gotenobject.FieldPath { 727 return cond.FieldPath 728 } 729 730 func (cond *FilterConditionContains) GetRawFieldPathItemValue() gotenobject.FieldPathArrayItemValue { 731 switch cond.ConditionContainsType() { 732 case gotenresource.ConditionContainsTypeValue: 733 return cond.Value 734 default: 735 panic(fmt.Errorf("unable to get value for condition contains type %s", cond.ConditionContainsType())) 736 } 737 } 738 739 func (cond *FilterConditionContains) GetRawFieldPathItemValues() (res []gotenobject.FieldPathArrayItemValue) { 740 switch cond.ConditionContainsType() { 741 case gotenresource.ConditionContainsTypeAny, gotenresource.ConditionContainsTypeAll: 742 for _, fpaiv := range cond.Values { 743 res = append(res, fpaiv) 744 } 745 default: 746 panic(fmt.Errorf("unable to get values for condition contains type %s", cond.ConditionContainsType())) 747 } 748 return 749 } 750 751 func (cond *FilterConditionContains) ConditionContains() {} 752 753 type FilterConditionIn struct { 754 Alert_FieldPathArrayOfValues 755 } 756 757 func (cond *FilterConditionIn) String() string { 758 jsonValues, err := utils.JsonMarshal(cond.Alert_FieldPathArrayOfValues.GetRawValues()) 759 if err != nil { 760 panic(err) 761 } 762 return fmt.Sprintf("%s IN %s", cond.Alert_FieldPathArrayOfValues, jsonValues) 763 } 764 765 func (cond *FilterConditionIn) _IsFilterCondition() {} 766 767 func (cond *FilterConditionIn) _IsAlertFilterBuilderOrCondition() {} 768 769 func (cond *FilterConditionIn) And(conds ...FilterCondition) FilterCondition { 770 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 771 } 772 773 func (cond *FilterConditionIn) Evaluate(res *Alert) bool { 774 for _, inValue := range cond.Alert_FieldPathArrayOfValues.GetRawValues() { 775 if cmp, ok := cond.Alert_FieldPathArrayOfValues.WithIValue(inValue).CompareWith(res); ok && cmp == 0 { 776 return true 777 } 778 } 779 return false 780 } 781 782 func (cond *FilterConditionIn) EvaluateRaw(res gotenresource.Resource) bool { 783 if typedRes, ok := res.(*Alert); !ok { 784 return false 785 } else { 786 return cond.Evaluate(typedRes) 787 } 788 } 789 790 func (cond *FilterConditionIn) Satisfies(other FilterCondition) bool { 791 switch tother := other.(type) { 792 case *FilterConditionIn: 793 outer: 794 for _, cval := range cond.Alert_FieldPathArrayOfValues.GetRawValues() { 795 for _, otherval := range tother.Alert_FieldPathArrayOfValues.GetRawValues() { 796 othertmp := new(Alert) 797 tother.Alert_FieldPathArrayOfValues.WithIValue(otherval).SetTo(&othertmp) 798 if cmp, comparable := cond.Alert_FieldPathArrayOfValues.WithIValue(cval).CompareWith(othertmp); comparable && cmp == 0 { 799 continue outer 800 } 801 } 802 return false 803 } 804 return true 805 default: 806 for _, cval := range cond.Alert_FieldPathArrayOfValues.GetRawValues() { 807 subcnd := &FilterConditionCompare{ 808 Operator: filterParser.Eq, 809 Alert_FieldPathValue: cond.Alert_FieldPathArrayOfValues.WithIValue(cval), 810 } 811 if !subcnd.Satisfies(tother) { 812 return false 813 } 814 } 815 return true 816 } 817 } 818 819 func (cond *FilterConditionIn) SatisfiesRaw(other gotenresource.FilterCondition) bool { 820 if typedCond, ok := other.(FilterCondition); !ok { 821 return false 822 } else { 823 return cond.Satisfies(typedCond) 824 } 825 } 826 827 func (cond *FilterConditionIn) SpecifiesFieldPath(fp Alert_FieldPath) bool { 828 return cond.Alert_FieldPathArrayOfValues.String() == fp.String() 829 } 830 831 func (cond *FilterConditionIn) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 832 if typedFp, ok := fp.(Alert_FieldPath); !ok { 833 return false 834 } else { 835 return cond.SpecifiesFieldPath(typedFp) 836 } 837 } 838 839 func (cond *FilterConditionIn) GetRawFieldPath() gotenobject.FieldPath { 840 return cond.Alert_FieldPathArrayOfValues 841 } 842 843 func (cond *FilterConditionIn) GetRawFieldPathArrayOfValues() gotenobject.FieldPathArrayOfValues { 844 return cond.Alert_FieldPathArrayOfValues 845 } 846 847 func (cond *FilterConditionIn) ConditionIn() {} 848 849 type FilterConditionNotIn struct { 850 Alert_FieldPathArrayOfValues 851 } 852 853 func (cond *FilterConditionNotIn) String() string { 854 jsonValues, err := utils.JsonMarshal(cond.Alert_FieldPathArrayOfValues.GetRawValues()) 855 if err != nil { 856 panic(err) 857 } 858 return fmt.Sprintf("%s NOT IN %s", cond.Alert_FieldPathArrayOfValues, jsonValues) 859 } 860 861 func (cond *FilterConditionNotIn) _IsFilterCondition() {} 862 863 func (cond *FilterConditionNotIn) _IsAlertFilterBuilderOrCondition() {} 864 865 func (cond *FilterConditionNotIn) And(conds ...FilterCondition) FilterCondition { 866 return AndFilterConditions(append([]FilterCondition{cond}, conds...)...) 867 } 868 869 func (cond *FilterConditionNotIn) Evaluate(res *Alert) bool { 870 for _, inValue := range cond.Alert_FieldPathArrayOfValues.GetRawValues() { 871 if cmp, ok := cond.Alert_FieldPathArrayOfValues.WithIValue(inValue).CompareWith(res); ok && cmp == 0 { 872 return false 873 } 874 } 875 return true 876 } 877 878 func (cond *FilterConditionNotIn) EvaluateRaw(res gotenresource.Resource) bool { 879 if typedRes, ok := res.(*Alert); !ok { 880 return false 881 } else { 882 return cond.Evaluate(typedRes) 883 } 884 } 885 886 func (cond *FilterConditionNotIn) Satisfies(other FilterCondition) bool { 887 return false 888 } 889 890 func (cond *FilterConditionNotIn) SatisfiesRaw(other gotenresource.FilterCondition) bool { 891 if typedCond, ok := other.(FilterCondition); !ok { 892 return false 893 } else { 894 return cond.Satisfies(typedCond) 895 } 896 } 897 898 func (cond *FilterConditionNotIn) SpecifiesFieldPath(fp Alert_FieldPath) bool { 899 return cond.Alert_FieldPathArrayOfValues.String() == fp.String() 900 } 901 902 func (cond *FilterConditionNotIn) SpecifiesRawFieldPath(fp gotenobject.FieldPath) bool { 903 if typedFp, ok := fp.(Alert_FieldPath); !ok { 904 return false 905 } else { 906 return cond.SpecifiesFieldPath(typedFp) 907 } 908 } 909 910 func (cond *FilterConditionNotIn) GetRawFieldPath() gotenobject.FieldPath { 911 return cond.Alert_FieldPathArrayOfValues 912 } 913 914 func (cond *FilterConditionNotIn) GetRawFieldPathArrayOfValues() gotenobject.FieldPathArrayOfValues { 915 return cond.Alert_FieldPathArrayOfValues 916 } 917 918 func (cond *FilterConditionNotIn) ConditionNotIn() {} 919 920 type Filter struct { 921 FilterCondition 922 } 923 924 func (filter *Filter) _IsAlertFilterBuilderOrCondition() {} 925 926 // GetCondition is a getter of FilterCondition, which also handles nil pointer 927 func (filter *Filter) GetCondition() FilterCondition { 928 if filter == nil { 929 return AndFilterConditions() 930 } else { 931 return filter.FilterCondition 932 } 933 } 934 935 // Evaluate is a wrapper on FilterCondition, which also handles nil pointer 936 func (filter *Filter) Evaluate(res *Alert) bool { 937 return filter.GetCondition().Evaluate(res) 938 } 939 940 func (filter *Filter) EvaluateRaw(res gotenresource.Resource) bool { 941 if typedRes, ok := res.(*Alert); !ok { 942 return false 943 } else { 944 return filter.Evaluate(typedRes) 945 } 946 } 947 948 func (filter *Filter) GetRawCondition() gotenresource.FilterCondition { 949 if filter == nil { 950 return nil 951 } 952 return filter.GetCondition() 953 } 954 955 // FilterSlice is a helper for filtering arrays 956 func (filter *Filter) FilterSlice(in []*Alert) (out []*Alert) { 957 for _, res := range in { 958 if filter.Evaluate(res) { 959 out = append(out, res) 960 } 961 } 962 return 963 } 964 965 // implement methods required by protobuf-go library for string-struct conversion 966 967 func (filter *Filter) ProtoString() (string, error) { 968 if filter == nil || filter.FilterCondition == nil { 969 return "", nil 970 } 971 return filter.FilterCondition.String(), nil 972 } 973 974 func (filter *Filter) ParseProtoString(data string) error { 975 expression, err := filterParser.Parse([]byte(data)) 976 if err != nil { 977 return status.Error(codes.InvalidArgument, err.Error()) 978 } 979 980 condition, err := makeFilterConditionFromOr(expression.And) 981 if err != nil { 982 return err 983 } 984 filter.FilterCondition = condition 985 return nil 986 } 987 988 func (filter *Filter) String() string { 989 if filter == nil || filter.FilterCondition == nil { 990 return "<nil>" 991 } 992 return filter.FilterCondition.String() 993 } 994 995 func (filter *Filter) SetFromCliFlag(raw string) error { 996 return filter.ParseProtoString(raw) 997 } 998 999 // helpers 1000 1001 func makeFilterConditionFromOperand(condition *filterParser.ConditionOperand) (FilterCondition, error) { 1002 path, err := ParseAlert_FieldPath(condition.FieldPath) 1003 if err != nil { 1004 return nil, err 1005 } 1006 rhs := condition.ConditionRHS 1007 valueJSON, err := rhs.JSONValue() 1008 if err != nil { 1009 return nil, status.Error(codes.Internal, err.Error()) 1010 } 1011 1012 if rhs.Compare != nil { 1013 cmp := rhs.Compare 1014 if !path.IsLeaf() && !(cmp.Operator == filterParser.Eq || cmp.Operator == filterParser.Neq) { 1015 return nil, status.Errorf(codes.InvalidArgument, "path '%s' is not comparable leaf value for operator %s", path, cmp.Operator) 1016 } 1017 1018 // translate null comparison to IS(NOT)NULL 1019 if cmp.Value.Null { 1020 switch cmp.Operator { 1021 case filterParser.Eq: 1022 return &FilterConditionIsNull{false, path}, nil 1023 case filterParser.Neq: 1024 return &FilterConditionIsNull{true, path}, nil 1025 default: 1026 return nil, status.Errorf(codes.InvalidArgument, "operator '%s' isn't valid when comparing null value", cmp.Operator) 1027 } 1028 } 1029 1030 pfv, err := ParseAlert_FieldPathValue(path.String(), string(valueJSON)) 1031 if err != nil { 1032 return nil, status.Errorf(codes.InvalidArgument, "error when parsing filter value for field path '%s': %s", path, err) 1033 } 1034 1035 return &FilterConditionCompare{ 1036 Operator: cmp.Operator, 1037 Alert_FieldPathValue: pfv, 1038 }, nil 1039 } else if rhs.Is != nil { 1040 if rhs.Is.Null { 1041 return &FilterConditionIsNull{rhs.Is.Not, path}, nil 1042 } else if rhs.Is.NaN { 1043 return &FilterConditionIsNaN{rhs.Is.Not, path}, nil 1044 } else { 1045 return nil, status.Error(codes.Internal, "unknown filter IS type - expected NULL or NaN") 1046 } 1047 } else if rhs.Contains != nil { 1048 ct := gotenresource.ConditionContainsTypeFromParser(rhs.Contains) 1049 fp, err := ParseAlert_FieldPath(path.String()) 1050 if err != nil { 1051 return nil, err 1052 } 1053 if rhs.Contains.Value != nil { 1054 pfav, err := ParseAlert_FieldPathArrayItemValue(path.String(), string(valueJSON)) 1055 if err != nil { 1056 return nil, err 1057 } 1058 return &FilterConditionContains{ct, fp, pfav, nil}, nil 1059 } else if rhs.Contains.Any != nil || rhs.Contains.All != nil { 1060 parrv := rhs.Contains.GetArray() 1061 vals := make([]Alert_FieldPathArrayItemValue, len(parrv)) 1062 for i, pv := range parrv { 1063 jsonv, err := utils.JsonMarshal(pv) 1064 if err != nil { 1065 return nil, err 1066 } 1067 if pfav, err := ParseAlert_FieldPathArrayItemValue(path.String(), string(jsonv)); err != nil { 1068 return nil, err 1069 } else { 1070 vals[i] = pfav 1071 } 1072 } 1073 return &FilterConditionContains{ct, fp, nil, vals}, nil 1074 } else { 1075 return nil, status.Error(codes.Internal, "unknown condition contains type") 1076 } 1077 } else if rhs.Like != nil { 1078 return nil, status.Errorf(codes.Unimplemented, "'LIKE' condition is not supported") 1079 } else if rhs.In != nil { 1080 if fpaov, err := ParseAlert_FieldPathArrayOfValues(path.String(), string(valueJSON)); err != nil { 1081 return nil, err 1082 } else { 1083 return &FilterConditionIn{fpaov}, nil 1084 } 1085 } else if rhs.NotIn != nil { 1086 if fpaov, err := ParseAlert_FieldPathArrayOfValues(path.String(), string(valueJSON)); err != nil { 1087 return nil, err 1088 } else { 1089 return &FilterConditionNotIn{fpaov}, nil 1090 } 1091 } 1092 return nil, status.Error(codes.Internal, "unknown filter RHS operand type") 1093 1094 } 1095 1096 func makeFilterConditionFromCondition(condition *filterParser.Condition) (FilterCondition, error) { 1097 if condition.SubExpression != nil { 1098 return makeFilterConditionFromOr(condition.SubExpression.And) 1099 } else if condition.Not != nil { 1100 not, err := makeFilterConditionFromCondition(condition.Not) 1101 if err != nil { 1102 return nil, err 1103 } 1104 return &FilterConditionNot{not}, nil 1105 } else if condition.Operand != nil { 1106 return makeFilterConditionFromOperand(condition.Operand) 1107 } else { 1108 return nil, status.Error(codes.Internal, "unknown condition type") 1109 } 1110 } 1111 1112 func makeFilterConditionFromAnd(conditions []filterParser.Condition) (FilterCondition, error) { 1113 if len(conditions) == 1 { 1114 return makeFilterConditionFromCondition(&conditions[0]) 1115 } else { 1116 cnds := make([]FilterCondition, 0, len(conditions)) 1117 for _, condition := range conditions { 1118 cnd, err := makeFilterConditionFromCondition(&condition) 1119 if err != nil { 1120 return nil, err 1121 } 1122 cnds = append(cnds, cnd) 1123 } 1124 return &FilterConditionComposite{Operator: filterParser.AND, Conditions: cnds}, nil 1125 } 1126 } 1127 1128 func makeFilterConditionFromOr(conditions []filterParser.AndCondition) (FilterCondition, error) { 1129 if len(conditions) == 1 { 1130 return makeFilterConditionFromAnd(conditions[0].Or) 1131 } else { 1132 cnds := make([]FilterCondition, 0, len(conditions)) 1133 for _, condition := range conditions { 1134 cnd, err := makeFilterConditionFromAnd(condition.Or) 1135 if err != nil { 1136 return nil, err 1137 } 1138 cnds = append(cnds, cnd) 1139 } 1140 return &FilterConditionComposite{Operator: filterParser.OR, Conditions: cnds}, nil 1141 } 1142 }