github.com/aliyun/credentials-go@v1.4.7/credentials/providers/profile.go (about)

     1  package providers
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path"
     8  
     9  	"github.com/aliyun/credentials-go/credentials/internal/utils"
    10  	"gopkg.in/ini.v1"
    11  )
    12  
    13  type ProfileCredentialsProvider struct {
    14  	profileName   string
    15  	innerProvider CredentialsProvider
    16  }
    17  
    18  type ProfileCredentialsProviderBuilder struct {
    19  	provider *ProfileCredentialsProvider
    20  }
    21  
    22  func NewProfileCredentialsProviderBuilder() (builder *ProfileCredentialsProviderBuilder) {
    23  	return &ProfileCredentialsProviderBuilder{
    24  		provider: &ProfileCredentialsProvider{},
    25  	}
    26  }
    27  
    28  func (b *ProfileCredentialsProviderBuilder) WithProfileName(profileName string) *ProfileCredentialsProviderBuilder {
    29  	b.provider.profileName = profileName
    30  	return b
    31  }
    32  
    33  func (b *ProfileCredentialsProviderBuilder) Build() (provider *ProfileCredentialsProvider, err error) {
    34  	// 优先级:
    35  	// 1. 使用显示指定的 profileName
    36  	// 2. 使用环境变量(ALIBABA_CLOUD_PROFILE)指定的 profileName
    37  	// 3. 兜底使用 default 作为 profileName
    38  	b.provider.profileName = utils.GetDefaultString(b.provider.profileName, os.Getenv("ALIBABA_CLOUD_PROFILE"), "default")
    39  
    40  	provider = b.provider
    41  	return
    42  }
    43  
    44  func (provider *ProfileCredentialsProvider) getCredentialsProvider(ini *ini.File) (credentialsProvider CredentialsProvider, err error) {
    45  	section, err := ini.GetSection(provider.profileName)
    46  	if err != nil {
    47  		err = errors.New("ERROR: Can not load section" + err.Error())
    48  		return
    49  	}
    50  
    51  	value, err := section.GetKey("type")
    52  	if err != nil {
    53  		err = errors.New("ERROR: Can not find credential type" + err.Error())
    54  		return
    55  	}
    56  
    57  	switch value.String() {
    58  	case "access_key":
    59  		value1, err1 := section.GetKey("access_key_id")
    60  		value2, err2 := section.GetKey("access_key_secret")
    61  		if err1 != nil || err2 != nil {
    62  			err = errors.New("ERROR: Failed to get value")
    63  			return
    64  		}
    65  
    66  		if value1.String() == "" || value2.String() == "" {
    67  			err = errors.New("ERROR: Value can't be empty")
    68  			return
    69  		}
    70  
    71  		credentialsProvider, err = NewStaticAKCredentialsProviderBuilder().
    72  			WithAccessKeyId(value1.String()).
    73  			WithAccessKeySecret(value2.String()).
    74  			Build()
    75  	case "ecs_ram_role":
    76  		value1, err1 := section.GetKey("role_name")
    77  		if err1 != nil {
    78  			err = errors.New("ERROR: Failed to get value")
    79  			return
    80  		}
    81  		credentialsProvider, err = NewECSRAMRoleCredentialsProviderBuilder().WithRoleName(value1.String()).Build()
    82  	case "ram_role_arn":
    83  		value1, err1 := section.GetKey("access_key_id")
    84  		value2, err2 := section.GetKey("access_key_secret")
    85  		value3, err3 := section.GetKey("role_arn")
    86  		value4, err4 := section.GetKey("role_session_name")
    87  		if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
    88  			err = errors.New("ERROR: Failed to get value")
    89  			return
    90  		}
    91  		if value1.String() == "" || value2.String() == "" || value3.String() == "" || value4.String() == "" {
    92  			err = errors.New("ERROR: Value can't be empty")
    93  			return
    94  		}
    95  		previous, err5 := NewStaticAKCredentialsProviderBuilder().
    96  			WithAccessKeyId(value1.String()).
    97  			WithAccessKeySecret(value2.String()).
    98  			Build()
    99  		if err5 != nil {
   100  			err = errors.New("get previous credentials provider failed")
   101  			return
   102  		}
   103  		rawPolicy, _ := section.GetKey("policy")
   104  		policy := ""
   105  		if rawPolicy != nil {
   106  			policy = rawPolicy.String()
   107  		}
   108  
   109  		credentialsProvider, err = NewRAMRoleARNCredentialsProviderBuilder().
   110  			WithCredentialsProvider(previous).
   111  			WithRoleArn(value3.String()).
   112  			WithRoleSessionName(value4.String()).
   113  			WithPolicy(policy).
   114  			WithDurationSeconds(3600).
   115  			Build()
   116  	default:
   117  		err = errors.New("ERROR: Failed to get credential")
   118  	}
   119  	return
   120  }
   121  
   122  func (provider *ProfileCredentialsProvider) GetCredentials() (cc *Credentials, err error) {
   123  	if provider.innerProvider == nil {
   124  		sharedCfgPath := os.Getenv("ALIBABA_CLOUD_CREDENTIALS_FILE")
   125  		if sharedCfgPath == "" {
   126  			homeDir := getHomePath()
   127  			if homeDir == "" {
   128  				err = fmt.Errorf("cannot found home dir")
   129  				return
   130  			}
   131  
   132  			sharedCfgPath = path.Join(homeDir, ".alibabacloud/credentials")
   133  		}
   134  
   135  		ini, err1 := ini.Load(sharedCfgPath)
   136  		if err1 != nil {
   137  			err = errors.New("ERROR: Can not open file" + err1.Error())
   138  			return
   139  		}
   140  
   141  		provider.innerProvider, err = provider.getCredentialsProvider(ini)
   142  		if err != nil {
   143  			return
   144  		}
   145  	}
   146  
   147  	innerCC, err := provider.innerProvider.GetCredentials()
   148  	if err != nil {
   149  		return
   150  	}
   151  
   152  	providerName := innerCC.ProviderName
   153  	if providerName == "" {
   154  		providerName = provider.innerProvider.GetProviderName()
   155  	}
   156  
   157  	cc = &Credentials{
   158  		AccessKeyId:     innerCC.AccessKeyId,
   159  		AccessKeySecret: innerCC.AccessKeySecret,
   160  		SecurityToken:   innerCC.SecurityToken,
   161  		ProviderName:    fmt.Sprintf("%s/%s", provider.GetProviderName(), providerName),
   162  	}
   163  
   164  	return
   165  }
   166  
   167  func (provider *ProfileCredentialsProvider) GetProviderName() string {
   168  	return "profile"
   169  }