GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — master ( b5116a...3bd38f )
by
unknown
05:35
created

credentials/internal/providers/ecs_ram_role.go   A

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 36
eloc 158
dl 0
loc 242
rs 9.52
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
D providers.*ECSRAMRoleCredentialsProvider.getCredentials 0 62 12
A providers.*ECSRAMRoleCredentialsProvider.needUpdateCredential 0 6 2
A providers.*ECSRAMRoleCredentialsProviderBuilder.WithEnableIMDSv2 0 3 1
A providers.*ECSRAMRoleCredentialsProvider.getMetadataToken 0 20 2
A providers.*ECSRAMRoleCredentialsProviderBuilder.WithRoleName 0 3 1
B providers.*ECSRAMRoleCredentialsProvider.getRoleName 0 32 5
A providers.*ECSRAMRoleCredentialsProvider.GetProviderName 0 2 1
A providers.*ECSRAMRoleCredentialsProviderBuilder.WithMetadataTokenDurationSeconds 0 3 1
A providers.*ECSRAMRoleCredentialsProvider.GetCredentials 0 22 5
A providers.NewECSRAMRoleCredentialsProviderBuilder 0 6 1
A providers.*ECSRAMRoleCredentialsProviderBuilder.Build 0 22 5
1
package providers
2
3
import (
4
	"encoding/json"
5
	"errors"
6
	"fmt"
7
	"os"
8
	"strconv"
9
	"strings"
10
	"time"
11
12
	httputil "github.com/aliyun/credentials-go/credentials/internal/http"
13
	"github.com/aliyun/credentials-go/credentials/internal/utils"
14
)
15
16
type ECSRAMRoleCredentialsProvider struct {
17
	roleName                     string
18
	metadataTokenDurationSeconds int
19
	enableIMDSv2                 bool
20
	runtime                      *utils.Runtime
21
	// for sts
22
	session             *sessionCredentials
23
	expirationTimestamp int64
24
}
25
26
type ECSRAMRoleCredentialsProviderBuilder struct {
27
	provider *ECSRAMRoleCredentialsProvider
28
}
29
30
func NewECSRAMRoleCredentialsProviderBuilder() *ECSRAMRoleCredentialsProviderBuilder {
31
	return &ECSRAMRoleCredentialsProviderBuilder{
32
		provider: &ECSRAMRoleCredentialsProvider{
33
			// TBD: 默认启用 IMDS v2
34
			// enableIMDSv2: os.Getenv("ALIBABA_CLOUD_IMDSV2_DISABLED") != "true", // 默认启用 v2
35
		},
36
	}
37
}
38
39
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithMetadataTokenDurationSeconds(metadataTokenDurationSeconds int) *ECSRAMRoleCredentialsProviderBuilder {
40
	builder.provider.metadataTokenDurationSeconds = metadataTokenDurationSeconds
41
	return builder
42
}
43
44
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithRoleName(roleName string) *ECSRAMRoleCredentialsProviderBuilder {
45
	builder.provider.roleName = roleName
46
	return builder
47
}
48
49
func (builder *ECSRAMRoleCredentialsProviderBuilder) WithEnableIMDSv2(enableIMDSv2 bool) *ECSRAMRoleCredentialsProviderBuilder {
50
	builder.provider.enableIMDSv2 = enableIMDSv2
51
	return builder
52
}
53
54
const defaultMetadataTokenDuration = 21600 // 6 hours
55
56
func (builder *ECSRAMRoleCredentialsProviderBuilder) Build() (provider *ECSRAMRoleCredentialsProvider, err error) {
57
	// 设置 roleName 默认值
58
	if builder.provider.roleName == "" {
59
		builder.provider.roleName = os.Getenv("ALIBABA_CLOUD_ECS_METADATA")
60
	}
61
62
	if builder.provider.metadataTokenDurationSeconds == 0 {
63
		builder.provider.metadataTokenDurationSeconds = defaultMetadataTokenDuration
64
	}
65
66
	if builder.provider.metadataTokenDurationSeconds < 1 || builder.provider.metadataTokenDurationSeconds > 21600 {
67
		err = errors.New("the metadata token duration seconds must be 1-21600")
68
		return
69
	}
70
71
	builder.provider.runtime = &utils.Runtime{
72
		ConnectTimeout: 5,
73
		ReadTimeout:    5,
74
	}
75
76
	provider = builder.provider
77
	return
78
}
79
80
type ecsRAMRoleResponse struct {
81
	Code            *string `json:"Code"`
82
	AccessKeyId     *string `json:"AccessKeyId"`
83
	AccessKeySecret *string `json:"AccessKeySecret"`
84
	SecurityToken   *string `json:"SecurityToken"`
85
	LastUpdated     *string `json:"LastUpdated"`
86
	Expiration      *string `json:"Expiration"`
87
}
88
89
func (provider *ECSRAMRoleCredentialsProvider) needUpdateCredential() bool {
90
	if provider.expirationTimestamp == 0 {
91
		return true
92
	}
93
94
	return provider.expirationTimestamp-time.Now().Unix() <= 180
95
}
96
97
func (provider *ECSRAMRoleCredentialsProvider) getRoleName() (roleName string, err error) {
98
	req := &httputil.Request{
99
		Method:         "GET",
100
		Protocol:       "http",
101
		Host:           "100.100.100.200",
102
		Path:           "/latest/meta-data/ram/security-credentials/",
103
		ConnectTimeout: 5 * time.Second,
104
		ReadTimeout:    5 * time.Second,
105
		Headers:        map[string]string{},
106
	}
107
108
	if provider.enableIMDSv2 {
109
		metadataToken, err := provider.getMetadataToken()
110
		if err != nil {
111
			return "", err
112
		}
113
		req.Headers["x-aliyun-ecs-metadata-token"] = metadataToken
114
	}
115
116
	res, err := httpDo(req)
117
	if err != nil {
118
		err = fmt.Errorf("get role name failed: %s", err.Error())
119
		return
120
	}
121
122
	if res.StatusCode != 200 {
123
		err = fmt.Errorf("get role name failed: %s %d", req.BuildRequestURL(), res.StatusCode)
124
		return
125
	}
126
127
	roleName = strings.TrimSpace(string(res.Body))
128
	return
129
}
130
131
func (provider *ECSRAMRoleCredentialsProvider) getCredentials() (session *sessionCredentials, err error) {
132
	roleName := provider.roleName
133
	if roleName == "" {
134
		roleName, err = provider.getRoleName()
135
		if err != nil {
136
			return
137
		}
138
	}
139
140
	req := &httputil.Request{
141
		Method:         "GET",
142
		Protocol:       "http",
143
		Host:           "100.100.100.200",
144
		Path:           "/latest/meta-data/ram/security-credentials/" + roleName,
145
		ConnectTimeout: 5 * time.Second,
146
		ReadTimeout:    5 * time.Second,
147
		Headers:        map[string]string{},
148
	}
149
150
	if provider.enableIMDSv2 {
151
		metadataToken, err := provider.getMetadataToken()
152
		if err != nil {
153
			return nil, err
154
		}
155
		req.Headers["x-aliyun-ecs-metadata-token"] = metadataToken
156
	}
157
158
	res, err := httpDo(req)
159
	if err != nil {
160
		err = fmt.Errorf("refresh Ecs sts token err: %s", err.Error())
161
		return
162
	}
163
164
	if res.StatusCode != 200 {
165
		err = fmt.Errorf("refresh Ecs sts token err, httpStatus: %d, message = %s", res.StatusCode, string(res.Body))
166
		return
167
	}
168
169
	var data ecsRAMRoleResponse
170
	err = json.Unmarshal(res.Body, &data)
171
	if err != nil {
172
		err = fmt.Errorf("refresh Ecs sts token err, json.Unmarshal fail: %s", err.Error())
173
		return
174
	}
175
176
	if data.AccessKeyId == nil || data.AccessKeySecret == nil || data.SecurityToken == nil {
177
		err = fmt.Errorf("refresh Ecs sts token err, fail to get credentials")
178
		return
179
	}
180
181
	if *data.Code != "Success" {
182
		err = fmt.Errorf("refresh Ecs sts token err, Code is not Success")
183
		return
184
	}
185
186
	session = &sessionCredentials{
187
		AccessKeyId:     *data.AccessKeyId,
188
		AccessKeySecret: *data.AccessKeySecret,
189
		SecurityToken:   *data.SecurityToken,
190
		Expiration:      *data.Expiration,
191
	}
192
	return
193
}
194
195
func (provider *ECSRAMRoleCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
196
	if provider.session == nil || provider.needUpdateCredential() {
197
		session, err1 := provider.getCredentials()
198
		if err1 != nil {
199
			return nil, err1
200
		}
201
202
		provider.session = session
203
		expirationTime, err2 := time.Parse("2006-01-02T15:04:05Z", session.Expiration)
204
		if err2 != nil {
205
			return nil, err2
206
		}
207
		provider.expirationTimestamp = expirationTime.Unix()
208
	}
209
210
	cc = &Credentials{
211
		AccessKeyId:     provider.session.AccessKeyId,
212
		AccessKeySecret: provider.session.AccessKeySecret,
213
		SecurityToken:   provider.session.SecurityToken,
214
		ProviderName:    provider.GetProviderName(),
215
	}
216
	return
217
}
218
219
func (provider *ECSRAMRoleCredentialsProvider) GetProviderName() string {
220
	return "ecs_ram_role"
221
}
222
223
func (provider *ECSRAMRoleCredentialsProvider) getMetadataToken() (metadataToken string, err error) {
224
	// PUT http://100.100.100.200/latest/api/token
225
	req := &httputil.Request{
226
		Method:   "PUT",
227
		Protocol: "http",
228
		Host:     "100.100.100.200",
229
		Path:     "/latest/api/token",
230
		Headers: map[string]string{
231
			"X-aliyun-ecs-metadata-token-ttl-seconds": strconv.Itoa(provider.metadataTokenDurationSeconds),
232
		},
233
		ConnectTimeout: 5 * time.Second,
234
		ReadTimeout:    5 * time.Second,
235
	}
236
	res, err := httpDo(req)
237
	if err != nil {
238
		err = fmt.Errorf("get metadata token failed: %s", err.Error())
239
		return
240
	}
241
	metadataToken = string(res.Body)
242
	return
243
}
244