From 815762a4ad576df4065fc40bea8a382eb91e1a7b Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Mon, 20 Mar 2017 14:17:04 +0100 Subject: [PATCH] Move retrieval.NewHTTPClient -> httputil.NewClientFromConfig --- .../remote_storage_bridge/opentsdb/client.go | 22 +++++----- notifier/notifier.go | 4 +- retrieval/scrape.go | 5 ++- retrieval/target.go | 40 ------------------ retrieval/target_test.go | 17 ++++---- storage/remote/client.go | 4 +- util/httputil/client.go | 42 +++++++++++++++++-- 7 files changed, 64 insertions(+), 70 deletions(-) diff --git a/documentation/examples/remote_storage/remote_storage_bridge/opentsdb/client.go b/documentation/examples/remote_storage/remote_storage_bridge/opentsdb/client.go index 46575313f3..fe8b79e77b 100644 --- a/documentation/examples/remote_storage/remote_storage_bridge/opentsdb/client.go +++ b/documentation/examples/remote_storage/remote_storage_bridge/opentsdb/client.go @@ -24,10 +24,9 @@ import ( "time" "github.com/prometheus/common/log" - "github.com/prometheus/common/model" - - "github.com/prometheus/prometheus/util/httputil" + "golang.org/x/net/context" + "golang.org/x/net/context/ctxhttp" ) const ( @@ -37,15 +36,15 @@ const ( // Client allows sending batches of Prometheus samples to OpenTSDB. type Client struct { - url string - httpClient *http.Client + url string + timeout time.Duration } // NewClient creates a new Client. func NewClient(url string, timeout time.Duration) *Client { return &Client{ - url: url, - httpClient: httputil.NewDeadlineClient(timeout, nil), + url: url, + timeout: timeout, } } @@ -100,11 +99,10 @@ func (c *Client) Store(samples model.Samples) error { return err } - resp, err := c.httpClient.Post( - u.String(), - contentTypeJSON, - bytes.NewBuffer(buf), - ) + ctx, cancel := context.WithTimeout(context.Background(), c.timeout) + defer cancel() + + resp, err := ctxhttp.Post(ctx, http.DefaultClient, u.String(), contentTypeJSON, bytes.NewBuffer(buf)) if err != nil { return err } diff --git a/notifier/notifier.go b/notifier/notifier.go index e9af00a4ca..2a582fd617 100644 --- a/notifier/notifier.go +++ b/notifier/notifier.go @@ -35,7 +35,7 @@ import ( "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/relabel" - "github.com/prometheus/prometheus/retrieval" + "github.com/prometheus/prometheus/util/httputil" ) const ( @@ -435,7 +435,7 @@ type alertmanagerSet struct { } func newAlertmanagerSet(cfg *config.AlertmanagerConfig) (*alertmanagerSet, error) { - client, err := retrieval.NewHTTPClient(cfg.HTTPClientConfig) + client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig) if err != nil { return nil, err } diff --git a/retrieval/scrape.go b/retrieval/scrape.go index a51e7ca7e8..dd482fa4a8 100644 --- a/retrieval/scrape.go +++ b/retrieval/scrape.go @@ -31,6 +31,7 @@ import ( "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/storage/local" + "github.com/prometheus/prometheus/util/httputil" ) const ( @@ -114,7 +115,7 @@ type scrapePool struct { } func newScrapePool(ctx context.Context, cfg *config.ScrapeConfig, app storage.SampleAppender) *scrapePool { - client, err := NewHTTPClient(cfg.HTTPClientConfig) + client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig) if err != nil { // Any errors that could occur here should be caught during config validation. log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err) @@ -161,7 +162,7 @@ func (sp *scrapePool) reload(cfg *config.ScrapeConfig) { sp.mtx.Lock() defer sp.mtx.Unlock() - client, err := NewHTTPClient(cfg.HTTPClientConfig) + client, err := httputil.NewClientFromConfig(cfg.HTTPClientConfig) if err != nil { // Any errors that could occur here should be caught during config validation. log.Errorf("Error creating HTTP client for job %q: %s", cfg.JobName, err) diff --git a/retrieval/target.go b/retrieval/target.go index 07628c70e7..66813604a8 100644 --- a/retrieval/target.go +++ b/retrieval/target.go @@ -16,9 +16,7 @@ package retrieval import ( "fmt" "hash/fnv" - "io/ioutil" "net" - "net/http" "net/url" "strings" "sync" @@ -29,7 +27,6 @@ import ( "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/relabel" "github.com/prometheus/prometheus/storage" - "github.com/prometheus/prometheus/util/httputil" ) // TargetHealth describes the health state of a target. @@ -67,43 +64,6 @@ func NewTarget(labels, discoveredLabels model.LabelSet, params url.Values) *Targ } } -// NewHTTPClient returns a new HTTP client configured for the given scrape configuration. -func NewHTTPClient(cfg config.HTTPClientConfig) (*http.Client, error) { - tlsConfig, err := httputil.NewTLSConfig(cfg.TLSConfig) - if err != nil { - return nil, err - } - // The only timeout we care about is the configured scrape timeout. - // It is applied on request. So we leave out any timings here. - var rt http.RoundTripper = &http.Transport{ - Proxy: http.ProxyURL(cfg.ProxyURL.URL), - DisableKeepAlives: true, - TLSClientConfig: tlsConfig, - } - - // If a bearer token is provided, create a round tripper that will set the - // Authorization header correctly on each request. - bearerToken := cfg.BearerToken - if len(bearerToken) == 0 && len(cfg.BearerTokenFile) > 0 { - b, err := ioutil.ReadFile(cfg.BearerTokenFile) - if err != nil { - return nil, fmt.Errorf("unable to read bearer token file %s: %s", cfg.BearerTokenFile, err) - } - bearerToken = strings.TrimSpace(string(b)) - } - - if len(bearerToken) > 0 { - rt = httputil.NewBearerAuthRoundTripper(bearerToken, rt) - } - - if cfg.BasicAuth != nil { - rt = httputil.NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, rt) - } - - // Return a new client with the configured round tripper. - return httputil.NewClient(rt), nil -} - func (t *Target) String() string { return t.URL().String() } diff --git a/retrieval/target_test.go b/retrieval/target_test.go index a0f7c0237d..640bca0878 100644 --- a/retrieval/target_test.go +++ b/retrieval/target_test.go @@ -29,6 +29,7 @@ import ( "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" + "github.com/prometheus/prometheus/util/httputil" ) const ( @@ -154,7 +155,7 @@ func TestNewHTTPBearerToken(t *testing.T) { cfg := config.HTTPClientConfig{ BearerToken: "1234", } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -181,7 +182,7 @@ func TestNewHTTPBearerTokenFile(t *testing.T) { cfg := config.HTTPClientConfig{ BearerTokenFile: "testdata/bearertoken.txt", } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -210,7 +211,7 @@ func TestNewHTTPBasicAuth(t *testing.T) { Password: "password123", }, } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -238,7 +239,7 @@ func TestNewHTTPCACert(t *testing.T) { CAFile: caCertPath, }, } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -272,7 +273,7 @@ func TestNewHTTPClientCert(t *testing.T) { KeyFile: "testdata/client.key", }, } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -301,7 +302,7 @@ func TestNewHTTPWithServerName(t *testing.T) { ServerName: "prometheus.rocks", }, } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -330,7 +331,7 @@ func TestNewHTTPWithBadServerName(t *testing.T) { ServerName: "badname", }, } - c, err := NewHTTPClient(cfg) + c, err := httputil.NewClientFromConfig(cfg) if err != nil { t.Fatal(err) } @@ -369,7 +370,7 @@ func TestNewClientWithBadTLSConfig(t *testing.T) { KeyFile: "testdata/nonexistent_client.key", }, } - _, err := NewHTTPClient(cfg) + _, err := httputil.NewClientFromConfig(cfg) if err == nil { t.Fatalf("Expected error, got nil.") } diff --git a/storage/remote/client.go b/storage/remote/client.go index d27c59c561..c3e4a33549 100644 --- a/storage/remote/client.go +++ b/storage/remote/client.go @@ -27,8 +27,8 @@ import ( "github.com/prometheus/common/model" "github.com/prometheus/prometheus/config" - "github.com/prometheus/prometheus/retrieval" "github.com/prometheus/prometheus/storage/metric" + "github.com/prometheus/prometheus/util/httputil" ) // Client allows reading and writing from/to a remote HTTP endpoint. @@ -47,7 +47,7 @@ type clientConfig struct { // NewClient creates a new Client. func NewClient(index int, conf *clientConfig) (*Client, error) { - httpClient, err := retrieval.NewHTTPClient(conf.httpClientConfig) + httpClient, err := httputil.NewClientFromConfig(conf.httpClientConfig) if err != nil { return nil, err } diff --git a/util/httputil/client.go b/util/httputil/client.go index 42b1615bd7..4123814328 100644 --- a/util/httputil/client.go +++ b/util/httputil/client.go @@ -21,6 +21,7 @@ import ( "net" "net/http" "net/url" + "strings" "time" "github.com/prometheus/prometheus/config" @@ -31,10 +32,42 @@ func NewClient(rt http.RoundTripper) *http.Client { return &http.Client{Transport: rt} } -// NewDeadlineClient returns a new http.Client which will time out long running -// requests. -func NewDeadlineClient(timeout time.Duration, proxyURL *url.URL) *http.Client { - return NewClient(NewDeadlineRoundTripper(timeout, proxyURL)) +// NewClientFromConfig returns a new HTTP client configured for the +// given config.HTTPClientConfig. +func NewClientFromConfig(cfg config.HTTPClientConfig) (*http.Client, error) { + tlsConfig, err := NewTLSConfig(cfg.TLSConfig) + if err != nil { + return nil, err + } + // The only timeout we care about is the configured scrape timeout. + // It is applied on request. So we leave out any timings here. + var rt http.RoundTripper = &http.Transport{ + Proxy: http.ProxyURL(cfg.ProxyURL.URL), + DisableKeepAlives: true, + TLSClientConfig: tlsConfig, + } + + // If a bearer token is provided, create a round tripper that will set the + // Authorization header correctly on each request. + bearerToken := cfg.BearerToken + if len(bearerToken) == 0 && len(cfg.BearerTokenFile) > 0 { + b, err := ioutil.ReadFile(cfg.BearerTokenFile) + if err != nil { + return nil, fmt.Errorf("unable to read bearer token file %s: %s", cfg.BearerTokenFile, err) + } + bearerToken = strings.TrimSpace(string(b)) + } + + if len(bearerToken) > 0 { + rt = NewBearerAuthRoundTripper(bearerToken, rt) + } + + if cfg.BasicAuth != nil { + rt = NewBasicAuthRoundTripper(cfg.BasicAuth.Username, cfg.BasicAuth.Password, rt) + } + + // Return a new client with the configured round tripper. + return NewClient(rt), nil } // NewDeadlineRoundTripper returns a new http.RoundTripper which will time out @@ -119,6 +152,7 @@ func cloneRequest(r *http.Request) *http.Request { return r2 } +// NewTLSConfig creates a new tls.Config from the given config.TLSConfig. func NewTLSConfig(cfg config.TLSConfig) (*tls.Config, error) { tlsConfig := &tls.Config{InsecureSkipVerify: cfg.InsecureSkipVerify}