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

Commit

Permalink
support tencent storage
Browse files Browse the repository at this point in the history
Signed-off-by: lentitude2tk <[email protected]>
  • Loading branch information
lentitude2tk committed Jan 31, 2024
1 parent 8deebd8 commit b3cf4ad
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 6 deletions.
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
}

0 comments on commit b3cf4ad

Please sign in to comment.