You've already forked prometheus-fail2ban-exporter
							
							refactor: move server setup code to new package (!90)
* Move code setting up the HTTP server to it's own package * This helps clean up the `main` function and make it easier to read * Rename the `BasicAuthMiddleware` to remove reference to Basic since it can now handle any type of auth type https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/-/merge_requests/90
This commit is contained in:
		
							
								
								
									
										42
									
								
								exporter.go
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								exporter.go
									
									
									
									
									
								
							@@ -3,23 +3,17 @@ package main
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/signal"
 | 
						"os/signal"
 | 
				
			||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/prometheus/client_golang/prometheus"
 | 
						"github.com/prometheus/client_golang/prometheus"
 | 
				
			||||||
	"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
					 | 
				
			||||||
	"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/cfg"
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/cfg"
 | 
				
			||||||
	"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/f2b"
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/f2b"
 | 
				
			||||||
	"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/textfile"
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/textfile"
 | 
				
			||||||
	"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/server"
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/server"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	metricsPath = "/metrics"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	version = "dev"
 | 
						version = "dev"
 | 
				
			||||||
	commit  = "none"
 | 
						commit  = "none"
 | 
				
			||||||
@@ -32,26 +26,6 @@ func printAppVersion() {
 | 
				
			|||||||
	fmt.Printf("    build date:  %s\r\n    commit hash: %s\r\n    built by:    %s\r\n", date, commit, builtBy)
 | 
						fmt.Printf("    build date:  %s\r\n    commit hash: %s\r\n    built by:    %s\r\n", date, commit, builtBy)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func rootHtmlHandler(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
	_, err := w.Write([]byte(
 | 
					 | 
				
			||||||
		`<html>
 | 
					 | 
				
			||||||
			<head><title>Fail2Ban Exporter</title></head>
 | 
					 | 
				
			||||||
			<body>
 | 
					 | 
				
			||||||
			<h1>Fail2Ban Exporter</h1>
 | 
					 | 
				
			||||||
			<p><a href="` + metricsPath + `">Metrics</a></p>
 | 
					 | 
				
			||||||
			</body>
 | 
					 | 
				
			||||||
		</html>`))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		log.Printf("error handling root url: %v", err)
 | 
					 | 
				
			||||||
		w.WriteHeader(http.StatusInternalServerError)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func metricHandler(w http.ResponseWriter, r *http.Request, collector *textfile.Collector) {
 | 
					 | 
				
			||||||
	promhttp.Handler().ServeHTTP(w, r)
 | 
					 | 
				
			||||||
	collector.WriteTextFileMetrics(w, r)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	appSettings := cfg.Parse()
 | 
						appSettings := cfg.Parse()
 | 
				
			||||||
	if appSettings.VersionMode {
 | 
						if appSettings.VersionMode {
 | 
				
			||||||
@@ -67,21 +41,7 @@ func main() {
 | 
				
			|||||||
		textFileCollector := textfile.NewCollector(appSettings)
 | 
							textFileCollector := textfile.NewCollector(appSettings)
 | 
				
			||||||
		prometheus.MustRegister(textFileCollector)
 | 
							prometheus.MustRegister(textFileCollector)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		http.HandleFunc("/", server.BasicAuthMiddleware(rootHtmlHandler, appSettings.AuthProvider))
 | 
							svrErr := server.StartServer(appSettings, textFileCollector)
 | 
				
			||||||
		http.HandleFunc(metricsPath, server.BasicAuthMiddleware(
 | 
					 | 
				
			||||||
			func(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
				metricHandler(w, r, textFileCollector)
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			appSettings.AuthProvider,
 | 
					 | 
				
			||||||
		))
 | 
					 | 
				
			||||||
		log.Printf("metrics available at '%s'", metricsPath)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		svrErr := make(chan error)
 | 
					 | 
				
			||||||
		go func() {
 | 
					 | 
				
			||||||
			svrErr <- http.ListenAndServe(appSettings.MetricsAddress, nil)
 | 
					 | 
				
			||||||
		}()
 | 
					 | 
				
			||||||
		log.Print("ready")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		err := <-svrErr
 | 
							err := <-svrErr
 | 
				
			||||||
		log.Fatal(err)
 | 
							log.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ import (
 | 
				
			|||||||
	"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/auth"
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/auth"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BasicAuthMiddleware(handlerFunc http.HandlerFunc, authProvider auth.AuthProvider) http.HandlerFunc {
 | 
					func AuthMiddleware(handlerFunc http.HandlerFunc, authProvider auth.AuthProvider) http.HandlerFunc {
 | 
				
			||||||
	return func(w http.ResponseWriter, r *http.Request) {
 | 
						return func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		if authProvider.IsAllowed(r) {
 | 
							if authProvider.IsAllowed(r) {
 | 
				
			||||||
			handlerFunc.ServeHTTP(w, r)
 | 
								handlerFunc.ServeHTTP(w, r)
 | 
				
			||||||
@@ -18,13 +18,13 @@ func newTestRequest() *http.Request {
 | 
				
			|||||||
	return httptest.NewRequest(http.MethodGet, "http://example.com", nil)
 | 
						return httptest.NewRequest(http.MethodGet, "http://example.com", nil)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func executeBasicAuthMiddlewareTest(t *testing.T, authMatches bool, expectedCode int, expectedCallCount int) {
 | 
					func executeAuthMiddlewareTest(t *testing.T, authMatches bool, expectedCode int, expectedCallCount int) {
 | 
				
			||||||
	callCount := 0
 | 
						callCount := 0
 | 
				
			||||||
	testHandler := func(w http.ResponseWriter, r *http.Request) {
 | 
						testHandler := func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		callCount++
 | 
							callCount++
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	handler := BasicAuthMiddleware(testHandler, testAuthProvider{match: authMatches})
 | 
						handler := AuthMiddleware(testHandler, testAuthProvider{match: authMatches})
 | 
				
			||||||
	recorder := httptest.NewRecorder()
 | 
						recorder := httptest.NewRecorder()
 | 
				
			||||||
	request := newTestRequest()
 | 
						request := newTestRequest()
 | 
				
			||||||
	handler.ServeHTTP(recorder, request)
 | 
						handler.ServeHTTP(recorder, request)
 | 
				
			||||||
@@ -38,9 +38,9 @@ func executeBasicAuthMiddlewareTest(t *testing.T, authMatches bool, expectedCode
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Test_GIVEN_MatchingBasicAuth_WHEN_MethodCalled_THEN_RequestProcessed(t *testing.T) {
 | 
					func Test_GIVEN_MatchingBasicAuth_WHEN_MethodCalled_THEN_RequestProcessed(t *testing.T) {
 | 
				
			||||||
	executeBasicAuthMiddlewareTest(t, true, http.StatusOK, 1)
 | 
						executeAuthMiddlewareTest(t, true, http.StatusOK, 1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Test_GIVEN_NonMatchingBasicAuth_WHEN_MethodCalled_THEN_RequestRejected(t *testing.T) {
 | 
					func Test_GIVEN_NonMatchingBasicAuth_WHEN_MethodCalled_THEN_RequestRejected(t *testing.T) {
 | 
				
			||||||
	executeBasicAuthMiddlewareTest(t, false, http.StatusUnauthorized, 0)
 | 
						executeAuthMiddlewareTest(t, false, http.StatusUnauthorized, 0)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								server/handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								server/handler.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/prometheus/client_golang/prometheus/promhttp"
 | 
				
			||||||
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/textfile"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						metricsPath = "/metrics"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func rootHtmlHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						_, err := w.Write([]byte(
 | 
				
			||||||
 | 
							`<html>
 | 
				
			||||||
 | 
								<head><title>Fail2Ban Exporter</title></head>
 | 
				
			||||||
 | 
								<body>
 | 
				
			||||||
 | 
								<h1>Fail2Ban Exporter</h1>
 | 
				
			||||||
 | 
								<p><a href="` + metricsPath + `">Metrics</a></p>
 | 
				
			||||||
 | 
								</body>
 | 
				
			||||||
 | 
							</html>`))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Printf("error handling root url: %v", err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func metricHandler(w http.ResponseWriter, r *http.Request, collector *textfile.Collector) {
 | 
				
			||||||
 | 
						promhttp.Handler().ServeHTTP(w, r)
 | 
				
			||||||
 | 
						collector.WriteTextFileMetrics(w, r)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								server/server.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								server/server.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					package server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/cfg"
 | 
				
			||||||
 | 
						"gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/collector/textfile"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func StartServer(
 | 
				
			||||||
 | 
						appSettings *cfg.AppSettings,
 | 
				
			||||||
 | 
						textFileCollector *textfile.Collector,
 | 
				
			||||||
 | 
					) chan error {
 | 
				
			||||||
 | 
						http.HandleFunc("/", AuthMiddleware(
 | 
				
			||||||
 | 
							rootHtmlHandler,
 | 
				
			||||||
 | 
							appSettings.AuthProvider,
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
						http.HandleFunc(metricsPath, AuthMiddleware(
 | 
				
			||||||
 | 
							func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
								metricHandler(w, r, textFileCollector)
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							appSettings.AuthProvider,
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
						log.Printf("metrics available at '%s'", metricsPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						svrErr := make(chan error)
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							svrErr <- http.ListenAndServe(appSettings.MetricsAddress, nil)
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						log.Print("ready")
 | 
				
			||||||
 | 
						return svrErr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user