gcsuploader.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package imguploader
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "os"
  9. "github.com/grafana/grafana/pkg/log"
  10. "github.com/grafana/grafana/pkg/util"
  11. "golang.org/x/oauth2/google"
  12. )
  13. type GCSUploader struct {
  14. keyFile string
  15. bucket string
  16. log log.Logger
  17. }
  18. func NewGCSUploader(keyFile, bucket string) *GCSUploader {
  19. return &GCSUploader{
  20. keyFile: keyFile,
  21. bucket: bucket,
  22. log: log.New("gcsuploader"),
  23. }
  24. }
  25. func (u *GCSUploader) Upload(ctx context.Context, imageDiskPath string) (string, error) {
  26. key := util.GetRandomString(20) + ".png"
  27. log.Debug("Opening key file ", u.keyFile)
  28. data, err := ioutil.ReadFile(u.keyFile)
  29. if err != nil {
  30. return "", err
  31. }
  32. log.Debug("Creating JWT conf")
  33. conf, err := google.JWTConfigFromJSON(data, "https://www.googleapis.com/auth/devstorage.read_write")
  34. if err != nil {
  35. return "", err
  36. }
  37. log.Debug("Creating HTTP client")
  38. client := conf.Client(ctx)
  39. err = u.uploadFile(client, imageDiskPath, key)
  40. if err != nil {
  41. return "", err
  42. }
  43. return fmt.Sprintf("https://storage.googleapis.com/%s/%s", u.bucket, key), nil
  44. }
  45. func (u *GCSUploader) uploadFile(client *http.Client, imageDiskPath, key string) error {
  46. log.Debug("Opening image file ", imageDiskPath)
  47. fileReader, err := os.Open(imageDiskPath)
  48. if err != nil {
  49. return err
  50. }
  51. reqUrl := fmt.Sprintf(
  52. "https://www.googleapis.com/upload/storage/v1/b/%s/o?uploadType=media&name=%s&predefinedAcl=publicRead",
  53. u.bucket,
  54. key,
  55. )
  56. log.Debug("Request URL: ", reqUrl)
  57. req, err := http.NewRequest("POST", reqUrl, fileReader)
  58. if err != nil {
  59. return err
  60. }
  61. req.Header.Add("Content-Type", "image/png")
  62. log.Debug("Sending POST request to GCS")
  63. resp, err := client.Do(req)
  64. if err != nil {
  65. return err
  66. }
  67. log.Debug("GCS API response header", resp.Header)
  68. if resp.StatusCode != 200 {
  69. return errors.New(fmt.Sprintf("GCS response status code %d", resp.StatusCode))
  70. }
  71. return nil
  72. }