Cloudwatch: use the backend HTTP client provider (#44036)

This commit is contained in:
Andres Martinez Gotor
2022-01-18 09:34:12 +01:00
committed by GitHub
parent fffd4c10b7
commit 4e1c7e868e
5 changed files with 42 additions and 30 deletions
+31 -27
View File
@@ -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.
+2 -1
View File
@@ -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 {
+1 -1
View File
@@ -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