costmetric.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package opencost
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. // CostMetricName a string type that acts as an enumeration of possible CostMetric options
  7. type CostMetricName string
  8. const (
  9. CostMetricNone CostMetricName = ""
  10. CostMetricListCost CostMetricName = "listCost"
  11. CostMetricNetCost CostMetricName = "netCost"
  12. CostMetricAmortizedNetCost CostMetricName = "amortizedNetCost"
  13. CostMetricInvoicedCost CostMetricName = "invoicedCost"
  14. CostMetricAmortizedCost CostMetricName = "amortizedCost"
  15. )
  16. // ParseCostMetricName provides a resilient way to parse one of the enumerated CostMetricName types from a string
  17. // or throws an error if it is not able to.
  18. func ParseCostMetricName(costMetric string) (CostMetricName, error) {
  19. switch strings.ToLower(costMetric) {
  20. case strings.ToLower(string(CostMetricListCost)):
  21. return CostMetricListCost, nil
  22. case strings.ToLower(string(CostMetricAmortizedCost)):
  23. return CostMetricAmortizedCost, nil
  24. case strings.ToLower(string(CostMetricAmortizedNetCost)):
  25. return CostMetricAmortizedNetCost, nil
  26. case strings.ToLower(string(CostMetricNetCost)):
  27. return CostMetricNetCost, nil
  28. case strings.ToLower(string(CostMetricInvoicedCost)):
  29. return CostMetricInvoicedCost, nil
  30. }
  31. return CostMetricNone, fmt.Errorf("failed to parse a valid CostMetricName from '%s'", costMetric)
  32. }
  33. // CostMetric is a container for values associated with a specific accounting method
  34. type CostMetric struct {
  35. Cost float64 `json:"cost"`
  36. KubernetesPercent float64 `json:"kubernetesPercent"`
  37. }
  38. func (cm CostMetric) Equal(that CostMetric) bool {
  39. return cm.Cost == that.Cost && cm.KubernetesPercent == that.KubernetesPercent
  40. }
  41. func (cm CostMetric) Clone() CostMetric {
  42. return CostMetric{
  43. Cost: cm.Cost,
  44. KubernetesPercent: cm.KubernetesPercent,
  45. }
  46. }
  47. func (cm CostMetric) add(that CostMetric) CostMetric {
  48. // Compute KubernetesPercent for sum
  49. k8sPct := 0.0
  50. sumCost := cm.Cost + that.Cost
  51. if sumCost > 0.0 {
  52. thisK8sCost := cm.Cost * cm.KubernetesPercent
  53. thatK8sCost := that.Cost * that.KubernetesPercent
  54. k8sPct = (thisK8sCost + thatK8sCost) / sumCost
  55. }
  56. return CostMetric{
  57. Cost: sumCost,
  58. KubernetesPercent: k8sPct,
  59. }
  60. }
  61. // percent returns the product of the given percent and the cost, KubernetesPercent remains the same
  62. func (cm CostMetric) percent(pct float64) CostMetric {
  63. return CostMetric{
  64. Cost: cm.Cost * pct,
  65. KubernetesPercent: cm.KubernetesPercent,
  66. }
  67. }