pkg/alibabacloudconfig/alibabacloudconfig.go (153 lines of code) (raw):

package alibabacloudconfig import ( "io/ioutil" "os" "path" "path/filepath" "runtime" config "github.com/aliyun/aliyun-cli/config" homedir "github.com/mitchellh/go-homedir" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) var ( // ErrCredentialsHomeNotFound returned when a user home directory can't be located. ErrCredentialsHomeNotFound = errors.New("user home directory not found") // ErrCredentialsNotFound returned when the required AlibabaCloud CLI credentials don't exist. ErrCredentialsNotFound = errors.New("AlibabaCloud CLI credentials not found") logger = logrus.WithField("pkg", "alibabacloudconfig") ) // AliCloudCredentials represents the set of attributes used to authenticate to AlibabaCloud with a short lived session type AliCloudCredentials struct { AliCloudAccessKey string `json:"access_key_id"` AliCloudSecretKey string `json:"access_key_secret"` AliCloudSessionToken string `json:"ram_session_name"` AliCloudSecurityToken string `json:"sts_token"` PrincipalARN string `json:"ram_role_arn"` Region string `json:"region,omitempty"` } // CredentialsProvider loads AlibabaCloud CLI credentials file type CredentialsProvider struct { Filename string Profile string } // NewSharedCredentials helper to create the credentials provider func NewSharedCredentials(profile string) *CredentialsProvider { return &CredentialsProvider{ Profile: profile, } } // CredsExists verify that the credentials exist func (p *CredentialsProvider) CredsExists() (bool, error) { filename, err := p.resolveFilename() if err != nil { return false, err } err = p.ensureConfigExists() if err != nil { if os.IsNotExist(err) { return false, nil } return false, errors.Wrapf(err, "unable to load file %s", filename) } return true, nil } // Save persist the credentials func (p *CredentialsProvider) Save(alibabacloudCreds *AliCloudCredentials) error { configuration, err := config.LoadConfiguration(config.GetConfigPath()+"/config.json", os.Stdout) if err != nil { return err } profile := config.Profile{ Name: p.Profile, Mode: config.StsToken, AccessKeyId: alibabacloudCreds.AliCloudAccessKey, AccessKeySecret: alibabacloudCreds.AliCloudSecretKey, StsToken: alibabacloudCreds.AliCloudSecurityToken, RegionId: alibabacloudCreds.Region, OutputFormat: "json", Language: "en", } configuration.PutProfile(profile) return config.SaveConfiguration(configuration) } // Load load the AlibabaCloud CLI credentials file func (p *CredentialsProvider) Load() (*AliCloudCredentials, error) { _, err := p.resolveFilename() if err != nil { return nil, err } configuration, err := config.LoadConfiguration(config.GetConfigPath()+"/config.json", os.Stdout) if err != nil { return nil, err } profile, ret := configuration.GetProfile(p.Profile) if !ret { return nil, errors.New("profile not found in AlibabaCloud CLI credentials") } return &AliCloudCredentials{ AliCloudAccessKey: profile.AccessKeyId, AliCloudSecretKey: profile.AccessKeySecret, AliCloudSessionToken: profile.RoleSessionName, AliCloudSecurityToken: profile.StsToken, PrincipalARN: profile.RamRoleArn, }, nil } // Expired checks if the current credentials are expired func (p *CredentialsProvider) Expired() bool { // _, err := p.Load() // if err != nil { // return true // } return true } // ensureConfigExists verify that the config file exists func (p *CredentialsProvider) ensureConfigExists() error { filename, err := p.resolveFilename() if err != nil { return err } logger.WithField("filename", filename).Debug("ensureConfigExists") if _, err := os.Stat(filename); err != nil { if os.IsNotExist(err) { dir := filepath.Dir(filename) err = os.MkdirAll(dir, os.ModePerm) if err != nil { return err } logger.WithField("dir", dir).Debug("Dir created") // create an base config file err = ioutil.WriteFile(filename, []byte("["+p.Profile+"]"), 0600) if err != nil { return err } logger.WithField("filename", filename).Debug("File created") } return err } return nil } func (p *CredentialsProvider) resolveFilename() (string, error) { if p.Filename == "" { filename, err := locateConfigFile() if err != nil { return "", err } p.Filename = filename } return p.Filename, nil } func locateConfigFile() (string, error) { var name string var err error if runtime.GOOS == "windows" { name = path.Join(os.Getenv("USERPROFILE"), ".aliyun", "config.json") } else { name, err = homedir.Expand("~/.aliyun/config.json") if err != nil { return "", ErrCredentialsHomeNotFound } } logger.WithField("name", name).Debug("Expand") // is the filename a symlink? name, err = resolveSymlink(name) if err != nil { return "", errors.Wrap(err, "unable to resolve symlink") } logger.WithField("name", name).Debug("resolveSymlink") return name, nil } func resolveSymlink(filename string) (string, error) { sympath, err := filepath.EvalSymlinks(filename) // return the un modified filename if os.IsNotExist(err) { return filename, nil } if err != nil { return "", err } return sympath, nil }