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 ( af7c74...f2abf1 )
by Jackson
07:39
created

credentials/internal/providers/ecs_ram_role.go   A

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 36
eloc 149
dl 0
loc 229
rs 9.52
c 0
b 0
f 0

10 Methods

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