imguploader.go 2.6 KB

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