hostSync/cmd/server.go

214 lines
5.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cmd
import (
"os"
"time"
"github.com/evil7/hostsync/config"
"github.com/evil7/hostsync/core"
"github.com/evil7/hostsync/utils"
"github.com/spf13/cobra"
)
// serverCmd 服务器管理命令
var serverCmd = &cobra.Command{
Use: "server [command]",
Short: "管理预设 DNS 服务器",
Long: `管理预设DNS服务器配置支持列出、测试服务器。
子命令:
list 列出所有预设服务器
test 测试所有服务器响应
test <name> 测试指定服务器
示例:
hostsync server # 列出所有预设服务器(默认)
hostsync server list # 列出所有预设服务器
hostsync server test # 测试所有服务器响应
hostsync server test Cloudflare # 测试指定服务器`,
Run: runServerDefault, // 添加默认运行函数
}
var serverListCmd = &cobra.Command{
Use: "list",
Short: "列出所有预设服务器",
Run: runServerList,
}
var serverTestCmd = &cobra.Command{
Use: "test [serverName]",
Short: "测试服务器响应时间",
Args: cobra.MaximumNArgs(1),
Run: runServerTest,
}
func init() {
serverCmd.AddCommand(serverListCmd)
serverCmd.AddCommand(serverTestCmd)
}
// runServerDefault 默认运行server命令时列出所有服务器
func runServerDefault(cmd *cobra.Command, args []string) {
runServerList(cmd, args)
}
func runServerList(cmd *cobra.Command, args []string) {
if len(config.DNSServers) == 0 {
utils.LogInfo("没有找到预设DNS服务器配置")
return
}
utils.LogResult("🌐 预设DNS服务器列表 (%d 个)\n", len(config.DNSServers))
headers := []string{"名称", "DNS地址", "DoH地址"}
var rows [][]string
for _, server := range config.DNSServers {
dnsAddr := server.DNS
if dnsAddr == "" {
dnsAddr = "-"
}
dohAddr := server.DoH
if dohAddr == "" {
dohAddr = "-"
} else {
dohAddr = utils.TruncateWithWidth(dohAddr, 50)
}
rows = append(rows, []string{server.Name, dnsAddr, dohAddr})
}
// 设置合适的列宽
columnWidths := []int{15, 20, 50}
utils.FormatTable(headers, rows, columnWidths)
}
func runServerTest(cmd *cobra.Command, args []string) {
resolver := core.NewDNSResolver()
if len(args) == 0 {
// 测试所有服务器
testAllServers(resolver)
} else {
// 测试指定服务器
serverName := args[0]
testServer(resolver, serverName)
}
}
func testAllServers(resolver *core.DNSResolver) {
if len(config.DNSServers) == 0 {
utils.LogInfo("没有找到预设DNS服务器配置")
return
}
utils.LogInfo("测试所有DNS服务器 (%d 个)", len(config.DNSServers))
// 并发测试结果
type testResult struct {
index int
name string
dnsTime string
dohTime string
status string
}
results := make(chan testResult, len(config.DNSServers))
// 并发测试所有服务器
for i, server := range config.DNSServers {
go func(idx int, srv config.DNSServer) {
dnsTime := "-"
dohTime := "-"
status := "❌ 不可用"
// 测试DNS
if srv.DNS != "" {
if duration, err := resolver.TestDNSServer(srv.DNS); err == nil {
dnsTime = duration.String()
status = "✅ 可用"
}
}
// 测试DoH
if srv.DoH != "" {
if duration, err := resolver.TestDoHServer(srv.DoH); err == nil {
dohTime = duration.String()
if status != "✅ 可用" {
status = "✅ 可用"
}
}
}
results <- testResult{
index: idx,
name: srv.Name,
dnsTime: dnsTime,
dohTime: dohTime,
status: status,
}
}(i, server)
}
// 收集结果并显示进度
headers := []string{"服务器", "DNS响应时间", "DoH响应时间", "状态"}
resultMap := make(map[int]testResult)
completed := 0
for completed < len(config.DNSServers) {
result := <-results
resultMap[result.index] = result
completed++
utils.LogInfo("已完成测试: %d/%d", completed, len(config.DNSServers))
}
// 按原始顺序排序结果
var rows [][]string
for i := 0; i < len(config.DNSServers); i++ {
result := resultMap[i]
rows = append(rows, []string{result.name, result.dnsTime, result.dohTime, result.status})
}
// 设置合适的列宽
columnWidths := []int{15, 15, 15, 12}
utils.FormatTable(headers, rows, columnWidths)
}
func testServer(resolver *core.DNSResolver, serverName string) {
server := config.GetDNSServer(serverName)
if server == nil {
utils.LogError("找不到服务器: %s", serverName)
utils.LogInfo("使用 'hostsync server list' 查看可用服务器")
os.Exit(1)
}
utils.LogInfo("测试服务器: %s", serverName)
// 测试DNS
if server.DNS != "" {
utils.LogInfo("测试DNS (%s)...", server.DNS)
start := time.Now()
if duration, err := resolver.TestDNSServer(server.DNS); err != nil {
elapsed := time.Since(start)
utils.LogError("失败: %v (耗时: %v)", err, elapsed)
} else {
utils.LogSuccess("成功 (%v)", duration)
}
} else {
utils.LogInfo("DNS: 未配置")
}
// 测试DoH
if server.DoH != "" {
utils.LogInfo("测试DoH (%s)...", server.DoH)
start := time.Now()
if duration, err := resolver.TestDoHServer(server.DoH); err != nil {
elapsed := time.Since(start)
utils.LogError("失败: %v (耗时: %v)", err, elapsed)
} else {
utils.LogSuccess("成功 (%v)", duration)
}
} else {
utils.LogInfo("DoH: 未配置")
}
}