Skip to content

Commit

Permalink
move get client to invoker
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonTian committed Apr 19, 2024
1 parent 90544f5 commit a300d2d
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 298 deletions.
185 changes: 0 additions & 185 deletions config/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ import (
"regexp"
"strconv"
"strings"
"time"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/responses"
"github.com/aliyun/aliyun-cli/cli"
Expand Down Expand Up @@ -401,93 +399,6 @@ func (cp *Profile) GetCredential(ctx *cli.Context) (cred credentialsv2.Credentia
return credentialsv2.NewCredential(config)
}

func (cp *Profile) GetClient(ctx *cli.Context) (*sdk.Client, error) {
config := sdk.NewConfig()
// get UserAgent from env
config.UserAgent = os.Getenv("ALIYUN_USER_AGENT")

if cp.RetryCount > 0 {
// when use --retry-count, enable auto retry
config.WithAutoRetry(true)
config.WithMaxRetryTime(cp.RetryCount)
}
var client *sdk.Client
var err error
switch cp.Mode {
case AK:
client, err = cp.GetClientByAK(config)
case StsToken:
client, err = cp.GetClientBySts(config)
case RamRoleArn:
client, err = cp.GetClientByRoleArn(config)
case EcsRamRole:
client, err = cp.GetClientByEcsRamRole(config)
case RsaKeyPair:
client, err = cp.GetClientByPrivateKey(config)
case RamRoleArnWithEcs:
client, err = cp.GetClientByRamRoleArnWithEcs(config)
case ChainableRamRoleArn:
return cp.GetClientByChainableRamRoleArn(config, ctx)
case External:
return cp.GetClientByExternal(config, ctx)
case CredentialsURI:
return cp.GetClientByCredentialsURI(config, ctx)
default:
client, err = nil, fmt.Errorf("unexcepted certificate mode: %s", cp.Mode)
}

if client != nil {
if cp.ReadTimeout > 0 {
client.SetReadTimeout(time.Duration(cp.ReadTimeout) * time.Second)
}
if cp.ConnectTimeout > 0 {
client.SetConnectTimeout(time.Duration(cp.ConnectTimeout) * time.Second)
}
if SkipSecureVerify(ctx.Flags()).IsAssigned() {
client.SetHTTPSInsecure(true)
}
}
return client, err
}

func (cp *Profile) GetClientByAK(config *sdk.Config) (*sdk.Client, error) {
if cp.AccessKeyId == "" || cp.AccessKeySecret == "" {
return nil, fmt.Errorf("AccessKeyId/AccessKeySecret is empty! run `aliyun configure` first")
}
if cp.RegionId == "" {
return nil, fmt.Errorf("default RegionId is empty! run `aliyun configure` first")
}
cred := credentials.NewAccessKeyCredential(cp.AccessKeyId, cp.AccessKeySecret)
client, err := sdk.NewClientWithOptions(cp.RegionId, config, cred)
return client, err
}

func (cp *Profile) GetClientBySts(config *sdk.Config) (*sdk.Client, error) {
cred := credentials.NewStsTokenCredential(cp.AccessKeyId, cp.AccessKeySecret, cp.StsToken)
client, err := sdk.NewClientWithOptions(cp.RegionId, config, cred)
return client, err
}

func (cp *Profile) GetClientByRoleArn(config *sdk.Config) (*sdk.Client, error) {
cred := credentials.NewRamRoleArnCredential(cp.AccessKeyId, cp.AccessKeySecret, cp.RamRoleArn, cp.RoleSessionName, cp.ExpiredSeconds)
cred.StsRegion = cp.StsRegion
client, err := sdk.NewClientWithOptions(cp.RegionId, config, cred)
return client, err
}

func (cp *Profile) GetClientByRamRoleArnWithEcs(config *sdk.Config) (*sdk.Client, error) {
client, err := cp.GetClientByEcsRamRole(config)
if err != nil {
return nil, err
}
accessKeyID, accessKeySecret, StsToken, err := cp.GetSessionCredential(client)
if err != nil {
return nil, err
}
cred := credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, StsToken)
return sdk.NewClientWithOptions(cp.RegionId, config, cred)
}

