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/storage2/client/types" "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/factory/reg" "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/types" "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/utils" cortypes "gitlink.org.cn/cloudream/storage2/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{ HasBypassWrite: true, HasBypassRead: true, HasBypassHTTPRead: false, } } func (b *builder) CreateShardStore() (types.ShardStore, error) { 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) } cli, bkt, err := createClient(s3Cred) if err != nil { return nil, err } return NewShardStore(b.detail, cli, bkt, ShardStoreOption{UseAWSSha256: true}) } func (b *builder) CreatePublicStore() (types.PublicStore, error) { 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) } cli, bkt, err := createClient(s3Cred) if err != nil { return nil, err } return NewPublicStore(b.detail, cli, bkt) } func createClient(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 = cred.Region options := []func(*s3.Options){} options = append(options, func(s3Opt *s3.Options) { s3Opt.BaseEndpoint = &cred.Endpoint }) cli := s3.NewFromConfig(awsConfig, options...) return cli, cred.Bucket, nil } func (b *builder) CreateMultiparter() (types.Multiparter, error) { feat := utils.FindFeature[*cortypes.MultipartUploadFeature](b.detail.Storage) 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 public store", b.detail.UserSpace.Credential) } cli, bucket, err := createClient(s3Cred) if err != nil { return nil, err } return NewMultiparter( b.detail, feat, bucket, cli, ), nil }