CLI Flag --bind (#77)

* CLI Flag for Bind Address

Signed-off-by: Bhargav Ravuri <bhargav.ravuri@infracloud.io>

* Update Documentation for --bind

Signed-off-by: Bhargav Ravuri <bhargav.ravuri@infracloud.io>

Signed-off-by: Bhargav Ravuri <bhargav.ravuri@infracloud.io>
This commit is contained in:
Bhargav Ravuri
2022-11-07 21:35:01 +05:30
committed by GitHub
parent 15ce9170f3
commit f29800ed5b
4 changed files with 63 additions and 39 deletions

View File

@@ -61,6 +61,8 @@ You can see the list of available command-line flags by running `helm dashboard
By default, the web server is only available locally. You can change that by specifying `HD_BIND` environment variable By default, the web server is only available locally. You can change that by specifying `HD_BIND` environment variable
to the desired value. For example, `0.0.0.0` would bind to all IPv4 addresses or `[::0]` would be all IPv6 addresses. to the desired value. For example, `0.0.0.0` would bind to all IPv4 addresses or `[::0]` would be all IPv6 addresses.
This can also be specified using flag `--bind <host>`, for example `--bind=0.0.0.0` or `--bind 0.0.0.0`.
> Precedence order: flag `--bind=<host>` > env `HD_BIND=<host>` > default value `localhost`
If your port 8080 is busy, you can specify a different port to use via `--port <number>` command-line flag. If your port 8080 is busy, you can specify a different port to use via `--port <number>` command-line flag.

2
go.mod
View File

@@ -7,6 +7,7 @@ require (
github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/go-version v1.6.0
github.com/hexops/gotextdiff v1.0.3 github.com/hexops/gotextdiff v1.0.3
github.com/jessevdk/go-flags v1.5.0 github.com/jessevdk/go-flags v1.5.0
github.com/olekukonko/tablewriter v0.0.5
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
@@ -31,7 +32,6 @@ require (
github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.3 // indirect github.com/pelletier/go-toml/v2 v2.0.3 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect github.com/ugorji/go/codec v1.2.7 // indirect
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect

34
main.go
View File

@@ -2,12 +2,13 @@ package main
import ( import (
"fmt" "fmt"
"os"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/komodorio/helm-dashboard/pkg/dashboard" "github.com/komodorio/helm-dashboard/pkg/dashboard"
"github.com/pkg/browser" "github.com/pkg/browser"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"os"
) )
var ( var (
@@ -17,22 +18,35 @@ var (
) )
type options struct { type options struct {
Version bool `long:"version" description:"Show tool version"` Version bool `long:"version" description:"Show tool version"`
Verbose bool `short:"v" long:"verbose" description:"Show verbose debug information"` Verbose bool `short:"v" long:"verbose" description:"Show verbose debug information"`
NoBrowser bool `short:"b" long:"no-browser" description:"Do not attempt to open Web browser upon start"` NoBrowser bool `short:"b" long:"no-browser" description:"Do not attempt to open Web browser upon start"`
NoTracking bool `long:"no-analytics" description:"Disable user analytics (GA, DataDog etc.)"` NoTracking bool `long:"no-analytics" description:"Disable user analytics (GA, DataDog etc.)"`
BindHost string `long:"bind" description:"Host binding to start server (default: localhost)"` // default should be printed but not assigned as the precedence: flag > env > default
Port uint `short:"p" long:"port" description:"Port to start server on" default:"8080"` // TODO: better default port to clash less? Port uint `short:"p" long:"port" description:"Port to start server on" default:"8080"` // TODO: better default port to clash less?
Namespace string `short:"n" long:"namespace" description:"Limit operations to a specific namespace"`
Namespace string `short:"n" long:"namespace" description:"Limit operations to a specific namespace"`
} }
func main() { func main() {
opts := parseFlags() opts := parseFlags()
if opts.BindHost == "" {
host := os.Getenv("HD_BIND")
if host == "" {
host = "localhost"
}
opts.BindHost = host
}
setupLogging(opts.Verbose) setupLogging(opts.Verbose)
address, webServerDone := dashboard.StartServer(version, int(opts.Port), opts.Namespace, opts.Verbose, opts.NoTracking) server := dashboard.Server{
Version: version,
Namespace: opts.Namespace,
Address: fmt.Sprintf("%s:%d", opts.BindHost, opts.Port),
Debug: opts.Verbose,
NoTracking: opts.NoTracking,
}
address, webServerDone := server.StartServer()
if !opts.NoTracking { if !opts.NoTracking {
log.Infof("User analytics is collected to improve the quality, disable it with --no-analytics") log.Infof("User analytics is collected to improve the quality, disable it with --no-analytics")

View File

@@ -3,22 +3,31 @@ package dashboard
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/hashicorp/go-version" "github.com/hashicorp/go-version"
"github.com/komodorio/helm-dashboard/pkg/dashboard/scanners" "github.com/komodorio/helm-dashboard/pkg/dashboard/scanners"
"github.com/komodorio/helm-dashboard/pkg/dashboard/subproc" "github.com/komodorio/helm-dashboard/pkg/dashboard/subproc"
"github.com/komodorio/helm-dashboard/pkg/dashboard/utils" "github.com/komodorio/helm-dashboard/pkg/dashboard/utils"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"net/http"
"os"
"strconv"
"strings"
"time"
) )
func StartServer(version string, port int, ns string, debug bool, noTracking bool) (string, utils.ControlChan) { type Server struct {
Version string
Namespace string
Address string
Debug bool
NoTracking bool
}
func (s Server) StartServer() (string, utils.ControlChan) {
data := subproc.DataLayer{ data := subproc.DataLayer{
Namespace: ns, Namespace: s.Namespace,
} }
err := data.CheckConnectivity() err := data.CheckConnectivity()
if err != nil { if err != nil {
@@ -27,37 +36,33 @@ func StartServer(version string, port int, ns string, debug bool, noTracking boo
} }
data.StatusInfo = &subproc.StatusInfo{ data.StatusInfo = &subproc.StatusInfo{
CurVer: version, CurVer: s.Version,
Analytics: !noTracking, Analytics: !s.NoTracking,
LimitedToNamespace: ns, LimitedToNamespace: s.Namespace,
} }
go checkUpgrade(data.StatusInfo) go checkUpgrade(data.StatusInfo)
discoverScanners(&data) discoverScanners(&data)
address := os.Getenv("HD_BIND")
if address == "" {
address = "localhost"
}
address += ":" + strconv.Itoa(port)
abort := make(utils.ControlChan) abort := make(utils.ControlChan)
api := NewRouter(abort, &data, debug) api := NewRouter(abort, &data, s.Debug)
done := startBackgroundServer(address, api, abort) done := s.startBackgroundServer(api, abort)
return "http://" + address, done return "http://" + s.Address, done
} }
func startBackgroundServer(addr string, routes *gin.Engine, abort utils.ControlChan) utils.ControlChan { func (s Server) startBackgroundServer(routes *gin.Engine, abort utils.ControlChan) utils.ControlChan {
done := make(utils.ControlChan) done := make(utils.ControlChan)
server := &http.Server{Addr: addr, Handler: routes} server := &http.Server{
Addr: s.Address,
Handler: routes,
}
go func() { go func() {
err := server.ListenAndServe() err := server.ListenAndServe()
if err != nil && err != http.ErrServerClosed { if err != nil && err != http.ErrServerClosed {
log.Warnf("Looks like port is busy for %s, checking if it's us...", addr) log.Warnf("Looks like port is busy for %s, checking if it's us...", s.Address)
if itIsUs(addr) { if s.itIsUs() {
log.Infof("Yes, it's another instance of us. Just reuse it.") log.Infof("Yes, it's another instance of us. Just reuse it.")
} else { } else {
panic(err) panic(err)
@@ -77,11 +82,14 @@ func startBackgroundServer(addr string, routes *gin.Engine, abort utils.ControlC
return done return done
} }
func itIsUs(addr string) bool { func (s Server) itIsUs() bool {
var myClient = &http.Client{Timeout: 5 * time.Second} url := fmt.Sprintf("http://%s/status", s.Address)
r, err := myClient.Get("http://" + addr + "/status") var myClient = &http.Client{
Timeout: 5 * time.Second,
}
r, err := myClient.Get(url)
if err != nil { if err != nil {
log.Debugf("It's not us on %s: %s", addr, err) log.Debugf("It's not us on %s: %s", s.Address, err)
return false return false
} }
defer r.Body.Close() defer r.Body.Close()