profile_credentials.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package provider
  2. import (
  3. "bufio"
  4. "errors"
  5. "os"
  6. "runtime"
  7. "strings"
  8. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
  9. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
  10. ini "gopkg.in/ini.v1"
  11. )
  12. type ProfileProvider struct {
  13. Profile string
  14. }
  15. var ProviderProfile = NewProfileProvider()
  16. // NewProfileProvider receive zero or more parameters,
  17. // when length of name is 0, the value of field Profile will be "default",
  18. // and when there are multiple inputs, the function will take the
  19. // first one and discard the other values.
  20. func NewProfileProvider(name ...string) Provider {
  21. p := new(ProfileProvider)
  22. if len(name) == 0 {
  23. p.Profile = "default"
  24. } else {
  25. p.Profile = name[0]
  26. }
  27. return p
  28. }
  29. // Resolve implements the Provider interface
  30. // when credential type is rsa_key_pair, the content of private_key file
  31. // must be able to be parsed directly into the required string
  32. // that NewRsaKeyPairCredential function needed
  33. func (p *ProfileProvider) Resolve() (auth.Credential, error) {
  34. path, ok := os.LookupEnv(ENVCredentialFile)
  35. if !ok {
  36. path, err := checkDefaultPath()
  37. if err != nil {
  38. return nil, err
  39. }
  40. if path == "" {
  41. return nil, nil
  42. }
  43. } else if path == "" {
  44. return nil, errors.New("Environment variable '" + ENVCredentialFile + "' cannot be empty")
  45. }
  46. ini, err := ini.Load(path)
  47. if err != nil {
  48. return nil, errors.New("ERROR: Can not open file" + err.Error())
  49. }
  50. section, err := ini.GetSection(p.Profile)
  51. if err != nil {
  52. return nil, errors.New("ERROR: Can not load section" + err.Error())
  53. }
  54. value, err := section.GetKey("type")
  55. if err != nil {
  56. return nil, errors.New("ERROR: Can not find credential type" + err.Error())
  57. }
  58. switch value.String() {
  59. case "access_key":
  60. value1, err1 := section.GetKey("access_key_id")
  61. value2, err2 := section.GetKey("access_key_secret")
  62. if err1 != nil || err2 != nil {
  63. return nil, errors.New("ERROR: Failed to get value")
  64. }
  65. if value1.String() == "" || value2.String() == "" {
  66. return nil, errors.New("ERROR: Value can't be empty")
  67. }
  68. return credentials.NewAccessKeyCredential(value1.String(), value2.String()), nil
  69. case "ecs_ram_role":
  70. value1, err1 := section.GetKey("role_name")
  71. if err1 != nil {
  72. return nil, errors.New("ERROR: Failed to get value")
  73. }
  74. if value1.String() == "" {
  75. return nil, errors.New("ERROR: Value can't be empty")
  76. }
  77. return credentials.NewEcsRamRoleCredential(value1.String()), nil
  78. case "ram_role_arn":
  79. value1, err1 := section.GetKey("access_key_id")
  80. value2, err2 := section.GetKey("access_key_secret")
  81. value3, err3 := section.GetKey("role_arn")
  82. value4, err4 := section.GetKey("role_session_name")
  83. if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
  84. return nil, errors.New("ERROR: Failed to get value")
  85. }
  86. if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" {
  87. return nil, errors.New("ERROR: Value can't be empty")
  88. }
  89. return credentials.NewRamRoleArnCredential(value1.String(), value2.String(), value3.String(), value4.String(), 3600), nil
  90. case "rsa_key_pair":
  91. value1, err1 := section.GetKey("public_key_id")
  92. value2, err2 := section.GetKey("private_key_file")
  93. if err1 != nil || err2 != nil {
  94. return nil, errors.New("ERROR: Failed to get value")
  95. }
  96. if value1.String() == "" || value2.String() == "" {
  97. return nil, errors.New("ERROR: Value can't be empty")
  98. }
  99. file, err := os.Open(value2.String())
  100. if err != nil {
  101. return nil, errors.New("ERROR: Can not get private_key")
  102. }
  103. defer file.Close()
  104. var privateKey string
  105. scan := bufio.NewScanner(file)
  106. var data string
  107. for scan.Scan() {
  108. if strings.HasPrefix(scan.Text(), "----") {
  109. continue
  110. }
  111. data += scan.Text() + "\n"
  112. }
  113. return credentials.NewRsaKeyPairCredential(privateKey, value1.String(), 3600), nil
  114. default:
  115. return nil, errors.New("ERROR: Failed to get credential")
  116. }
  117. }
  118. // GetHomePath return home directory according to the system.
  119. // if the environmental virables does not exist, will return empty
  120. func GetHomePath() string {
  121. if runtime.GOOS == "windows" {
  122. path, ok := os.LookupEnv("USERPROFILE")
  123. if !ok {
  124. return ""
  125. }
  126. return path
  127. }
  128. path, ok := os.LookupEnv("HOME")
  129. if !ok {
  130. return ""
  131. }
  132. return path
  133. }
  134. func checkDefaultPath() (path string, err error) {
  135. path = GetHomePath()
  136. if path == "" {
  137. return "", errors.New("The default credential file path is invalid")
  138. }
  139. path = strings.Replace("~/.alibabacloud/credentials", "~", path, 1)
  140. _, err = os.Stat(path)
  141. if err != nil {
  142. return "", nil
  143. }
  144. return path, nil
  145. }