profile.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package providers
  2. import (
  3. "errors"
  4. "fmt"
  5. "os"
  6. "path"
  7. "github.com/aliyun/credentials-go/credentials/internal/utils"
  8. "gopkg.in/ini.v1"
  9. )
  10. type ProfileCredentialsProvider struct {
  11. profileName string
  12. innerProvider CredentialsProvider
  13. }
  14. type ProfileCredentialsProviderBuilder struct {
  15. provider *ProfileCredentialsProvider
  16. }
  17. func NewProfileCredentialsProviderBuilder() (builder *ProfileCredentialsProviderBuilder) {
  18. return &ProfileCredentialsProviderBuilder{
  19. provider: &ProfileCredentialsProvider{},
  20. }
  21. }
  22. func (b *ProfileCredentialsProviderBuilder) WithProfileName(profileName string) *ProfileCredentialsProviderBuilder {
  23. b.provider.profileName = profileName
  24. return b
  25. }
  26. func (b *ProfileCredentialsProviderBuilder) Build() (provider *ProfileCredentialsProvider, err error) {
  27. // 优先级:
  28. // 1. 使用显示指定的 profileName
  29. // 2. 使用环境变量(ALIBABA_CLOUD_PROFILE)指定的 profileName
  30. // 3. 兜底使用 default 作为 profileName
  31. b.provider.profileName = utils.GetDefaultString(b.provider.profileName, os.Getenv("ALIBABA_CLOUD_PROFILE"), "default")
  32. provider = b.provider
  33. return
  34. }
  35. func (provider *ProfileCredentialsProvider) getCredentialsProvider(ini *ini.File) (credentialsProvider CredentialsProvider, err error) {
  36. section, err := ini.GetSection(provider.profileName)
  37. if err != nil {
  38. err = errors.New("ERROR: Can not load section" + err.Error())
  39. return
  40. }
  41. value, err := section.GetKey("type")
  42. if err != nil {
  43. err = errors.New("ERROR: Can not find credential type" + err.Error())
  44. return
  45. }
  46. switch value.String() {
  47. case "access_key":
  48. value1, err1 := section.GetKey("access_key_id")
  49. value2, err2 := section.GetKey("access_key_secret")
  50. if err1 != nil || err2 != nil {
  51. err = errors.New("ERROR: Failed to get value")
  52. return
  53. }
  54. if value1.String() == "" || value2.String() == "" {
  55. err = errors.New("ERROR: Value can't be empty")
  56. return
  57. }
  58. credentialsProvider, err = NewStaticAKCredentialsProviderBuilder().
  59. WithAccessKeyId(value1.String()).
  60. WithAccessKeySecret(value2.String()).
  61. Build()
  62. case "ecs_ram_role":
  63. value1, err1 := section.GetKey("role_name")
  64. if err1 != nil {
  65. err = errors.New("ERROR: Failed to get value")
  66. return
  67. }
  68. credentialsProvider, err = NewECSRAMRoleCredentialsProviderBuilder().WithRoleName(value1.String()).Build()
  69. case "ram_role_arn":
  70. value1, err1 := section.GetKey("access_key_id")
  71. value2, err2 := section.GetKey("access_key_secret")
  72. value3, err3 := section.GetKey("role_arn")
  73. value4, err4 := section.GetKey("role_session_name")
  74. if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
  75. err = errors.New("ERROR: Failed to get value")
  76. return
  77. }
  78. if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" {
  79. err = errors.New("ERROR: Value can't be empty")
  80. return
  81. }
  82. previous, err5 := NewStaticAKCredentialsProviderBuilder().
  83. WithAccessKeyId(value1.String()).
  84. WithAccessKeySecret(value2.String()).
  85. Build()
  86. if err5 != nil {
  87. err = errors.New("get previous credentials provider failed")
  88. return
  89. }
  90. rawPolicy, _ := section.GetKey("policy")
  91. policy := ""
  92. if rawPolicy != nil {
  93. policy = rawPolicy.String()
  94. }
  95. credentialsProvider, err = NewRAMRoleARNCredentialsProviderBuilder().
  96. WithCredentialsProvider(previous).
  97. WithRoleArn(value3.String()).
  98. WithRoleSessionName(value4.String()).
  99. WithPolicy(policy).
  100. WithDurationSeconds(3600).
  101. Build()
  102. default:
  103. err = errors.New("ERROR: Failed to get credential")
  104. }
  105. return
  106. }
  107. func (provider *ProfileCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
  108. if provider.innerProvider == nil {
  109. sharedCfgPath := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
  110. if sharedCfgPath == "" {
  111. homeDir := getHomePath()
  112. if homeDir == "" {
  113. err = fmt.Errorf("cannot found home dir")
  114. return
  115. }
  116. sharedCfgPath = path.Join(homeDir, ".alibabacloud/credentials")
  117. }
  118. ini, err1 := ini.Load(sharedCfgPath)
  119. if err1 != nil {
  120. err = errors.New("ERROR: Can not open file" + err1.Error())
  121. return
  122. }
  123. provider.innerProvider, err = provider.getCredentialsProvider(ini)
  124. if err != nil {
  125. return
  126. }
  127. }
  128. innerCC, err := provider.innerProvider.GetCredentials()
  129. if err != nil {
  130. return
  131. }
  132. providerName := innerCC.ProviderName
  133. if providerName == "" {
  134. providerName = provider.innerProvider.GetProviderName()
  135. }
  136. cc = &Credentials{
  137. AccessKeyId: innerCC.AccessKeyId,
  138. AccessKeySecret: innerCC.AccessKeySecret,
  139. SecurityToken: innerCC.SecurityToken,
  140. ProviderName: fmt.Sprintf("%s/%s", provider.GetProviderName(), providerName),
  141. }
  142. return
  143. }
  144. func (provider *ProfileCredentialsProvider) GetProviderName() string {
  145. return "profile"
  146. }