diff --git a/internal/config/aws/credentials.go b/internal/config/aws/credentials.go new file mode 100644 index 000000000..9516702d0 --- /dev/null +++ b/internal/config/aws/credentials.go @@ -0,0 +1,49 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/awslabs/aws-sdk-go/aws/credentials" + "github.com/kelseyhightower/confd/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/kelseyhightower/confd/vendor/github.com/aws/aws-sdk-go/aws/session" +) + +type AwsCredentials struct { + Region string `toml:"region"` // AWS Region + AccessKey string `toml:"access_key"` // Explicit AWS Access Key ID + SecretKey string `toml:"secret_key"` // Explicit AWS Secret Access Key + RoleArn string `toml:"role_arn"` // Role ARN to assume + Profile string `toml:"profile"` // the shared profile to use + SharedCredentialFile string `toml:"shared_credential_file"` // location of shared credential file + Token string `toml:"token"` // STS session token +} + +func (c *AwsCredentials) Credentials() client.ConfigProvider { + if c.RoleArn != "" { + return c.assumeCredentials() + } else { + return c.rootCredentials() + } +} + +func (c *AwsCredentials) rootCredentials() client.ConfigProvider { + config := &aws.Config{ + Region: aws.String(c.Region), + } + if c.AccessKey != "" || c.SecretKey != "" { + config.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, c.Token) + } else if c.Profile != "" || c.SharedCredentialFile != "" { + config.Credentials = credentials.NewSharedCredentials(c.SharedCredentialFile, c.Profile) + } + + return session.New(config) +} + +func (c *AwsCredentials) assumeCredentials() client.ConfigProvider { + rootCredentials := c.rootCredentials() + config := &aws.Config{ + Region: aws.String(c.Region), + } + config.Credentials = stscreds.NewCredentials(rootCredentials, c.RoleArn) + return session.New(config) +} diff --git a/plugins/inputs/cloudwatch/cloudwatch.go b/plugins/inputs/cloudwatch/cloudwatch.go index 8edf2f895..bf6fe7031 100644 --- a/plugins/inputs/cloudwatch/cloudwatch.go +++ b/plugins/inputs/cloudwatch/cloudwatch.go @@ -6,21 +6,18 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/influxdata/telegraf" "github.com/influxdata/telegraf/internal" + influxaws "github.com/influxdata/telegraf/internal/config/aws" "github.com/influxdata/telegraf/plugins/inputs" ) type ( CloudWatch struct { - Region string `toml:"region"` - AccessKey string `toml:"access_key"` - SecretKey string `toml:"secret_key"` + influxaws.AwsCredentials Period internal.Duration `toml:"period"` Delay internal.Duration `toml:"delay"` Namespace string `toml:"namespace"` @@ -58,10 +55,12 @@ func (c *CloudWatch) SampleConfig() string { ## Amazon Credentials ## Credentials are loaded in the following order - ## 1) explicit credentials from 'access_key' and 'secret_key' - ## 2) environment variables - ## 3) shared credentials file - ## 4) EC2 Instance Profile + ## 1) Assumed credentials via STS if role_arn is specified + ## 2) explicit credentials from 'access_key' and 'secret_key' + ## 3) shared profile from 'profile' + ## 4) environment variables + ## 5) shared credentials file + ## 6) EC2 Instance Profile #access_key = "" #secret_key = "" @@ -161,14 +160,9 @@ func init() { * Initialize CloudWatch client */ func (c *CloudWatch) initializeCloudWatch() error { - config := &aws.Config{ - Region: aws.String(c.Region), - } - if c.AccessKey != "" || c.SecretKey != "" { - config.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, "") - } + configProvider := c.Credentials() - c.client = cloudwatch.New(session.New(config)) + c.client = cloudwatch.New(configProvider) return nil } diff --git a/plugins/outputs/cloudwatch/cloudwatch.go b/plugins/outputs/cloudwatch/cloudwatch.go index e4bfa0666..56cbc8111 100644 --- a/plugins/outputs/cloudwatch/cloudwatch.go +++ b/plugins/outputs/cloudwatch/cloudwatch.go @@ -8,19 +8,16 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/influxdata/telegraf" + influxaws "github.com/influxdata/telegraf/internal/config/aws" "github.com/influxdata/telegraf/plugins/outputs" ) type CloudWatch struct { - Region string `toml:"region"` // AWS Region - AccessKey string `toml:"access_key"` // Explicit AWS Access Key ID - SecretKey string `toml:"secret_key"` // Explicit AWS Secret Access Key - Namespace string `toml:"namespace"` // CloudWatch Metrics Namespace + influxaws.AwsCredentials + Namespace string `toml:"namespace"` // CloudWatch Metrics Namespace svc *cloudwatch.CloudWatch } @@ -30,10 +27,12 @@ var sampleConfig = ` ## Amazon Credentials ## Credentials are loaded in the following order - ## 1) explicit credentials from 'access_key' and 'secret_key' - ## 2) environment variables - ## 3) shared credentials file - ## 4) EC2 Instance Profile + ## 1) Assumed credentials via STS if role_arn is specified + ## 2) explicit credentials from 'access_key' and 'secret_key' + ## 3) shared profile from 'profile' + ## 4) environment variables + ## 5) shared credentials file + ## 6) EC2 Instance Profile #access_key = "" #secret_key = "" @@ -50,14 +49,9 @@ func (c *CloudWatch) Description() string { } func (c *CloudWatch) Connect() error { - Config := &aws.Config{ - Region: aws.String(c.Region), - } - if c.AccessKey != "" || c.SecretKey != "" { - Config.Credentials = credentials.NewStaticCredentials(c.AccessKey, c.SecretKey, "") - } + configProvider := c.Credentials() - svc := cloudwatch.New(session.New(Config)) + svc := cloudwatch.New(configProvider) params := &cloudwatch.ListMetricsInput{ Namespace: aws.String(c.Namespace), diff --git a/plugins/outputs/kinesis/kinesis.go b/plugins/outputs/kinesis/kinesis.go index fabec2402..6d2a714d5 100644 --- a/plugins/outputs/kinesis/kinesis.go +++ b/plugins/outputs/kinesis/kinesis.go @@ -8,18 +8,15 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/credentials" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/kinesis" "github.com/influxdata/telegraf" + influxaws "github.com/influxdata/telegraf/internal/config/aws" "github.com/influxdata/telegraf/plugins/outputs" ) type KinesisOutput struct { - Region string `toml:"region"` - AccessKey string `toml:"access_key"` - SecretKey string `toml:"secret_key"` + influxaws.AwsCredentials StreamName string `toml:"streamname"` PartitionKey string `toml:"partitionkey"` Format string `toml:"format"` @@ -33,10 +30,12 @@ var sampleConfig = ` ## Amazon Credentials ## Credentials are loaded in the following order - ## 1) explicit credentials from 'access_key' and 'secret_key' - ## 2) environment variables - ## 3) shared credentials file - ## 4) EC2 Instance Profile + ## 1) Assumed credentials via STS if role_arn is specified + ## 2) explicit credentials from 'access_key' and 'secret_key' + ## 3) shared profile from 'profile' + ## 4) environment variables + ## 5) shared credentials file + ## 6) EC2 Instance Profile #access_key = "" #secret_key = "" @@ -75,13 +74,9 @@ func (k *KinesisOutput) Connect() error { if k.Debug { log.Printf("kinesis: Establishing a connection to Kinesis in %+v", k.Region) } - Config := &aws.Config{ - Region: aws.String(k.Region), - } - if k.AccessKey != "" || k.SecretKey != "" { - Config.Credentials = credentials.NewStaticCredentials(k.AccessKey, k.SecretKey, "") - } - svc := kinesis.New(session.New(Config)) + + configProvider := k.Credentials() + svc := kinesis.New(configProvider) KinesisParams := &kinesis.ListStreamsInput{ Limit: aws.Int64(100),