From 5cd001daee3312aa1a723f847379e5e2ccecbf53 Mon Sep 17 00:00:00 2001 From: Chris Gaffney Date: Fri, 23 Apr 2021 22:58:32 -0400 Subject: [PATCH] Add redis-url and redis-insecure-tls command line options A URL can contain all of the information in the individual flags as a single string rather than as separate pieces. I've mostly run into URLs pointing to Redis and this make those existing URLs easier to work with. This also introduces the -redis-insecure-tls flag which turns off TLS certificate hostname verification. We've chosen Heroku Redis for a recent project which requires TLS but, for reasons I don't know, they don't provide a certificate that is valid for the hostname. I also wasn't able to get the existing -redis-tls flag to work. --- main.go | 74 +++++++++++++++++++++++++++++------------- redis_info_handlers.go | 2 +- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/main.go b/main.go index 355b9fd..cad3cfc 100644 --- a/main.go +++ b/main.go @@ -21,19 +21,23 @@ import ( // Command-line flags var ( - flagPort int - flagRedisAddr string - flagRedisDB int - flagRedisPassword string - flagRedisTLS string + flagPort int + flagRedisAddr string + flagRedisDB int + flagRedisPassword string + flagRedisTLS string + flagRedisURL string + flagRedisInsecureTLS bool ) func init() { flag.IntVar(&flagPort, "port", 8080, "port number to use for web ui server") - flag.StringVar(&flagRedisAddr, "redis_addr", "127.0.0.1:6379", "address of redis server to connect to") - flag.IntVar(&flagRedisDB, "redis_db", 0, "redis database number") - flag.StringVar(&flagRedisPassword, "redis_password", "", "password to use when connecting to redis server") - flag.StringVar(&flagRedisTLS, "redis_tls", "", "server name for TLS validation used when connecting to redis server") + flag.StringVar(&flagRedisAddr, "redis-addr", "127.0.0.1:6379", "address of redis server to connect to") + flag.IntVar(&flagRedisDB, "redis-db", 0, "redis database number") + flag.StringVar(&flagRedisPassword, "redis-password", "", "password to use when connecting to redis server") + flag.StringVar(&flagRedisTLS, "redis-tls", "", "server name for TLS validation used when connecting to redis server") + flag.StringVar(&flagRedisURL, "redis-url", "", "URL to redis server") + flag.BoolVar(&flagRedisInsecureTLS, "redis-insecure-tls", false, "Disable TLS certificate host checks") } // staticFileServer implements the http.Handler interface, so we can use it @@ -85,31 +89,57 @@ func (srv *staticFileServer) indexFilePath() string { return filepath.Join(srv.staticDirPath, srv.indexFileName) } +func getRedisOptionsFromFlags() (*redis.Options, error) { + var err error + var opts *redis.Options + + if flagRedisURL != "" { + opts, err = redis.ParseURL(flagRedisURL) + if err != nil { + return nil, err + } + } else { + opts = &redis.Options{ + Addr: flagRedisAddr, + DB: flagRedisDB, + Password: flagRedisPassword, + TLSConfig: &tls.Config{}, + } + } + + if tls := opts.TLSConfig; tls != nil { + if tlsHost := flagRedisTLS; tlsHost != "" { + tls.ServerName = tlsHost + } + + if flagRedisInsecureTLS { + tls.InsecureSkipVerify = true + } + } + + return opts, nil +} + //go:embed ui/build/* var staticContents embed.FS func main() { flag.Parse() - var tlsConfig *tls.Config - if flagRedisTLS != "" { - tlsConfig = &tls.Config{ServerName: flagRedisTLS} + opts, err := getRedisOptionsFromFlags() + if err != nil { + log.Fatal(err) } inspector := inspeq.New(asynq.RedisClientOpt{ - Addr: flagRedisAddr, - DB: flagRedisDB, - Password: flagRedisPassword, - TLSConfig: tlsConfig, + Addr: opts.Addr, + DB: opts.DB, + Password: opts.Password, + TLSConfig: opts.TLSConfig, }) defer inspector.Close() - rdb := redis.NewClient(&redis.Options{ - Addr: flagRedisAddr, - DB: flagRedisDB, - Password: flagRedisPassword, - TLSConfig: tlsConfig, - }) + rdb := redis.NewClient(opts) defer rdb.Close() router := mux.NewRouter() diff --git a/redis_info_handlers.go b/redis_info_handlers.go index 2dc0cbe..ac3958b 100644 --- a/redis_info_handlers.go +++ b/redis_info_handlers.go @@ -30,7 +30,7 @@ func newRedisInfoHandlerFunc(rdb *redis.Client) http.HandlerFunc { } info := parseRedisInfo(res) resp := RedisInfoResponse{ - Addr: flagRedisAddr, + Addr: rdb.Options().Addr, Info: info, RawInfo: res, }