Skip to content

Commit

Permalink
support profile credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
JacksonTian committed Aug 16, 2024
1 parent 71312df commit da396dd
Show file tree
Hide file tree
Showing 8 changed files with 534 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestCLIProfileCredentialsProvider(t *testing.T) {
rollback := Memory("ALIBABA_CLOUD_PROFILE")
rollback := internal.Memory("ALIBABA_CLOUD_PROFILE")
defer rollback()
b := NewCLIProfileCredentialsProviderBuilder().Build()
assert.Equal(t, "", b.profileName)
Expand Down
17 changes: 0 additions & 17 deletions sdk/auth/credentials/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,6 @@ import (
"github.com/stretchr/testify/assert"
)

// set back the memoried enviroment variables
type Rollback func()

func Memory(keys ...string) Rollback {
// remenber enviroment variables
m := make(map[string]string)
for _, key := range keys {
m[key] = os.Getenv(key)
}

return func() {
for _, key := range keys {
os.Setenv(key, m[key])
}
}
}

func mockResponse(statusCode int, content string) (res *http.Response) {
status := strconv.Itoa(statusCode)
res = &http.Response{
Expand Down
3 changes: 2 additions & 1 deletion sdk/auth/credentials/env_credentials_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import (
"os"
"testing"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk/internal"
"github.com/stretchr/testify/assert"
)

func TestEnvironmentVariableCredentialsProvider(t *testing.T) {
rollback := Memory("ALIBABA_CLOUD_ACCESS_KEY_ID", "ALIBABA_CLOUD_ACCESS_KEY_SECRET", "ALIBABA_CLOUD_SECURITY_TOKEN")
rollback := internal.Memory("ALIBABA_CLOUD_ACCESS_KEY_ID", "ALIBABA_CLOUD_ACCESS_KEY_SECRET", "ALIBABA_CLOUD_SECURITY_TOKEN")
defer rollback()

p := NewEnvironmentVariableCredentialsProvider()
Expand Down
73 changes: 73 additions & 0 deletions sdk/auth/credentials/fixtures/.alibabacloud/credentials
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[default]
enable = true
type = access_key
access_key_id = foo
access_key_secret = bar

[notype]
access_key_id = foo
access_key_secret = bar

[noak]
type = access_key
access_key_secret = bar

[emptyak]
type = access_key
access_key_id =
access_key_secret = bar

[ecs]
type = ecs_ram_role
role_name = EcsRamRoleTest

[noecs]
type = ecs_ram_role

[emptyecs]
type = ecs_ram_role
role_name =

[ram]
type = ram_role_arn
access_key_id = foo
access_key_secret = bar
role_arn = role_arn
role_session_name = session_name

[noram]
type = ram_role_arn
access_key_secret = bar
role_arn = role_arn
role_session_name = session_name

[emptyram]
type = ram_role_arn
access_key_id =
access_key_secret = bar
role_arn = role_arn
role_session_name = session_name

[rsa]
type = rsa_key_pair
public_key_id = publicKeyId
private_key_file = ./pk.pem

[norsa]
type = rsa_key_pair
public_key_id = publicKeyId

[emptyrsa]
type = rsa_key_pair
public_key_id = publicKeyId
private_key_file =

[error_rsa]
type = rsa_key_pair
public_key_id = publicKeyId
private_key_file = ./pk_error.pem

[error_type]
type = error_type
public_key_id = publicKeyId
private_key_file = ./pk_error.pem
128 changes: 128 additions & 0 deletions sdk/auth/credentials/profile_credentials_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package credentials

import (
"errors"
"fmt"
"os"
"path"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk/internal"
"gopkg.in/ini.v1"
)

type ProfileCredentialsProvider struct {
profileName string
innerProvider CredentialsProvider
}

type ProfileCredentialsProviderBuilder struct {
provider *ProfileCredentialsProvider
}

func NewProfileCredentialsProviderBuilder() (builder *ProfileCredentialsProviderBuilder) {
return &ProfileCredentialsProviderBuilder{
provider: &ProfileCredentialsProvider{},
}
}

func (b *ProfileCredentialsProviderBuilder) WithProfileName(profileName string) *ProfileCredentialsProviderBuilder {
b.provider.profileName = profileName
return b
}

func (b *ProfileCredentialsProviderBuilder) Build() (provider *ProfileCredentialsProvider, err error) {
// 优先级:
// 1. 使用显示指定的 profileName
// 2. 使用环境变量(ALIBABA_CLOUD_PROFILE)指定的 profileName
// 3. 兜底使用 default 作为 profileName
b.provider.profileName = internal.GetDefaultString(b.provider.profileName, os.Getenv("ALIBABA_CLOUD_PROFILE"), "default")

provider = b.provider
return
}

func (provider *ProfileCredentialsProvider) getCredentialsProvider(ini *ini.File) (credentialsProvider CredentialsProvider, err error) {
section, err := ini.GetSection(provider.profileName)
if err != nil {
err = errors.New("ERROR: Can not load section" + err.Error())
return
}

value, err := section.GetKey("type")
if err != nil {
err = errors.New("ERROR: Can not find credential type" + err.Error())
return
}

switch value.String() {
case "access_key":
value1, err1 := section.GetKey("access_key_id")
value2, err2 := section.GetKey("access_key_secret")
if err1 != nil || err2 != nil {
err = errors.New("ERROR: Failed to get value")
return
}

if value1.String() == "" || value2.String() == "" {
err = errors.New("ERROR: Value can't be empty")
return
}

credentialsProvider = NewStaticAKCredentialsProvider(value1.String(), value2.String())
case "ecs_ram_role":
value1, err1 := section.GetKey("role_name")
if err1 != nil {
err = errors.New("ERROR: Failed to get value")
return
}
credentialsProvider = NewECSRAMRoleCredentialsProvider(value1.String())
case "ram_role_arn":
value1, err1 := section.GetKey("access_key_id")
value2, err2 := section.GetKey("access_key_secret")
value3, err3 := section.GetKey("role_arn")
value4, err4 := section.GetKey("role_session_name")
if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
err = errors.New("ERROR: Failed to get value")
return
}
if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" {
err = errors.New("ERROR: Value can't be empty")
return
}
previous := NewStaticAKCredentialsProvider(value1.String(), value2.String())
credentialsProvider, err = NewRAMRoleARNCredentialsProvider(previous, value3.String(), value4.String(), 3600, "", "", "")
default:
err = errors.New("ERROR: Failed to get credential")
}
return
}

func (provider *ProfileCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
if provider.innerProvider != nil {
return provider.innerProvider.GetCredentials()
}

sharedCfgPath := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
if sharedCfgPath == "" {
homeDir := getHomePath()
if homeDir == "" {
err = fmt.Errorf("cannot found home dir")
return
}

sharedCfgPath = path.Join(homeDir, ".alibabacloud/credentials")
}

ini, err := ini.Load(sharedCfgPath)
if err != nil {
err = errors.New("ERROR: Can not open file" + err.Error())
return
}

provider.innerProvider, err = provider.getCredentialsProvider(ini)
if err != nil {
return
}

return provider.innerProvider.GetCredentials()
}
Loading

0 comments on commit da396dd

Please sign in to comment.