package tencent 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" ) // NewMinioClient returns a minio.Client which is compatible for tencent OSS func NewMinioClient(address string, opts *minio.Options) (*minio.Client, error) { if opts == nil { opts = &minio.Options{} } if opts.Creds == nil { credProvider, err := NewCredentialProvider() if err != nil { return nil, errors.Wrap(err, "failed to create credential provider") } opts.Creds = minioCred.New(credProvider) } if address == "" { address = fmt.Sprintf("cos.%s.myqcloud.com", opts.Region) opts.Secure = true } return minio.New(address, opts) } // 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 NewCredentialProvider() (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 }