From 1cf561711105225f3abcb43d6741374053a8e35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Eduardo=20Jer=C3=A9z=20Gir=C3=B3n?= Date: Fri, 19 Jul 2024 23:16:10 -0600 Subject: [PATCH] Add S3 integration for uploading files to dynamic buckets --- internal/integration/integration.go | 8 ++++- internal/integration/s3/s3.go | 50 +++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 internal/integration/s3/s3.go diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 4bad90b..5f4b528 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -1,15 +1,21 @@ package integration -import "github.com/eduardolat/pgbackweb/internal/integration/pgdump" +import ( + "github.com/eduardolat/pgbackweb/internal/integration/pgdump" + "github.com/eduardolat/pgbackweb/internal/integration/s3" +) type Integration struct { PGDumpClient *pgdump.Client + S3Client *s3.Client } func New() *Integration { pgdumpClient := pgdump.New() + s3Client := s3.New() return &Integration{ PGDumpClient: pgdumpClient, + S3Client: s3Client, } } diff --git a/internal/integration/s3/s3.go b/internal/integration/s3/s3.go new file mode 100644 index 0000000..80cb90d --- /dev/null +++ b/internal/integration/s3/s3.go @@ -0,0 +1,50 @@ +package s3 + +import ( + "bytes" + "fmt" + + "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/eduardolat/pgbackweb/internal/util/strutil" +) + +type Client struct{} + +func New() *Client { + return &Client{} +} + +func (c *Client) Upload( + accessKey, secretKey, region, endpoint, bucketName, key string, + fileContent []byte, +) (string, error) { + sess, err := session.NewSession(&aws.Config{ + Credentials: credentials.NewStaticCredentials(accessKey, secretKey, ""), + Region: aws.String(region), + Endpoint: aws.String(endpoint), + S3ForcePathStyle: aws.Bool(true), + }) + if err != nil { + return "", fmt.Errorf("failed to create aws session: %w", err) + } + + s3Client := s3.New(sess) + reader := bytes.NewReader(fileContent) + key = strutil.RemoveLeadingSlash(key) + contentType := strutil.GetContentTypeFromFileName(key) + + _, err = s3Client.PutObject(&s3.PutObjectInput{ + Bucket: aws.String(bucketName), + Key: aws.String(key), + Body: aws.ReadSeekCloser(reader), + ContentType: aws.String(contentType), + }) + if err != nil { + return "", fmt.Errorf("failed to upload file to S3: %w", err) + } + + return fmt.Sprintf("s3://%s/%s", bucketName, key), nil +}