-
Notifications
You must be signed in to change notification settings - Fork 194
/
cvm_role_provider.go
97 lines (83 loc) · 2.5 KB
/
cvm_role_provider.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package common
import (
"errors"
"io/ioutil"
"net/http"
"time"
tcerr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json"
)
const (
metaUrl = "http://metadata.tencentyun.com/latest/meta-data/"
roleUrl = metaUrl + "cam/security-credentials/"
)
var roleNotBound = errors.New("get cvm role name failed, Please confirm whether the role is bound")
type CvmRoleProvider struct {
roleName string
}
type roleRsp struct {
TmpSecretId string `json:"TmpSecretId"`
TmpSecretKey string `json:"TmpSecretKey"`
ExpiredTime int64 `json:"ExpiredTime"`
Expiration time.Time `json:"Expiration"`
Token string `json:"Token"`
Code string `json:"Code"`
}
// NewCvmRoleProvider need you to specify the roleName of the cvm currently in use
func NewCvmRoleProvider(roleName string) *CvmRoleProvider {
return &CvmRoleProvider{roleName: roleName}
}
// DefaultCvmRoleProvider will auto get the cvm role name by accessing the metadata api
// more info please lookup: https://cloud.tencent.com/document/product/213/4934
func DefaultCvmRoleProvider() *CvmRoleProvider {
return NewCvmRoleProvider("")
}
func get(url string) ([]byte, error) {
rsp, err := http.Get(url)
if err != nil {
return nil, err
}
if rsp.StatusCode == http.StatusNotFound {
return nil, roleNotBound
}
body, err := ioutil.ReadAll(rsp.Body)
if err != nil {
return []byte{}, err
}
return body, nil
}
func (r *CvmRoleProvider) getRoleName() (string, error) {
if r.roleName != "" {
return r.roleName, nil
}
rn, err := get(roleUrl)
return string(rn), err
}
func (r *CvmRoleProvider) GetCredential() (CredentialIface, error) {
roleName, err := r.getRoleName()
if err != nil {
return nil, noCvmRole
}
// get the cvm role name by accessing the metadata api
// https://cloud.tencent.com/document/product/213/4934
body, err := get(roleUrl + roleName)
if err != nil {
return nil, err
}
rspSt := new(roleRsp)
if err = json.Unmarshal(body, rspSt); err != nil {
return nil, tcerr.NewTencentCloudSDKError(creErr, err.Error(), "")
}
if rspSt.Code != "Success" {
return nil, tcerr.NewTencentCloudSDKError(creErr, "Get credential from metadata server by role name "+roleName+" failed, code="+rspSt.Code, "")
}
cre := &CvmRoleCredential{
tmpSecretId: rspSt.TmpSecretId,
tmpSecretKey: rspSt.TmpSecretKey,
token: rspSt.Token,
roleName: roleName,
expiredTime: rspSt.ExpiredTime,
source: r,
}
return cre, nil
}