func (cp *Profile) GetSessionCredential(client *sdk.Client) (string, string, string, error) {
req := requests.NewCommonRequest()
rep := responses.NewCommonResponse()
Expand Down Expand Up @@ -523,102 +434,6 @@ func (cp *Profile) GetSessionCredential(client *sdk.Client) (string, string, str
return accessKeyID.(string), accessKeySecret.(string), StsToken.(string), nil
}

func (cp *Profile) GetClientByEcsRamRole(config *sdk.Config) (*sdk.Client, error) {
cred := credentials.NewEcsRamRoleCredential(cp.RamRoleName)
client, err := sdk.NewClientWithOptions(cp.RegionId, config, cred)
return client, err
}

func (cp *Profile) GetClientByPrivateKey(config *sdk.Config) (*sdk.Client, error) {
cred := credentials.NewRsaKeyPairCredential(cp.PrivateKey, cp.KeyPairName, cp.ExpiredSeconds)
client, err := sdk.NewClientWithOptions(cp.RegionId, config, cred)
return client, err
}

func (cp *Profile) GetClientByExternal(config *sdk.Config, ctx *cli.Context) (*sdk.Client, error) {
args := strings.Fields(cp.ProcessCommand)
cmd := exec.Command(args[0], args[1:]...)
buf, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
err = json.Unmarshal(buf, cp)
if err != nil {
fmt.Println(cp.ProcessCommand)
fmt.Println(string(buf))
return nil, err
}
return cp.GetClient(ctx)
}

func (cp *Profile) GetClientByCredentialsURI(config *sdk.Config, ctx *cli.Context) (*sdk.Client, error) {
uri := cp.CredentialsURI

if uri == "" {
uri = os.Getenv("ALIBABA_CLOUD_CREDENTIALS_URI")
}

if uri == "" {
return nil, fmt.Errorf("invalid credentials uri")
}

res, err := http.Get(uri)
if err != nil {
return nil, err
}

if res.StatusCode != 200 {
return nil, fmt.Errorf("get credentials from %s failed, status code %d", uri, res.StatusCode)
}

body, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
return nil, err
}

type Response struct {
Code string
AccessKeyId string
AccessKeySecret string
SecurityToken string
Expiration string
}
var response Response
err = json.Unmarshal(body, &response)
if err != nil {
return nil, fmt.Errorf("unmarshal credentials failed, the body %s", string(body))
}

if response.Code != "Success" {
return nil, fmt.Errorf("get sts token err, Code is not Success")
}

cred := credentials.NewStsTokenCredential(response.AccessKeyId, response.AccessKeySecret, response.SecurityToken)
return sdk.NewClientWithOptions(cp.RegionId, config, cred)
}

func (cp *Profile) GetClientByChainableRamRoleArn(config *sdk.Config, ctx *cli.Context) (*sdk.Client, error) {
profileName := cp.SourceProfile

// 从 configuration 中重新获取 source profile
source, loaded := cp.parent.GetProfile(profileName)
if !loaded {
return nil, fmt.Errorf("can not load the source profile: " + profileName)
}

client, err := source.GetClient(ctx)
if err != nil {
return nil, err
}
accessKeyID, accessKeySecret, StsToken, err := cp.GetSessionCredential(client)
if err != nil {
return nil, err
}
cred := credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, StsToken)
return sdk.NewClientWithOptions(cp.RegionId, config, cred)
}

