From 67cacb22ac5ddad6a2247323f78b85748251115e Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Fri, 7 Aug 2020 10:56:50 +0300 Subject: [PATCH] lib/httpserver: add `-tls`, `-tlsCertFile` and `-tlsKeyFile` command-line flags in every vm binary This makes such binaries compatible with binaries from `master` branch (aka single-node version) See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/677 --- app/vmalert/main.go | 2 +- lib/httpserver/httpserver.go | 36 +++++++++++++++++++++++++++++++----- lib/httpserver/metrics.go | 3 ++- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app/vmalert/main.go b/app/vmalert/main.go index 8c41f3edfa..754a35dbe2 100644 --- a/app/vmalert/main.go +++ b/app/vmalert/main.go @@ -109,7 +109,7 @@ func newManager(ctx context.Context) (*manager, error) { if err != nil { return nil, fmt.Errorf("failed to init datasource: %w", err) } - eu, err := getExternalURL(*externalURL, *httpListenAddr, false) + eu, err := getExternalURL(*externalURL, *httpListenAddr, httpserver.IsTLS()) if err != nil { return nil, fmt.Errorf("failed to init `external.url`: %w", err) } diff --git a/lib/httpserver/httpserver.go b/lib/httpserver/httpserver.go index eec3c19a7e..06416db7df 100644 --- a/lib/httpserver/httpserver.go +++ b/lib/httpserver/httpserver.go @@ -25,9 +25,14 @@ import ( ) var ( + tlsEnable = flag.Bool("tls", false, "Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set") + tlsCertFile = flag.String("tlsCertFile", "", "Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs, since RSA certs are slow") + tlsKeyFile = flag.String("tlsKeyFile", "", "Path to file with TLS key. Used only if -tls is set") + pathPrefix = flag.String("http.pathPrefix", "", "An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, "+ "then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. "+ "See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus") + disableResponseCompression = flag.Bool("http.disableResponseCompression", false, "Disable compression of HTTP responses for saving CPU resources. By default compression is enabled to save network bandwidth") maxGracefulShutdownDuration = flag.Duration("http.maxGracefulShutdownDuration", 7*time.Second, "The maximum duration for graceful shutdown of HTTP server. "+ "Highly loaded server may require increased value for graceful shutdown") @@ -61,11 +66,27 @@ type RequestHandler func(w http.ResponseWriter, r *http.Request) bool // // The compression is also disabled if -http.disableResponseCompression flag is set. func Serve(addr string, rh RequestHandler) { - logger.Infof("starting http server at http://%s/", addr) - logger.Infof("pprof handlers are exposed at http://%s/debug/pprof/", addr) - ln, err := netutil.NewTCPListener("http", addr) + scheme := "http" + if *tlsEnable { + scheme = "https" + } + logger.Infof("starting http server at %s://%s/", scheme, addr) + logger.Infof("pprof handlers are exposed at %s://%s/debug/pprof/", scheme, addr) + lnTmp, err := netutil.NewTCPListener(scheme, addr) if err != nil { - logger.Panicf("FATAL: cannot start http server at %s: %s", addr, err) + logger.Fatalf("cannot start http server at %s: %s", addr, err) + } + ln := net.Listener(lnTmp) + + if *tlsEnable { + cert, err := tls.LoadX509KeyPair(*tlsCertFile, *tlsKeyFile) + if err != nil { + logger.Fatalf("cannot load TLS cert from tlsCertFile=%q, tlsKeyFile=%q: %s", *tlsCertFile, *tlsKeyFile, err) + } + cfg := &tls.Config{ + Certificates: []tls.Certificate{cert}, + } + ln = tls.NewListener(ln, cfg) } serveWithListener(addr, ln, rh) } @@ -187,7 +208,7 @@ func handlerWrapper(s *server, w http.ResponseWriter, r *http.Request, rh Reques metricsRequests.Inc() startTime := time.Now() w.Header().Set("Content-Type", "text/plain") - writePrometheusMetrics(w) + WritePrometheusMetrics(w) metricsHandlerDuration.UpdateDuration(startTime) return default: @@ -485,3 +506,8 @@ func isTrivialNetworkError(err error) bool { } return false } + +// IsTLS indicates is tls enabled or not +func IsTLS() bool { + return *tlsEnable +} diff --git a/lib/httpserver/metrics.go b/lib/httpserver/metrics.go index 56c7eefabd..7fab0a134e 100644 --- a/lib/httpserver/metrics.go +++ b/lib/httpserver/metrics.go @@ -12,7 +12,8 @@ import ( "github.com/VictoriaMetrics/metrics" ) -func writePrometheusMetrics(w io.Writer) { +// WritePrometheusMetrics writes all the registered metrics to w in Prometheus exposition format. +func WritePrometheusMetrics(w io.Writer) { metrics.WritePrometheus(w, true) fmt.Fprintf(w, "vm_app_version{version=%q} 1\n", buildinfo.Version)