Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

support tencent storage #79

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.2
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.853
github.com/tidwall/gjson v1.17.0
github.com/uber/jaeger-client-go v2.30.0+incompatible
go.uber.org/atomic v1.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+z
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04=
github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.853 h1:TNYjF1jDLLNTirAkq7zRT9iF9xC2ZjgwpXsVSEBQvgQ=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.853/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
Expand Down
4 changes: 2 additions & 2 deletions storage/aliyun.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type credentialProvider struct {
aliyunCred aliyunCred.Credential
}

func newCredentialProvider() (*credentialProvider, error) {
func newAliCredentialProvider() (*credentialProvider, error) {
cred, err := aliyunCred.NewCredential(nil)
if err != nil {
return nil, fmt.Errorf("create aliyun credential %w", err)
Expand Down Expand Up @@ -66,7 +66,7 @@ func (c *credentialProvider) IsExpired() bool {
func NewAliyunClient(cfg Cfg) (*MinioClient, error) {
opts := minio.Options{Secure: cfg.UseSSL, Region: cfg.Region, BucketLookup: minio.BucketLookupDNS}
if cfg.UseIAM {
provider, err := newCredentialProvider()
provider, err := newAliCredentialProvider()
if err != nil {
return nil, fmt.Errorf("storage: new aliyun credential provider %w", err)
}
Expand Down
11 changes: 7 additions & 4 deletions storage/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ type Provider string
const (
AWS Provider = "aws"
GCP Provider = "gcp"
ALI Provider = "ali"
AZURE Provider = "azure"
ALI Provider = "ali"
TC Provider = "tc"
unknown Provider = "unknown"
)

const _defaultPageSize = 1000

var _providerMap = map[string]Provider{"aws": AWS, "gcp": GCP, "ali": ALI, "azure": AZURE, "az": AZURE}
var _providerMap = map[string]Provider{"aws": AWS, "gcp": GCP, "ali": ALI, "azure": AZURE, "az": AZURE, "tc": TC}

func ParseProvider(s string) Provider {
if p, ok := _providerMap[s]; ok {
Expand Down Expand Up @@ -53,10 +54,12 @@ func NewClient(cfg Cfg) (Client, error) {
return NewAWSClient(cfg)
case GCP:
return NewGCPClient(cfg)
case ALI:
return NewAliyunClient(cfg)
case AZURE:
return NewAzureClient(cfg)
case ALI:
return NewAliyunClient(cfg)
case TC:
return NewTencentClient(cfg)
default:
return nil, fmt.Errorf("storage: unknown provide %s", cfg.Provider)
}
Expand Down
94 changes: 94 additions & 0 deletions storage/tencent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package storage

import (
"fmt"

"github.com/cockroachdb/errors"
"github.com/minio/minio-go/v7"
minioCred "github.com/minio/minio-go/v7/pkg/credentials"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
)

// NewTencentClient returns a minio.Client which is compatible for tencent COS
func NewTencentClient(cfg Cfg) (*MinioClient, error) {
opts := minio.Options{Secure: cfg.UseSSL, Region: cfg.Region, BucketLookup: minio.BucketLookupDNS}
if cfg.UseIAM {
provider, err := newTcCredentialProvider()
if err != nil {
return nil, fmt.Errorf("storage: new tencent credential provider %w", err)
}
opts.Creds = minioCred.New(provider)
} else {
opts.Creds = minioCred.NewStaticV4(cfg.AK, cfg.SK, "")
}

var addr string
if len(cfg.Endpoint) <= 0 {
addr = fmt.Sprintf("cos.%s.myqcloud.com", opts.Region)
opts.Secure = true
} else {
addr = cfg.Endpoint
}
cli, err := minio.New(addr, &opts)
if err != nil {
return nil, fmt.Errorf("storage: new tencent client %w", err)
}

return &MinioClient{cli: cli, provider: TC}, nil
}

// Credential is defined to mock tencent credential.Credentials
//
//go:generate mockery --name=Credential --with-expecter
type Credential interface {
common.CredentialIface
}

// CredentialProvider implements "github.com/minio/minio-go/v7/pkg/credentials".Provider
// also implements transport
type CredentialProvider struct {
// tencentCreds doesn't provide a way to get the expired time, so we use the cache to check if it's expired
// when tencentCreds.GetSecretId is different from the cache, we know it's expired
akCache string
tencentCreds Credential
}

func newTcCredentialProvider() (minioCred.Provider, error) {
provider, err := common.DefaultTkeOIDCRoleArnProvider()
if err != nil {
return nil, errors.Wrap(err, "failed to create tencent credential provider")
}

cred, err := provider.GetCredential()
if err != nil {
return nil, errors.Wrap(err, "failed to get tencent credential")
}
return &CredentialProvider{tencentCreds: cred}, nil
}

// Retrieve returns nil if it successfully retrieved the value.
// Error is returned if the value were not obtainable, or empty.
// according to the caller minioCred.Credentials.Get(),
// it already has a lock, so we don't need to worry about concurrency
func (c *CredentialProvider) Retrieve() (minioCred.Value, error) {
ret := minioCred.Value{}
ak := c.tencentCreds.GetSecretId()
ret.AccessKeyID = ak
c.akCache = ak

sk := c.tencentCreds.GetSecretKey()
ret.SecretAccessKey = sk

securityToken := c.tencentCreds.GetToken()
ret.SessionToken = securityToken
return ret, nil
}

// IsExpired returns if the credentials are no longer valid, and need
// to be retrieved.
// according to the caller minioCred.Credentials.IsExpired(),
// it already has a lock, so we don't need to worry about concurrency
func (c CredentialProvider) IsExpired() bool {
ak := c.tencentCreds.GetSecretId()
return ak != c.akCache
}
Loading