s3uploader.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package imguploader
  2. import (
  3. "context"
  4. "os"
  5. "time"
  6. "github.com/aws/aws-sdk-go/aws"
  7. "github.com/aws/aws-sdk-go/aws/credentials"
  8. "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
  9. "github.com/aws/aws-sdk-go/aws/ec2metadata"
  10. "github.com/aws/aws-sdk-go/aws/session"
  11. "github.com/aws/aws-sdk-go/service/s3"
  12. "github.com/grafana/grafana/pkg/log"
  13. "github.com/grafana/grafana/pkg/util"
  14. )
  15. type S3Uploader struct {
  16. region string
  17. bucket string
  18. acl string
  19. secretKey string
  20. accessKey string
  21. log log.Logger
  22. }
  23. func NewS3Uploader(region, bucket, acl, accessKey, secretKey string) *S3Uploader {
  24. return &S3Uploader{
  25. region: region,
  26. bucket: bucket,
  27. acl: acl,
  28. accessKey: accessKey,
  29. secretKey: secretKey,
  30. log: log.New("s3uploader"),
  31. }
  32. }
  33. func (u *S3Uploader) Upload(ctx context.Context, imageDiskPath string) (string, error) {
  34. sess, err := session.NewSession()
  35. if err != nil {
  36. return "", err
  37. }
  38. creds := credentials.NewChainCredentials(
  39. []credentials.Provider{
  40. &credentials.StaticProvider{Value: credentials.Value{
  41. AccessKeyID: u.accessKey,
  42. SecretAccessKey: u.secretKey,
  43. }},
  44. &credentials.EnvProvider{},
  45. &ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
  46. })
  47. cfg := &aws.Config{
  48. Region: aws.String(u.region),
  49. Credentials: creds,
  50. }
  51. key := util.GetRandomString(20) + ".png"
  52. log.Debug("Uploading image to s3", "bucket = ", u.bucket, ", key = ", key)
  53. file, err := os.Open(imageDiskPath)
  54. if err != nil {
  55. return "", err
  56. }
  57. sess, err = session.NewSession(cfg)
  58. if err != nil {
  59. return "", err
  60. }
  61. svc := s3.New(sess, cfg)
  62. params := &s3.PutObjectInput{
  63. Bucket: aws.String(u.bucket),
  64. Key: aws.String(key),
  65. ACL: aws.String(u.acl),
  66. Body: file,
  67. ContentType: aws.String("image/png"),
  68. }
  69. _, err = svc.PutObject(params)
  70. if err != nil {
  71. return "", err
  72. }
  73. if u.region == "us-east-1" {
  74. return "https://" + u.bucket + ".s3.amazonaws.com/" + key, nil
  75. } else {
  76. return "https://" + u.bucket + ".s3-" + u.region + ".amazonaws.com/" + key, nil
  77. }
  78. }