package s3 import ( "context" "io" "git.kapelle.org/niklas/s3browser/internal/types" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) type minioS3 struct { client *minio.Client } func NewMinio(config types.AppConfig) (S3Service, error) { client, err := minio.New(config.S3Endoint, &minio.Options{ Creds: credentials.NewStaticV4(config.S3AccessKey, config.S3SecretKey, ""), Secure: config.S3SSL, }) if err != nil { return nil, err } return &minioS3{ client: client, }, nil } func (m *minioS3) ListBuckets(ctx context.Context) ([]Bucket, error) { buckets, err := m.client.ListBuckets(ctx) if err != nil { return nil, err } var rtn []Bucket for _, v := range buckets { rtn = append(rtn, Bucket(v.Name)) } return rtn, nil } func (m *minioS3) ListObjects(ctx context.Context, id types.ID) ([]types.File, []types.Directory, error) { var files []types.File var dirs []types.Directory for objInfo := range m.client.ListObjects(ctx, id.Bucket, minio.ListObjectsOptions{}) { objId := types.ID{ Bucket: id.Bucket, Key: objInfo.Key, } objId.Normalize() if objId.IsDirectory() { dirs = append(dirs, *obkInfoToDir(objInfo, objId)) } else { files = append(files, *objInfoToFile(objInfo, objId)) } } return files, dirs, nil } func (m *minioS3) GetObject(ctx context.Context, id types.ID) (Object, error) { object, err := m.client.GetObject(ctx, id.Bucket, id.Key, minio.GetObjectOptions{}) if err != nil { return nil, err } return object, nil } func (m *minioS3) PutObject(ctx context.Context, id types.ID, reader io.Reader, objectSize int64) error { _, err := m.client.PutObject(ctx, id.Bucket, id.Key, reader, objectSize, minio.PutObjectOptions{}) return err } func (m *minioS3) CopyObject(ctx context.Context, src types.ID, dest types.ID) error { _, err := m.client.CopyObject(ctx, minio.CopyDestOptions{ Bucket: dest.Bucket, Object: dest.Key, }, minio.CopySrcOptions{ Bucket: src.Bucket, Object: src.Key, }) return err } func (m *minioS3) StatObject(ctx context.Context, id types.ID) (*types.File, error) { info, err := m.client.StatObject(ctx, id.Bucket, id.Key, minio.GetObjectOptions{}) if err != nil { return nil, err } return objInfoToFile(info, id), nil } func (m *minioS3) RemoveObject(ctx context.Context, id types.ID) error { return m.client.RemoveObject(ctx, id.Bucket, id.Key, minio.RemoveObjectOptions{}) } func objInfoToFile(objInfo minio.ObjectInfo, id types.ID) *types.File { return &types.File{ ID: id, Name: id.Name(), Size: objInfo.Size, ContentType: objInfo.ContentType, ETag: objInfo.ETag, LastModified: objInfo.LastModified, } } func obkInfoToDir(objInfo minio.ObjectInfo, id types.ID) *types.Directory { return &types.Directory{ ID: id, Name: id.Name(), } }