Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for exporter basic auth #6

Merged
merged 3 commits into from
Jan 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,21 @@ Help:

```
$ sensu-prometheus-collector -h
Usage of ./sensu-prometheus-collector:
Usage of sensu-prometheus-collector:
-exporter-password string
Prometheus exporter basic auth password
-exporter-url string
Prometheus exporter URL to pull metrics from.
Prometheus exporter URL to pull metrics from.
-exporter-user string
Prometheus exporter basic auth user
-metric-prefix string
Metric name prefix, only supported by line protocol output formats.
Metric name prefix, only supported by line protocol output formats.
-output-format string
The check output format to use for metrics {influx|graphite|json}. (default "influx")
The check output format to use for metrics {influx|graphite|json}. (default "influx")
-prom-query string
Prometheus API query string. (default "up")
Prometheus API query string. (default "up")
-prom-url string
Prometheus API URL. (default "http://localhost:9090")
Prometheus API URL. (default "http://localhost:9090")
```

Application instrumentation:
Expand All @@ -82,12 +86,14 @@ go_memstats_mspan_sys_bytes value=32768 1506991233
```

```
$ sensu-prometheus-collector -exporter-url http://localhost:8080/metrics -output-format graphite -metric-prefix foo.bar.
$ sensu-prometheus-collector -exporter-url http://localhost:8080/metrics -exporter-user admin -exporter-password secretpassword -output-format graphite -metric-prefix foo.bar.
foo.bar.go_memstats_stack_inuse_bytes 294912 1506991405
foo.bar.go_memstats_mallocs_total 6375 1506991405
...
```

Exporter basic auth credentials can also be set via environment vars `EXPORTER_USER` and `EXPORTER_PASSWORD`.

Prometheus query API:

```
Expand Down
61 changes: 53 additions & 8 deletions sensu-prometheus-collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ import (
"strconv"
"time"

"github.com/kelseyhightower/envconfig"
"github.com/prometheus/client_golang/api/prometheus"
"github.com/prometheus/common/expfmt"
"github.com/prometheus/common/model"
)

const (
exporterAuthID = "exporter"
)

type Tag struct {
Name model.LabelName
Value model.LabelValue
Expand All @@ -26,6 +31,12 @@ type Metric struct {
Value float64
}

type ExporterAuth struct {
User string `envconfig:"user" default:""`
Password string `envconfig:"password" default:""`
Header string `envconfig:"header" default:""`
}

func CreateJSONMetrics(samples model.Vector) string {
metrics := []Metric{}

Expand Down Expand Up @@ -138,14 +149,20 @@ func QueryPrometheus(promURL string, queryString string) (model.Vector, error) {
return nil, errors.New("unexpected response type")
}

func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
func QueryExporter(exporterURL string, auth ExporterAuth) (model.Vector, error) {
client := &http.Client{}
req, err := http.NewRequest("GET", exporterURL, nil)

if err != nil {
return nil, err
}
if authorization != "" {
req.Header.Set("Authorization", authorization)

if auth.User != "" && auth.Password != "" {
req.SetBasicAuth(auth.User, auth.Password)
}

if auth.Header != "" {
req.Header.Set("Authorization", auth.Header)
}

expResponse, err := client.Do(req)
Expand All @@ -156,7 +173,7 @@ func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
}

if expResponse.StatusCode != http.StatusOK {
return nil, errors.New("exporter returned non OK HTTP response status")
return nil, errors.New("exporter returned non OK HTTP response status: " + expResponse.Status)
}

var parser expfmt.TextParser
Expand All @@ -181,33 +198,61 @@ func QueryExporter(exporterURL, authorization string) (model.Vector, error) {
return samples, nil
}

func setExporterAuth(user string, password string, header string) (auth ExporterAuth, error error) {
err := envconfig.Process(exporterAuthID, &auth)

if err != nil {
return auth, err
}

if user != "" && password != "" {
auth.User = user
auth.Password = password
}

if auth.Header != "" {
auth.Header = header
}

return auth, nil
}

func main() {
exporterURL := flag.String("exporter-url", "", "Prometheus exporter URL to pull metrics from.")
exporterUser := flag.String("exporter-user", "", "Prometheus exporter basic auth user.")
exporterPassword := flag.String("exporter-password", "", "Prometheus exporter basic auth password.")
exporterAuthorizationHeader := flag.String("exporter-authorization", "", "Prometheus exporter Authorization header.")
promURL := flag.String("prom-url", "http://localhost:9090", "Prometheus API URL.")
queryString := flag.String("prom-query", "up", "Prometheus API query string.")
outputFormat := flag.String("output-format", "influx", "The check output format to use for metrics {influx|graphite|json}.")
metricPrefix := flag.String("metric-prefix", "", "Metric name prefix, only supported by line protocol output formats.")
flag.Parse()

samples := model.Vector{}
var samples model.Vector
var err error

if *exporterURL != "" {
samples, err = QueryExporter(*exporterURL, *exporterAuthorizationHeader)
auth, err := setExporterAuth(*exporterUser, *exporterPassword, *exporterAuthorizationHeader)

if err != nil {
_ = fmt.Errorf("%v", err)
os.Exit(2)
}

samples, err = QueryExporter(*exporterURL, auth)
} else {
samples, err = QueryPrometheus(*promURL, *queryString)
}

if err != nil {
fmt.Errorf("%v", err)
_ = fmt.Errorf("%v", err)
os.Exit(2)
}

err = OutputMetrics(samples, *outputFormat, *metricPrefix)

if err != nil {
fmt.Errorf("%v", err)
_ = fmt.Errorf("%v", err)
os.Exit(2)
}
}
2 changes: 1 addition & 1 deletion sensu-prometheus-collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func TestQueryExporter(t *testing.T) {

time.Sleep(2 * time.Second)

samples, err := QueryExporter("http://localhost:7777/metrics", "")
samples, err := QueryExporter("http://localhost:7777/metrics", ExporterAuth{User: "", Password: "", Header: ""})

assert.NoError(t, err)
assert.NotNil(t, samples)
Expand Down
19 changes: 19 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/MAINTAINERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

188 changes: 188 additions & 0 deletions vendor/github.com/kelseyhightower/envconfig/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading