diff --git a/go.mod b/go.mod index a6b10ddbae9..6f2312a020a 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/gosimple/slug v1.9.0 github.com/grafana/cuetsy v0.0.0-20211119211437-8c25464cc9bf - github.com/grafana/grafana-aws-sdk v0.7.0 + github.com/grafana/grafana-aws-sdk v0.9.1 github.com/grafana/grafana-plugin-sdk-go v0.121.0 github.com/grafana/loki v1.6.2-0.20211015002020-7832783b1caa github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 diff --git a/go.sum b/go.sum index 8ee7b4e3291..417e57d30b2 100644 --- a/go.sum +++ b/go.sum @@ -175,6 +175,7 @@ github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3 github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -1234,9 +1235,14 @@ github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5J github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/grafana/grafana-aws-sdk v0.7.0 h1:D+Lhxi3P/7vpyDHUK/fdX9bL2mRz8hLG04ucNf1E02o= github.com/grafana/grafana-aws-sdk v0.7.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U= +github.com/grafana/grafana-aws-sdk v0.9.0 h1:oAEpSlNaD09S25F2TX8WwxCwnKk/ModUh0Uxgl+NP6M= +github.com/grafana/grafana-aws-sdk v0.9.0/go.mod h1:6KaQ8uUD4KpXr/b7bAC7zbfSXTVOiTk4XhIrwkGWn4w= +github.com/grafana/grafana-aws-sdk v0.9.1 h1:jMZlsLsWnqOwLt2UNcLUsJ2z6289hLYlscK35QgS158= +github.com/grafana/grafana-aws-sdk v0.9.1/go.mod h1:6KaQ8uUD4KpXr/b7bAC7zbfSXTVOiTk4XhIrwkGWn4w= github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58 h1:2ud7NNM7LrGPO4x0NFR8qLq68CqI4SmB7I2yRN2w9oE= github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58/go.mod h1:Vo2TKWfDVmNTELBUM+3lkrZvFtBws0qSZdXhQxRdJrE= github.com/grafana/grafana-plugin-sdk-go v0.79.0/go.mod h1:NvxLzGkVhnoBKwzkst6CFfpMFKwAdIUZ1q8ssuLeF60= +github.com/grafana/grafana-plugin-sdk-go v0.94.0/go.mod h1:3VXz4nCv6wH5SfgB3mlW39s+c+LetqSCjFj7xxPC5+M= github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk= github.com/grafana/grafana-plugin-sdk-go v0.121.0 h1:4+dXoezL9L40iu7ym4u7ZJ4OE57NaVc4WSHlbxtCtGM= github.com/grafana/grafana-plugin-sdk-go v0.121.0/go.mod h1:Mhy+5mC6rSqEhnzop1wEh//n/fgkzNK5pRgg3DfCp4g= @@ -1244,6 +1250,7 @@ github.com/grafana/loki v1.6.2-0.20211015002020-7832783b1caa h1:+pXjAxavVR2FKKNs github.com/grafana/loki v1.6.2-0.20211015002020-7832783b1caa/go.mod h1:0O8o/juxNSKN/e+DzWDTRkl7Zm8CkZcz0NDqEdojlrk= github.com/grafana/saml v0.0.0-20211007135653-aed1b2edd86b h1:YiSGp34F4V0G08HHx1cJBf2GVgwYAkXQjzuVs1t8jYk= github.com/grafana/saml v0.0.0-20211007135653-aed1b2edd86b/go.mod h1:q83kyQoMD0vhy+RzFLlbw0UgHJ6TAihQpuXvdFmm4s4= +github.com/grafana/sqlds/v2 v2.3.2/go.mod h1:34uyqPBWsEvg4V/xxh6V4uIqwu1qLfOfsmScll/ukrk= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index 8ef02c05fcd..676b83cc898 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -4,11 +4,12 @@ import ( "context" "encoding/json" "fmt" + "net/http" "regexp" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/client" - "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatch" "github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface" @@ -24,6 +25,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" @@ -43,6 +45,8 @@ type datasourceInfo struct { secretKey string datasourceID int64 + + HTTPClient *http.Client } const cloudWatchTSFormat = "2006-01-02 15:04:05.000" @@ -57,10 +61,10 @@ const pluginID = "cloudwatch" var plog = log.New("tsdb.cloudwatch") var aliasFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) -func ProvideService(cfg *setting.Cfg, logsService *LogsService, pluginStore plugins.Store) (*CloudWatchService, error) { +func ProvideService(cfg *setting.Cfg, logsService *LogsService, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*CloudWatchService, error) { plog.Debug("initing") - executor := newExecutor(logsService, datasource.NewInstanceManager(NewInstanceSettings()), cfg, awsds.NewSessionCache()) + executor := newExecutor(logsService, datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), cfg, awsds.NewSessionCache()) factory := coreplugin.New(backend.ServeOpts{ QueryDataHandler: executor, }) @@ -85,7 +89,7 @@ type CloudWatchService struct { } type SessionCache interface { - GetSession(region string, s awsds.AWSDatasourceSettings) (*session.Session, error) + GetSession(c awsds.SessionConfig) (*session.Session, error) } func newExecutor(logsService *LogsService, im instancemgmt.InstanceManager, cfg *setting.Cfg, sessions SessionCache) *cloudWatchExecutor { @@ -97,7 +101,7 @@ func newExecutor(logsService *LogsService, im instancemgmt.InstanceManager, cfg } } -func NewInstanceSettings() datasource.InstanceFactoryFunc { +func NewInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc { return func(settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) { jsonData := struct { Profile string `json:"profile"` @@ -114,6 +118,11 @@ func NewInstanceSettings() datasource.InstanceFactoryFunc { return nil, fmt.Errorf("error reading settings: %w", err) } + httpClient, err := httpClientProvider.New() + if err != nil { + return nil, fmt.Errorf("error creating http client: %w", err) + } + model := datasourceInfo{ profile: jsonData.Profile, region: jsonData.Region, @@ -122,6 +131,7 @@ func NewInstanceSettings() datasource.InstanceFactoryFunc { endpoint: jsonData.Endpoint, namespace: jsonData.Namespace, datasourceID: settings.ID, + HTTPClient: httpClient, } at := awsds.AuthTypeDefault @@ -172,16 +182,20 @@ func (e *cloudWatchExecutor) newSession(region string, pluginCtx backend.PluginC region = dsInfo.region } - return e.sessions.GetSession(region, awsds.AWSDatasourceSettings{ - Profile: dsInfo.profile, - Region: region, - AuthType: dsInfo.authType, - AssumeRoleARN: dsInfo.assumeRoleARN, - ExternalID: dsInfo.externalID, - Endpoint: dsInfo.endpoint, - DefaultRegion: dsInfo.region, - AccessKey: dsInfo.accessKey, - SecretKey: dsInfo.secretKey, + return e.sessions.GetSession(awsds.SessionConfig{ + HTTPClient: dsInfo.HTTPClient, + Settings: awsds.AWSDatasourceSettings{ + Profile: dsInfo.profile, + Region: region, + AuthType: dsInfo.authType, + AssumeRoleARN: dsInfo.assumeRoleARN, + ExternalID: dsInfo.externalID, + Endpoint: dsInfo.endpoint, + DefaultRegion: dsInfo.region, + AccessKey: dsInfo.accessKey, + SecretKey: dsInfo.secretKey, + }, + UserAgentName: aws.String("Cloudwatch"), }) } @@ -383,24 +397,14 @@ func isTerminated(queryStatus string) bool { // // Stubbable by tests. var NewCWClient = func(sess *session.Session) cloudwatchiface.CloudWatchAPI { - client := cloudwatch.New(sess) - client.Handlers.Send.PushFront(func(r *request.Request) { - r.HTTPRequest.Header.Set("User-Agent", fmt.Sprintf("Grafana/%s", setting.BuildVersion)) - }) - - return client + return cloudwatch.New(sess) } // NewCWLogsClient is a CloudWatch logs client factory. // // Stubbable by tests. var NewCWLogsClient = func(sess *session.Session) cloudwatchlogsiface.CloudWatchLogsAPI { - client := cloudwatchlogs.New(sess) - client.Handlers.Send.PushFront(func(r *request.Request) { - r.HTTPRequest.Header.Set("User-Agent", fmt.Sprintf("Grafana/%s", setting.BuildVersion)) - }) - - return client + return cloudwatchlogs.New(sess) } // EC2 client factory. diff --git a/pkg/tsdb/cloudwatch/cloudwatch_test.go b/pkg/tsdb/cloudwatch/cloudwatch_test.go index def00c2e7e2..928667d61f9 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_test.go @@ -6,6 +6,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/grafana/grafana-aws-sdk/pkg/awsds" "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/stretchr/testify/require" ) @@ -50,7 +51,7 @@ func TestNewInstanceSettings(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - f := NewInstanceSettings() + f := NewInstanceSettings(httpclient.NewProvider()) model, err := f(tt.settings) tt.Err(t, err) datasourceComparer := cmp.Comparer(func(d1 datasourceInfo, d2 datasourceInfo) bool { diff --git a/pkg/tsdb/cloudwatch/test_utils.go b/pkg/tsdb/cloudwatch/test_utils.go index 9633606cbe8..a6727f74ca0 100644 --- a/pkg/tsdb/cloudwatch/test_utils.go +++ b/pkg/tsdb/cloudwatch/test_utils.go @@ -162,7 +162,7 @@ func newTestConfig() *setting.Cfg { type fakeSessionCache struct { } -func (s fakeSessionCache) GetSession(region string, settings awsds.AWSDatasourceSettings) (*session.Session, error) { +func (s fakeSessionCache) GetSession(c awsds.SessionConfig) (*session.Session, error) { return &session.Session{ Config: &aws.Config{}, }, nil