Skip to content

Commit 410b6c8

Browse files
authored
s3: storage class for files in result storage bucket (#402)
* s3: storage class for files in result storage bucket * s3: review fixes. add missed storage class * s3: review fixes, add tests for s3storageclass
1 parent c11b178 commit 410b6c8

File tree

4 files changed

+85
-19
lines changed

4 files changed

+85
-19
lines changed

config/awsconfig/awsconfig.go

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package awsconfig
22

33
import (
44
"flag"
5+
56
"github.com/aws/aws-sdk-go/aws"
67
"github.com/aws/aws-sdk-go/aws/credentials"
78
"github.com/aws/aws-sdk-go/aws/session"
@@ -90,6 +91,8 @@ func WithAWS(fs *flag.FlagSet, cb func() (*zap.Logger, bool)) imagor.Option {
9091
"Upload ACL for S3 Result Storage")
9192
s3ResultStorageExpiration = fs.Duration("s3-result-storage-expiration", 0,
9293
"S3 Result Storage expiration duration e.g. 24h. Default no expiration")
94+
s3StorageClass = fs.String("s3-storage-class", "STANDARD",
95+
"S3 File Storage Class. Available values: REDUCED_REDUNDANCY, STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER, DEEP_ARCHIVE. Default: STANDARD.")
9396

9497
_, _ = cb()
9598
)
@@ -160,6 +163,7 @@ func WithAWS(fs *flag.FlagSet, cb func() (*zap.Logger, bool)) imagor.Option {
160163
s3storage.WithACL(*s3StorageACL),
161164
s3storage.WithSafeChars(*s3SafeChars),
162165
s3storage.WithExpiration(*s3StorageExpiration),
166+
s3storage.WithStorageClass(*s3StorageClass),
163167
),
164168
)
165169
}
@@ -182,6 +186,7 @@ func WithAWS(fs *flag.FlagSet, cb func() (*zap.Logger, bool)) imagor.Option {
182186
s3storage.WithACL(*s3ResultStorageACL),
183187
s3storage.WithSafeChars(*s3SafeChars),
184188
s3storage.WithExpiration(*s3ResultStorageExpiration),
189+
s3storage.WithStorageClass(*s3StorageClass),
185190
),
186191
)
187192
}

config/awsconfig/awsconfig_test.go

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package awsconfig
22

33
import (
4+
"testing"
5+
46
"github.com/cshum/imagor"
57
"github.com/cshum/imagor/config"
68
"github.com/cshum/imagor/storage/s3storage"
79
"github.com/stretchr/testify/assert"
8-
"testing"
910
)
1011

