imguploader.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. path := s3sec.Key("path").MustString("")
  26. bucketUrl := s3sec.Key("bucket_url").MustString("")
  27. accessKey := s3sec.Key("access_key").MustString("")
  28. secretKey := s3sec.Key("secret_key").MustString("")
  29. if path != "" && path[len(path)-1:] != "/" {
  30. path += "/"
  31. }
  32. if bucket == "" || region == "" {
  33. info, err := getRegionAndBucketFromUrl(bucketUrl)
  34. if err != nil {
  35. return nil, err
  36. }
  37. bucket = info.bucket
  38. region = info.region
  39. }
  40. return NewS3Uploader(region, bucket, path, "public-read", accessKey, secretKey), nil
  41. case "webdav":
  42. webdavSec, err := setting.Cfg.GetSection("external_image_storage.webdav")
  43. if err != nil {
  44. return nil, err
  45. }
  46. url := webdavSec.Key("url").String()
  47. if url == "" {
  48. return nil, fmt.Errorf("Could not find url key for image.uploader.webdav")
  49. }
  50. public_url := webdavSec.Key("public_url").String()
  51. username := webdavSec.Key("username").String()
  52. password := webdavSec.Key("password").String()
  53. return NewWebdavImageUploader(url, username, password, public_url)
  54. case "gcs":
  55. gcssec, err := setting.Cfg.GetSection("external_image_storage.gcs")
  56. if err != nil {
  57. return nil, err
  58. }
  59. keyFile := gcssec.Key("key_file").MustString("")
  60. bucketName := gcssec.Key("bucket").MustString("")
  61. return NewGCSUploader(keyFile, bucketName), nil
  62. }
  63. return NopImageUploader{}, nil
  64. }
  65. type s3Info struct {
  66. region string
  67. bucket string
  68. }
  69. func getRegionAndBucketFromUrl(url string) (*s3Info, error) {
  70. info := &s3Info{}
  71. urlRegex := regexp.MustCompile(`https?:\/\/(.*)\.s3(-([^.]+))?\.amazonaws\.com\/?`)
  72. matches := urlRegex.FindStringSubmatch(url)
  73. if len(matches) > 0 {
  74. info.bucket = matches[1]
  75. if matches[3] != "" {
  76. info.region = matches[3]
  77. } else {
  78. info.region = "us-east-1"
  79. }
  80. return info, nil
  81. }
  82. urlRegex2 := regexp.MustCompile(`https?:\/\/s3(-([^.]+))?\.amazonaws\.com\/(.*)?`)
  83. matches2 := urlRegex2.FindStringSubmatch(url)
  84. if len(matches2) > 0 {
  85. info.bucket = matches2[3]
  86. if matches2[2] != "" {
  87. info.region = matches2[2]
  88. } else {
  89. info.region = "us-east-1"
  90. }
  91. return info, nil
  92. }
  93. return nil, fmt.Errorf("Could not find bucket setting for image.uploader.s3")
  94. }