imguploader.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. package imguploader
  2. import (
  3. "context"
  4. "fmt"
  5. "regexp"
  6. "github.com/grafana/grafana/pkg/log"
  7. "github.com/grafana/grafana/pkg/setting"
  8. )
  9. type ImageUploader interface {
  10. Upload(ctx context.Context, path string) (string, error)
  11. }
  12. type NopImageUploader struct {
  13. }
  14. func (NopImageUploader) Upload(ctx context.Context, path string) (string, error) {
  15. return "", nil
  16. }
  17. func NewImageUploader() (ImageUploader, error) {
  18. switch setting.ImageUploadProvider {
  19. case "s3":
  20. s3sec, err := setting.Raw.GetSection("external_image_storage.s3")
  21. if err != nil {
  22. return nil, err
  23. }
  24. bucket := s3sec.Key("bucket").MustString("")
  25. region := s3sec.Key("region").MustString("")
  26. path := s3sec.Key("path").MustString("")
  27. bucketUrl := s3sec.Key("bucket_url").MustString("")
  28. accessKey := s3sec.Key("access_key").MustString("")
  29. secretKey := s3sec.Key("secret_key").MustString("")
  30. if path != "" && path[len(path)-1:] != "/" {
  31. path += "/"
  32. }
  33. if bucket == "" || region == "" {
  34. info, err := getRegionAndBucketFromUrl(bucketUrl)
  35. if err != nil {
  36. return nil, err
  37. }
  38. bucket = info.bucket
  39. region = info.region
  40. }
  41. return NewS3Uploader(region, bucket, path, "public-read", accessKey, secretKey), nil
  42. case "webdav":
  43. webdavSec, err := setting.Raw.GetSection("external_image_storage.webdav")
  44. if err != nil {
  45. return nil, err
  46. }
  47. url := webdavSec.Key("url").String()
  48. if url == "" {
  49. return nil, fmt.Errorf("Could not find url key for image.uploader.webdav")
  50. }
  51. public_url := webdavSec.Key("public_url").String()
  52. username := webdavSec.Key("username").String()
  53. password := webdavSec.Key("password").String()
  54. return NewWebdavImageUploader(url, username, password, public_url)
  55. case "gcs":
  56. gcssec, err := setting.Raw.GetSection("external_image_storage.gcs")
  57. if err != nil {
  58. return nil, err
  59. }
  60. keyFile := gcssec.Key("key_file").MustString("")
  61. bucketName := gcssec.Key("bucket").MustString("")
  62. path := gcssec.Key("path").MustString("")
  63. return NewGCSUploader(keyFile, bucketName, path), nil
  64. case "azure_blob":
  65. azureBlobSec, err := setting.Raw.GetSection("external_image_storage.azure_blob")
  66. if err != nil {
  67. return nil, err
  68. }
  69. account_name := azureBlobSec.Key("account_name").MustString("")
  70. account_key := azureBlobSec.Key("account_key").MustString("")
  71. container_name := azureBlobSec.Key("container_name").MustString("")
  72. return NewAzureBlobUploader(account_name, account_key, container_name), nil
  73. case "local":
  74. return NewLocalImageUploader()
  75. }
  76. if setting.ImageUploadProvider != "" {
  77. log.Error2("The external image storage configuration is invalid", "unsupported provider", setting.ImageUploadProvider)
  78. }
  79. return NopImageUploader{}, nil
  80. }
  81. type s3Info struct {
  82. region string
  83. bucket string
  84. }
  85. func getRegionAndBucketFromUrl(url string) (*s3Info, error) {
  86. info := &s3Info{}
  87. urlRegex := regexp.MustCompile(`https?:\/\/(.*)\.s3(-([^.]+))?\.amazonaws\.com\/?`)
  88. matches := urlRegex.FindStringSubmatch(url)
  89. if len(matches) > 0 {
  90. info.bucket = matches[1]
  91. if matches[3] != "" {
  92. info.region = matches[3]
  93. } else {
  94. info.region = "us-east-1"
  95. }
  96. return info, nil
  97. }
  98. urlRegex2 := regexp.MustCompile(`https?:\/\/s3(-([^.]+))?\.amazonaws\.com\/(.*)?`)
  99. matches2 := urlRegex2.FindStringSubmatch(url)
  100. if len(matches2) > 0 {
  101. info.bucket = matches2[3]
  102. if matches2[2] != "" {
  103. info.region = matches2[2]
  104. } else {
  105. info.region = "us-east-1"
  106. }
  107. return info, nil
  108. }
  109. return nil, fmt.Errorf("Could not find bucket setting for image.uploader.s3")
  110. }