mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 08:52:38 +08:00

Remove usage of http.DefaultClient and http.DefaultTransport Part of grafana/data-sources#484
111 lines
4.0 KiB
Go
111 lines
4.0 KiB
Go
package httpclientprovider
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/grafana/grafana-aws-sdk/pkg/awsds"
|
|
awssdk "github.com/grafana/grafana-aws-sdk/pkg/sigv4"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
|
|
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
|
"github.com/mwitkow/go-conntrack"
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/infra/metrics/metricutil"
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
|
"github.com/grafana/grafana/pkg/services/validations"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
var newProviderFunc = sdkhttpclient.NewProvider
|
|
|
|
// New creates a new HTTP client provider with pre-configured middlewares.
|
|
func New(cfg *setting.Cfg, validator validations.DataSourceRequestURLValidator, tracer tracing.Tracer) *sdkhttpclient.Provider {
|
|
logger := log.New("httpclient")
|
|
|
|
middlewares := []sdkhttpclient.Middleware{
|
|
TracingMiddleware(logger, tracer),
|
|
DataSourceMetricsMiddleware(),
|
|
sdkhttpclient.ContextualMiddleware(),
|
|
SetUserAgentMiddleware(cfg.DataProxyUserAgent),
|
|
sdkhttpclient.BasicAuthenticationMiddleware(),
|
|
sdkhttpclient.CustomHeadersMiddleware(),
|
|
sdkhttpclient.ResponseLimitMiddleware(cfg.ResponseLimit),
|
|
RedirectLimitMiddleware(validator),
|
|
}
|
|
|
|
if httpLoggingEnabled(cfg.PluginSettings) {
|
|
middlewares = append(middlewares, HTTPLoggerMiddleware(cfg.PluginSettings))
|
|
}
|
|
|
|
if cfg.IPRangeACEnabled {
|
|
middlewares = append(middlewares, GrafanaRequestIDHeaderMiddleware(cfg, logger))
|
|
}
|
|
|
|
middlewares = append(middlewares, sdkhttpclient.ErrorSourceMiddleware())
|
|
|
|
// SigV4 signing should be performed after all headers are added
|
|
if cfg.SigV4AuthEnabled {
|
|
authSettings := awsds.AuthSettings{
|
|
AllowedAuthProviders: cfg.AWSAllowedAuthProviders,
|
|
AssumeRoleEnabled: cfg.AWSAssumeRoleEnabled,
|
|
ExternalID: cfg.AWSExternalId,
|
|
ListMetricsPageLimit: cfg.AWSListMetricsPageLimit,
|
|
SecureSocksDSProxyEnabled: cfg.SecureSocksDSProxy.Enabled,
|
|
}
|
|
if cfg.AWSSessionDuration != "" {
|
|
sessionDuration, err := gtime.ParseDuration(cfg.AWSSessionDuration)
|
|
if err == nil {
|
|
authSettings.SessionDuration = &sessionDuration
|
|
}
|
|
}
|
|
|
|
middlewares = append(middlewares, awssdk.SigV4MiddlewareWithAuthSettings(cfg.SigV4VerboseLogging, authSettings))
|
|
}
|
|
|
|
setDefaultTimeoutOptions(cfg)
|
|
|
|
return newProviderFunc(sdkhttpclient.ProviderOptions{
|
|
Middlewares: middlewares,
|
|
ConfigureTransport: func(opts sdkhttpclient.Options, transport *http.Transport) {
|
|
datasourceName, exists := opts.Labels["datasource_name"]
|
|
if !exists {
|
|
return
|
|
}
|
|
datasourceLabelName, err := metricutil.SanitizeLabelName(datasourceName)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
newConntrackRoundTripper(datasourceLabelName, transport)
|
|
},
|
|
})
|
|
}
|
|
|
|
// newConntrackRoundTripper takes a http.Transport and adds the Conntrack Dialer
|
|
// so we can instrument outbound connections
|
|
func newConntrackRoundTripper(name string, transport *http.Transport) *http.Transport {
|
|
transport.DialContext = conntrack.NewDialContextFunc(
|
|
conntrack.DialWithName(name),
|
|
conntrack.DialWithDialContextFunc(transport.DialContext),
|
|
)
|
|
return transport
|
|
}
|
|
|
|
// setDefaultTimeoutOptions overrides the default timeout options for the SDK.
|
|
//
|
|
// Note: Not optimal changing global state, but hard to not do in this case.
|
|
func setDefaultTimeoutOptions(cfg *setting.Cfg) {
|
|
sdkhttpclient.DefaultTimeoutOptions = sdkhttpclient.TimeoutOptions{
|
|
Timeout: time.Duration(cfg.DataProxyTimeout) * time.Second,
|
|
DialTimeout: time.Duration(cfg.DataProxyDialTimeout) * time.Second,
|
|
KeepAlive: time.Duration(cfg.DataProxyKeepAlive) * time.Second,
|
|
TLSHandshakeTimeout: time.Duration(cfg.DataProxyTLSHandshakeTimeout) * time.Second,
|
|
ExpectContinueTimeout: time.Duration(cfg.DataProxyExpectContinueTimeout) * time.Second,
|
|
MaxConnsPerHost: cfg.DataProxyMaxConnsPerHost,
|
|
MaxIdleConns: cfg.DataProxyMaxIdleConns,
|
|
MaxIdleConnsPerHost: cfg.DataProxyMaxIdleConns,
|
|
IdleConnTimeout: time.Duration(cfg.DataProxyIdleConnTimeout) * time.Second,
|
|
}
|
|
}
|