diff --git a/plugins/outputs/prometheus_client/prometheus_client.go b/plugins/outputs/prometheus_client/prometheus_client.go index 5611a0a9e..db7b0c207 100644 --- a/plugins/outputs/prometheus_client/prometheus_client.go +++ b/plugins/outputs/prometheus_client/prometheus_client.go @@ -8,6 +8,7 @@ import ( "log" "net" "net/http" + "net/url" "regexp" "sort" "strconv" @@ -70,6 +71,7 @@ type PrometheusClient struct { tlsint.ServerConfig server *http.Server + url string sync.Mutex // fam is the non-expired MetricFamily by Prometheus metric name. @@ -107,7 +109,7 @@ var sampleConfig = ` ## If set, enable TLS with the given certificate. # tls_cert = "/etc/ssl/telegraf.crt" # tls_key = "/etc/ssl/telegraf.key" - + ## Set one or more allowed client CA certificate file names to ## enable mutually authenticated TLS connections # tls_allowed_cacerts = ["/etc/telegraf/clientca.pem"] @@ -213,6 +215,8 @@ func (p *PrometheusClient) Connect() error { return err } + p.url = createURL(tlsConfig, listener, p.Path) + go func() { err := p.server.Serve(listener) if err != nil && err != http.ErrServerClosed { @@ -224,11 +228,31 @@ func (p *PrometheusClient) Connect() error { return nil } +// Address returns the address the plugin is listening on. If not listening +// an empty string is returned. +func (p *PrometheusClient) URL() string { + return p.url +} + +func createURL(tlsConfig *tls.Config, listener net.Listener, path string) string { + u := url.URL{ + Scheme: "http", + Host: listener.Addr().String(), + Path: path, + } + + if tlsConfig != nil { + u.Scheme = "https" + } + return u.String() +} + func (p *PrometheusClient) Close() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() err := p.server.Shutdown(ctx) prometheus.Unregister(p) + p.url = "" return err } diff --git a/plugins/outputs/prometheus_client/prometheus_client_tls_test.go b/plugins/outputs/prometheus_client/prometheus_client_tls_test.go index d7484d61f..bcf6b4381 100644 --- a/plugins/outputs/prometheus_client/prometheus_client_tls_test.go +++ b/plugins/outputs/prometheus_client/prometheus_client_tls_test.go @@ -3,25 +3,26 @@ package prometheus_client_test import ( "crypto/tls" "fmt" + "net/http" + "testing" + "github.com/influxdata/telegraf/plugins/outputs/prometheus_client" "github.com/influxdata/telegraf/testutil" "github.com/influxdata/toml" "github.com/stretchr/testify/require" - "net/http" - "testing" ) var pki = testutil.NewPKI("../../../testutil/pki") var configWithTLS = fmt.Sprintf(` - listen = "127.0.0.1:9090" + listen = "127.0.0.1:0" tls_allowed_cacerts = ["%s"] tls_cert = "%s" tls_key = "%s" `, pki.TLSServerConfig().TLSAllowedCACerts[0], pki.TLSServerConfig().TLSCert, pki.TLSServerConfig().TLSKey) var configWithoutTLS = ` - listen = "127.0.0.1:9090" + listen = "127.0.0.1:0" ` type PrometheusClientTestContext struct { @@ -33,11 +34,10 @@ type PrometheusClientTestContext struct { func TestWorksWithoutTLS(t *testing.T) { tc := buildTestContext(t, []byte(configWithoutTLS)) err := tc.Output.Connect() + require.NoError(t, err) defer tc.Output.Close() - require.NoError(t, err) - - response, err := tc.Client.Get("http://localhost:9090/metrics") + response, err := tc.Client.Get(tc.Output.URL()) require.NoError(t, err) require.NoError(t, err) @@ -47,24 +47,21 @@ func TestWorksWithoutTLS(t *testing.T) { func TestWorksWithTLS(t *testing.T) { tc := buildTestContext(t, []byte(configWithTLS)) err := tc.Output.Connect() - defer tc.Output.Close() require.NoError(t, err) + defer tc.Output.Close() - response, err := tc.Client.Get("https://localhost:9090/metrics") + response, err := tc.Client.Get(tc.Output.URL()) require.NoError(t, err) require.NoError(t, err) require.Equal(t, response.StatusCode, http.StatusOK) - response, err = tc.Client.Get("http://localhost:9090/metrics") - require.Error(t, err) - tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} - response, err = client.Get("https://localhost:9090/metrics") + response, err = client.Get(tc.Output.URL()) require.Error(t, err) }