Skip to content

Commit

Permalink
cluster: display dashboard server URLs (#2472)
Browse files Browse the repository at this point in the history
* cluster: display dashboard server URLs

Signed-off-by: xhe <[email protected]>

* revert legacy behavior back

Signed-off-by: xhe <[email protected]>

---------

Signed-off-by: xhe <[email protected]>
  • Loading branch information
xhebox authored Nov 12, 2024
1 parent c561ec9 commit 505444d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 37 deletions.
84 changes: 49 additions & 35 deletions pkg/cluster/manager/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"errors"
"fmt"
"math"
"net/url"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -102,6 +101,7 @@ type ClusterMetaInfo struct {
TLSClientCert string `json:"tls_client_cert,omitempty"`
TLSClientKey string `json:"tls_client_key,omitempty"`
DashboardURL string `json:"dashboard_url,omitempty"`
DashboardURLS []string `json:"dashboard_urls,omitempty"`
GrafanaURLS []string `json:"grafana_urls,omitempty"`
}

Expand Down Expand Up @@ -157,6 +157,7 @@ func (m *Manager) Display(dopt DisplayOption, opt operator.Options) error {
"", // Client Key
"",
nil,
nil,
},
InstanceInfos: clusterInstInfos,
}
Expand Down Expand Up @@ -261,26 +262,13 @@ func (m *Manager) Display(dopt DisplayOption, opt operator.Options) error {
return err
}

var dashboardAddr string
ctx := ctxt.New(
context.Background(),
opt.Concurrency,
m.logger,
)
if t, ok := topo.(*spec.Specification); ok {
var err error
dashboardAddr, err = t.GetDashboardAddress(ctx, tlsCfg, statusTimeout, masterActive...)
if err == nil && !set.NewStringSet("", "auto", "none").Exist(dashboardAddr) {
scheme := "http"
if tlsCfg != nil {
scheme = "https"
}
if m.logger.GetDisplayMode() == logprinter.DisplayModeJSON {
j.ClusterMetaInfo.DashboardURL = fmt.Sprintf("%s://%s/dashboard", scheme, dashboardAddr)
} else {
fmt.Printf("Dashboard URL: %s\n", cyan.Sprintf("%s://%s/dashboard", scheme, dashboardAddr))
}
}
_ = m.displayDashboards(ctx, t, j, statusTimeout, tlsCfg, "", masterActive...)
}

if m.logger.GetDisplayMode() == logprinter.DisplayModeJSON {
Expand Down Expand Up @@ -386,6 +374,7 @@ func (m *Manager) DisplayTiKVLabels(dopt DisplayOption, opt operator.Options) er
"", // Client Key
"",
nil,
nil,
},
}

Expand Down Expand Up @@ -582,7 +571,7 @@ func (m *Manager) GetClusterTopology(dopt DisplayOption, opt operator.Options) (

var dashboardAddr string
if t, ok := topo.(*spec.Specification); ok {
dashboardAddr, _ = t.GetDashboardAddress(ctx, tlsCfg, statusTimeout, masterActive...)
dashboardAddr, _ = t.GetPDDashboardAddress(ctx, tlsCfg, statusTimeout, masterActive...)
}

clusterInstInfos := []InstInfo{}
Expand Down Expand Up @@ -801,25 +790,28 @@ func (m *Manager) DisplayDashboardInfo(clusterName string, timeout time.Duration
}

ctx := context.WithValue(context.Background(), logprinter.ContextKeyLogger, m.logger)
pdAPI := api.NewPDClient(ctx, metadata.Topology.GetPDListWithManageHost(), timeout, tlsCfg)
dashboardAddr, err := pdAPI.GetDashboardAddress()
if err != nil {
return fmt.Errorf("failed to retrieve TiDB Dashboard instance from PD: %s", err)
}
if dashboardAddr == "auto" {
return fmt.Errorf("TiDB Dashboard is not initialized, please start PD and try again")
} else if dashboardAddr == "none" {
return fmt.Errorf("TiDB Dashboard is disabled")
}
return m.displayDashboards(ctx, metadata.Topology, nil, timeout, tlsCfg, clusterName, metadata.Topology.GetPDListWithManageHost()...)
}

u, err := url.Parse(dashboardAddr)
if err != nil {
return fmt.Errorf("unknown TiDB Dashboard PD instance: %s", dashboardAddr)
func (m *Manager) displayDashboards(ctx context.Context, t *spec.Specification, j *JSONOutput, timeout time.Duration, tlsCfg *tls.Config, clusterName string, pdList ...string) error {
dashboardAddrs := []string{}
t.IterInstance(func(ins spec.Instance) {
if ins.Role() != spec.ComponentDashboard {
return
}
dashboardAddrs = append(dashboardAddrs, utils.JoinHostPort(ins.GetManageHost(), ins.GetPort()))
})

pdDashboardAddr, err := t.GetPDDashboardAddress(ctx, tlsCfg, timeout, pdList...)
if err == nil && !set.NewStringSet("", "auto", "none").Exist(pdDashboardAddr) {
dashboardAddrs = append(dashboardAddrs, pdDashboardAddr)
}

u.Path = "/dashboard/"
if len(dashboardAddrs) == 0 {
return fmt.Errorf("TiDB Dashboard is missing, try again later")
}

if tlsCfg != nil {
if clusterName != "" && tlsCfg != nil {
fmt.Println(
"Client certificate:",
color.CyanString(m.specManager.Path(clusterName, spec.TLSCertKeyDir, spec.PFXClientCert)),
Expand All @@ -829,10 +821,32 @@ func (m *Manager) DisplayDashboardInfo(clusterName string, timeout time.Duration
color.CyanString(crypto.PKCS12Password),
)
}
fmt.Println(
"Dashboard URL:",
color.CyanString(u.String()),
)

for i, addr := range dashboardAddrs {
scheme := "http"

// show the original info
if addr == pdDashboardAddr {
if tlsCfg != nil {
scheme = "https"
}
if m.logger.GetDisplayMode() == logprinter.DisplayModeJSON && j != nil {
j.ClusterMetaInfo.DashboardURL = fmt.Sprintf("%s://%s/dashboard", scheme, addr)
} else {
fmt.Printf("Dashboard URL: %s\n", color.CyanString("%s://%s/dashboard", scheme, addr))
}
}

if m.logger.GetDisplayMode() == logprinter.DisplayModeJSON && j != nil {
j.ClusterMetaInfo.DashboardURLS = append(j.ClusterMetaInfo.DashboardURLS, fmt.Sprintf("%s://%s/dashboard", scheme, addr))
} else {
dashboardAddrs[i] = color.CyanString("%s://%s/dashboard", scheme, addr)
}
}

if m.logger.GetDisplayMode() != logprinter.DisplayModeJSON || j == nil {
fmt.Printf("Dashboard URLs: %s\n", strings.Join(dashboardAddrs, ","))
}

return nil
}
4 changes: 2 additions & 2 deletions pkg/cluster/spec/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,8 @@ func (s *Specification) AdjustByVersion(clusterVersion string) {
}
}

// GetDashboardAddress returns the cluster's dashboard addr
func (s *Specification) GetDashboardAddress(ctx context.Context, tlsCfg *tls.Config, timeout time.Duration, pdList ...string) (string, error) {
// GetPDDashboardAddress returns the cluster's dashboard addr
func (s *Specification) GetPDDashboardAddress(ctx context.Context, tlsCfg *tls.Config, timeout time.Duration, pdList ...string) (string, error) {
if timeout < time.Second {
timeout = statusQueryTimeout
}
Expand Down

0 comments on commit 505444d

Please sign in to comment.