Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions plugins/common/aliyun/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package aliyun

import (
"fmt"

"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/providers"
)

// CredentialConfig holds Aliyun authentication configuration
type CredentialConfig struct {
AccessKeyID string
AccessKeySecret string
AccessKeyStsToken string
RoleArn string
RoleSessionName string
PrivateKey string
PublicKeyID string
RoleName string
}

// GetCredentials retrieves Aliyun credentials using the credential chain
// Credentials are loaded in the following order:
// 1) Ram RoleArn credential
// 2) AccessKey STS token credential
// 3) AccessKey credential
// 4) Ecs Ram Role credential
// 5) RSA keypair credential
// 6) Environment variables credential
// 7) Instance metadata credential
func GetCredentials(config CredentialConfig) (auth.Credential, error) {
var (
roleSessionExpiration = 3600
sessionExpiration = 3600
)
Comment on lines +32 to +35
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use

Suggested change
var (
roleSessionExpiration = 3600
sessionExpiration = 3600
)
roleSessionExpiration := 3600
sessionExpiration := 3600


configuration := &providers.Configuration{
AccessKeyID: config.AccessKeyID,
AccessKeySecret: config.AccessKeySecret,
AccessKeyStsToken: config.AccessKeyStsToken,
RoleArn: config.RoleArn,
RoleSessionName: config.RoleSessionName,
RoleSessionExpiration: &roleSessionExpiration,
PrivateKey: config.PrivateKey,
PublicKeyID: config.PublicKeyID,
SessionExpiration: &sessionExpiration,
RoleName: config.RoleName,
}

credentialProviders := []providers.Provider{
providers.NewConfigurationCredentialProvider(configuration),
providers.NewEnvCredentialProvider(),
providers.NewInstanceMetadataProvider(),
}

credential, err := providers.NewChainProvider(credentialProviders).Retrieve()
if err != nil {
return nil, fmt.Errorf("failed to retrieve credential: %w", err)
}

return credential, nil
}
105 changes: 105 additions & 0 deletions plugins/common/aliyun/auth_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package aliyun

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestGetCredentials(t *testing.T) {
tests := []struct {
name string
config CredentialConfig
expectError bool
}{
{
name: "with access key credentials",
config: CredentialConfig{
AccessKeyID: "test-key-id",
AccessKeySecret: "test-key-secret",
},
expectError: false,
},
{
name: "with access key and STS token",
config: CredentialConfig{
AccessKeyID: "test-key-id",
AccessKeySecret: "test-key-secret",
AccessKeyStsToken: "test-sts-token",
},
expectError: false,
},
{
name: "with role ARN",
config: CredentialConfig{
AccessKeyID: "test-key-id",
AccessKeySecret: "test-key-secret",
RoleArn: "acs:ram::123456:role/test-role",
RoleSessionName: "test-session",
},
expectError: false,
},
{
name: "with RSA keypair",
config: CredentialConfig{
PublicKeyID: "test-public-key-id",
PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\ntest\n-----END RSA PRIVATE KEY-----",
},
expectError: true,
},
{
name: "with ECS RAM role name",
config: CredentialConfig{
RoleName: "test-ecs-role",
},
expectError: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cred, err := GetCredentials(tt.config)

if tt.expectError {
if err == nil {
require.NotNil(t, cred)
}
} else {
require.NoError(t, err)
require.NotNil(t, cred)
}
})
}
}

func TestGetCredentialsEmpty(t *testing.T) {
cred, err := GetCredentials(CredentialConfig{})

if err != nil {
require.Contains(t, err.Error(), "failed to retrieve credential")
} else {
require.NotNil(t, cred)
}
Comment on lines +78 to +82
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No! You should know what you expect from that call! Either this should return an error, then check for it, or it doesn't!

}

func TestCredentialConfigFields(t *testing.T) {
config := CredentialConfig{
AccessKeyID: "key-id",
AccessKeySecret: "key-secret",
AccessKeyStsToken: "sts-token",
RoleArn: "role-arn",
RoleSessionName: "session-name",
PrivateKey: "private-key",
PublicKeyID: "public-key-id",
RoleName: "role-name",
}

require.Equal(t, "key-id", config.AccessKeyID)
require.Equal(t, "key-secret", config.AccessKeySecret)
require.Equal(t, "sts-token", config.AccessKeyStsToken)
require.Equal(t, "role-arn", config.RoleArn)
require.Equal(t, "session-name", config.RoleSessionName)
require.Equal(t, "private-key", config.PrivateKey)
require.Equal(t, "public-key-id", config.PublicKeyID)
require.Equal(t, "role-name", config.RoleName)
}
Loading
Loading