diff --git a/cmd/tidb-dashboard/main.go b/cmd/tidb-dashboard/main.go index a20b49a2b5..4654076eff 100755 --- a/cmd/tidb-dashboard/main.go +++ b/cmd/tidb-dashboard/main.go @@ -23,6 +23,7 @@ import ( "os" "os/signal" "path" + "strconv" "strings" "sync" "syscall" @@ -240,7 +241,7 @@ func main() { loadDistroStringsRes() - listenAddr := fmt.Sprintf("%s:%d", cliConfig.ListenHost, cliConfig.ListenPort) + listenAddr := net.JoinHostPort(cliConfig.ListenHost, strconv.Itoa(cliConfig.ListenPort)) listener, err := net.Listen("tcp", listenAddr) if err != nil { log.Fatal("Dashboard server listen failed", zap.String("addr", listenAddr), zap.Error(err)) @@ -273,9 +274,9 @@ func main() { mux.Handle(config.SwaggerPathPrefix, swaggerserver.Handler()) log.Info(fmt.Sprintf("Dashboard server is listening at %s", listenAddr)) - log.Info(fmt.Sprintf("UI: http://%s:%d/dashboard/", cliConfig.ListenHost, cliConfig.ListenPort)) - log.Info(fmt.Sprintf("API: http://%s:%d/dashboard/api/", cliConfig.ListenHost, cliConfig.ListenPort)) - log.Info(fmt.Sprintf("Swagger: http://%s:%d/dashboard/api/swagger/", cliConfig.ListenHost, cliConfig.ListenPort)) + log.Info(fmt.Sprintf("UI: http://%s/dashboard/", net.JoinHostPort(cliConfig.ListenHost, strconv.Itoa(cliConfig.ListenPort)))) + log.Info(fmt.Sprintf("API: http://%s/dashboard/api/", net.JoinHostPort(cliConfig.ListenHost, strconv.Itoa(cliConfig.ListenPort)))) + log.Info(fmt.Sprintf("Swagger: http://%s/dashboard/api/swagger/", net.JoinHostPort(cliConfig.ListenHost, strconv.Itoa(cliConfig.ListenPort)))) srv := &http.Server{Handler: mux} // nolint:gosec var wg sync.WaitGroup diff --git a/pkg/apiserver/clusterinfo/statistics.go b/pkg/apiserver/clusterinfo/statistics.go index a665a19efc..94991f0c0e 100644 --- a/pkg/apiserver/clusterinfo/statistics.go +++ b/pkg/apiserver/clusterinfo/statistics.go @@ -3,8 +3,9 @@ package clusterinfo import ( - "fmt" + "net" "sort" + "strconv" "github.com/samber/lo" "gorm.io/gorm" @@ -83,8 +84,8 @@ func (s *Service) calculateStatistics(db *gorm.DB) (*ClusterStatistics, error) { for _, i := range pdInfo { globalHostsSet[i.IP] = struct{}{} globalVersionsSet[i.Version] = struct{}{} - globalInfo.instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} - infoByIk["pd"].instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} + globalInfo.instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} + infoByIk["pd"].instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} } tikvInfo, tiFlashInfo, err := topology.FetchStoreTopology(s.params.PDClient) if err != nil { @@ -93,14 +94,14 @@ func (s *Service) calculateStatistics(db *gorm.DB) (*ClusterStatistics, error) { for _, i := range tikvInfo { globalHostsSet[i.IP] = struct{}{} globalVersionsSet[i.Version] = struct{}{} - globalInfo.instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} - infoByIk["tikv"].instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} + globalInfo.instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} + infoByIk["tikv"].instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} } for _, i := range tiFlashInfo { globalHostsSet[i.IP] = struct{}{} globalVersionsSet[i.Version] = struct{}{} - globalInfo.instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} - infoByIk["tiflash"].instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} + globalInfo.instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} + infoByIk["tiflash"].instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} } tidbInfo, err := topology.FetchTiDBTopology(s.lifecycleCtx, s.params.EtcdClient) if err != nil { @@ -109,8 +110,8 @@ func (s *Service) calculateStatistics(db *gorm.DB) (*ClusterStatistics, error) { for _, i := range tidbInfo { globalHostsSet[i.IP] = struct{}{} globalVersionsSet[i.Version] = struct{}{} - globalInfo.instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} - infoByIk["tidb"].instances[fmt.Sprintf("%s:%d", i.IP, i.Port)] = struct{}{} + globalInfo.instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} + infoByIk["tidb"].instances[net.JoinHostPort(i.IP, strconv.Itoa(int(i.Port)))] = struct{}{} } // Fill from hardware info diff --git a/pkg/apiserver/configuration/service.go b/pkg/apiserver/configuration/service.go index 5ec8418e33..d1497834cf 100644 --- a/pkg/apiserver/configuration/service.go +++ b/pkg/apiserver/configuration/service.go @@ -7,7 +7,9 @@ import ( "context" "encoding/json" "fmt" + "net" "sort" + "strconv" "github.com/joomcode/errorx" "go.etcd.io/etcd/clientv3" @@ -105,7 +107,7 @@ func (s *Service) getConfigItemsFromPD() (map[string]interface{}, error) { } func (s *Service) getConfigItemsFromTiDBToChannel(tidb *topology.TiDBInfo, ch chan<- channelItem) { - displayAddress := fmt.Sprintf("%s:%d", tidb.IP, tidb.Port) + displayAddress := net.JoinHostPort(tidb.IP, strconv.Itoa(int(tidb.Port))) r, err := s.getConfigItemsFromTiDB(tidb.IP, int(tidb.StatusPort)) if err != nil { @@ -129,7 +131,7 @@ func (s *Service) getConfigItemsFromTiDB(host string, statusPort int) (map[strin } func (s *Service) getConfigItemsFromTiKVToChannel(tikv *topology.StoreInfo, ch chan<- channelItem) { - displayAddress := fmt.Sprintf("%s:%d", tikv.IP, tikv.Port) + displayAddress := net.JoinHostPort(tikv.IP, strconv.Itoa(int(tikv.Port))) r, err := s.getConfigItemsFromTiKV(tikv.IP, int(tikv.StatusPort)) if err != nil { @@ -335,7 +337,7 @@ func (s *Service) editConfig(db *gorm.DB, kind ItemKind, id string, newValue int // TODO: What about tombstone stores? _, err := s.params.TiKVClient.SendPostRequest(kvStore.IP, int(kvStore.StatusPort), "/config", bytes.NewBuffer(bodyJSON)) if err != nil { - failures = append(failures, ErrEditFailed.Wrap(err, "Failed to edit config for TiKV instance `%s:%d`", kvStore.IP, kvStore.Port)) + failures = append(failures, ErrEditFailed.Wrap(err, "Failed to edit config for TiKV instance `%s`", net.JoinHostPort(kvStore.IP, strconv.Itoa(int(kvStore.Port))))) } } if len(failures) == len(tikvInfo) { diff --git a/pkg/apiserver/debugapi/endpoint/payload.go b/pkg/apiserver/debugapi/endpoint/payload.go index 4392f64e3b..c61e864e33 100644 --- a/pkg/apiserver/debugapi/endpoint/payload.go +++ b/pkg/apiserver/debugapi/endpoint/payload.go @@ -6,9 +6,11 @@ import ( "context" "fmt" "io" + "net" "net/http" "net/url" "regexp" + "strconv" "go.etcd.io/etcd/clientv3" @@ -192,7 +194,7 @@ func (p *ResolvedRequestPayload) SendRequestAndPipe( } req := httpClient.LR(). SetDebugTag("origin:debug_api"). - SetTLSAwareBaseURL(fmt.Sprintf("http://%s:%d", p.host, p.port)). + SetTLSAwareBaseURL(fmt.Sprintf("http://%s", net.JoinHostPort(p.host, strconv.Itoa(p.port)))). SetMethod(p.api.Method). SetURL(p.path). SetQueryParamsFromValues(p.queryValues) diff --git a/pkg/apiserver/logsearch/task.go b/pkg/apiserver/logsearch/task.go index 26a4f04095..fc746543a4 100644 --- a/pkg/apiserver/logsearch/task.go +++ b/pkg/apiserver/logsearch/task.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "math" + "net" "os" "path" "path/filepath" @@ -168,7 +169,7 @@ func (t *Task) SyncRun() { secureOpt = grpc.WithTransportCredentials(creds) } - conn, err := grpc.Dial(fmt.Sprintf("%s:%d", t.model.Target.IP, t.model.Target.Port), + conn, err := grpc.Dial(net.JoinHostPort(t.model.Target.IP, strconv.Itoa(t.model.Target.Port)), secureOpt, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(MaxRecvMsgSize)), ) diff --git a/pkg/apiserver/metrics/prom_resolve.go b/pkg/apiserver/metrics/prom_resolve.go index e86a6ead84..313937e83b 100644 --- a/pkg/apiserver/metrics/prom_resolve.go +++ b/pkg/apiserver/metrics/prom_resolve.go @@ -6,7 +6,9 @@ import ( "bytes" "encoding/json" "fmt" + "net" "net/url" + "strconv" "strings" "time" @@ -84,7 +86,7 @@ func (s *Service) resolveDeployedPromAddress() (string, error) { if pi == nil { return "", nil } - return fmt.Sprintf("http://%s:%d", pi.IP, pi.Port), nil + return fmt.Sprintf("http://%s", net.JoinHostPort(pi.IP, strconv.Itoa(int(pi.Port)))), nil } // Resolve the final Prometheus address. When user has customized an address, this address is returned. Otherwise, diff --git a/pkg/apiserver/profiling/fetcher.go b/pkg/apiserver/profiling/fetcher.go index 94557bd1b0..77d57656b6 100644 --- a/pkg/apiserver/profiling/fetcher.go +++ b/pkg/apiserver/profiling/fetcher.go @@ -6,6 +6,7 @@ import ( _ "embed" "fmt" "io" + "net" "os/exec" "strconv" "strings" @@ -128,7 +129,7 @@ type pdFetcher struct { } func (f *pdFetcher) fetch(op *fetchOptions) ([]byte, error) { - baseURL := fmt.Sprintf("%s://%s:%d", f.statusAPIHTTPScheme, op.ip, op.port) + baseURL := fmt.Sprintf("%s://%s", f.statusAPIHTTPScheme, net.JoinHostPort(op.ip, strconv.Itoa(op.port))) return f.client. WithTimeout(maxProfilingTimeout). WithBaseURL(baseURL). diff --git a/pkg/pd/client.go b/pkg/pd/client.go index 31549dea4a..75cd60a449 100644 --- a/pkg/pd/client.go +++ b/pkg/pd/client.go @@ -6,7 +6,9 @@ import ( "context" "fmt" "io" + "net" "net/http" + "strconv" "time" "go.uber.org/fx" @@ -56,7 +58,7 @@ func (c Client) WithBaseURL(baseURL string) *Client { } func (c Client) WithAddress(host string, port int) *Client { - c.baseURL = fmt.Sprintf("%s://%s:%d", c.httpScheme, host, port) + c.baseURL = fmt.Sprintf("%s://%s", c.httpScheme, net.JoinHostPort(host, strconv.Itoa(port))) return &c } diff --git a/pkg/tidb/client.go b/pkg/tidb/client.go index 9b688a3e4a..9837bb59a0 100644 --- a/pkg/tidb/client.go +++ b/pkg/tidb/client.go @@ -9,6 +9,7 @@ import ( "net" "net/http" "os" + "strconv" "strings" "time" @@ -90,18 +91,18 @@ func (c Client) WithStatusAPITimeout(timeout time.Duration) *Client { } func (c Client) WithStatusAPIAddress(host string, statusPort int) *Client { - c.statusAPIAddress = fmt.Sprintf("%s:%d", host, statusPort) + c.statusAPIAddress = net.JoinHostPort(host, strconv.Itoa(statusPort)) return &c } func (c Client) WithEnforcedStatusAPIAddress(host string, statusPort int) *Client { c.enforceStatusAPIAddresss = true - c.statusAPIAddress = fmt.Sprintf("%s:%d", host, statusPort) + c.statusAPIAddress = net.JoinHostPort(host, strconv.Itoa(statusPort)) return &c } func (c Client) WithSQLAPIAddress(host string, sqlPort int) *Client { - c.sqlAPIAddress = fmt.Sprintf("%s:%d", host, sqlPort) + c.sqlAPIAddress = net.JoinHostPort(host, strconv.Itoa(sqlPort)) return &c } diff --git a/pkg/tidb/forwarder.go b/pkg/tidb/forwarder.go index af9167dd8e..b6969165df 100644 --- a/pkg/tidb/forwarder.go +++ b/pkg/tidb/forwarder.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "net" + "strconv" "time" "github.com/cenkalti/backoff/v4" @@ -85,8 +86,8 @@ func (f *Forwarder) pollingForTiDB() { tidbEndpoints := make(map[string]struct{}, len(allTiDB)) for _, server := range allTiDB { if server.Status == topology.ComponentStatusUp { - tidbEndpoints[fmt.Sprintf("%s:%d", server.IP, server.Port)] = struct{}{} - statusEndpoints[fmt.Sprintf("%s:%d", server.IP, server.StatusPort)] = struct{}{} + tidbEndpoints[net.JoinHostPort(server.IP, strconv.Itoa(int(server.Port)))] = struct{}{} + statusEndpoints[net.JoinHostPort(server.IP, strconv.Itoa(int(server.StatusPort)))] = struct{}{} } } f.sqlProxy.updateRemotes(tidbEndpoints) diff --git a/pkg/tiflash/client.go b/pkg/tiflash/client.go index b3761550d6..5896a0063f 100644 --- a/pkg/tiflash/client.go +++ b/pkg/tiflash/client.go @@ -6,7 +6,9 @@ import ( "context" "fmt" "io" + "net" "net/http" + "strconv" "time" "go.uber.org/fx" @@ -58,7 +60,7 @@ func (c Client) AddRequestHeader(key, value string) *Client { } func (c *Client) Get(host string, statusPort int, relativeURI string) (*httpc.Response, error) { - uri := fmt.Sprintf("%s://%s:%d%s", c.httpScheme, host, statusPort, relativeURI) + uri := fmt.Sprintf("%s://%s%s", c.httpScheme, net.JoinHostPort(host, strconv.Itoa(statusPort)), relativeURI) return c.httpClient.WithTimeout(c.timeout).Send(c.lifecycleCtx, uri, http.MethodGet, nil, ErrFlashClientRequestFailed, distro.R().TiFlash) } @@ -71,6 +73,6 @@ func (c *Client) SendGetRequest(host string, statusPort int, relativeURI string) } func (c *Client) SendPostRequest(host string, statusPort int, relativeURI string, body io.Reader) ([]byte, error) { - uri := fmt.Sprintf("%s://%s:%d%s", c.httpScheme, host, statusPort, relativeURI) + uri := fmt.Sprintf("%s://%s%s", c.httpScheme, net.JoinHostPort(host, strconv.Itoa(statusPort)), relativeURI) return c.httpClient.WithTimeout(c.timeout).SendRequest(c.lifecycleCtx, uri, http.MethodPost, body, ErrFlashClientRequestFailed, distro.R().TiFlash) } diff --git a/pkg/tikv/client.go b/pkg/tikv/client.go index 03f72d9cd5..64d42d3d74 100644 --- a/pkg/tikv/client.go +++ b/pkg/tikv/client.go @@ -6,7 +6,9 @@ import ( "context" "fmt" "io" + "net" "net/http" + "strconv" "time" "go.uber.org/fx" @@ -58,7 +60,7 @@ func (c Client) AddRequestHeader(key, value string) *Client { } func (c *Client) Get(host string, statusPort int, relativeURI string) (*httpc.Response, error) { - uri := fmt.Sprintf("%s://%s:%d%s", c.httpScheme, host, statusPort, relativeURI) + uri := fmt.Sprintf("%s://%s%s", c.httpScheme, net.JoinHostPort(host, strconv.Itoa(statusPort)), relativeURI) return c.httpClient.WithTimeout(c.timeout).Send(c.lifecycleCtx, uri, http.MethodGet, nil, ErrTiKVClientRequestFailed, distro.R().TiKV) } @@ -71,6 +73,6 @@ func (c *Client) SendGetRequest(host string, statusPort int, relativeURI string) } func (c *Client) SendPostRequest(host string, statusPort int, relativeURI string, body io.Reader) ([]byte, error) { - uri := fmt.Sprintf("%s://%s:%d%s", c.httpScheme, host, statusPort, relativeURI) + uri := fmt.Sprintf("%s://%s%s", c.httpScheme, net.JoinHostPort(host, strconv.Itoa(statusPort)), relativeURI) return c.httpClient.WithTimeout(c.timeout).SendRequest(c.lifecycleCtx, uri, http.MethodPost, body, ErrTiKVClientRequestFailed, distro.R().TiKV) } diff --git a/util/client/tidbclient/sql_client.go b/util/client/tidbclient/sql_client.go index 1d0ab58b35..e17fe38dfe 100644 --- a/util/client/tidbclient/sql_client.go +++ b/util/client/tidbclient/sql_client.go @@ -5,7 +5,8 @@ package tidbclient import ( "context" "errors" - "fmt" + "net" + "strconv" "time" "github.com/VividCortex/mysqlerr" @@ -50,7 +51,7 @@ func NewSQLClient(config SQLClientConfig) *SQLClient { func (c *SQLClient) OpenConn(user string, pass string) (*gorm.DB, error) { dsnConfig := mysql.NewConfig() dsnConfig.Net = "tcp" - dsnConfig.Addr = fmt.Sprintf("%s:%d", c.config.Host, c.config.Port) + dsnConfig.Addr = net.JoinHostPort(c.config.Host, strconv.Itoa(c.config.Port)) dsnConfig.User = user dsnConfig.Passwd = pass dsnConfig.Timeout = time.Second * 60