| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- 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 (p *InstanceMetadataProvider) Retrieve() (auth.Credential, error) {
- if p.RoleName == "" {
- // 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.
- resp, err := http.Get(securityCredURL)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- bodyBytes, _ := ioutil.ReadAll(resp.Body)
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("received %d getting role name: %s", resp.StatusCode, bodyBytes)
- }
- roleName := string(bodyBytes)
- if roleName == "" {
- return nil, errors.New("unable to retrieve role name, it may be unset")
- }
- p.RoleName = roleName
- }
- resp, err := http.Get(securityCredURL + p.RoleName)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- if resp.StatusCode != 200 {
- return nil, fmt.Errorf("received %d getting security credentials for %s", resp.StatusCode, p.RoleName)
- }
- body := make(map[string]interface{})
- if err := json.NewDecoder(resp.Body).Decode(&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 %+v", key, m)
- }
- str, ok := raw.(string)
- if !ok {
- return "", fmt.Errorf("%s is not a string in %+v", key, m)
- }
- return str, nil
- }
|