//go:build dev // +build dev package s3 import ( "context" "fmt" "io" "log" "os" "github.com/aws/aws-sdk-go-v2/aws" awsconfig "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" ) var Client Uploader type Uploader interface { Upload(ctx context.Context, bucket, key string, body io.Reader) error Download(ctx context.Context, bucket, key string, w io.Writer) error Delete(ctx context.Context, bucket, key string) error GetURL(ctx context.Context, bucket, key string) (string, error) } type S3Client struct { client *s3.Client bucket string publicURL string } func Connect() error { endpoint := os.Getenv("S3_ENDPOINT") if endpoint == "" { endpoint = "http://localhost:9000" } accessKey := os.Getenv("S3_ACCESS_KEY") if accessKey == "" { accessKey = "minioadmin" } secretKey := os.Getenv("S3_SECRET_KEY") if secretKey == "" { secretKey = "minioadmin" } bucket := os.Getenv("S3_BUCKET") if bucket == "" { bucket = "crussell" } region := os.Getenv("AWS_REGION") if region == "" { region = "us-east-1" } awsCfg, err := awsconfig.LoadDefaultConfig(context.Background(), awsconfig.WithRegion(region), awsconfig.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( accessKey, secretKey, "", )), ) if err != nil { return fmt.Errorf("failed to load AWS config: %w", err) } Client = &S3Client{ client: s3.NewFromConfig(awsCfg, func(o *s3.Options) { o.BaseEndpoint = aws.String(endpoint) o.UsePathStyle = true }), bucket: bucket, publicURL: endpoint, } log.Printf("Connected to local S3 (Rustfs): bucket=%s, endpoint=%s", bucket, endpoint) return nil } func (s *S3Client) Upload(ctx context.Context, bucket, key string, body io.Reader) error { _, err := s.client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), Body: body, }) return err } func (s *S3Client) Download(ctx context.Context, bucket, key string, w io.Writer) error { result, err := s.client.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }) if err != nil { return err } defer result.Body.Close() _, err = io.Copy(w, result.Body) return err } func (s *S3Client) Delete(ctx context.Context, bucket, key string) error { _, err := s.client.DeleteObject(ctx, &s3.DeleteObjectInput{ Bucket: aws.String(bucket), Key: aws.String(key), }) return err } func (s *S3Client) GetURL(ctx context.Context, bucket, key string) (string, error) { return fmt.Sprintf("%s/%s/%s", s.publicURL, bucket, key), nil }