/
data_client.go
79 lines (70 loc) · 2.24 KB
/
data_client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package aws
import (
"context"
"io"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/sns"
"github.com/pkg/errors"
)
const (
//StatusCodeForbidden is returned by AWS when a user does not have access to perform a given operation
StatusCodeForbidden = "Forbidden"
)
//DataClient is a client to AWS' S3 service. The client implements the v1data.DataOps interface.
type DataClient struct {
Service *s3.S3
}
//NewDataClient creates a new DataClient.
func NewDataClient(c *credentials.Credentials, region string) (*DataClient, error) {
sess, err := session.NewSession(&aws.Config{
Credentials: c,
Region: aws.String(region),
})
if err != nil {
return nil, errors.Wrap(err, "could not create AWS sessions")
}
return &DataClient{
Service: s3.New(sess),
}, nil
}
//Upload uploads an object to S3.
func (c *DataClient) Upload(ctx context.Context, bucket, key string, body io.ReadSeeker) error {
input := &s3.PutObjectInput{
Bucket: aws.String(bucket), // Required
Key: aws.String(key), // Required
Body: body,
}
_, err := c.Service.PutObjectWithContext(ctx, input)
return err
}
//Download downloads an object to S3.
func (c *DataClient) Download(ctx context.Context, bucket, key string) (body io.ReadCloser, err error) {
input := &s3.GetObjectInput{
Bucket: aws.String(bucket), // Required
Key: aws.String(key), // Required
}
resp, err := c.Service.GetObjectWithContext(ctx, input)
if err != nil {
return nil, err
}
return resp.Body, nil
}
//Exists checks whether an object exists on S3.
func (c *DataClient) Exists(ctx context.Context, bucket, key string) (exists bool, err error) {
input := &s3.HeadObjectInput{
Bucket: aws.String(bucket), // Required
Key: aws.String(key),
}
_, err = c.Service.HeadObjectWithContext(ctx, input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok && (aerr.Code() == s3.ErrCodeNoSuchKey || aerr.Code() == sns.ErrCodeNotFoundException || aerr.Code() == StatusCodeForbidden) {
return false, nil
}
return false, errors.Wrapf(err, "failed to check if key %v exists", key)
}
return true, nil
}