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  	_ = &notification_channel.NotificationChannel{}
    48  	_ = &rcommon.LogCndSpec{}
    49  	_ = &ts_condition.TsCondition{}
    50  	_ = &durationpb.Duration{}
    51  	_ = &timestamppb.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  }