gcsuploader.go 1.9 KB

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