1 package credentials
2
3 import (
4 "encoding/json"
5 "fmt"
6 "time"
7
8 "github.com/alibabacloud-go/tea/tea"
9 "github.com/aliyun/credentials-go/credentials/request"
10 "github.com/aliyun/credentials-go/credentials/utils"
11 )
12
13 var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
14
15
16 type EcsRAMRoleCredential struct {
17 *credentialUpdater
18 RoleName string
19 sessionCredential *sessionCredential
20 runtime *utils.Runtime
21 }
22
23 type ecsRAMRoleResponse struct {
24 Code string `json:"Code" xml:"Code"`
25 AccessKeyId string `json:"AccessKeyId" xml:"AccessKeyId"`
26 AccessKeySecret string `json:"AccessKeySecret" xml:"AccessKeySecret"`
27 SecurityToken string `json:"SecurityToken" xml:"SecurityToken"`
28 Expiration string `json:"Expiration" xml:"Expiration"`
29 }
30
31 func newEcsRAMRoleCredential(roleName string, inAdvanceScale float64, runtime *utils.Runtime) *EcsRAMRoleCredential {
32 credentialUpdater := new(credentialUpdater)
33 if inAdvanceScale < 1 && inAdvanceScale > 0 {
34 credentialUpdater.inAdvanceScale = inAdvanceScale
35 }
36 return &EcsRAMRoleCredential{
37 RoleName: roleName,
38 credentialUpdater: credentialUpdater,
39 runtime: runtime,
40 }
41 }
42
43 func (e *EcsRAMRoleCredential) GetCredential() (*CredentialModel, error) {
44 if e.sessionCredential == nil || e.needUpdateCredential() {
45 err := e.updateCredential()
46 if err != nil {
47 return nil, err
48 }
49 }
50 credential := &CredentialModel{
51 AccessKeyId: tea.String(e.sessionCredential.AccessKeyId),
52 AccessKeySecret: tea.String(e.sessionCredential.AccessKeySecret),
53 SecurityToken: tea.String(e.sessionCredential.SecurityToken),
54 Type: tea.String("ecs_ram_role"),
55 }
56 return credential, nil
57 }
58
59
60
61 func (e *EcsRAMRoleCredential) GetAccessKeyId() (*string, error) {
62 if e.sessionCredential == nil || e.needUpdateCredential() {
63 err := e.updateCredential()
64 if err != nil {
65 if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) {
66 return &e.sessionCredential.AccessKeyId, nil
67 }
68 return tea.String(""), err
69 }
70 }
71 return tea.String(e.sessionCredential.AccessKeyId), nil
72 }
73
74
75
76 func (e *EcsRAMRoleCredential) GetAccessKeySecret() (*string, error) {
77 if e.sessionCredential == nil || e.needUpdateCredential() {
78 err := e.updateCredential()
79 if err != nil {
80 if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) {
81 return &e.sessionCredential.AccessKeySecret, nil
82 }
83 return tea.String(""), err
84 }
85 }
86 return tea.String(e.sessionCredential.AccessKeySecret), nil
87 }
88
89
90
91 func (e *EcsRAMRoleCredential) GetSecurityToken() (*string, error) {
92 if e.sessionCredential == nil || e.needUpdateCredential() {
93 err := e.updateCredential()
94 if err != nil {
95 if e.credentialExpiration > (int(time.Now().Unix()) - int(e.lastUpdateTimestamp)) {
96 return &e.sessionCredential.SecurityToken, nil
97 }
98 return tea.String(""), err
99 }
100 }
101 return tea.String(e.sessionCredential.SecurityToken), nil
102 }
103
104
105 func (e *EcsRAMRoleCredential) GetBearerToken() *string {
106 return tea.String("")
107 }
108
109
110 func (e *EcsRAMRoleCredential) GetType() *string {
111 return tea.String("ecs_ram_role")
112 }
113
114 func getRoleName() (string, error) {
115 runtime := utils.NewRuntime(1, 1, "", "")
116 request := request.NewCommonRequest()
117 request.URL = securityCredURL
118 request.Method = "GET"
119 content, err := doAction(request, runtime)
120 if err != nil {
121 return "", err
122 }
123 return string(content), nil
124 }
125
126 func (e *EcsRAMRoleCredential) updateCredential() (err error) {
127 if e.runtime == nil {
128 e.runtime = new(utils.Runtime)
129 }
130 request := request.NewCommonRequest()
131 if e.RoleName == "" {
132 e.RoleName, err = getRoleName()
133 if err != nil {
134 return fmt.Errorf("refresh Ecs sts token err: %s", err.Error())
135 }
136 }
137 request.URL = securityCredURL + e.RoleName
138 request.Method = "GET"
139 content, err := doAction(request, e.runtime)
140 if err != nil {
141 return fmt.Errorf("refresh Ecs sts token err: %s", err.Error())
142 }
143 var resp *ecsRAMRoleResponse
144 err = json.Unmarshal(content, &resp)
145 if err != nil {
146 return fmt.Errorf("refresh Ecs sts token err: Json Unmarshal fail: %s", err.Error())
147 }
148 if resp.Code != "Success" {
149 return fmt.Errorf("refresh Ecs sts token err: Code is not Success")
150 }
151 if resp.AccessKeyId == "" || resp.AccessKeySecret == "" || resp.SecurityToken == "" || resp.Expiration == "" {
152 return fmt.Errorf("refresh Ecs sts token err: AccessKeyId: %s, AccessKeySecret: %s, SecurityToken: %s, Expiration: %s", resp.AccessKeyId, resp.AccessKeySecret, resp.SecurityToken, resp.Expiration)
153 }
154
155 expirationTime, err := time.Parse("2006-01-02T15:04:05Z", resp.Expiration)
156 e.lastUpdateTimestamp = time.Now().Unix()
157 e.credentialExpiration = int(expirationTime.Unix() - time.Now().Unix())
158 e.sessionCredential = &sessionCredential{
159 AccessKeyId: resp.AccessKeyId,
160 AccessKeySecret: resp.AccessKeySecret,
161 SecurityToken: resp.SecurityToken,
162 }
163
164 return
165 }
166
View as plain text