package cfg import ( "fmt" "log" "os" "git.cryptic.systems/volker.raschek/prometheus-fail2ban-exporter/auth" "github.com/alecthomas/kong" ) var cliStruct struct { VersionMode bool `name:"version" short:"v" help:"Show version info and exit"` DryRunMode bool `name:"dry-run" help:"Attempt to connect to the fail2ban socket then exit before starting the server"` ServerAddress string `name:"web.listen-address" env:"F2B_WEB_LISTEN_ADDRESS" help:"Address to use for the metrics server" default:"${default_address}"` F2bSocketPath string `name:"collector.f2b.socket" env:"F2B_COLLECTOR_SOCKET" help:"Path to the fail2ban server socket" default:"${default_socket}"` ExitOnSocketError bool `name:"collector.f2b.exit-on-socket-connection-error" env:"F2B_EXIT_ON_SOCKET_CONN_ERROR" help:"When set to true the exporter will immediately exit on a fail2ban socket connection error"` TextFileExporterPath string `name:"collector.textfile.directory" env:"F2B_COLLECTOR_TEXT_PATH" help:"Directory to read text files with metrics from"` BasicAuthUser string `name:"web.basic-auth.username" env:"F2B_WEB_BASICAUTH_USER" help:"Username to use to protect endpoints with basic auth"` BasicAuthPass string `name:"web.basic-auth.password" env:"F2B_WEB_BASICAUTH_PASS" help:"Password to use to protect endpoints with basic auth"` } func Parse() *AppSettings { ctx := kong.Parse( &cliStruct, kong.Vars{ "default_socket": "/var/run/fail2ban/fail2ban.sock", "default_address": ":9191", }, kong.Name("fail2ban_exporter"), kong.Description("🚀 Export prometheus metrics from a running Fail2Ban instance"), kong.UsageOnError(), ) validateFlags(ctx) settings := &AppSettings{ VersionMode: cliStruct.VersionMode, DryRunMode: cliStruct.DryRunMode, MetricsAddress: cliStruct.ServerAddress, Fail2BanSocketPath: cliStruct.F2bSocketPath, FileCollectorPath: cliStruct.TextFileExporterPath, ExitOnSocketConnError: cliStruct.ExitOnSocketError, AuthProvider: createAuthProvider(), } return settings } func createAuthProvider() auth.AuthProvider { username := cliStruct.BasicAuthUser password := cliStruct.BasicAuthPass if len(username) == 0 && len(password) == 0 { return auth.NewEmptyAuthProvider() } log.Print("basic auth enabled") return auth.NewBasicAuthProvider(username, password) } func validateFlags(cliCtx *kong.Context) { var flagsValid = true var messages = []string{} if !cliStruct.VersionMode { if cliStruct.F2bSocketPath == "" { messages = append(messages, "error: fail2ban socket path must not be blank") flagsValid = false } if cliStruct.ServerAddress == "" { messages = append(messages, "error: invalid server address, must not be blank") flagsValid = false } if (len(cliStruct.BasicAuthUser) > 0) != (len(cliStruct.BasicAuthPass) > 0) { messages = append(messages, "error: to enable basic auth both the username and the password must be provided") flagsValid = false } } if !flagsValid { cliCtx.PrintUsage(false) fmt.Println() for i := 0; i < len(messages); i++ { fmt.Println(messages[i]) } os.Exit(1) } }