@ -3,14 +3,12 @@ package common
import (
"fmt"
"log"
"os"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/hashicorp/go-cleanhttp"
@ -38,66 +36,13 @@ func (c *AccessConfig) Session() (*session.Session, error) {
return c . session , nil
}
// build a chain provider, lazy-evaluated by aws-sdk
providers := [ ] credentials . Provider {
& credentials . StaticProvider { Value : credentials . Value {
AccessKeyID : c . AccessKey ,
SecretAccessKey : c . SecretKey ,
SessionToken : c . Token ,
} } ,
& credentials . EnvProvider { } ,
& credentials . SharedCredentialsProvider {
Filename : "" ,
Profile : c . ProfileName ,
} ,
}
// Build isolated HTTP client to avoid issues with globally-shared settings
client := cleanhttp . DefaultClient ( )
// Keep the default timeout (100ms) low as we don't want to wait in non-EC2 environments
client . Timeout = 100 * time . Millisecond
const userTimeoutEnvVar = "AWS_METADATA_TIMEOUT"
userTimeout := os . Getenv ( userTimeoutEnvVar )
if userTimeout != "" {
newTimeout , err := time . ParseDuration ( userTimeout )
if err == nil {
if newTimeout . Nanoseconds ( ) > 0 {
client . Timeout = newTimeout
} else {
log . Printf ( "[WARN] Non-positive value of %s (%s) is meaningless, ignoring" , userTimeoutEnvVar , newTimeout . String ( ) )
}
} else {
log . Printf ( "[WARN] Error converting %s to time.Duration: %s" , userTimeoutEnvVar , err )
}
}
config := aws . NewConfig ( ) . WithCredentialsChainVerboseErrors ( true )
log . Printf ( "[INFO] Setting AWS metadata API timeout to %s" , client . Timeout . String ( ) )
cfg := & aws . Config {
HTTPClient : client ,
}
if ! c . SkipMetadataApiCheck {
// Real AWS should reply to a simple metadata request.
// We check it actually does to ensure something else didn't just
// happen to be listening on the same IP:Port
metadataClient := ec2metadata . New ( session . New ( cfg ) )
if metadataClient . Available ( ) {
providers = append ( providers , & ec2rolecreds . EC2RoleProvider {
Client : metadataClient ,
} )
log . Print ( "[INFO] AWS EC2 instance detected via default metadata" +
" API endpoint, EC2RoleProvider added to the auth chain" )
} else {
log . Printf ( "[INFO] Ignoring AWS metadata API endpoint " +
"as it doesn't return any instance-id" )
}
staticCreds := credentials . NewStaticCredentials ( c . AccessKey , c . SecretKey , c . Token )
if _ , err := staticCreds . Get ( ) ; err != credentials . ErrStaticCredentialsEmpty {
config . WithCredentials ( staticCreds )
}
creds := credentials . NewChainCredentials ( providers )
config := aws . NewConfig ( ) . WithCredentialsChainVerboseErrors ( true )
if c . RawRegion != "" {
config = config . WithRegion ( c . RawRegion )
} else if region := c . metadataRegion ( ) ; region != "" {
@ -123,8 +68,6 @@ func (c *AccessConfig) Session() (*session.Session, error) {
}
}
config = config . WithCredentials ( creds )
if sess , err := session . NewSessionWithOptions ( opts ) ; err != nil {
return nil , err
} else if * sess . Config . Region == "" {
@ -185,6 +128,9 @@ func (c *AccessConfig) metadataRegion() string {
func ( c * AccessConfig ) Prepare ( ctx * interpolate . Context ) [ ] error {
var errs [ ] error
if c . SkipMetadataApiCheck {
log . Println ( "(WARN) skip_metadata_api_check ignored." )
}
// Either both access and secret key must be set or neither of them should
// be.
if ( len ( c . AccessKey ) > 0 ) != ( len ( c . SecretKey ) > 0 ) {