imguploader.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package imguploader
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/grafana/grafana/pkg/log"
  6. "regexp"
  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.Cfg.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.Cfg.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.Cfg.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.Cfg.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. }
  74. if setting.ImageUploadProvider != "" {
  75. log.Error2("The external image storage configuration is invalid", "unsupported provider", setting.ImageUploadProvider)
  76. }
  77. return NopImageUploader{}, nil
  78. }
  79. type s3Info struct {
  80. region string
  81. bucket string
  82. }
  83. func getRegionAndBucketFromUrl(url string) (*s3Info, error) {
  84. info := &s3Info{}
  85. urlRegex := regexp.MustCompile(`https?:\/\/(.*)\.s3(-([^.]+))?\.amazonaws\.com\/?`)
  86. matches := urlRegex.FindStringSubmatch(url)
  87. if len(matches) > 0 {
  88. info.bucket = matches[1]
  89. if matches[3] != "" {
  90. info.region = matches[3]
  91. } else {
  92. info.region = "us-east-1"
  93. }
  94. return info, nil
  95. }
  96. urlRegex2 := regexp.MustCompile(`https?:\/\/s3(-([^.]+))?\.amazonaws\.com\/(.*)?`)
  97. matches2 := urlRegex2.FindStringSubmatch(url)
  98. if len(matches2) > 0 {
  99. info.bucket = matches2[3]
  100. if matches2[2] != "" {
  101. info.region = matches2[2]
  102. } else {
  103. info.region = "us-east-1"
  104. }
  105. return info, nil
  106. }
  107. return nil, fmt.Errorf("Could not find bucket setting for image.uploader.s3")
  108. }