Skip to content

Commit

Permalink
feat: add imds and external uri in default chain && refactor credenti…
Browse files Browse the repository at this point in the history
…als provider
  • Loading branch information
yndu13 committed Nov 11, 2024
1 parent 1a7bea3 commit d12d548
Show file tree
Hide file tree
Showing 11 changed files with 1,765 additions and 65 deletions.
72 changes: 61 additions & 11 deletions sdk/auth/credentials/cli_profile_credentials_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"io/ioutil"
"os"
"path"
"strings"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/internal"
)

Expand Down Expand Up @@ -52,10 +54,13 @@ type profile struct {
RoleSessionName string `json:"ram_session_name"`
DurationSeconds int `json:"expired_seconds"`
StsRegion string `json:"sts_region"`
EnableVpc bool `json:"enable_vpc"`
SourceProfile string `json:"source_profile"`
RoleName string `json:"ram_role_name"`
OIDCTokenFile string `json:"oidc_token_file"`
OIDCProviderARN string `json:"oidc_provider_arn"`
Policy string `json:"policy"`
ExternalId string `json:"external_id"`
}

type configuration struct {
Expand Down Expand Up @@ -106,29 +111,59 @@ func (provider *CLIProfileCredentialsProvider) getCredentialsProvider(conf *conf

switch p.Mode {
case "AK":
credentialsProvider = NewStaticAKCredentialsProvider(p.AccessKeyID, p.AccessKeySecret)
credentialsProvider, err = NewStaticAKCredentialsProviderBuilder().
WithAccessKeyId(p.AccessKeyID).
WithAccessKeySecret(p.AccessKeySecret).
Build()
case "RamRoleArn":
previousProvider := NewStaticAKCredentialsProvider(p.AccessKeyID, p.AccessKeySecret)
credentialsProvider, err = NewRAMRoleARNCredentialsProvider(previousProvider, p.RoleArn, p.RoleSessionName, p.DurationSeconds, "", p.StsRegion, "")
previousProvider, err1 := NewStaticAKCredentialsProviderBuilder().
WithAccessKeyId(p.AccessKeyID).
WithAccessKeySecret(p.AccessKeySecret).
Build()
if err1 != nil {
return nil, err1
}

credentialsProvider, err = NewRAMRoleARNCredentialsProviderBuilder().
WithCredentialsProvider(previousProvider).
WithRoleArn(p.RoleArn).
WithRoleSessionName(p.RoleSessionName).
WithDurationSeconds(p.DurationSeconds).
WithStsRegion(p.StsRegion).
WithEnableVpc(p.EnableVpc).
WithPolicy(p.Policy).
WithExternalId(p.ExternalId).
Build()
case "EcsRamRole":
credentialsProvider = NewECSRAMRoleCredentialsProvider(p.RoleName)
credentialsProvider, err = NewECSRAMRoleCredentialsProviderBuilder().WithRoleName(p.RoleName).Build()
case "OIDC":
credentialsProvider, err = NewOIDCCredentialsProviderBuilder().
WithOIDCTokenFilePath(p.OIDCTokenFile).
WithOIDCProviderARN(p.OIDCProviderARN).
WithRoleArn(p.RoleArn).
WithStsRegion(p.StsRegion).
WithEnableVpc(p.EnableVpc).
WithDurationSeconds(p.DurationSeconds).
WithRoleSessionName(p.RoleSessionName).
WithPolicy(p.Policy).
Build()
case "ChainableRamRoleArn":
var previousProvider CredentialsProvider
previousProvider, err = provider.getCredentialsProvider(conf, p.SourceProfile)
if err != nil {
err = fmt.Errorf("get source profile failed: %s", err.Error())
previousProvider, err1 := provider.getCredentialsProvider(conf, p.SourceProfile)
if err1 != nil {
err = fmt.Errorf("get source profile failed: %s", err1.Error())
return
}
credentialsProvider, err = NewRAMRoleARNCredentialsProvider(previousProvider, p.RoleArn, p.RoleSessionName, p.DurationSeconds, "", p.StsRegion, "")
credentialsProvider, err = NewRAMRoleARNCredentialsProviderBuilder().
WithCredentialsProvider(previousProvider).
WithRoleArn(p.RoleArn).
WithRoleSessionName(p.RoleSessionName).
WithDurationSeconds(p.DurationSeconds).
WithStsRegion(p.StsRegion).
WithEnableVpc(p.EnableVpc).
WithPolicy(p.Policy).
WithExternalId(p.ExternalId).
Build()
default:
err = fmt.Errorf("unsupported profile mode '%s'", p.Mode)
}
Expand All @@ -140,6 +175,10 @@ func (provider *CLIProfileCredentialsProvider) getCredentialsProvider(conf *conf
var getHomePath = internal.GetHomePath

func (provider *CLIProfileCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
if strings.ToLower(os.Getenv("ALIBABA_CLOUD_CLI_PROFILE_DISABLED")) == "true" {
err = errors.NewClientError(errors.InvalidParamErrorCode, "The CLI profile is disabled", nil)
return
}
if provider.innerProvider == nil {
homedir := getHomePath()
if homedir == "" {
Expand All @@ -164,15 +203,26 @@ func (provider *CLIProfileCredentialsProvider) GetCredentials() (cc *Credentials
}
}

cc, err = provider.innerProvider.GetCredentials()
innerCC, err := provider.innerProvider.GetCredentials()
if err != nil {
return
}

cc.ProviderName = fmt.Sprintf("%s/%s", provider.GetProviderName(), provider.innerProvider.GetProviderName())
providerName := innerCC.ProviderName
if providerName == "" {
providerName = provider.innerProvider.GetProviderName()
}

cc = &Credentials{
AccessKeyId: innerCC.AccessKeyId,
AccessKeySecret: innerCC.AccessKeySecret,
SecurityToken: innerCC.SecurityToken,
ProviderName: fmt.Sprintf("%s/%s", provider.GetProviderName(), providerName),
}

return
}

func (provider *CLIProfileCredentialsProvider) GetProviderName() string {
return "cli_provider"
return "cli_profile"
}
41 changes: 40 additions & 1 deletion sdk/auth/credentials/cli_profile_credentials_provider_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package credentials

import (
"net/http"
"os"
"path"
"strings"
Expand Down Expand Up @@ -83,6 +84,14 @@ func TestCLIProfileCredentialsProvider_getCredentialsProvider(t *testing.T) {
AccessKeyID: "akid",
AccessKeySecret: "secret",
RoleArn: "arn",
StsRegion: "cn-hangzhou",
EnableVpc: true,
Policy: "policy",
ExternalId: "externalId",
},
{
Mode: "RamRoleArn",
Name: "Invalid_RamRoleArn",
},
{
Mode: "EcsRamRole",
Expand All @@ -95,10 +104,14 @@ func TestCLIProfileCredentialsProvider_getCredentialsProvider(t *testing.T) {
RoleArn: "role_arn",
OIDCTokenFile: "path/to/oidc/file",
OIDCProviderARN: "provider_arn",
StsRegion: "cn-hangzhou",
EnableVpc: true,
Policy: "policy",
},
{
Mode: "ChainableRamRoleArn",
Name: "ChainableRamRoleArn",
RoleArn: "arn",
SourceProfile: "AK",
},
{
Expand Down Expand Up @@ -130,6 +143,9 @@ func TestCLIProfileCredentialsProvider_getCredentialsProvider(t *testing.T) {
assert.Nil(t, err)
_, ok = cp.(*RAMRoleARNCredentialsProvider)
assert.True(t, ok)
// RamRoleArn invalid ak
_, err = provider.getCredentialsProvider(conf, "Invalid_RamRoleArn")
assert.EqualError(t, err, "[SDK.InvalidParam] The access key id is empty")
// EcsRamRole
cp, err = provider.getCredentialsProvider(conf, "EcsRamRole")
assert.Nil(t, err)
Expand Down Expand Up @@ -157,6 +173,10 @@ func TestCLIProfileCredentialsProvider_getCredentialsProvider(t *testing.T) {
}

func TestCLIProfileCredentialsProvider_GetCredentials(t *testing.T) {
originDo := hookDo
defer func() { hookDo = originDo }()
rollback := internal.Memory("ALIBABA_CLOUD_CLI_PROFILE_DISABLED")
defer rollback()
defer func() {
getHomePath = internal.GetHomePath
}()
Expand Down Expand Up @@ -189,7 +209,7 @@ func TestCLIProfileCredentialsProvider_GetCredentials(t *testing.T) {
AccessKeySecret: "secret",
SecurityToken: "",
BearerToken: "",
ProviderName: "cli_provider/static_ak",
ProviderName: "cli_profile/static_ak",
}, cc)

provider = NewCLIProfileCredentialsProviderBuilder().WithProfileName("inexist").Build()
Expand All @@ -202,4 +222,23 @@ func TestCLIProfileCredentialsProvider_GetCredentials(t *testing.T) {
_, err = provider.GetCredentials()
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "InvalidAccessKeyId.NotFound")

hookDo = func(fn do) do {
return func(req *http.Request) (res *http.Response, err error) {
res = mockResponse(200, `{"Credentials": {"AccessKeyId":"akid","AccessKeySecret":"aksecret","Expiration":"2021-10-20T04:27:09Z","SecurityToken":"ststoken"}}`)
return
}
}
provider = NewCLIProfileCredentialsProviderBuilder().WithProfileName("ChainableRamRoleArn").Build()
cc, err = provider.GetCredentials()
assert.Nil(t, err)
assert.Equal(t, "akid", cc.AccessKeyId)
assert.Equal(t, "aksecret", cc.AccessKeySecret)
assert.Equal(t, "ststoken", cc.SecurityToken)
assert.Equal(t, "cli_profile/ram_role_arn/ram_role_arn/static_ak", cc.ProviderName)

os.Setenv("ALIBABA_CLOUD_CLI_PROFILE_DISABLED", "True")
_, err = provider.GetCredentials()
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "The CLI profile is disabled")
}
Loading

0 comments on commit d12d548

Please sign in to comment.