-
Notifications
You must be signed in to change notification settings - Fork 18
/
s3.go
131 lines (119 loc) · 3.51 KB
/
s3.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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package helpers
import (
"context"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
awsConfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/rotisserie/eris"
)
type S3TestSuite struct {
BaseTestSuite
Client *s3.Client
testBuckets []string
}
// NewS3TestSuite creates a new instance of S3TestSuite.
func NewS3TestSuite(testBuckets ...string) S3TestSuite {
return S3TestSuite{
testBuckets: testBuckets,
}
}
func (s *S3TestSuite) SetupSuite() {
s.BaseTestSuite.SetupSuite()
client, err := NewS3Client(GetS3EndpointUri())
s.Require().Nil(err)
s.Client = client
s.AddSetupHook(func() {
s.Require().Nil(s.CreateTestBuckets())
})
s.AddTearDownHook(func() {
s.Require().Nil(s.DeleteTestBuckets())
})
}
// NewS3Client creates new instance of S3 client.
func NewS3Client(endpoint string) (*s3.Client, error) {
cfg, err := awsConfig.LoadDefaultConfig(context.Background(), awsConfig.WithEndpointResolverWithOptions(
aws.EndpointResolverWithOptionsFunc(
func(service, region string, options ...interface{}) (aws.Endpoint, error) {
if service == s3.ServiceID {
return aws.Endpoint{
URL: endpoint,
SigningRegion: region,
}, nil
}
return aws.Endpoint{}, eris.Errorf("unknown endpoint requested for the service: %s", service)
},
),
))
if err != nil {
return nil, eris.Wrap(err, "error loading configuration for S3 client")
}
return s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
}), nil
}
// CreateTestBuckets creates the test buckets.
func (s *S3TestSuite) CreateTestBuckets() error {
for _, bucket := range s.testBuckets {
_, err := s.Client.CreateBucket(context.Background(), &s3.CreateBucketInput{
Bucket: aws.String(bucket),
})
if err != nil {
return eris.Wrapf(err, "failed to create bucket %q", bucket)
}
}
return nil
}
// DeleteTestBuckets deletes the test buckets.
func (s *S3TestSuite) DeleteTestBuckets() error {
for _, bucket := range s.testBuckets {
if err := s.deleteBucket(bucket); err != nil {
return eris.Wrapf(err, "failed to delete bucket %q", bucket)
}
}
return nil
}
// deleteBucket deletes a bucket and its objects.
func (s *S3TestSuite) deleteBucket(bucket string) error {
// Delete all objects in the bucket
var objectIDs []types.ObjectIdentifier
paginator := s3.NewListObjectsV2Paginator(s.Client, &s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
})
for paginator.HasMorePages() {
page, err := paginator.NextPage(context.Background())
if err != nil {
return eris.Wrapf(err, "failed to list objects in bucket %q", bucket)
}
for _, object := range page.Contents {
objectIDs = append(objectIDs, types.ObjectIdentifier{Key: object.Key})
}
}
if len(objectIDs) > 0 {
_, err := s.Client.DeleteObjects(context.Background(), &s3.DeleteObjectsInput{
Bucket: aws.String(bucket),
Delete: &types.Delete{Objects: objectIDs},
})
if err != nil {
return eris.Wrapf(err, "failed to delete objects in bucket %q", bucket)
}
}
// Delete the bucket
if _, err := s.Client.DeleteBucket(context.Background(), &s3.DeleteBucketInput{
Bucket: aws.String(bucket),
}); err != nil {
return eris.Wrapf(err, "failed to delete bucket %q", bucket)
}
waiter := s3.NewBucketNotExistsWaiter(s.Client)
if err := waiter.Wait(
context.Background(),
&s3.HeadBucketInput{
Bucket: aws.String(bucket),
},
time.Second*10,
); err != nil {
return eris.Wrapf(err, "failed to wait for bucket %q deletion", bucket)
}
return nil
}