azurestorageintegration.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package azure
  2. import (
  3. "strings"
  4. "time"
  5. "github.com/opencost/opencost/core/pkg/opencost"
  6. "github.com/opencost/opencost/core/pkg/util/timeutil"
  7. )
  8. type AzureStorageIntegration struct {
  9. AzureStorageBillingParser
  10. }
  11. func (asi *AzureStorageIntegration) GetCloudCost(start, end time.Time) (*opencost.CloudCostSetRange, error) {
  12. ccsr, err := opencost.NewCloudCostSetRange(start, end, opencost.AccumulateOptionDay, asi.Key())
  13. if err != nil {
  14. return nil, err
  15. }
  16. err = asi.ParseBillingData(start, end, func(abv *BillingRowValues) error {
  17. s := abv.Date
  18. e := abv.Date.Add(timeutil.Day)
  19. window := opencost.NewWindow(&s, &e)
  20. k8sPtc := 0.0
  21. if AzureIsK8s(abv.Tags) {
  22. k8sPtc = 1.0
  23. }
  24. providerID, _ := AzureSetProviderID(abv)
  25. // Create CloudCost
  26. // Using the NetCost as a 'placeholder' for Invoiced and Amortized Net costs now,
  27. // until we can revisit and spend the time to do the calculations correctly
  28. cc := &opencost.CloudCost{
  29. Properties: &opencost.CloudCostProperties{
  30. ProviderID: providerID,
  31. Provider: opencost.AzureProvider,
  32. AccountID: abv.SubscriptionID,
  33. AccountName: abv.SubscriptionName,
  34. InvoiceEntityID: abv.InvoiceEntityID,
  35. InvoiceEntityName: abv.InvoiceEntityName,
  36. RegionID: abv.Region,
  37. Service: abv.Service,
  38. Category: SelectAzureCategory(abv.MeterCategory),
  39. Labels: abv.Tags,
  40. },
  41. Window: window,
  42. AmortizedNetCost: opencost.CostMetric{
  43. Cost: abv.NetCost,
  44. KubernetesPercent: k8sPtc,
  45. },
  46. InvoicedCost: opencost.CostMetric{
  47. Cost: abv.NetCost,
  48. KubernetesPercent: k8sPtc,
  49. },
  50. ListCost: opencost.CostMetric{
  51. Cost: abv.Cost,
  52. KubernetesPercent: k8sPtc,
  53. },
  54. NetCost: opencost.CostMetric{
  55. Cost: abv.NetCost,
  56. KubernetesPercent: k8sPtc,
  57. },
  58. // NOTE: on Azure, there is no "AmortizedCost" per se, so we use
  59. // AmortizedNetCost, or NetCost, instead.
  60. AmortizedCost: opencost.CostMetric{
  61. Cost: abv.NetCost,
  62. KubernetesPercent: k8sPtc,
  63. },
  64. }
  65. ccsr.LoadCloudCost(cc)
  66. return nil
  67. })
  68. if err != nil {
  69. return nil, err
  70. }
  71. return ccsr, nil
  72. }
  73. // Check for the presence of k8s labels
  74. func AzureIsK8s(labels map[string]string) bool {
  75. for key := range labels {
  76. if strings.HasPrefix(key, "aks-managed-") {
  77. return true
  78. }
  79. if strings.HasPrefix(key, "kubernetes.io-created-") {
  80. return true
  81. }
  82. if strings.HasPrefix(key, "k8s-azure-created-") {
  83. return true
  84. }
  85. }
  86. return false
  87. }