JCS-pub/common/pkgs/storage/obs/obs.go

140 lines
3.7 KiB
Go

package obs
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"
s3stg "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/s3"
"gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
cortypes "gitlink.org.cn/cloudream/jcs-pub/coordinator/types"
)
func init() {
reg.RegisterBuilder[*cortypes.OBSType](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.OBSType)
cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred)
if !ok {
return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential)
}
if typeOnly {
return (*ShardStore)(nil), nil
}
cli, bucket, err := createClient(stgType, cred)
if err != nil {
return nil, err
}
return NewShardStore(b.detail, stgType, cred, cli, bucket)
}
func (b *builder) CreateBaseStore(typeOnly bool) (types.BaseStore, error) {
stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType)
cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred)
if !ok {
return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential)
}
if typeOnly {
return (*s3stg.BaseStore)(nil), nil
}
cli, bucket, err := createClient(stgType, cred)
if err != nil {
return nil, err
}
return s3stg.NewBaseStore(b.detail, cli, bucket, s3stg.BaseStoreOption{UseAWSSha256: false})
}
func createClient(stgType *cortypes.OBSType, cred *cortypes.OBSCred) (*s3.Client, string, error) {
awsConfig := aws.Config{}
cre := aws.Credentials{
AccessKeyID: cred.AK,
SecretAccessKey: cred.SK,
}
awsConfig.Credentials = &credentials.StaticCredentialsProvider{Value: cre}
awsConfig.Region = stgType.Region
awsConfig.RetryMaxAttempts = 1
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.OBSType)
feat := types.FindFeature[*cortypes.MultipartUploadFeature](b.detail)
if feat == nil {
return nil, fmt.Errorf("feature %T not found", cortypes.MultipartUploadFeature{})
}
if typeOnly {
return (*s3stg.Multiparter)(nil), nil
}
cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred)
if !ok {
return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential)
}
cli, bucket, err := createClient(stgType, cred)
if err != nil {
return nil, err
}
return s3stg.NewMultiparter(
b.detail,
feat,
bucket,
cli,
), nil
}
func (b *builder) CreateS2STransfer(typeOnly bool) (types.S2STransfer, error) {
stgType := b.detail.UserSpace.Storage.(*cortypes.OBSType)
feat := types.FindFeature[*cortypes.S2STransferFeature](b.detail)
if feat == nil {
return nil, fmt.Errorf("feature %T not found", cortypes.S2STransferFeature{})
}
if typeOnly {
return (*S2STransfer)(nil), nil
}
cred, ok := b.detail.UserSpace.Credential.(*cortypes.OBSCred)
if !ok {
return nil, fmt.Errorf("invalid storage credential type %T for obs storage", b.detail.UserSpace.Credential)
}
return NewS2STransfer(b.detail, stgType, cred, feat), nil
}