1112
func TestS3Empty(t *testing.T) {
@@ -120,3 +121,44 @@ func TestS3SessionOverride(t *testing.T) {
120121
assert.Equal(t, "/bcda/", resultStorage.PathPrefix)
121122
assert.Equal(t, "!", resultStorage.SafeChars)
122123
}
124+
125+
func TestS3StorageClassWithResultStorageBucket(t *testing.T) {
126+
srv := config.CreateServer([]string{
127+
"-s3-storage-class", "asdf",
128+
"-s3-storage-bucket", "a",
129+
"-s3-result-storage-bucket", "b",
130+
}, WithAWS)
131+
app := srv.App.(*imagor.Imagor)
132+
storage := app.Storages[0].(*s3storage.S3Storage)
133+
assert.Equal(t, "STANDARD", storage.StorageClass)
134+
135+
}
136+
137+
func TestS3StorageClassWithoutResultStorageBucket(t *testing.T) {
138+
srv := config.CreateServer([]string{
139+
"-s3-storage-class", "asdf",
140+
"-s3-storage-bucket", "a",
141+
}, WithAWS)
142+
app := srv.App.(*imagor.Imagor)
143+
storage := app.Storages[0].(*s3storage.S3Storage)
144+
assert.Equal(t, "STANDARD", storage.StorageClass)
145+
146+
}
147+
148+
func TestS3StorageClass(t *testing.T) {
149+
srv := config.CreateServer([]string{
150+
"-s3-storage-class", "asdf",
151+
"-s3-storage-bucket", "a",
152+
}, WithAWS)
153+
app := srv.App.(*imagor.Imagor)
154+
storage := app.Storages[0].(*s3storage.S3Storage)
155+
assert.Equal(t, "STANDARD", storage.StorageClass)
156+
157+
srv = config.CreateServer([]string{
158+
"-s3-storage-class", "REDUCED_REDUNDANCY",
159+
"-s3-storage-bucket", "a",
160+
}, WithAWS)
161+
app = srv.App.(*imagor.Imagor)
162+
storage = app.Storages[0].(*s3storage.S3Storage)
163+
assert.Equal(t, "REDUCED_REDUNDANCY", storage.StorageClass)
164+
}

storage/s3storage/option.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package s3storage
22

33
import (
4-
"github.com/aws/aws-sdk-go/service/s3"
54
"strings"
65
"time"
6+
7+
"github.com/aws/aws-sdk-go/service/s3"
78
)
89

910
// Option S3Storage option
@@ -70,3 +71,18 @@ func WithExpiration(exp time.Duration) Option {
7071
}
7172
}
7273
}
74+
75+
// WithFileStorageClass with storage storage class option
76+
func WithStorageClass(storageClass string) Option {
77+
return func(h *S3Storage) {
78+
allowedStorageClasses := [6]string{"REDUCED_REDUNDANCY", "STANDARD_IA", "ONEZONE_IA",
79+
"INTELLIGENT_TIERING", "GLACIER", "DEEP_ARCHIVE"}
80+
h.StorageClass = "STANDARD"
81+
for _, allowedStorageClass := range allowedStorageClasses {
82+
if storageClass == allowedStorageClass {
83+
h.StorageClass = storageClass
84+
break
85+
}
86+
}
87+
}
88+
}

storage/s3storage/s3storage.go

+20-17
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,20 @@ package s3storage
22

33
import (
44
"context"
5+
"io"
6+
"net/http"
7+
"path/filepath"
8+
"strings"
9+
"sync"
10+
"time"
11+
512
"github.com/aws/aws-sdk-go/aws"
613
"github.com/aws/aws-sdk-go/aws/awserr"
714
"github.com/aws/aws-sdk-go/aws/session"
815
"github.com/aws/aws-sdk-go/service/s3"
916
"github.com/aws/aws-sdk-go/service/s3/s3manager"
1017
"github.com/cshum/imagor"
1118
"github.com/cshum/imagor/imagorpath"
12-
"io"
13-
"net/http"
14-
"path/filepath"
15-
"strings"
16-
"sync"
17-
"time"
1819
)
1920

2021
// S3Storage AWS S3 Storage implements imagor.Storage interface
@@ -24,11 +25,12 @@ type S3Storage struct {
2425
Downloader *s3manager.Downloader
2526
Bucket string
2627

27-
BaseDir string
28-
PathPrefix string
29-
ACL string
30-
SafeChars string
31-
Expiration time.Duration
28+
BaseDir string
29+
PathPrefix string
30+
ACL string
31+
SafeChars string
32+
StorageClass string
33+
Expiration time.Duration
3234

3335
safeChars imagorpath.SafeChars
3436
}
@@ -128,12 +130,13 @@ func (s *S3Storage) Put(ctx context.Context, image string, blob *imagor.Blob) er
128130
}()
129131
var metadata map[string]*string
130132
input := &s3manager.UploadInput{
131-
ACL: aws.String(s.ACL),
132-
Body: reader,
133-
Bucket: aws.String(s.Bucket),
134-
ContentType: aws.String(blob.ContentType()),
135-
Metadata: metadata,
136-
Key: aws.String(image),
133+
ACL: aws.String(s.ACL),
134+
Body: reader,
135+
Bucket: aws.String(s.Bucket),
136+
ContentType: aws.String(blob.ContentType()),
137+
Metadata: metadata,
138+
Key: aws.String(image),
139+
StorageClass: aws.String(s.StorageClass),
137140
}
138141
_, err = s.Uploader.UploadWithContext(ctx, input)
139142
return err

0 commit comments

Comments
 (0)