storageconnection.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package azure
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
  9. "github.com/opencost/opencost/core/pkg/log"
  10. "github.com/opencost/opencost/pkg/cloud"
  11. )
  12. // StorageConnection provides access to Azure Storage
  13. type StorageConnection struct {
  14. StorageConfiguration
  15. ConnectionStatus cloud.ConnectionStatus
  16. }
  17. func (sc *StorageConnection) GetStatus() cloud.ConnectionStatus {
  18. // initialize status if it has not done so; this can happen if the integration is inactive
  19. if sc.ConnectionStatus.String() == "" {
  20. sc.ConnectionStatus = cloud.InitialStatus
  21. }
  22. return sc.ConnectionStatus
  23. }
  24. func (sc *StorageConnection) Equals(config cloud.Config) bool {
  25. thatConfig, ok := config.(*StorageConnection)
  26. if !ok {
  27. return false
  28. }
  29. return sc.StorageConfiguration.Equals(&thatConfig.StorageConfiguration)
  30. }
  31. // getBlobURLTemplate returns the correct BlobUrl for whichever Cloud storage account is specified by the AzureCloud configuration
  32. // defaults to the Public Cloud template
  33. func (sc *StorageConnection) getBlobURLTemplate() string {
  34. // Use gov cloud blob url if gov is detected in AzureCloud
  35. if strings.Contains(strings.ToLower(sc.Cloud), "gov") {
  36. return "https://%s.blob.core.usgovcloudapi.net/%s"
  37. }
  38. // default to Public Cloud template
  39. return "https://%s.blob.core.windows.net/%s"
  40. }
  41. // DownloadBlobToFile downloads the Azure Billing CSV to a local file
  42. func (sc *StorageConnection) DownloadBlobToFile(localFilePath string, blobName string, client *azblob.Client, ctx context.Context) error {
  43. // If file exists, don't download it again
  44. if _, err := os.Stat(localFilePath); err == nil {
  45. log.DedupedInfof(3, "CloudCost: Azure: DownloadBlobToFile: file %v already exists, not downloading %v", localFilePath, blobName)
  46. return nil
  47. }
  48. // Create filepath
  49. dir := filepath.Dir(localFilePath)
  50. if err := os.MkdirAll(dir, os.ModePerm); err != nil {
  51. return fmt.Errorf("CloudCost: Azure: DownloadBlobToFile: failed to create directory %w", err)
  52. }
  53. fp, err := os.Create(localFilePath)
  54. if err != nil {
  55. return fmt.Errorf("CloudCost: Azure: DownloadBlobToFile: failed to create file %w", err)
  56. }
  57. defer fp.Close()
  58. // Download newest Azure Billing CSV to disk
  59. log.Infof("CloudCost: Azure: DownloadBlobToFile: retrieving blob: %v", blobName)
  60. filesize, err := client.DownloadFile(ctx, sc.Container, blobName, fp, nil)
  61. if err != nil {
  62. return fmt.Errorf("CloudCost: Azure: DownloadBlobToFile: failed to download %w", err)
  63. }
  64. log.Infof("CloudCost: Azure: DownloadBlobToFile: retrieved %v of size %dMB", blobName, filesize/1024/1024)
  65. return nil
  66. }