From 42084122e9d631acf9cdca0033e6c7d19b3fe1c8 Mon Sep 17 00:00:00 2001 From: Conor Broderick Date: Thu, 29 Jun 2017 11:57:16 +0100 Subject: [PATCH] Use HTTP auth in blackbox exporter (#173) --- README.md | 10 ++++++++++ http.go | 25 ++++--------------------- http_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- main.go | 22 +++++++++++----------- 4 files changed, 73 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 9ac3060..f113853 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,16 @@ modules: headers: Content-Type: application/json body: '{}' + http_basic_auth_example: + prober: http + timeout: 5s + http: + method: POST + headers: + Host: "login.example.com" + basic_auth: + username: "username" + password: "mysecret" tcp_connect_example: prober: tcp timeout: 5s diff --git a/http.go b/http.go index d21be60..cb91288 100644 --- a/http.go +++ b/http.go @@ -59,7 +59,6 @@ func matchRegularExpressions(reader io.Reader, httpConfig HTTPProbe) bool { func probeHTTP(target string, module Module, registry *prometheus.Registry) (success bool) { var redirects int - var dialProtocol string var ( contentLengthGauge = prometheus.NewGauge(prometheus.GaugeOpts{ @@ -114,30 +113,14 @@ func probeHTTP(target string, module Module, registry *prometheus.Registry) (suc return false } - if ip.IP.To4() == nil { - dialProtocol = "tcp6" - } else { - dialProtocol = "tcp4" - } - - client := &http.Client{ - Timeout: module.Timeout, - } + httpClientConfig := &module.HTTP.HTTPClientConfig - tlsconfig, err := config.NewTLSConfig(&module.HTTP.TLSConfig) + client, err := config.NewHTTPClientFromConfig(httpClientConfig) if err != nil { - log.Errorf("Error generating TLS config: %s", err) + log.Errorf("Error generating HTTP client: %v", err) return false } - dial := func(network, address string) (net.Conn, error) { - return net.Dial(dialProtocol, address) - } - client.Transport = &http.Transport{ - TLSClientConfig: tlsconfig, - Dial: dial, - Proxy: http.ProxyFromEnvironment, - DisableKeepAlives: true, - } + client.Timeout = module.Timeout client.CheckRedirect = func(_ *http.Request, via []*http.Request) error { redirects = len(via) diff --git a/http_test.go b/http_test.go index bb8063a..976a300 100644 --- a/http_test.go +++ b/http_test.go @@ -121,6 +121,45 @@ func TestPost(t *testing.T) { } } +func TestBasicAuth(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + })) + defer ts.Close() + + recorder := httptest.NewRecorder() + registry := prometheus.NewRegistry() + result := probeHTTP(ts.URL, + Module{Timeout: time.Second, HTTP: HTTPProbe{ + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{InsecureSkipVerify: false}, + BasicAuth: &config.BasicAuth{Username: "username", Password: "password"}, + }, + }}, registry) + body := recorder.Body.String() + if !result { + t.Fatalf("HTTP probe failed, got %s", body) + } +} + +func TestBearerToken(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + })) + defer ts.Close() + + recorder := httptest.NewRecorder() + registry := prometheus.NewRegistry() + result := probeHTTP(ts.URL, + Module{Timeout: time.Second, HTTP: HTTPProbe{ + HTTPClientConfig: config.HTTPClientConfig{ + BearerToken: config.Secret("mysecret"), + }, + }}, registry) + body := recorder.Body.String() + if !result { + t.Fatalf("HTTP probe failed, got %s", body) + } +} + func TestFailIfNotSSL(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { })) @@ -303,7 +342,9 @@ func TestFailIfSelfSignedCA(t *testing.T) { registry := prometheus.NewRegistry() result := probeHTTP(ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{ - TLSConfig: config.TLSConfig{InsecureSkipVerify: false}, + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{InsecureSkipVerify: false}, + }, }}, registry) body := recorder.Body.String() if result { @@ -328,7 +369,9 @@ func TestSucceedIfSelfSignedCA(t *testing.T) { registry := prometheus.NewRegistry() result := probeHTTP(ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{ - TLSConfig: config.TLSConfig{InsecureSkipVerify: true}, + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{InsecureSkipVerify: true}, + }, }}, registry) body := recorder.Body.String() if !result { @@ -353,7 +396,9 @@ func TestTLSConfigIsIgnoredForPlainHTTP(t *testing.T) { registry := prometheus.NewRegistry() result := probeHTTP(ts.URL, Module{Timeout: time.Second, HTTP: HTTPProbe{ - TLSConfig: config.TLSConfig{InsecureSkipVerify: false}, + HTTPClientConfig: config.HTTPClientConfig{ + TLSConfig: config.TLSConfig{InsecureSkipVerify: false}, + }, }}, registry) body := recorder.Body.String() if !result { diff --git a/main.go b/main.go index 09c004b..b6dc8ff 100644 --- a/main.go +++ b/main.go @@ -54,17 +54,17 @@ type Module struct { type HTTPProbe struct { // Defaults to 2xx. - ValidStatusCodes []int `yaml:"valid_status_codes"` - PreferredIPProtocol string `yaml:"preferred_ip_protocol"` - NoFollowRedirects bool `yaml:"no_follow_redirects"` - FailIfSSL bool `yaml:"fail_if_ssl"` - FailIfNotSSL bool `yaml:"fail_if_not_ssl"` - Method string `yaml:"method"` - Headers map[string]string `yaml:"headers"` - FailIfMatchesRegexp []string `yaml:"fail_if_matches_regexp"` - FailIfNotMatchesRegexp []string `yaml:"fail_if_not_matches_regexp"` - TLSConfig config.TLSConfig `yaml:"tls_config"` - Body string `yaml:"body"` + ValidStatusCodes []int `yaml:"valid_status_codes"` + PreferredIPProtocol string `yaml:"preferred_ip_protocol"` + NoFollowRedirects bool `yaml:"no_follow_redirects"` + FailIfSSL bool `yaml:"fail_if_ssl"` + FailIfNotSSL bool `yaml:"fail_if_not_ssl"` + Method string `yaml:"method"` + Headers map[string]string `yaml:"headers"` + FailIfMatchesRegexp []string `yaml:"fail_if_matches_regexp"` + FailIfNotMatchesRegexp []string `yaml:"fail_if_not_matches_regexp"` + Body string `yaml:"body"` + HTTPClientConfig config.HTTPClientConfig `yaml:"http_client_config,inline"` } type QueryResponse struct { -- 2.25.1