diff --git a/weed/admin/dash/admin_data.go b/weed/admin/dash/admin_data.go index 499de6e154..770c58d23d 100644 --- a/weed/admin/dash/admin_data.go +++ b/weed/admin/dash/admin_data.go @@ -12,6 +12,7 @@ import ( "github.com/seaweedfs/seaweedfs/weed/iam" "github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb/master_pb" + "github.com/seaweedfs/seaweedfs/weed/util" ) // Access key status constants @@ -290,6 +291,17 @@ func (s *AdminServer) ShowOverview(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, topology) } +// raftMasterHttpAddress returns a raft member's HTTP address. Members are +// named after their master address, while the raft address only carries the +// gRPC port, which is not always the HTTP port + 10000. +func raftMasterHttpAddress(server *master_pb.RaftListClusterServersResponse_ClusterServers) string { + httpAddress := pb.ServerAddress(server.Id).ToHttpAddress() + if _, port, err := util.ParseHostPort(httpAddress); err == nil && port > 0 && port < 65536 { + return httpAddress + } + return pb.GrpcAddressToServerAddress(server.Address) +} + // getMasterNodesStatus returns the full set of master nodes in the cluster. // It prefers the authoritative raft membership (RaftListClusterServers) and // falls back to the currently-connected master if the raft call fails, so the @@ -313,7 +325,7 @@ func (s *AdminServer) getMasterNodesStatus() []MasterNode { glog.Warningf("skip master with invalid raft address %q: %v", server.Address, splitErr) continue } - httpAddress := pb.GrpcAddressToServerAddress(server.Address) + httpAddress := raftMasterHttpAddress(server) if httpAddress == "" { glog.Warningf("skip master with invalid raft address %q", server.Address) continue diff --git a/weed/admin/dash/admin_data_test.go b/weed/admin/dash/admin_data_test.go new file mode 100644 index 0000000000..53a6bd8939 --- /dev/null +++ b/weed/admin/dash/admin_data_test.go @@ -0,0 +1,28 @@ +package dash + +import ( + "testing" + + "github.com/seaweedfs/seaweedfs/weed/pb/master_pb" +) + +func TestRaftMasterHttpAddress(t *testing.T) { + tests := []struct { + name, id, address, want string + }{ + {"goraft names members by full address", "127.101.0.1:11111.11112", "127.101.0.1:11112", "127.101.0.1:11111"}, + {"hashicorp names members by http address", "127.102.0.1:2222", "127.102.0.1:3333", "127.102.0.1:2222"}, + {"default ports", "10.0.0.1:9333", "10.0.0.1:19333", "10.0.0.1:9333"}, + {"ipv6", "[::1]:2222.3333", "[::1]:3333", "[::1]:2222"}, + {"id that is not an address", "master-a", "10.0.0.2:19333", "10.0.0.2:9333"}, + {"id without a valid port", "10.0.0.3:0", "10.0.0.3:19334", "10.0.0.3:9334"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := raftMasterHttpAddress(&master_pb.RaftListClusterServersResponse_ClusterServers{Id: tt.id, Address: tt.address}) + if got != tt.want { + t.Errorf("raftMasterHttpAddress(%q, %q) = %q, want %q", tt.id, tt.address, got, tt.want) + } + }) + } +} diff --git a/weed/admin/dash/admin_server.go b/weed/admin/dash/admin_server.go index afdb28b39e..c79263ca24 100644 --- a/weed/admin/dash/admin_server.go +++ b/weed/admin/dash/admin_server.go @@ -1371,8 +1371,7 @@ func (s *AdminServer) GetClusterMasters() (*ClusterMastersData, error) { // Process each raft server for _, server := range resp.ClusterServers { - // Raft stores gRPC addresses, convert to HTTP address - httpAddress := pb.GrpcAddressToServerAddress(server.Address) + httpAddress := raftMasterHttpAddress(server) if httpAddress == "" { continue }