2019-05-24 22:03:06 +00:00
|
|
|
package storage
|
2015-07-06 19:41:21 +00:00
|
|
|
|
|
|
|
import (
|
2015-07-06 23:01:14 +00:00
|
|
|
"bytes"
|
2015-07-06 19:41:21 +00:00
|
|
|
"io/ioutil"
|
2019-05-24 22:03:06 +00:00
|
|
|
"net/url"
|
|
|
|
"path"
|
2015-07-06 19:41:21 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
2017-11-22 20:42:00 +00:00
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
2015-07-06 19:41:21 +00:00
|
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
|
|
|
)
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// S3Storage is a storage adapter storing the data into single S3 files
|
2015-07-06 19:41:21 +00:00
|
|
|
type S3Storage struct {
|
|
|
|
s3connection *s3.S3
|
2019-05-24 22:03:06 +00:00
|
|
|
bucket string
|
|
|
|
prefix string
|
2015-07-06 19:41:21 +00:00
|
|
|
}
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// NewS3Storage instanciates a new S3Storage
|
2019-05-24 22:03:06 +00:00
|
|
|
func NewS3Storage(uri *url.URL) *S3Storage {
|
2017-11-22 20:42:00 +00:00
|
|
|
s3connection := s3.New(session.Must(session.NewSession()))
|
2015-07-06 19:41:21 +00:00
|
|
|
return &S3Storage{
|
|
|
|
s3connection: s3connection,
|
2019-05-24 22:03:06 +00:00
|
|
|
bucket: uri.Host,
|
|
|
|
prefix: uri.Path,
|
2015-07-06 19:41:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// Put writes the given data to S3
|
2015-07-06 19:41:21 +00:00
|
|
|
func (s *S3Storage) Put(dashboardID string, data []byte) error {
|
|
|
|
_, err := s.s3connection.PutObject(&s3.PutObjectInput{
|
2019-05-24 22:03:06 +00:00
|
|
|
Bucket: aws.String(s.bucket),
|
2015-07-06 19:41:21 +00:00
|
|
|
ContentType: aws.String("application/json"),
|
2019-05-24 22:03:06 +00:00
|
|
|
Key: s.getKey(dashboardID),
|
2015-07-06 23:01:14 +00:00
|
|
|
Body: bytes.NewReader(data),
|
|
|
|
ACL: aws.String("private"),
|
2015-07-06 19:41:21 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// Get loads the data for the given dashboard from S3
|
2015-07-06 19:41:21 +00:00
|
|
|
func (s *S3Storage) Get(dashboardID string) ([]byte, error) {
|
|
|
|
res, err := s.s3connection.GetObject(&s3.GetObjectInput{
|
2019-05-24 22:03:06 +00:00
|
|
|
Bucket: aws.String(s.bucket),
|
|
|
|
Key: s.getKey(dashboardID),
|
2015-07-06 19:41:21 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
data, err := ioutil.ReadAll(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// Delete deletes the given dashboard from S3
|
2015-07-06 19:41:21 +00:00
|
|
|
func (s *S3Storage) Delete(dashboardID string) error {
|
|
|
|
_, err := s.s3connection.DeleteObject(&s3.DeleteObjectInput{
|
2019-05-24 22:03:06 +00:00
|
|
|
Bucket: aws.String(s.bucket),
|
|
|
|
Key: s.getKey(dashboardID),
|
2015-07-06 19:41:21 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-07-06 19:44:13 +00:00
|
|
|
// Exists checks for the existence of the given dashboard
|
2015-07-06 19:41:21 +00:00
|
|
|
func (s *S3Storage) Exists(dashboardID string) (bool, error) {
|
|
|
|
_, err := s.s3connection.HeadObject(&s3.HeadObjectInput{
|
2019-05-24 22:03:06 +00:00
|
|
|
Bucket: aws.String(s.bucket),
|
|
|
|
Key: s.getKey(dashboardID),
|
2015-07-06 19:41:21 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if awsErr, ok := err.(awserr.Error); ok {
|
|
|
|
if strings.Contains(awsErr.Error(), "status code: 404") {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return false, err
|
|
|
|
}
|
2015-07-06 19:44:13 +00:00
|
|
|
return false, err
|
2015-07-06 19:41:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
}
|
2019-05-24 22:03:06 +00:00
|
|
|
|
|
|
|
func (s S3Storage) getKey(dashboardID string) *string {
|
|
|
|
p := path.Join(s.prefix, dashboardID)
|
|
|
|
return aws.String(strings.TrimLeft(p, "/"))
|
|
|
|
}
|