imguploader.go 2.5 KB

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