cloudcost.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package util
  2. import (
  3. "strings"
  4. "github.com/opencost/opencost/pkg/filter"
  5. "github.com/opencost/opencost/pkg/kubecost"
  6. "github.com/opencost/opencost/pkg/log"
  7. "github.com/opencost/opencost/pkg/util/mapper"
  8. )
  9. func parseWildcardEnd(rawFilterValue string) (string, bool) {
  10. return strings.TrimSuffix(rawFilterValue, "*"), strings.HasSuffix(rawFilterValue, "*")
  11. }
  12. func CloudCostFilterFromParams(pmr mapper.PrimitiveMapReader) filter.Filter[*kubecost.CloudCost] {
  13. filter := filter.And[*kubecost.CloudCost]{
  14. Filters: []filter.Filter[*kubecost.CloudCost]{},
  15. }
  16. if raw := pmr.GetList("filterInvoiceEntityIDs", ","); len(raw) > 0 {
  17. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostInvoiceEntityIDProp))
  18. }
  19. if raw := pmr.GetList("filterAccountIDs", ","); len(raw) > 0 {
  20. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostAccountIDProp))
  21. }
  22. if raw := pmr.GetList("filterProviders", ","); len(raw) > 0 {
  23. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostProviderProp))
  24. }
  25. if raw := pmr.GetList("filterProviderIDs", ","); len(raw) > 0 {
  26. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostProviderIDProp))
  27. }
  28. if raw := pmr.GetList("filterServices", ","); len(raw) > 0 {
  29. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostServiceProp))
  30. }
  31. if raw := pmr.GetList("filterCategories", ","); len(raw) > 0 {
  32. filter.Filters = append(filter.Filters, filterV1SingleValueFromList(raw, kubecost.CloudCostCategoryProp))
  33. }
  34. if raw := pmr.GetList("filterLabels", ","); len(raw) > 0 {
  35. filter.Filters = append(filter.Filters, filterV1DoubleValueFromList(raw, kubecost.CloudCostLabelProp))
  36. }
  37. if len(filter.Filters) == 0 {
  38. return nil
  39. }
  40. return filter
  41. }
  42. func filterV1SingleValueFromList(rawFilterValues []string, field string) filter.Filter[*kubecost.CloudCost] {
  43. result := filter.Or[*kubecost.CloudCost]{
  44. Filters: []filter.Filter[*kubecost.CloudCost]{},
  45. }
  46. for _, filterValue := range rawFilterValues {
  47. filterValue = strings.TrimSpace(filterValue)
  48. filterValue, wildcard := parseWildcardEnd(filterValue)
  49. subFilter := filter.StringProperty[*kubecost.CloudCost]{
  50. Field: field,
  51. Op: filter.StringEquals,
  52. Value: filterValue,
  53. }
  54. if wildcard {
  55. subFilter.Op = kubecost.FilterStartsWith
  56. }
  57. result.Filters = append(result.Filters, subFilter)
  58. }
  59. return result
  60. }
  61. // filterV1DoubleValueFromList creates an OR of key:value equality filters for
  62. // colon-split filter values.
  63. //
  64. // The v1 query language (e.g. "filterLabels=app:foo,l2:bar") uses OR within
  65. // a field (e.g. label[app] = foo OR label[l2] = bar)
  66. func filterV1DoubleValueFromList(rawFilterValuesUnsplit []string, filterField string) filter.Filter[*kubecost.CloudCost] {
  67. result := filter.Or[*kubecost.CloudCost]{
  68. Filters: []filter.Filter[*kubecost.CloudCost]{},
  69. }
  70. for _, unsplit := range rawFilterValuesUnsplit {
  71. if unsplit != "" {
  72. split := strings.Split(unsplit, ":")
  73. if len(split) != 2 {
  74. log.Warnf("illegal key/value filter (ignoring): %s", unsplit)
  75. continue
  76. }
  77. labelName := strings.TrimSpace(split[0])
  78. val := strings.TrimSpace(split[1])
  79. val, wildcard := parseWildcardEnd(val)
  80. subFilter := filter.StringMapProperty[*kubecost.CloudCost]{
  81. Field: filterField,
  82. // All v1 filters are equality comparisons
  83. Op: filter.StringMapEquals,
  84. Key: labelName,
  85. Value: val,
  86. }
  87. if wildcard {
  88. subFilter.Op = filter.StringMapStartsWith
  89. }
  90. result.Filters = append(result.Filters, subFilter)
  91. }
  92. }
  93. return result
  94. }