Add TLS and http basic_auth to prometheus_client output (#3719)
This commit is contained in:
		
							parent
							
								
									ec8e923fda
								
							
						
					
					
						commit
						a2635573a8
					
				|  | @ -10,6 +10,14 @@ This plugin starts a [Prometheus](https://prometheus.io/) Client, it exposes all | ||||||
|   # Address to listen on |   # Address to listen on | ||||||
|   listen = ":9273" |   listen = ":9273" | ||||||
| 
 | 
 | ||||||
|  |   # Use TLS | ||||||
|  |   tls_cert = "/etc/ssl/telegraf.crt" | ||||||
|  |   tls_key = "/etc/ssl/telegraf.key" | ||||||
|  | 
 | ||||||
|  |   # Use http basic authentication | ||||||
|  |   basic_username = "Foo" | ||||||
|  |   basic_password = "Bar" | ||||||
|  | 
 | ||||||
|   # Path to publish the metrics on, defaults to /metrics |   # Path to publish the metrics on, defaults to /metrics | ||||||
|   path = "/metrics"    |   path = "/metrics"    | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ package prometheus_client | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"crypto/subtle" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"log" | 	"log" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | @ -53,6 +54,10 @@ type MetricFamily struct { | ||||||
| 
 | 
 | ||||||
| type PrometheusClient struct { | type PrometheusClient struct { | ||||||
| 	Listen             string | 	Listen             string | ||||||
|  | 	TLSCert            string            `toml:"tls_cert"` | ||||||
|  | 	TLSKey             string            `toml:"tls_key"` | ||||||
|  | 	BasicUsername      string            `toml:"basic_username"` | ||||||
|  | 	BasicPassword      string            `toml:"basic_password"` | ||||||
| 	ExpirationInterval internal.Duration `toml:"expiration_interval"` | 	ExpirationInterval internal.Duration `toml:"expiration_interval"` | ||||||
| 	Path               string            `toml:"path"` | 	Path               string            `toml:"path"` | ||||||
| 	CollectorsExclude  []string          `toml:"collectors_exclude"` | 	CollectorsExclude  []string          `toml:"collectors_exclude"` | ||||||
|  | @ -70,6 +75,14 @@ var sampleConfig = ` | ||||||
|   ## Address to listen on |   ## Address to listen on | ||||||
|   # listen = ":9273" |   # listen = ":9273" | ||||||
| 
 | 
 | ||||||
|  |   ## Use TLS | ||||||
|  |   #tls_cert = "/etc/ssl/telegraf.crt" | ||||||
|  |   #tls_key = "/etc/ssl/telegraf.key" | ||||||
|  | 
 | ||||||
|  |   ## Use http basic authentication | ||||||
|  |   #basic_username = "Foo" | ||||||
|  |   #basic_password = "Bar" | ||||||
|  | 
 | ||||||
|   ## Interval to expire metrics and not deliver to prometheus, 0 == no expiration |   ## Interval to expire metrics and not deliver to prometheus, 0 == no expiration | ||||||
|   # expiration_interval = "60s" |   # expiration_interval = "60s" | ||||||
| 
 | 
 | ||||||
|  | @ -78,6 +91,24 @@ var sampleConfig = ` | ||||||
|   collectors_exclude = ["gocollector", "process"] |   collectors_exclude = ["gocollector", "process"] | ||||||
| ` | ` | ||||||
| 
 | 
 | ||||||
|  | func (p *PrometheusClient) basicAuth(h http.Handler) http.Handler { | ||||||
|  | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 		if p.BasicUsername != "" && p.BasicPassword != "" { | ||||||
|  | 			w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) | ||||||
|  | 
 | ||||||
|  | 			username, password, ok := r.BasicAuth() | ||||||
|  | 			if !ok || | ||||||
|  | 				subtle.ConstantTimeCompare([]byte(username), []byte(p.BasicUsername)) != 1 || | ||||||
|  | 				subtle.ConstantTimeCompare([]byte(password), []byte(p.BasicPassword)) != 1 { | ||||||
|  | 				http.Error(w, "Not authorized", 401) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		h.ServeHTTP(w, r) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (p *PrometheusClient) Start() error { | func (p *PrometheusClient) Start() error { | ||||||
| 	defaultCollectors := map[string]bool{ | 	defaultCollectors := map[string]bool{ | ||||||
| 		"gocollector": true, | 		"gocollector": true, | ||||||
|  | @ -110,8 +141,8 @@ func (p *PrometheusClient) Start() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	mux := http.NewServeMux() | 	mux := http.NewServeMux() | ||||||
| 	mux.Handle(p.Path, promhttp.HandlerFor( | 	mux.Handle(p.Path, p.basicAuth(promhttp.HandlerFor( | ||||||
| 		registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError})) | 		registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError}))) | ||||||
| 
 | 
 | ||||||
| 	p.server = &http.Server{ | 	p.server = &http.Server{ | ||||||
| 		Addr:    p.Listen, | 		Addr:    p.Listen, | ||||||
|  | @ -119,13 +150,18 @@ func (p *PrometheusClient) Start() error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	go func() { | 	go func() { | ||||||
| 		if err := p.server.ListenAndServe(); err != nil { | 		var err error | ||||||
| 			if err != http.ErrServerClosed { | 		if p.TLSCert != "" && p.TLSKey != "" { | ||||||
|  | 			err = p.server.ListenAndServeTLS(p.TLSCert, p.TLSKey) | ||||||
|  | 		} else { | ||||||
|  | 			err = p.server.ListenAndServe() | ||||||
|  | 		} | ||||||
|  | 		if err != nil && err != http.ErrServerClosed { | ||||||
| 			log.Printf("E! Error creating prometheus metric endpoint, err: %s\n", | 			log.Printf("E! Error creating prometheus metric endpoint, err: %s\n", | ||||||
| 				err.Error()) | 				err.Error()) | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
| 	}() | 	}() | ||||||
|  | 
 | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue