| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- package filter
- import (
- "fmt"
- "strings"
- "github.com/opencost/opencost/pkg/log"
- )
- const unallocatedSuffix = "__unallocated__"
- type StringMapPropertied interface {
- StringMapProperty(string) (map[string]string, error)
- }
- // StringMapOperation is an enum that represents operations that can be performed
- // when filtering (equality, inequality, etc.)
- type StringMapOperation string
- const (
- // StringMapHasKey passes if the map has the provided key
- StringMapHasKey StringMapOperation = "stringmapcontains"
- StringMapStartsWith = "stringmapstartswith"
- // StringMapEquals when the given key and value match
- StringMapEquals = "stringmapequals"
- )
- // StringMapProperty is the lowest-level type of filter. It represents
- // a filter operation (equality, inequality, etc.) on a property that contains a string map
- type StringMapProperty[T StringMapPropertied] struct {
- Field string
- Op StringMapOperation
- Key string
- Value string
- }
- func (smp StringMapProperty[T]) String() string {
- return fmt.Sprintf(`(%s %s[%s] "%s")`, smp.Op, smp.Field, smp.Key, smp.Value)
- }
- func (smp StringMapProperty[T]) Matches(that T) bool {
- thatMap, err := that.StringMapProperty(smp.Field)
- if err != nil {
- log.Errorf("Filter: StringMapProperty: could not retrieve field %s: %s", smp.Field, err.Error())
- return false
- }
- valueToCompare, keyIsPresent := thatMap[smp.Key]
- switch smp.Op {
- case StringMapHasKey:
- return keyIsPresent
- case StringMapEquals:
- // namespace:"__unallocated__" should match a.Properties.Namespace = ""
- // label[app]:"__unallocated__" should match _, ok := Labels[app]; !ok
- if !keyIsPresent || valueToCompare == "" {
- return smp.Value == unallocatedSuffix
- }
- if valueToCompare == smp.Value {
- return true
- }
- case StringMapStartsWith:
- if !keyIsPresent {
- return false
- }
- // We don't need special __unallocated__ logic here because a query
- // asking for "__unallocated__" won't have a wildcard and unallocated
- // properties are the empty string.
- return strings.HasPrefix(valueToCompare, smp.Value)
- default:
- log.Errorf("Filter: StringMapProperty: Unhandled filter op. This is a filter implementation error and requires immediate patching. Op: %s", smp.Op)
- return false
- }
- return false
- }
|