diff --git a/pkg/cfg/cluster.go b/pkg/cfg/cluster.go index addf92b..98374c3 100644 --- a/pkg/cfg/cluster.go +++ b/pkg/cfg/cluster.go @@ -17,10 +17,10 @@ along with this program. If not, see . package cfg import ( - "context" "crypto/tls" "errors" "fmt" + "net" "net/http" "os" "strings" @@ -185,42 +185,24 @@ func (conf *Config) SwitchCluster(name string) error { // We do NOT use go-elasticsearch to check for cluster reachability, // because at this stage, auth may not have been configured. So -// instead we just connect to the cluster using plan net/http, ignore -// HTTP response status and return true if we could just reach ith +// instead we just connect to the cluster using plan net/tcp func (cluster *Cluster) IsReachable() (bool, error) { - ctx, cancel := context.WithTimeout( - context.Background(), - time.Duration(500)*time.Millisecond) - defer cancel() + timeout := 500 * time.Millisecond - req, err := http.NewRequestWithContext( - ctx, - "GET", - cluster.Uri, - nil, - ) + url := strings.TrimPrefix(strings.TrimPrefix(cluster.Uri, "https://"), "http://") + host := strings.Split(url, "/") + + if !strings.Contains(host[0], ":") { + host[0] += ":443" + } + + conn, err := net.DialTimeout("tcp", host[0], timeout) if err != nil { return false, err } - client := &http.Client{Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - }} - - resp, err := client.Do(req) - - if err != nil { - return false, err - } - - if resp != nil { - // at this stage we do not care if the elasticsearch cluster - // accepts our request or if it's misconfigured in some way - return true, nil - } - - return false, nil + return true, conn.Close() } func (conf *Config) SetupES() error { diff --git a/pkg/cfg/config.go b/pkg/cfg/config.go index ac61757..191d33b 100644 --- a/pkg/cfg/config.go +++ b/pkg/cfg/config.go @@ -28,7 +28,7 @@ import ( ) const ( - Version string = `v0.0.24` + Version string = `v0.0.25` ) var ( @@ -137,6 +137,18 @@ func (conf *Config) Init() error { return err } + if err := conf.determineDefaultCluster(); err != nil { + return err + } + + conf.HaveJQ = isJQinstalled() + + conf.PrintDebug() + + return nil +} + +func (conf *Config) determineDefaultCluster() error { if conf.CurrentCluster != "" { // -C specified, set current cluster explicitly, no matter what the config says current, exists := conf.Clusters[conf.CurrentCluster] @@ -172,10 +184,6 @@ func (conf *Config) Init() error { } } - conf.HaveJQ = isJQinstalled() - - conf.PrintDebug() - return nil } diff --git a/pkg/es/cluster.go b/pkg/es/cluster.go index fe17035..bb5399b 100644 --- a/pkg/es/cluster.go +++ b/pkg/es/cluster.go @@ -31,44 +31,62 @@ import ( type ClusterIndices map[string]map[string]*types.IndicesRecord -func ClusterList(conf *cfg.Config) error { - table := printer.NewTable(conf, 5, len(conf.Clusters)) +type clusterReachable struct { + reachable bool + err error +} +func ClusterList(conf *cfg.Config) error { + var mu sync.Mutex + var wg sync.WaitGroup + reachable := make(map[string]clusterReachable, len(conf.Clusters)) + + // check endpoints in parallel to speed things up + for name, cluster := range conf.Clusters { + wg.Add(1) + + go func() { + defer wg.Done() + online, err := cluster.IsReachable() + + mu.Lock() + reachable[name] = clusterReachable{reachable: online, err: err} + mu.Unlock() + }() + } + + wg.Wait() + + table := printer.NewTable(conf, 5, len(conf.Clusters)) table.Addheaders("cluster", "uri", "reachable", "current", "error") idx := 0 for name, cluster := range conf.Clusters { - reachable := "no" + reachableStr := "no" current := "no" errmsg := "" - online, err := cluster.IsReachable() - - if online { - reachable = printer.Colorize(conf, "green", "reachable") + if reachable[name].reachable { + reachableStr = printer.Colorize(conf, "green", "reachable") } if cluster.Default { current = printer.Colorize(conf, "green", "yes") - if !online { - reachable = printer.Colorize(conf, "red", "no") - errmsg = err.Error() + if !reachable[name].reachable { + reachableStr = printer.Colorize(conf, "red", "no") + errmsg = reachable[name].err.Error() } } - table.Entries[idx] = []string{name, cluster.Uri, reachable, current, errmsg} + table.Entries[idx] = []string{name, cluster.Uri, reachableStr, current, errmsg} idx++ } table.Sort() - if err := table.Print(); err != nil { - return err - } - - return nil + return table.Print() } // We're using goroutines here to parallelize API requests, since we