Commit 3ef06a0c by Dhananjay Committed by GitHub

Cloudwatch: Add Support for external ID in assume role (#23685)

Co-authored by: Arve Knudsen
parent 2d4bcbef
......@@ -34,6 +34,7 @@ build dashboards or use Explore with CloudWatch metrics and CloudWatch Logs.
| _Auth Provider_ | Specify the provider to get credentials. |
| _Credentials_ profile name | Specify the name of the profile to use (if you use `~/.aws/credentials` file), leave blank for default. |
| _Assume Role Arn_ | Specify the ARN of the role to assume |
| _External ID_ | If you are assuming a role in another account, that has been created with an external ID, specify the exterrnal ID here. |
## Authentication
......
......@@ -25,6 +25,7 @@ require (
github.com/go-sql-driver/mysql v1.5.0
github.com/go-stack/stack v1.8.0
github.com/gobwas/glob v0.2.3
github.com/golang/mock v1.4.3
github.com/golang/protobuf v1.4.0
github.com/google/go-cmp v0.4.0
github.com/gorilla/websocket v1.4.1
......
......@@ -108,7 +108,10 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
......@@ -437,6 +440,7 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
......@@ -450,6 +454,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190802220118-1d1727260058/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
......@@ -526,6 +531,8 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
......
......@@ -32,6 +32,7 @@ type DatasourceInfo struct {
Region string
AuthType string
AssumeRoleArn string
ExternalID string
Namespace string
AccessKey string
......
......@@ -7,6 +7,7 @@ import (
"time"
"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/endpointcreds"
......@@ -18,6 +19,7 @@ import (
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/aws/aws-sdk-go/service/sts/stsiface"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
)
......@@ -30,7 +32,25 @@ type cache struct {
var awsCredentialCache = make(map[string]cache)
var credentialCacheLock sync.RWMutex
func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
// Session factory.
// Stubbable by tests.
var newSession = func(cfgs ...*aws.Config) (*session.Session, error) {
return session.NewSession(cfgs...)
}
// STS service factory.
// Stubbable by tests.
var newSTSService = func(p client.ConfigProvider, cfgs ...*aws.Config) stsiface.STSAPI {
return sts.New(p, cfgs...)
}
// EC2Metadata service factory.
// Stubbable by tests.
var newEC2Metadata = func(p client.ConfigProvider, cfgs ...*aws.Config) *ec2metadata.EC2Metadata {
return ec2metadata.New(p, cfgs...)
}
func getCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
cacheKey := fmt.Sprintf("%s:%s:%s:%s", dsInfo.AuthType, dsInfo.AccessKey, dsInfo.Profile, dsInfo.AssumeRoleArn)
credentialCacheLock.RLock()
if _, ok := awsCredentialCache[cacheKey]; ok {
......@@ -53,8 +73,11 @@ func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
RoleSessionName: aws.String("GrafanaSession"),
DurationSeconds: aws.Int64(900),
}
if dsInfo.ExternalID != "" {
params.ExternalId = aws.String(dsInfo.ExternalID)
}
stsSess, err := session.NewSession()
stsSess, err := newSession()
if err != nil {
return nil, err
}
......@@ -70,11 +93,11 @@ func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
Credentials: stsCreds,
}
sess, err := session.NewSession(stsConfig)
sess, err := newSession(stsConfig)
if err != nil {
return nil, err
}
svc := sts.New(sess, stsConfig)
svc := newSTSService(sess, stsConfig)
resp, err := svc.AssumeRole(params)
if err != nil {
return nil, err
......@@ -91,7 +114,7 @@ func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
expiration = &e
}
sess, err := session.NewSession()
sess, err := newSession()
if err != nil {
return nil, err
}
......@@ -123,7 +146,7 @@ func GetCredentials(dsInfo *DatasourceInfo) (*credentials.Credentials, error) {
}
func webIdentityProvider(sess *session.Session) credentials.Provider {
svc := sts.New(sess)
svc := newSTSService(sess)
roleARN := os.Getenv("AWS_ROLE_ARN")
tokenFilepath := os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE")
......@@ -152,7 +175,7 @@ func ecsCredProvider(sess *session.Session, uri string) credentials.Provider {
}
func ec2RoleProvider(sess *session.Session) credentials.Provider {
return &ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute}
return &ec2rolecreds.EC2RoleProvider{Client: newEC2Metadata(sess), ExpiryWindow: 5 * time.Minute}
}
func (e *CloudWatchExecutor) getDsInfo(region string) *DatasourceInfo {
......@@ -167,6 +190,7 @@ func retrieveDsInfo(datasource *models.DataSource, region string) *DatasourceInf
authType := datasource.JsonData.Get("authType").MustString()
assumeRoleArn := datasource.JsonData.Get("assumeRoleArn").MustString()
externalID := datasource.JsonData.Get("externalId").MustString()
decrypted := datasource.DecryptedValues()
accessKey := decrypted["accessKey"]
secretKey := decrypted["secretKey"]
......@@ -176,6 +200,7 @@ func retrieveDsInfo(datasource *models.DataSource, region string) *DatasourceInf
Profile: datasource.Database,
AuthType: authType,
AssumeRoleArn: assumeRoleArn,
ExternalID: externalID,
AccessKey: accessKey,
SecretKey: secretKey,
}
......@@ -184,7 +209,7 @@ func retrieveDsInfo(datasource *models.DataSource, region string) *DatasourceInf
}
func getAwsConfig(dsInfo *DatasourceInfo) (*aws.Config, error) {
creds, err := GetCredentials(dsInfo)
creds, err := getCredentials(dsInfo)
if err != nil {
return nil, err
}
......@@ -204,7 +229,7 @@ func (e *CloudWatchExecutor) getClient(region string) (*cloudwatch.CloudWatch, e
return nil, err
}
sess, err := session.NewSession(cfg)
sess, err := newSession(cfg)
if err != nil {
return nil, err
}
......@@ -224,7 +249,7 @@ func retrieveLogsClient(datasourceInfo *DatasourceInfo) (*cloudwatchlogs.CloudWa
return nil, err
}
sess, err := session.NewSession(cfg)
sess, err := newSession(cfg)
if err != nil {
return nil, err
}
......
......@@ -4,39 +4,120 @@ import (
"os"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
. "github.com/smartystreets/goconvey/convey"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/aws/aws-sdk-go/service/sts/stsiface"
"github.com/golang/mock/gomock"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch/mock_stsiface"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestECSCredProvider(t *testing.T) {
Convey("Running in an ECS container task", t, func() {
defer os.Clearenv()
os.Setenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/abc/123")
sess, _ := session.NewSession()
provider := remoteCredProvider(sess)
os.Setenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/abc/123")
t.Cleanup(func() {
os.Unsetenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
})
So(provider, ShouldNotBeNil)
sess, err := session.NewSession()
require.NoError(t, err)
provider := remoteCredProvider(sess)
require.NotNil(t, provider)
ecsProvider, ok := provider.(*endpointcreds.Provider)
So(ecsProvider, ShouldNotBeNil)
So(ok, ShouldBeTrue)
ecsProvider, ok := provider.(*endpointcreds.Provider)
require.NotNil(t, ecsProvider)
require.True(t, ok)
So(ecsProvider.Client.Endpoint, ShouldEqual, "http://169.254.170.2/abc/123")
})
assert.Equal(t, "http://169.254.170.2/abc/123", ecsProvider.Client.Endpoint)
}
func TestDefaultEC2RoleProvider(t *testing.T) {
Convey("Running outside an ECS container task", t, func() {
sess, _ := session.NewSession()
provider := remoteCredProvider(sess)
sess, err := session.NewSession()
require.NoError(t, err)
provider := remoteCredProvider(sess)
require.NotNil(t, provider)
ec2Provider, ok := provider.(*ec2rolecreds.EC2RoleProvider)
require.NotNil(t, ec2Provider)
require.True(t, ok)
}
func TestGetCredentials_ARNAuthType(t *testing.T) {
ctrl := gomock.NewController(t)
var stsMock *mock_stsiface.MockSTSAPI
origNewSession := newSession
origNewSTSService := newSTSService
origNewEC2Metadata := newEC2Metadata
t.Cleanup(func() {
newSession = origNewSession
newSTSService = origNewSTSService
newEC2Metadata = origNewEC2Metadata
})
newSession = func(cfgs ...*aws.Config) (*session.Session, error) {
return &session.Session{}, nil
}
newSTSService = func(p client.ConfigProvider, cfgs ...*aws.Config) stsiface.STSAPI {
return stsMock
}
newEC2Metadata = func(p client.ConfigProvider, cfgs ...*aws.Config) *ec2metadata.EC2Metadata {
return nil
}
t.Run("Without external ID", func(t *testing.T) {
stsMock = mock_stsiface.NewMockSTSAPI(ctrl)
stsMock.
EXPECT().
AssumeRole(gomock.Eq(&sts.AssumeRoleInput{
RoleArn: aws.String(""),
DurationSeconds: aws.Int64(900),
RoleSessionName: aws.String("GrafanaSession"),
})).
Return(&sts.AssumeRoleOutput{
Credentials: &sts.Credentials{
AccessKeyId: aws.String("id"),
SecretAccessKey: aws.String("secret"),
SessionToken: aws.String("token"),
},
}, nil).
Times(1)
creds, err := getCredentials(&DatasourceInfo{
AuthType: "arn",
})
require.NoError(t, err)
require.NotNil(t, creds)
})
So(provider, ShouldNotBeNil)
t.Run("With external ID", func(t *testing.T) {
stsMock = mock_stsiface.NewMockSTSAPI(ctrl)
stsMock.
EXPECT().
AssumeRole(gomock.Eq(&sts.AssumeRoleInput{
RoleArn: aws.String(""),
DurationSeconds: aws.Int64(900),
RoleSessionName: aws.String("GrafanaSession"),
ExternalId: aws.String("external-id"),
})).
Return(&sts.AssumeRoleOutput{
Credentials: &sts.Credentials{
AccessKeyId: aws.String("id"),
SecretAccessKey: aws.String("secret"),
SessionToken: aws.String("token"),
},
}, nil).
Times(1)
ec2Provider, ok := provider.(*ec2rolecreds.EC2RoleProvider)
So(ec2Provider, ShouldNotBeNil)
So(ok, ShouldBeTrue)
creds, err := getCredentials(&DatasourceInfo{
AuthType: "arn",
ExternalID: "external-id",
})
require.NoError(t, err)
require.NotNil(t, creds)
})
}
......@@ -740,7 +740,7 @@ func (e *CloudWatchExecutor) resourceGroupsGetResources(region string, filters [
}
func getAllMetrics(cwData *DatasourceInfo) (cloudwatch.ListMetricsOutput, error) {
creds, err := GetCredentials(cwData)
creds, err := getCredentials(cwData)
if err != nil {
return cloudwatch.ListMetricsOutput{}, err
}
......
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/aws/aws-sdk-go/service/sts/stsiface (interfaces: STSAPI)
// Package mock_stsiface is a generated GoMock package.
package mock_stsiface
import (
context "context"
request "github.com/aws/aws-sdk-go/aws/request"
sts "github.com/aws/aws-sdk-go/service/sts"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockSTSAPI is a mock of STSAPI interface
type MockSTSAPI struct {
ctrl *gomock.Controller
recorder *MockSTSAPIMockRecorder
}
// MockSTSAPIMockRecorder is the mock recorder for MockSTSAPI
type MockSTSAPIMockRecorder struct {
mock *MockSTSAPI
}
// NewMockSTSAPI creates a new mock instance
func NewMockSTSAPI(ctrl *gomock.Controller) *MockSTSAPI {
mock := &MockSTSAPI{ctrl: ctrl}
mock.recorder = &MockSTSAPIMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockSTSAPI) EXPECT() *MockSTSAPIMockRecorder {
return m.recorder
}
// AssumeRole mocks base method
func (m *MockSTSAPI) AssumeRole(arg0 *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRole", arg0)
ret0, _ := ret[0].(*sts.AssumeRoleOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRole indicates an expected call of AssumeRole
func (mr *MockSTSAPIMockRecorder) AssumeRole(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRole", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRole), arg0)
}
// AssumeRoleRequest mocks base method
func (m *MockSTSAPI) AssumeRoleRequest(arg0 *sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRoleRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.AssumeRoleOutput)
return ret0, ret1
}
// AssumeRoleRequest indicates an expected call of AssumeRoleRequest
func (mr *MockSTSAPIMockRecorder) AssumeRoleRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleRequest), arg0)
}
// AssumeRoleWithContext mocks base method
func (m *MockSTSAPI) AssumeRoleWithContext(arg0 context.Context, arg1 *sts.AssumeRoleInput, arg2 ...request.Option) (*sts.AssumeRoleOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "AssumeRoleWithContext", varargs...)
ret0, _ := ret[0].(*sts.AssumeRoleOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRoleWithContext indicates an expected call of AssumeRoleWithContext
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithContext), varargs...)
}
// AssumeRoleWithSAML mocks base method
func (m *MockSTSAPI) AssumeRoleWithSAML(arg0 *sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRoleWithSAML", arg0)
ret0, _ := ret[0].(*sts.AssumeRoleWithSAMLOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRoleWithSAML indicates an expected call of AssumeRoleWithSAML
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAML(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAML", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAML), arg0)
}
// AssumeRoleWithSAMLRequest mocks base method
func (m *MockSTSAPI) AssumeRoleWithSAMLRequest(arg0 *sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRoleWithSAMLRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.AssumeRoleWithSAMLOutput)
return ret0, ret1
}
// AssumeRoleWithSAMLRequest indicates an expected call of AssumeRoleWithSAMLRequest
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAMLRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAMLRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAMLRequest), arg0)
}
// AssumeRoleWithSAMLWithContext mocks base method
func (m *MockSTSAPI) AssumeRoleWithSAMLWithContext(arg0 context.Context, arg1 *sts.AssumeRoleWithSAMLInput, arg2 ...request.Option) (*sts.AssumeRoleWithSAMLOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "AssumeRoleWithSAMLWithContext", varargs...)
ret0, _ := ret[0].(*sts.AssumeRoleWithSAMLOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRoleWithSAMLWithContext indicates an expected call of AssumeRoleWithSAMLWithContext
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithSAMLWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithSAMLWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithSAMLWithContext), varargs...)
}
// AssumeRoleWithWebIdentity mocks base method
func (m *MockSTSAPI) AssumeRoleWithWebIdentity(arg0 *sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentity", arg0)
ret0, _ := ret[0].(*sts.AssumeRoleWithWebIdentityOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRoleWithWebIdentity indicates an expected call of AssumeRoleWithWebIdentity
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentity(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentity", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentity), arg0)
}
// AssumeRoleWithWebIdentityRequest mocks base method
func (m *MockSTSAPI) AssumeRoleWithWebIdentityRequest(arg0 *sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentityRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.AssumeRoleWithWebIdentityOutput)
return ret0, ret1
}
// AssumeRoleWithWebIdentityRequest indicates an expected call of AssumeRoleWithWebIdentityRequest
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentityRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentityRequest", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentityRequest), arg0)
}
// AssumeRoleWithWebIdentityWithContext mocks base method
func (m *MockSTSAPI) AssumeRoleWithWebIdentityWithContext(arg0 context.Context, arg1 *sts.AssumeRoleWithWebIdentityInput, arg2 ...request.Option) (*sts.AssumeRoleWithWebIdentityOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "AssumeRoleWithWebIdentityWithContext", varargs...)
ret0, _ := ret[0].(*sts.AssumeRoleWithWebIdentityOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// AssumeRoleWithWebIdentityWithContext indicates an expected call of AssumeRoleWithWebIdentityWithContext
func (mr *MockSTSAPIMockRecorder) AssumeRoleWithWebIdentityWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssumeRoleWithWebIdentityWithContext", reflect.TypeOf((*MockSTSAPI)(nil).AssumeRoleWithWebIdentityWithContext), varargs...)
}
// DecodeAuthorizationMessage mocks base method
func (m *MockSTSAPI) DecodeAuthorizationMessage(arg0 *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecodeAuthorizationMessage", arg0)
ret0, _ := ret[0].(*sts.DecodeAuthorizationMessageOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DecodeAuthorizationMessage indicates an expected call of DecodeAuthorizationMessage
func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessage(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessage", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessage), arg0)
}
// DecodeAuthorizationMessageRequest mocks base method
func (m *MockSTSAPI) DecodeAuthorizationMessageRequest(arg0 *sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DecodeAuthorizationMessageRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.DecodeAuthorizationMessageOutput)
return ret0, ret1
}
// DecodeAuthorizationMessageRequest indicates an expected call of DecodeAuthorizationMessageRequest
func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessageRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessageRequest", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessageRequest), arg0)
}
// DecodeAuthorizationMessageWithContext mocks base method
func (m *MockSTSAPI) DecodeAuthorizationMessageWithContext(arg0 context.Context, arg1 *sts.DecodeAuthorizationMessageInput, arg2 ...request.Option) (*sts.DecodeAuthorizationMessageOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "DecodeAuthorizationMessageWithContext", varargs...)
ret0, _ := ret[0].(*sts.DecodeAuthorizationMessageOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// DecodeAuthorizationMessageWithContext indicates an expected call of DecodeAuthorizationMessageWithContext
func (mr *MockSTSAPIMockRecorder) DecodeAuthorizationMessageWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DecodeAuthorizationMessageWithContext", reflect.TypeOf((*MockSTSAPI)(nil).DecodeAuthorizationMessageWithContext), varargs...)
}
// GetAccessKeyInfo mocks base method
func (m *MockSTSAPI) GetAccessKeyInfo(arg0 *sts.GetAccessKeyInfoInput) (*sts.GetAccessKeyInfoOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAccessKeyInfo", arg0)
ret0, _ := ret[0].(*sts.GetAccessKeyInfoOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAccessKeyInfo indicates an expected call of GetAccessKeyInfo
func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfo(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfo", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfo), arg0)
}
// GetAccessKeyInfoRequest mocks base method
func (m *MockSTSAPI) GetAccessKeyInfoRequest(arg0 *sts.GetAccessKeyInfoInput) (*request.Request, *sts.GetAccessKeyInfoOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAccessKeyInfoRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.GetAccessKeyInfoOutput)
return ret0, ret1
}
// GetAccessKeyInfoRequest indicates an expected call of GetAccessKeyInfoRequest
func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfoRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfoRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfoRequest), arg0)
}
// GetAccessKeyInfoWithContext mocks base method
func (m *MockSTSAPI) GetAccessKeyInfoWithContext(arg0 context.Context, arg1 *sts.GetAccessKeyInfoInput, arg2 ...request.Option) (*sts.GetAccessKeyInfoOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetAccessKeyInfoWithContext", varargs...)
ret0, _ := ret[0].(*sts.GetAccessKeyInfoOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAccessKeyInfoWithContext indicates an expected call of GetAccessKeyInfoWithContext
func (mr *MockSTSAPIMockRecorder) GetAccessKeyInfoWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAccessKeyInfoWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetAccessKeyInfoWithContext), varargs...)
}
// GetCallerIdentity mocks base method
func (m *MockSTSAPI) GetCallerIdentity(arg0 *sts.GetCallerIdentityInput) (*sts.GetCallerIdentityOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCallerIdentity", arg0)
ret0, _ := ret[0].(*sts.GetCallerIdentityOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCallerIdentity indicates an expected call of GetCallerIdentity
func (mr *MockSTSAPIMockRecorder) GetCallerIdentity(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentity", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentity), arg0)
}
// GetCallerIdentityRequest mocks base method
func (m *MockSTSAPI) GetCallerIdentityRequest(arg0 *sts.GetCallerIdentityInput) (*request.Request, *sts.GetCallerIdentityOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCallerIdentityRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.GetCallerIdentityOutput)
return ret0, ret1
}
// GetCallerIdentityRequest indicates an expected call of GetCallerIdentityRequest
func (mr *MockSTSAPIMockRecorder) GetCallerIdentityRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentityRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentityRequest), arg0)
}
// GetCallerIdentityWithContext mocks base method
func (m *MockSTSAPI) GetCallerIdentityWithContext(arg0 context.Context, arg1 *sts.GetCallerIdentityInput, arg2 ...request.Option) (*sts.GetCallerIdentityOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetCallerIdentityWithContext", varargs...)
ret0, _ := ret[0].(*sts.GetCallerIdentityOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCallerIdentityWithContext indicates an expected call of GetCallerIdentityWithContext
func (mr *MockSTSAPIMockRecorder) GetCallerIdentityWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCallerIdentityWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetCallerIdentityWithContext), varargs...)
}
// GetFederationToken mocks base method
func (m *MockSTSAPI) GetFederationToken(arg0 *sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetFederationToken", arg0)
ret0, _ := ret[0].(*sts.GetFederationTokenOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetFederationToken indicates an expected call of GetFederationToken
func (mr *MockSTSAPIMockRecorder) GetFederationToken(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationToken", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationToken), arg0)
}
// GetFederationTokenRequest mocks base method
func (m *MockSTSAPI) GetFederationTokenRequest(arg0 *sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetFederationTokenRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.GetFederationTokenOutput)
return ret0, ret1
}
// GetFederationTokenRequest indicates an expected call of GetFederationTokenRequest
func (mr *MockSTSAPIMockRecorder) GetFederationTokenRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationTokenRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationTokenRequest), arg0)
}
// GetFederationTokenWithContext mocks base method
func (m *MockSTSAPI) GetFederationTokenWithContext(arg0 context.Context, arg1 *sts.GetFederationTokenInput, arg2 ...request.Option) (*sts.GetFederationTokenOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetFederationTokenWithContext", varargs...)
ret0, _ := ret[0].(*sts.GetFederationTokenOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetFederationTokenWithContext indicates an expected call of GetFederationTokenWithContext
func (mr *MockSTSAPIMockRecorder) GetFederationTokenWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFederationTokenWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetFederationTokenWithContext), varargs...)
}
// GetSessionToken mocks base method
func (m *MockSTSAPI) GetSessionToken(arg0 *sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSessionToken", arg0)
ret0, _ := ret[0].(*sts.GetSessionTokenOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSessionToken indicates an expected call of GetSessionToken
func (mr *MockSTSAPIMockRecorder) GetSessionToken(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionToken", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionToken), arg0)
}
// GetSessionTokenRequest mocks base method
func (m *MockSTSAPI) GetSessionTokenRequest(arg0 *sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSessionTokenRequest", arg0)
ret0, _ := ret[0].(*request.Request)
ret1, _ := ret[1].(*sts.GetSessionTokenOutput)
return ret0, ret1
}
// GetSessionTokenRequest indicates an expected call of GetSessionTokenRequest
func (mr *MockSTSAPIMockRecorder) GetSessionTokenRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTokenRequest", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionTokenRequest), arg0)
}
// GetSessionTokenWithContext mocks base method
func (m *MockSTSAPI) GetSessionTokenWithContext(arg0 context.Context, arg1 *sts.GetSessionTokenInput, arg2 ...request.Option) (*sts.GetSessionTokenOutput, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0, arg1}
for _, a := range arg2 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "GetSessionTokenWithContext", varargs...)
ret0, _ := ret[0].(*sts.GetSessionTokenOutput)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetSessionTokenWithContext indicates an expected call of GetSessionTokenWithContext
func (mr *MockSTSAPIMockRecorder) GetSessionTokenWithContext(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0, arg1}, arg2...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSessionTokenWithContext", reflect.TypeOf((*MockSTSAPI)(nil).GetSessionTokenWithContext), varargs...)
}
......@@ -42,6 +42,7 @@ const setup = (propOverrides?: object) => {
},
jsonData: {
assumeRoleArn: '',
externalId: '',
database: '',
customMetricsNamespaces: '',
authType: 'keys',
......
......@@ -130,6 +130,7 @@ export class ConfigEditor extends PureComponent<Props, State> {
onChange={option => {
if (options.jsonData.authType === 'arn' && option.value !== 'arn') {
delete this.props.options.jsonData.assumeRoleArn;
delete this.props.options.jsonData.externalId;
}
onUpdateDatasourceJsonDataOptionSelect(this.props, 'authType')(option);
}}
......@@ -239,6 +240,22 @@ export class ConfigEditor extends PureComponent<Props, State> {
/>
</div>
</div>
<div className="gf-form">
<InlineFormLabel
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</InlineFormLabel>
<div className="width-30">
<Input
className="width-30"
placeholder="External ID"
value={options.jsonData.externalId || ''}
onChange={onUpdateDatasourceJsonDataOption(this.props, 'externalId')}
/>
</div>
</div>
</div>
)}
<div className="gf-form-inline">
......
......@@ -59,6 +59,7 @@ export type SelectableStrings = Array<SelectableValue<string>>;
export interface CloudWatchJsonData extends DataSourceJsonData {
timeField?: string;
assumeRoleArn?: string;
externalId?: string;
database?: string;
customMetricsNamespaces?: string;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment