You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
2.5 KiB
82 lines
2.5 KiB
package storage
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/url"
|
|
"time"
|
|
|
|
"github.com/minio/minio-go/v7"
|
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
|
"github.com/youruser/base/internal/config"
|
|
)
|
|
|
|
type MinIOStorage struct {
|
|
client *minio.Client
|
|
bucket string
|
|
}
|
|
|
|
func NewMinIOStorage(cfg config.MinIOStorageConfig) (*MinIOStorage, error) {
|
|
if cfg.Endpoint == "" || cfg.AccessKeyId == "" || cfg.AccessKeySecret == "" || cfg.Bucket == "" {
|
|
return nil, fmt.Errorf("MinIO config incomplete: endpoint, accessKeyId, accessKeySecret, bucket are required")
|
|
}
|
|
client, err := minio.New(cfg.Endpoint, &minio.Options{
|
|
Creds: credentials.NewStaticV4(cfg.AccessKeyId, cfg.AccessKeySecret, ""),
|
|
Secure: cfg.UseSSL,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create MinIO client: %w", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
exists, err := client.BucketExists(ctx, cfg.Bucket)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to check MinIO bucket: %w", err)
|
|
}
|
|
if !exists {
|
|
if err := client.MakeBucket(ctx, cfg.Bucket, minio.MakeBucketOptions{}); err != nil {
|
|
return nil, fmt.Errorf("failed to create MinIO bucket: %w", err)
|
|
}
|
|
}
|
|
|
|
return &MinIOStorage{client: client, bucket: cfg.Bucket}, nil
|
|
}
|
|
|
|
func (s *MinIOStorage) Upload(ctx context.Context, key string, reader io.Reader, size int64, contentType string) error {
|
|
opts := minio.PutObjectOptions{
|
|
ContentType: contentType,
|
|
}
|
|
if _, err := s.client.PutObject(ctx, s.bucket, key, reader, size, opts); err != nil {
|
|
return fmt.Errorf("failed to upload to MinIO: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *MinIOStorage) Delete(ctx context.Context, key string) error {
|
|
if err := s.client.RemoveObject(ctx, s.bucket, key, minio.RemoveObjectOptions{}); err != nil {
|
|
return fmt.Errorf("failed to delete from MinIO: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *MinIOStorage) GetURL(ctx context.Context, key string) (string, error) {
|
|
reqParams := make(url.Values)
|
|
presignedURL, err := s.client.PresignedGetObject(ctx, s.bucket, key, time.Hour, reqParams)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to generate MinIO presigned URL: %w", err)
|
|
}
|
|
return presignedURL.String(), nil
|
|
}
|
|
|
|
func (s *MinIOStorage) Exists(ctx context.Context, key string) (bool, error) {
|
|
_, err := s.client.StatObject(ctx, s.bucket, key, minio.StatObjectOptions{})
|
|
if err != nil {
|
|
errResponse := minio.ToErrorResponse(err)
|
|
if errResponse.Code == "NoSuchKey" {
|
|
return false, nil
|
|
}
|
|
return false, fmt.Errorf("failed to check MinIO object: %w", err)
|
|
}
|
|
return true, nil
|
|
}
|
|
|