Cloudwatch: use the backend HTTP client provider (#44036)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user