Skip to content

Commit

Permalink
Refactor prober function and metrics collection
Browse files Browse the repository at this point in the history
The existing implementation consists of a collector that exports
information from a tls.ConnectionState returned by the prober function.
This won't necessarily integrate well with additional probers that
retrieve certs from sources other than a tls handshake (from file, for
instance).

I've made the probing more generically expandable by removing the
collector and instead registering and collecting metrics inside the
prober. This makes it possible to collect the same metrics in a
different way, or collect different metrics depending on the prober.
  • Loading branch information
ribbybibby committed Nov 7, 2020
1 parent e05745b commit c74c0de
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 440 deletions.
26 changes: 12 additions & 14 deletions prober/https.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package prober

import (
"crypto/tls"
"fmt"
"io"
"io/ioutil"
Expand All @@ -10,16 +9,20 @@ import (
"strings"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/log"
"github.com/ribbybibby/ssl_exporter/config"

pconfig "github.com/prometheus/common/config"
)

// ProbeHTTPS performs a https probe
func ProbeHTTPS(target string, module config.Module, timeout time.Duration) (*tls.ConnectionState, error) {
func ProbeHTTPS(target string, module config.Module, timeout time.Duration, registry *prometheus.Registry) error {
tlsConfig, err := newTLSConfig("", registry, &module.TLSConfig)
if err != nil {
return err
}

if strings.HasPrefix(target, "http:https://") {
return nil, fmt.Errorf("Target is using http scheme: %s", target)
return fmt.Errorf("Target is using http scheme: %s", target)
}

if !strings.HasPrefix(target, "https://") {
Expand All @@ -28,12 +31,7 @@ func ProbeHTTPS(target string, module config.Module, timeout time.Duration) (*tl

targetURL, err := url.Parse(target)
if err != nil {
return nil, err
}

tlsConfig, err := pconfig.NewTLSConfig(&module.TLSConfig)
if err != nil {
return nil, err
return err
}

proxy := http.ProxyFromEnvironment
Expand All @@ -56,7 +54,7 @@ func ProbeHTTPS(target string, module config.Module, timeout time.Duration) (*tl
// Issue a GET request to the target
resp, err := client.Get(targetURL.String())
if err != nil {
return nil, err
return err
}
defer func() {
_, err := io.Copy(ioutil.Discard, resp.Body)
Expand All @@ -68,8 +66,8 @@ func ProbeHTTPS(target string, module config.Module, timeout time.Duration) (*tl

// Check if the response from the target is encrypted
if resp.TLS == nil {
return nil, fmt.Errorf("The response from %s is unencrypted", targetURL.String())
return fmt.Errorf("The response from %s is unencrypted", targetURL.String())
}

return resp.TLS, nil
return nil
}
62 changes: 34 additions & 28 deletions prober/https_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"
"time"

"github.com/prometheus/client_golang/prometheus"
pconfig "github.com/prometheus/common/config"
"github.com/ribbybibby/ssl_exporter/config"
"github.com/ribbybibby/ssl_exporter/test"
Expand All @@ -34,13 +35,12 @@ func TestProbeHTTPS(t *testing.T) {
},
}

state, err := ProbeHTTPS(server.URL, module, 5*time.Second)
if err != nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
if state == nil {
t.Fatalf("expected state but got nil")
}

}

// TestProbeHTTPSInvalidName tests hitting the server on an address which isn't
Expand All @@ -67,7 +67,9 @@ func TestProbeHTTPSInvalidName(t *testing.T) {
t.Fatalf(err.Error())
}

if _, err := ProbeHTTPS("https://localhost:"+u.Port(), module, 5*time.Second); err == nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS("https://localhost:"+u.Port(), module, 5*time.Second, registry); err == nil {
t.Fatalf("expected error, but err was nil")
}
}
Expand Down Expand Up @@ -96,7 +98,9 @@ func TestProbeHTTPSNoScheme(t *testing.T) {
t.Fatalf(err.Error())
}

if _, err := ProbeHTTPS(u.Host, module, 5*time.Second); err != nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(u.Host, module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
}
Expand Down Expand Up @@ -126,7 +130,9 @@ func TestProbeHTTPSServerName(t *testing.T) {
},
}

if _, err := ProbeHTTPS("https://localhost:"+u.Port(), module, 5*time.Second); err != nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS("https://localhost:"+u.Port(), module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
}
Expand All @@ -139,7 +145,9 @@ func TestProbeHTTPSHTTP(t *testing.T) {
server.Start()
defer server.Close()

if _, err := ProbeHTTPS(server.URL, config.Module{}, 5*time.Second); err == nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, config.Module{}, 5*time.Second, registry); err == nil {
t.Fatalf("expected error, but err was nil")
}
}
Expand Down Expand Up @@ -186,13 +194,11 @@ func TestProbeHTTPSClientAuth(t *testing.T) {
},
}

state, err := ProbeHTTPS(server.URL, module, 5*time.Second)
if err != nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
if state == nil {
t.Fatalf("expected state but got nil")
}
}

// TestProbeHTTPSClientAuthWrongClientCert tests that the probe fails with a bad
Expand Down Expand Up @@ -241,7 +247,9 @@ func TestProbeHTTPSClientAuthWrongClientCert(t *testing.T) {
},
}

if _, err := ProbeHTTPS(server.URL, module, 5*time.Second); err == nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err == nil {
t.Fatalf("expected error but err is nil")
}
}
Expand Down Expand Up @@ -272,7 +280,9 @@ func TestProbeHTTPSExpired(t *testing.T) {
},
}

if _, err := ProbeHTTPS(server.URL, module, 5*time.Second); err == nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err == nil {
t.Fatalf("expected error but err is nil")
}
}
Expand Down Expand Up @@ -304,13 +314,11 @@ func TestProbeHTTPSExpiredInsecure(t *testing.T) {
},
}

state, err := ProbeHTTPS(server.URL, module, 5*time.Second)
if err != nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
if state == nil {
t.Fatalf("expected state but got nil")
}
}

// TestProbeHTTPSProxy tests the proxy_url field in the configuration
Expand Down Expand Up @@ -352,19 +360,17 @@ func TestProbeHTTPSProxy(t *testing.T) {
},
}

_, err = ProbeHTTPS(server.URL, module, 5*time.Second)
if err == nil {
registry := prometheus.NewRegistry()

if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err == nil {
t.Fatalf("expected error but err was nil")
}

// Test with the proxy url, this shouldn't return an error
module.HTTPS.ProxyURL = config.URL{URL: proxyURL}

state, err := ProbeHTTPS(server.URL, module, 5*time.Second)
if err != nil {
if err := ProbeHTTPS(server.URL, module, 5*time.Second, registry); err != nil {
t.Fatalf("error: %s", err)
}
if state == nil {
t.Fatalf("expected state but got nil")
}

}
Loading

0 comments on commit c74c0de

Please sign in to comment.