diff --git a/README.md b/README.md index 02b3676..2a2cc8a 100644 --- a/README.md +++ b/README.md @@ -35,26 +35,39 @@ No additional runtime dependencies are required. Compiled binaries for various platforms are provided in each release. See the [releases page](https://gitlab.com/hectorjsmith/fail2ban-prometheus-exporter/-/releases) for more information. -**Usage** +**CLI Usage** ``` $ fail2ban-prometheus-exporter -h +usage: exporter [] - -collector.textfile - enable the textfile collector - -collector.textfile.directory string - directory to read text files with metrics from - -port int - port to use for the metrics server (default 9191) - -socket string - path to the fail2ban server socket - -version - show version info and exit - -web.basic-auth.password string - password to use to protect endpoints with basic auth - -web.basic-auth.username string - username to use to protect endpoints with basic auth - -web.listen-address string - address to use for the metrics server (default "0.0.0.0") +Flags: + -h, --help Show context-sensitive help (also try --help-long and --help-man). + --version show version info and exit + --port=9191 port to use for the metrics server + --web.listen-address="0.0.0.0" + address to use for the metrics server + --socket="" path to the fail2ban server socket + --collector.textfile enable the textfile collector + --collector.textfile.directory="" + directory to read text files with metrics from + --web.basic-auth.username="" + username to use to protect endpoints with basic auth + --web.basic-auth.password="" + password to use to protect endpoints with basic auth +``` + +**Environment variables** + +The tool can also be configured using environment variables. Each CLI parameter has a corresponding environment variable. + +``` +F2B_COLLECTOR_SOCKET +F2B_COLLECTOR_TEXT +F2B_COLLECTOR_TEXT_PATH +F2B_WEB_PORT +F2B_WEB_LISTEN_ADDRESS +F2B_WEB_BASICAUTH_USER +F2B_WEB_BASICAUTH_PASS ``` **Example** diff --git a/docker/run.sh b/docker/run.sh index f6bf771..36ade9e 100644 --- a/docker/run.sh +++ b/docker/run.sh @@ -15,6 +15,6 @@ fi # Start the exporter (use exec to support graceful shutdown) # Inspired by: https://akomljen.com/stopping-docker-containers-gracefully/ exec /app/fail2ban-prometheus-exporter \ - -socket "$socket_path" \ - -collector.textfile=$textfile_enabled \ - -collector.textfile.directory="$textfile_dir" + --socket "$socket_path" \ + --collector.textfile=$textfile_enabled \ + --collector.textfile.directory="$textfile_dir" diff --git a/src/cfg/cfg.go b/src/cfg/cfg.go index 008fef1..c71b360 100644 --- a/src/cfg/cfg.go +++ b/src/cfg/cfg.go @@ -3,12 +3,20 @@ package cfg import ( "flag" "fmt" + "gopkg.in/alecthomas/kingpin.v2" "os" ) const ( - minServerPort = 1000 - maxServerPort = 65535 + minServerPort = 1000 + maxServerPort = 65535 + socketEnvName = "F2B_COLLECTOR_SOCKET" + fileCollectorEnabledEnvName = "F2B_COLLECTOR_TEXT" + fileCollectorPathEnvName = "F2B_COLLECTOR_TEXT_PATH" + portEnvName = "F2B_WEB_PORT" + addressEnvName = "F2B_WEB_LISTEN_ADDRESS" + basicAuthUserEnvName = "F2B_WEB_BASICAUTH_USER" + basicAuthPassEnvName = "F2B_WEB_BASICAUTH_PASS" ) type AppSettings struct { @@ -21,24 +29,67 @@ type AppSettings struct { BasicAuthProvider *hashedBasicAuth } +func init() { + kingpin.HelpFlag.Short('h') +} + func Parse() *AppSettings { - var rawBasicAuthUsername string - var rawBasicAuthPassword string + settings := &AppSettings{} + readParamsFromCli(settings) + settings.validateFlags() + return settings +} - appSettings := &AppSettings{} - flag.BoolVar(&appSettings.VersionMode, "version", false, "show version info and exit") - flag.StringVar(&appSettings.MetricsAddress, "web.listen-address", "0.0.0.0", "address to use for the metrics server") - flag.IntVar(&appSettings.MetricsPort, "port", 9191, "port to use for the metrics server") - flag.StringVar(&appSettings.Fail2BanSocketPath, "socket", "", "path to the fail2ban server socket") - flag.BoolVar(&appSettings.FileCollectorEnabled, "collector.textfile", false, "enable the textfile collector") - flag.StringVar(&appSettings.FileCollectorPath, "collector.textfile.directory", "", "directory to read text files with metrics from") - flag.StringVar(&rawBasicAuthUsername, "web.basic-auth.username", "", "username to use to protect endpoints with basic auth") - flag.StringVar(&rawBasicAuthPassword, "web.basic-auth.password", "", "password to use to protect endpoints with basic auth") +func readParamsFromCli(settings *AppSettings) { + versionMode := kingpin. + Flag("version", "show version info and exit"). + Default("false"). + Bool() + socketPath := kingpin. + Flag("socket", "path to the fail2ban server socket"). + Default(""). + Envar(socketEnvName). + String() + fileCollectorEnabled := kingpin. + Flag("collector.textfile", "enable the textfile collector"). + Default("false"). + Envar(fileCollectorEnabledEnvName). + Bool() + fileCollectorPath := kingpin. + Flag("collector.textfile.directory", "directory to read text files with metrics from"). + Default(""). + Envar(fileCollectorPathEnvName). + String() + port := kingpin. + Flag("port", "port to use for the metrics server"). + Default("9191"). + Envar(portEnvName). + Int() + address := kingpin. + Flag("web.listen-address", "address to use for the metrics server"). + Default("0.0.0.0"). + Envar(addressEnvName). + String() + rawBasicAuthUsername := kingpin. + Flag("web.basic-auth.username", "username to use to protect endpoints with basic auth"). + Default(""). + Envar(basicAuthUserEnvName). + String() + rawBasicAuthPassword := kingpin. + Flag("web.basic-auth.password", "password to use to protect endpoints with basic auth"). + Default(""). + Envar(basicAuthPassEnvName). + String() - flag.Parse() - appSettings.setBasicAuthValues(rawBasicAuthUsername, rawBasicAuthPassword) - appSettings.validateFlags() - return appSettings + settings.VersionMode = *versionMode + settings.MetricsPort = *port + settings.MetricsAddress = *address + settings.Fail2BanSocketPath = *socketPath + settings.FileCollectorEnabled = *fileCollectorEnabled + settings.FileCollectorPath = *fileCollectorPath + settings.setBasicAuthValues(*rawBasicAuthUsername, *rawBasicAuthPassword) + + kingpin.Parse() } func (settings *AppSettings) setBasicAuthValues(rawUsername, rawPassword string) { diff --git a/src/go.mod b/src/go.mod index 31db45f..23d3a9e 100644 --- a/src/go.mod +++ b/src/go.mod @@ -6,4 +6,5 @@ require ( github.com/kisielk/og-rek v1.1.0 github.com/nlpodyssey/gopickle v0.1.0 github.com/prometheus/client_golang v1.9.0 + gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) diff --git a/src/go.sum b/src/go.sum index 3200d34..303e233 100644 --- a/src/go.sum +++ b/src/go.sum @@ -7,9 +7,11 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -40,6 +42,7 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -142,8 +145,10 @@ github.com/kisielk/og-rek v1.1.0/go.mod h1:6ihsOSzSAxR/65S3Bn9zNihoEqRquhDQZ2c6I github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= @@ -202,6 +207,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -255,6 +261,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -379,9 +386,11 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -395,6 +404,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=