Files

177 lines
4.6 KiB
Go

package miniohelper
import (
"context"
"errors"
"fmt"
"net/url"
"path"
m "simrs-vx/internal/infra/minio"
"github.com/minio/minio-go/v7"
)
type minioRepository struct {
client *minio.Client
}
var I minioRepository = minioRepository{}
func (repo *minioRepository) SetClient() {
repo.client = m.I
}
// Check exist bucket if not exist create Bucket
func (repo *minioRepository) createBucket(bucketName string, region string) error {
exist, err := repo.client.BucketExists(context.Background(), bucketName)
if err != nil {
return err
}
if !exist {
// create bucket
if err := repo.client.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: region}); err != nil {
return err
}
// set bucket policy to public read
policy := fmt.Sprintf(`{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"AWS": ["*"]},
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::%s/*"]
}
]
}`, bucketName)
if err := repo.client.SetBucketPolicy(context.Background(), bucketName, policy); err != nil {
return err
}
}
return nil
}
// Upload file reader to MinIO
func (repo *minioRepository) PutObject(input UploadReaderInput) (*minio.UploadInfo, error) {
if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
return nil, err
}
options := minio.PutObjectOptions{
ContentType: input.ContentType,
UserMetadata: map[string]string{"x-amz-acl": "public-read"},
}
uploadInfo, err := repo.client.PutObject(context.Background(), input.BucketName, input.Name, input.File, input.Size, options)
if err != nil {
return nil, err
}
return &uploadInfo, err
}
// Upload file path to MinIO
func (repo *minioRepository) FPutObject(input UploadPathInput) (*minio.UploadInfo, error) {
if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
return nil, err
}
options := minio.PutObjectOptions{
ContentType: input.ContentType,
UserMetadata: map[string]string{"x-amz-acl": "public-read"},
}
uploadInfo, err := repo.client.FPutObject(context.Background(), input.BucketName, input.Name, input.Path, options)
if err != nil {
return nil, err
}
return &uploadInfo, err
}
// Move file from old to new MinIO path
func (repo *minioRepository) MoveObject(src minio.CopySrcOptions, dst minio.CopyDestOptions) (*minio.UploadInfo, error) {
uploadInfo, err := repo.client.CopyObject(context.Background(), dst, src)
if err != nil {
return nil, err
}
if err := repo.RemoveObject(src.Bucket, src.Object); err != nil {
return nil, err
}
return &uploadInfo, err
}
// Generatet public link MinIO
func (repo *minioRepository) GenerateUrl(bucket, object string) string {
mode := "http"
if m.O.GetUseSsl() {
mode = "https"
}
return fmt.Sprintf("%s://%s/%s/%s", mode, m.O.GetEndpoint(), bucket, object)
}
// Download file from MinIO
func (repo *minioRepository) GetObject(bucket string, fileName string) (*minio.Object, error) {
object, err := repo.client.GetObject(context.Background(), bucket, fileName, minio.GetObjectOptions{})
if err != nil {
return nil, err
}
return object, nil
}
// Delete file from MinIO
func (repo *minioRepository) RemoveObject(bucket string, fileName string) error {
if err := repo.client.RemoveObject(context.Background(), bucket, fileName, minio.RemoveObjectOptions{}); err != nil {
return err
}
return nil
}
// create presigned url to post object with custom policy
func (repo *minioRepository) GeneratePresignedPost(policy *minio.PostPolicy) (*url.URL, map[string]string, error) {
presignedUrl, formData, err := repo.client.PresignedPostPolicy(context.Background(), policy)
if err != nil {
return nil, nil, err
}
return presignedUrl, formData, nil
}
// create presigned url to get object
func (repo *minioRepository) GeneratePresignedGetObject(input PresignedGetInput) (*url.URL, error) {
presignedUrl, err := repo.client.PresignedGetObject(context.Background(), input.Bucket, input.Object, input.Expiry, input.ReqParams)
if err != nil {
return nil, err
}
return presignedUrl, nil
}
func getBucketName(idx int) string {
return m.O.GetBucketName()[idx]
}
func GetBucketPatient() (string, error) {
bucketName := getBucketName(0)
if bucketName == "" {
return "", errors.New("bucket name unknown")
}
return bucketName, nil
}
func GetEndpointUrl(bucket string) string {
mode := "http"
if m.O.GetUseSsl() {
mode = "https"
}
return fmt.Sprintf("%s://%s/%s", mode, m.O.GetEndpoint(), bucket)
}
func GetFilename(rawUrl string) (string, error) {
parsed, err := url.Parse(rawUrl)
if err != nil {
return "", err
}
return path.Base(parsed.Path), nil
}