122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package s3
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/credentials"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
|
|
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/factory/reg"
|
|
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
|
|
cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
|
|
)
|
|
|
|
func init() {
|
|
reg.RegisterBuilder[*cortypes.S3Type](newBuilder)
|
|
}
|
|
|
|
type builder struct {
|
|
types.EmptyBuilder
|
|
detail *clitypes.UserSpaceDetail
|
|
}
|
|
|
|
func newBuilder(detail *clitypes.UserSpaceDetail) types.StorageBuilder {
|
|
return &builder{
|
|
detail: detail,
|
|
}
|
|
}
|
|
|
|
func (b *builder) FeatureDesc() types.FeatureDesc {
|
|
return types.FeatureDesc{}
|
|
}
|
|
|
|
func (b *builder) CreateShardStore(typeOnly bool) (types.ShardStore, error) {
|
|
stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type)
|
|
s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred)
|
|
if !ok {
|
|
return nil, fmt.Errorf("invalid storage credential type %T for s3 storage", b.detail.UserSpace.Credential)
|
|
}
|
|
|
|
if typeOnly {
|
|
return (*ShardStore)(nil), nil
|
|
}
|
|
|
|
cli, bkt, err := createClient(stgType, s3Cred)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewShardStore(b.detail, cli, bkt, ShardStoreOption{UseAWSSha256: true})
|
|
}
|
|
|
|
func (b *builder) CreateBaseStore(typeOnly bool) (types.BaseStore, error) {
|
|
stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type)
|
|
s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred)
|
|
if !ok {
|
|
return nil, fmt.Errorf("invalid storage credential type %T for s3 storage", b.detail.UserSpace.Credential)
|
|
}
|
|
|
|
if typeOnly {
|
|
return (*BaseStore)(nil), nil
|
|
}
|
|
|
|
cli, bkt, err := createClient(stgType, s3Cred)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewBaseStore(b.detail, cli, bkt, BaseStoreOption{UseAWSSha256: false})
|
|
}
|
|
|
|
func createClient(stgType *cortypes.S3Type, cred *cortypes.S3Cred) (*s3.Client, string, error) {
|
|
awsConfig := aws.Config{}
|
|
|
|
if cred.AK != "" && cred.SK != "" {
|
|
cre := aws.Credentials{
|
|
AccessKeyID: cred.AK,
|
|
SecretAccessKey: cred.SK,
|
|
}
|
|
awsConfig.Credentials = &credentials.StaticCredentialsProvider{Value: cre}
|
|
}
|
|
|
|
awsConfig.Region = stgType.Region
|
|
|
|
options := []func(*s3.Options){}
|
|
options = append(options, func(s3Opt *s3.Options) {
|
|
s3Opt.BaseEndpoint = &stgType.Endpoint
|
|
})
|
|
|
|
cli := s3.NewFromConfig(awsConfig, options...)
|
|
return cli, stgType.Bucket, nil
|
|
}
|
|
|
|
func (b *builder) CreateMultiparter(typeOnly bool) (types.Multiparter, error) {
|
|
stgType := b.detail.UserSpace.Storage.(*cortypes.S3Type)
|
|
feat := types.FindFeature[*cortypes.MultipartUploadFeature](b.detail)
|
|
if feat == nil {
|
|
return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{})
|
|
}
|
|
|
|
s3Cred, ok := b.detail.UserSpace.Credential.(*cortypes.S3Cred)
|
|
if !ok {
|
|
return nil, fmt.Errorf("invalid storage credential type %T for s3 base store", b.detail.UserSpace.Credential)
|
|
}
|
|
|
|
if typeOnly {
|
|
return (*Multiparter)(nil), nil
|
|
}
|
|
|
|
cli, bucket, err := createClient(stgType, s3Cred)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return NewMultiparter(
|
|
b.detail,
|
|
feat,
|
|
bucket,
|
|
cli,
|
|
), nil
|
|
}
|