| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- package providers
- import (
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
- "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
- )
- var securityCredURL = "http://100.100.100.200/latest/meta-data/ram/security-credentials/"
- func NewInstanceMetadataProvider() Provider {
- return &InstanceMetadataProvider{}
- }
- type InstanceMetadataProvider struct {
- RoleName string
- }
- func get(url string) (status int, content string, err error) {
- resp, err := http.Get(url)
- if err != nil {
- return
- }
- defer resp.Body.Close()
- bodyBytes, err := ioutil.ReadAll(resp.Body)
- return resp.StatusCode, string(bodyBytes), err
- }
- func (p *InstanceMetadataProvider) GetRoleName() (roleName string, err error) {
- // Instances can have only one role name that never changes,
- // so attempt to populate it.
- // If this call is executed in an environment that doesn't support instance metadata,
- // it will time out after 30 seconds and return an err.
- status, roleName, err := get(securityCredURL)
- if err != nil {
- return
- }
- if status != 200 {
- err = fmt.Errorf("received %d getting role name: %s", status, roleName)
- return
- }
- if roleName == "" {
- err = errors.New("unable to retrieve role name, it may be unset")
- }
- return
- }
- func (p *InstanceMetadataProvider) Retrieve() (auth.Credential, error) {
- if p.RoleName == "" {
- roleName, err := p.GetRoleName()
- if err != nil {
- return nil, err
- }
- p.RoleName = roleName
- }
- status, content, err := get(securityCredURL + p.RoleName)
- if err != nil {
- return nil, err
- }
- if status != 200 {
- return nil, fmt.Errorf("received %d getting security credentials for %s", status, p.RoleName)
- }
- body := make(map[string]interface{})
- if err := json.Unmarshal([]byte(content), &body); err != nil {
- return nil, err
- }
- accessKeyID, err := extractString(body, "AccessKeyId")
- if err != nil {
- return nil, err
- }
- accessKeySecret, err := extractString(body, "AccessKeySecret")
- if err != nil {
- return nil, err
- }
- securityToken, err := extractString(body, "SecurityToken")
- if err != nil {
- return nil, err
- }
- return credentials.NewStsTokenCredential(accessKeyID, accessKeySecret, securityToken), nil
- }
- func extractString(m map[string]interface{}, key string) (string, error) {
- raw, ok := m[key]
- if !ok {
- return "", fmt.Errorf("%s not in map", key)
- }
- str, ok := raw.(string)
- if !ok {
- return "", fmt.Errorf("%s is not a string in map", key)
- }
- return str, nil
- }
|