-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AWS S3 driver for BLOB CAS repository (#15)
Signed-off-by: Igor Shishkin <me@teran.dev>
- Loading branch information
Showing
7 changed files
with
228 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/s3" | ||
"github.com/pkg/errors" | ||
|
||
"github.com/teran/archived/repositories/blob" | ||
) | ||
|
||
var _ blob.Repository = (*s3driver)(nil) | ||
|
||
type s3driver struct { | ||
cli *s3.S3 | ||
bucket string | ||
ttl time.Duration | ||
} | ||
|
||
func New(cli *s3.S3, bucket string, ttl time.Duration) blob.Repository { | ||
return &s3driver{ | ||
cli: cli, | ||
bucket: bucket, | ||
ttl: ttl, | ||
} | ||
} | ||
|
||
func (s *s3driver) PutBlob(ctx context.Context, key string, rd io.ReadSeeker) error { | ||
_, err := s.cli.PutObject(&s3.PutObjectInput{ | ||
Body: rd, | ||
Bucket: aws.String(s.bucket), | ||
Key: aws.String(key), | ||
}) | ||
return errors.Wrap(err, "error putting object") | ||
} | ||
|
||
func (s *s3driver) GetBlobURL(ctx context.Context, key string) (string, error) { | ||
req, _ := s.cli.GetObjectRequest(&s3.GetObjectInput{ | ||
Bucket: aws.String(s.bucket), | ||
Key: aws.String(key), | ||
}) | ||
|
||
url, err := req.Presign(s.ttl) | ||
if err != nil { | ||
return "", errors.Wrap(err, "error signing URL") | ||
} | ||
|
||
return url, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package aws | ||
|
||
import ( | ||
"context" | ||
"io" | ||
"net/http" | ||
"strings" | ||
"testing" | ||
"time" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"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/stretchr/testify/suite" | ||
"github.com/teran/archived/repositories/blob" | ||
"github.com/teran/go-docker-testsuite/applications/minio" | ||
) | ||
|
||
func (s *repoTestSuite) TestAll() { | ||
err := s.driver.PutBlob(s.ctx, "blah/test/key.txt", strings.NewReader("test data")) | ||
s.Require().NoError(err) | ||
|
||
url, err := s.driver.GetBlobURL(s.ctx, "blah/test/key.txt") | ||
s.Require().NoError(err) | ||
|
||
data, err := fetchURL(s.ctx, url) | ||
s.Require().NoError(err) | ||
s.Require().Equal("test data", string(data)) | ||
} | ||
|
||
// Definitions ... | ||
type repoTestSuite struct { | ||
suite.Suite | ||
|
||
ctx context.Context | ||
cli *s3.S3 | ||
driver blob.Repository | ||
minio minio.Minio | ||
} | ||
|
||
func (s *repoTestSuite) SetupSuite() { | ||
s.ctx = context.Background() | ||
|
||
app, err := minio.New(s.ctx) | ||
s.Require().NoError(err) | ||
|
||
s.minio = app | ||
} | ||
|
||
func (s *repoTestSuite) SetupTest() { | ||
endpoint, err := s.minio.GetEndpointURL() | ||
s.Require().NoError(err) | ||
|
||
sess, err := session.NewSession(&aws.Config{ | ||
Endpoint: aws.String(endpoint), | ||
Region: aws.String("default"), | ||
DisableSSL: aws.Bool(true), | ||
S3ForcePathStyle: aws.Bool(true), | ||
Credentials: credentials.NewStaticCredentials( | ||
minio.MinioAccessKey, minio.MinioAccessKeySecret, "", | ||
), | ||
}) | ||
s.Require().NoError(err) | ||
|
||
s.cli = s3.New(sess) | ||
|
||
_, err = s.cli.CreateBucket(&s3.CreateBucketInput{ | ||
Bucket: aws.String("test-bucket"), | ||
}) | ||
s.Require().NoError(err) | ||
|
||
s.driver = New(s.cli, "test-bucket", 5*time.Second) | ||
} | ||
|
||
func (s *repoTestSuite) TearDownTest() { | ||
out, err := s.cli.ListObjects(&s3.ListObjectsInput{ | ||
Bucket: aws.String("test-bucket"), | ||
}) | ||
s.Require().NoError(err) | ||
|
||
for _, obj := range out.Contents { | ||
_, err := s.cli.DeleteObject(&s3.DeleteObjectInput{ | ||
Bucket: aws.String("test-bucket"), | ||
Key: obj.Key, | ||
}) | ||
s.Require().NoError(err) | ||
} | ||
|
||
_, err = s.cli.DeleteBucket(&s3.DeleteBucketInput{ | ||
Bucket: aws.String("test-bucket"), | ||
}) | ||
s.Require().NoError(err) | ||
} | ||
|
||
func (s *repoTestSuite) TearDownSuite() { | ||
err := s.minio.Close(s.ctx) | ||
s.Require().NoError(err) | ||
} | ||
|
||
func TestRepoTestSuite(t *testing.T) { | ||
suite.Run(t, &repoTestSuite{}) | ||
} | ||
|
||
func fetchURL(ctx context.Context, url string) ([]byte, error) { | ||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp, err := http.DefaultClient.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
return io.ReadAll(resp.Body) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters