cmd/hub/aws/creds.go (95 lines of code) (raw):

// Copyright (c) 2022 EPAM Systems, Inc. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. package aws import ( "fmt" "log" "os" awsaws "github.com/aws/aws-sdk-go/aws" awscredentials "github.com/aws/aws-sdk-go/aws/credentials" awsec2rolecreds "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" awsec2metadata "github.com/aws/aws-sdk-go/aws/ec2metadata" awssession "github.com/aws/aws-sdk-go/aws/session" "github.com/epam/hubctl/cmd/hub/config" ) var ( credentialsCache = make(map[string]*awscredentials.Credentials) ) const optionsHelp = "Try --aws_profile and --aws_region command-line options" func cachedCredentials(purpose string) *awscredentials.Credentials { creds, exist := credentialsCache[purpose] if !exist { creds = DefaultCredentials(purpose) credentialsCache[purpose] = creds } return creds } func ProfileCredentials(profile, purpose string) *awscredentials.Credentials { if config.Debug { printEC2Metadata := "" if config.AwsUseIamRoleCredentials { printEC2Metadata = " and EC2 metadata" } if purpose != "" { purpose = fmt.Sprintf(" to access %s", purpose) } log.Printf("Asking `%s` AWS profile%s for credentials%s", profile, printEC2Metadata, purpose) } shared := &awscredentials.SharedCredentialsProvider{} if profile != "" { shared.Profile = profile } env := &awscredentials.EnvProvider{} providers := []awscredentials.Provider{env, shared} if config.AwsPreferProfileCredentials { providers = []awscredentials.Provider{shared, env} } if config.AwsUseIamRoleCredentials { awsSession, _ := awssession.NewSession() providers = append(providers, &awsec2rolecreds.EC2RoleProvider{Client: awsec2metadata.New(awsSession)}) } return awscredentials.NewCredentials(&awscredentials.ChainProvider{Providers: providers, VerboseErrors: config.Verbose}) } func DefaultCredentials(purpose string) *awscredentials.Credentials { profile := "default" if envProfile := os.Getenv("AWS_PROFILE"); envProfile != "" { profile = envProfile } if config.AwsProfile != "" { profile = config.AwsProfile } return ProfileCredentials(profile, purpose) } func Session(region, purpose string) (*awssession.Session, error) { var session *awssession.Session var err error if config.AwsProfile != "" || !config.AwsUseIamRoleCredentials || config.AwsPreferProfileCredentials { session, err = SessionWithCredentials(region, purpose, cachedCredentials(purpose)) } else { session, err = SessionWithSharedConfig(region) } if err != nil { if purpose != "" { purpose = fmt.Sprintf(" for %s", purpose) } return nil, fmt.Errorf("Error initializing AWS session%s: %v", purpose, err) } return session, nil } func SessionWithStaticCredentials(region, purpose, accessKey, secretKey, token string) (*awssession.Session, error) { return SessionWithCredentials(region, purpose, awscredentials.NewStaticCredentials(accessKey, secretKey, token)) } func SessionWithCredentials(region, purpose string, credentials *awscredentials.Credentials) (*awssession.Session, error) { awsConfig := awsaws.NewConfig() if region != "" { awsConfig = awsConfig.WithRegion(region) } awsConfig = awsConfig.WithCredentials(credentials) return awssession.NewSession(awsConfig) } func SessionWithSharedConfig(region string) (*awssession.Session, error) { options := awssession.Options{SharedConfigState: awssession.SharedConfigEnable} if region != "" { options.Config = *awsaws.NewConfig().WithRegion(region) } return awssession.NewSessionWithOptions(options) }