CloudWatch: Add support for EC2 IAM role (#31804)

* add support for iam role auth

* add stubbable func

* fix broken test

* goimports

* pr feedback
This commit is contained in:
Erik Sundell 2021-03-09 20:50:16 +01:00 committed by GitHub
parent d583875a63
commit 13dd9dff50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 1 deletions

View File

@ -147,6 +147,13 @@ func (e *cloudWatchExecutor) newSession(region string) (*session.Session, error)
})
case authTypeDefault:
plog.Debug("Authenticating towards AWS with default SDK method", "region", dsInfo.Region)
case authTypeEC2IAMRole:
plog.Debug("Authenticating towards AWS with IAM Role", "region", dsInfo.Region)
sess, err := newSession(cfgs...)
if err != nil {
return nil, err
}
cfgs = append(cfgs, &aws.Config{Credentials: newEC2RoleCredentials(sess)})
default:
panic(fmt.Sprintf("Unrecognized authType: %d", dsInfo.AuthType))
}
@ -396,6 +403,7 @@ const (
authTypeDefault authType = iota
authTypeSharedCreds
authTypeKeys
authTypeEC2IAMRole
)
func (at authType) String() string {
@ -403,9 +411,11 @@ func (at authType) String() string {
case authTypeDefault:
return "default"
case authTypeSharedCreds:
return "sharedCreds"
return "credentials"
case authTypeKeys:
return "keys"
case authTypeEC2IAMRole:
return "ec2_iam_role"
default:
panic(fmt.Sprintf("Unrecognized auth type %d", at))
}
@ -432,6 +442,8 @@ func (e *cloudWatchExecutor) getDSInfo(region string) *datasourceInfo {
at = authTypeKeys
case "default":
at = authTypeDefault
case "ec2_iam_role":
at = authTypeEC2IAMRole
case "arn":
at = authTypeDefault
plog.Warn("Authentication type \"arn\" is deprecated, falling back to default")

View File

@ -5,6 +5,8 @@ import (
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
@ -34,3 +36,9 @@ var newSTSCredentials = stscreds.NewCredentials
// Stubbable by tests.
//nolint:gocritic
var newEC2Metadata = ec2metadata.New
// EC2 role credentials factory.
// Stubbable by tests.
var newEC2RoleCredentials = func(sess *session.Session) *credentials.Credentials {
return credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: stscreds.DefaultDuration})
}

View File

@ -7,6 +7,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
@ -105,3 +106,38 @@ func TestNewSession_AssumeRole(t *testing.T) {
assert.Empty(t, diff)
})
}
func TestNewSession_EC2IAMRole(t *testing.T) {
newSession = func(cfgs ...*aws.Config) (*session.Session, error) {
cfg := aws.Config{}
cfg.MergeIn(cfgs...)
return &session.Session{
Config: &cfg,
}, nil
}
newEC2Metadata = func(p client.ConfigProvider, cfgs ...*aws.Config) *ec2metadata.EC2Metadata {
return nil
}
newEC2RoleCredentials = func(sess *session.Session) *credentials.Credentials {
return credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{Client: newEC2Metadata(nil), ExpiryWindow: stscreds.DefaultDuration})
}
t.Run("Credentials are created", func(t *testing.T) {
e := newExecutor(nil)
e.DataSource = fakeDataSource()
e.DataSource.JsonData.Set("authType", "ec2_iam_role")
sess, err := e.newSession(defaultRegion)
require.NoError(t, err)
require.NotNil(t, sess)
expCreds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{
Client: newEC2Metadata(nil), ExpiryWindow: stscreds.DefaultDuration,
})
diff := cmp.Diff(expCreds, sess.Config.Credentials, cmp.Exporter(func(_ reflect.Type) bool {
return true
}), cmpopts.IgnoreFields(stscreds.AssumeRoleProvider{}, "Expiry"))
assert.Empty(t, diff)
})
}