[v7.5.x] HTTP Client: Introduce go-conntrack (#35321)
* Introduce go-conntrack into http transport * Fix linting * Add sanitize label name for datasource names * Fix tests - add one to check missing datasource name * Fix more tests * Remove DialWithTracing()
This commit is contained in:
@@ -63,6 +63,7 @@ require (
|
||||
github.com/magefile/mage v1.11.0
|
||||
github.com/mattn/go-isatty v0.0.12
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
||||
@@ -551,7 +551,7 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
|
||||
}))
|
||||
t.Cleanup(backend.Close)
|
||||
|
||||
ds := &models.DataSource{Url: backend.URL, Type: models.DS_GRAPHITE}
|
||||
ds := &models.DataSource{Url: backend.URL, Type: models.DS_GRAPHITE, Name: "graphite"}
|
||||
|
||||
responseRecorder := &closeNotifierResponseRecorder{
|
||||
ResponseRecorder: httptest.NewRecorder(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
@@ -11,9 +12,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-aws-sdk/pkg/sigv4"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/metrics/metricutil"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/mwitkow/go-conntrack"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
@@ -154,13 +155,15 @@ func (ds *DataSource) GetHttpTransport() (*dataSourceTransport, error) {
|
||||
|
||||
// Create transport which adds all
|
||||
customHeaders := ds.getCustomHeaders()
|
||||
datasourceLabelName, err := metricutil.SanitizeLabelName(ds.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: tlsConfig,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: time.Duration(setting.DataProxyTimeout) * time.Second,
|
||||
KeepAlive: time.Duration(setting.DataProxyKeepAlive) * time.Second,
|
||||
}).Dial,
|
||||
TLSClientConfig: tlsConfig,
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: newConntrackDialContext(datasourceLabelName),
|
||||
TLSHandshakeTimeout: time.Duration(setting.DataProxyTLSHandshakeTimeout) * time.Second,
|
||||
ExpectContinueTimeout: time.Duration(setting.DataProxyExpectContinueTimeout) * time.Second,
|
||||
MaxIdleConns: setting.DataProxyMaxIdleConns,
|
||||
@@ -332,3 +335,15 @@ func awsServiceNamespace(dsType string) string {
|
||||
panic(fmt.Sprintf("Unsupported datasource %q", dsType))
|
||||
}
|
||||
}
|
||||
|
||||
// newConntrackDialContext takes a http.DefaultTransport and adds the Conntrack Dialer
|
||||
// so we can instrument outbound connections
|
||||
func newConntrackDialContext(name string) func(context.Context, string, string) (net.Conn, error) {
|
||||
return conntrack.NewDialContextFunc(
|
||||
conntrack.DialWithName(name),
|
||||
conntrack.DialWithDialer(&net.Dialer{
|
||||
Timeout: time.Duration(setting.DataProxyTimeout) * time.Second,
|
||||
KeepAlive: time.Duration(setting.DataProxyKeepAlive) * time.Second,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Id: 1,
|
||||
Url: "http://k8s:8001",
|
||||
Type: "Kubernetes",
|
||||
Name: "kubernetes",
|
||||
}
|
||||
|
||||
tr1, err := ds.GetHttpTransport()
|
||||
@@ -54,6 +55,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Type: "Kubernetes",
|
||||
SecureJsonData: map[string][]byte{"tlsCACert": tlsCaCert},
|
||||
Updated: time.Now().Add(-2 * time.Minute),
|
||||
Name: "kubernetes",
|
||||
}
|
||||
|
||||
tr1, err := ds.GetHttpTransport()
|
||||
@@ -91,6 +93,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Id: 1,
|
||||
Url: "http://k8s:8001",
|
||||
Type: "Kubernetes",
|
||||
Name: "kubernetes",
|
||||
JsonData: json,
|
||||
SecureJsonData: map[string][]byte{
|
||||
"tlsClientCert": tlsClientCert,
|
||||
@@ -120,6 +123,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Id: 1,
|
||||
Url: "http://k8s:8001",
|
||||
Type: "Kubernetes",
|
||||
Name: "kubernetes",
|
||||
JsonData: json,
|
||||
SecureJsonData: map[string][]byte{
|
||||
"tlsCACert": tlsCaCert,
|
||||
@@ -144,6 +148,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Id: 1,
|
||||
Url: "http://k8s:8001",
|
||||
Type: "Kubernetes",
|
||||
Name: "kubernetes",
|
||||
JsonData: json,
|
||||
}
|
||||
|
||||
@@ -173,6 +178,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
Id: 1,
|
||||
Url: "http://k8s:8001",
|
||||
Type: "Kubernetes",
|
||||
Name: "kubernetes",
|
||||
JsonData: json,
|
||||
SecureJsonData: map[string][]byte{"httpHeaderValue1": encryptedData},
|
||||
}
|
||||
@@ -221,7 +227,9 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
setting.SigV4AuthEnabled = true
|
||||
t.Cleanup(func() { setting.SigV4AuthEnabled = origEnabled })
|
||||
|
||||
ds := DataSource{}
|
||||
ds := DataSource{
|
||||
Name: "empty",
|
||||
}
|
||||
|
||||
tr, err := ds.GetHttpTransport()
|
||||
require.NoError(t, err)
|
||||
@@ -242,6 +250,7 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
|
||||
ds := DataSource{
|
||||
JsonData: json,
|
||||
Name: "empty",
|
||||
}
|
||||
|
||||
tr, err := ds.GetHttpTransport()
|
||||
@@ -250,6 +259,15 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
||||
_, ok := tr.next.(*http.Transport)
|
||||
require.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("Datasource name not set", func(t *testing.T) {
|
||||
clearDSProxyCache(t)
|
||||
ds := DataSource{}
|
||||
|
||||
_, err := ds.GetHttpTransport()
|
||||
require.Error(t, err)
|
||||
require.Equal(t, err.Error(), "label name cannot be empty")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDataSource_DecryptedValue(t *testing.T) {
|
||||
@@ -259,6 +277,7 @@ func TestDataSource_DecryptedValue(t *testing.T) {
|
||||
ds := DataSource{
|
||||
Id: 1,
|
||||
Type: DS_INFLUXDB_08,
|
||||
Name: "influx-db",
|
||||
JsonData: simplejson.New(),
|
||||
User: "user",
|
||||
SecureJsonData: securejsondata.GetEncryptedJsonData(map[string]string{
|
||||
@@ -286,6 +305,7 @@ func TestDataSource_DecryptedValue(t *testing.T) {
|
||||
ds := DataSource{
|
||||
Id: 1,
|
||||
Type: DS_INFLUXDB_08,
|
||||
Name: "influx-db",
|
||||
JsonData: simplejson.New(),
|
||||
User: "user",
|
||||
SecureJsonData: securejsondata.GetEncryptedJsonData(map[string]string{
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
)
|
||||
|
||||
func TestTempo(t *testing.T) {
|
||||
plug, err := NewExecutor(&models.DataSource{})
|
||||
plug, err := NewExecutor(&models.DataSource{
|
||||
Name: "tempo",
|
||||
})
|
||||
executor := plug.(*tempoExecutor)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user