func IsRegion(region string) bool {
if match, _ := regexp.MatchString("^[a-zA-Z0-9-]*$", region); !match {
return false
Expand Down
108 changes: 1 addition & 107 deletions config/profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import (
"os"
"testing"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk"

"github.com/aliyun/aliyun-cli/cli"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -49,6 +47,7 @@ func newProfile() *Profile {
RetryCount: 0,
}
}

func TestNewProfile(t *testing.T) {
exp := newProfile()
exp.Mode = AK
Expand Down Expand Up @@ -337,111 +336,6 @@ func resetEnv() {
os.Setenv("REGION", "")
}

func TestGetClient(t *testing.T) {
actual := newProfile()
buf := new(bytes.Buffer)
buf2 := new(bytes.Buffer)
ctx := cli.NewCommandContext(buf, buf2)
AddFlags(ctx.Flags())
actual.RetryCount = 2

actual.Mode = AK
client, err := actual.GetClient(ctx)
assert.Nil(t, client)
assert.NotNil(t, err)

actual.Mode = RamRoleArnWithEcs
client, err = actual.GetClient(ctx)
assert.Nil(t, client)
assert.NotNil(t, err)

actual.Mode = StsToken
client, err = actual.GetClient(ctx)
assert.Nil(t, err)
assert.NotNil(t, client)

actual.Mode = RamRoleArn
client, err = actual.GetClient(ctx)
assert.Nil(t, err)
assert.NotNil(t, client)

actual.Mode = EcsRamRole
client, err = actual.GetClient(ctx)
assert.Nil(t, err)
assert.NotNil(t, client)

actual.Mode = RsaKeyPair
client, err = actual.GetClient(ctx)
assert.Nil(t, err)
assert.NotNil(t, client)

// config to client
actual.Mode = StsToken
actual.ReadTimeout = 2
actual.ConnectTimeout = 2
SkipSecureVerify(ctx.Flags()).SetAssigned(true)
client, err = actual.GetClient(ctx)
assert.Nil(t, err)
assert.NotNil(t, client)
assert.Equal(t, 2, client.GetConfig().MaxRetryTime)
assert.Equal(t, float64(2), client.GetReadTimeout().Seconds())
assert.Equal(t, float64(2), client.GetConnectTimeout().Seconds())
assert.True(t, client.GetHTTPSInsecure())
}

func TestGetClientByAK(t *testing.T) {
actual := newProfile()
config := sdk.NewConfig()

actual.AccessKeyId = "accessKeyId"
client, err := actual.GetClientByAK(config)
assert.Nil(t, client)
assert.EqualError(t, err, "AccessKeyId/AccessKeySecret is empty! run `aliyun configure` first")

actual.AccessKeySecret = "accessKeySecret"
client, err = actual.GetClientByAK(config)
assert.Nil(t, client)
assert.EqualError(t, err, "default RegionId is empty! run `aliyun configure` first")

actual.RegionId = "cn-hangzhou"
client, err = actual.GetClientByAK(config)
assert.Nil(t, err)
assert.NotNil(t, client)
}

func TestGetClientWithNoError(t *testing.T) {
actual := newProfile()
config := sdk.NewConfig()

// GetClientBySts
client, err := actual.GetClientBySts(config)
assert.Nil(t, err)
assert.NotNil(t, client)

// GetClientByRoleArn
client, err = actual.GetClientByRoleArn(config)
assert.Nil(t, err)
assert.NotNil(t, client)

// GetClientByEcsRamRole
client, err = actual.GetClientByEcsRamRole(config)
assert.Nil(t, err)
assert.NotNil(t, client)

// GetClientByPrivateKey
client, err = actual.GetClientByPrivateKey(config)
assert.Nil(t, err)
assert.NotNil(t, client)
}

func TestGetClientByRamRoleArnWithEcs(t *testing.T) {
actual := newProfile()
config := sdk.NewConfig()
client, err := actual.GetClientByRamRoleArnWithEcs(config)
assert.Nil(t, client)
assert.NotNil(t, err)
}

func TestValidateAk(t *testing.T) {
actual := newProfile()
err := actual.ValidateAK()
Expand Down
Loading

0 comments on commit a300d2d

Please sign in to comment.