From 4fa375ee6f687b97f7907a8438514f2c2eba631d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E7=A5=A5=E8=B6=85?= Date: Wed, 23 Dec 2020 10:31:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=88=97=E8=A1=A8=E4=B8=AD?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E2=80=9C=E6=A3=80=E6=9F=A5=E5=9F=9F=E5=90=8D?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E2=80=9D=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/utils/recover.go | 12 ++ internal/web/actions/default/servers/index.go | 2 + internal/web/actions/default/servers/init.go | 1 + .../web/actions/default/servers/status.go | 187 ++++++++++++++++++ web/views/@default/servers/index.html | 57 ++++-- web/views/@default/servers/index.js | 37 ++++ 6 files changed, 276 insertions(+), 20 deletions(-) create mode 100644 internal/utils/recover.go create mode 100644 internal/web/actions/default/servers/status.go diff --git a/internal/utils/recover.go b/internal/utils/recover.go new file mode 100644 index 00000000..6ade68a3 --- /dev/null +++ b/internal/utils/recover.go @@ -0,0 +1,12 @@ +package utils + +import ( + "runtime/debug" +) + +func Recover() { + e := recover() + if e != nil { + debug.PrintStack() + } +} diff --git a/internal/web/actions/default/servers/index.go b/internal/web/actions/default/servers/index.go index de6bebf1..eae05670 100644 --- a/internal/web/actions/default/servers/index.go +++ b/internal/web/actions/default/servers/index.go @@ -22,11 +22,13 @@ func (this *IndexAction) RunGet(params struct { GroupId int64 Keyword string AuditingFlag int32 + CheckDNS bool }) { this.Data["clusterId"] = params.ClusterId this.Data["groupId"] = params.GroupId this.Data["keyword"] = params.Keyword this.Data["auditingFlag"] = params.AuditingFlag + this.Data["checkDNS"] = params.CheckDNS if params.AuditingFlag > 0 { this.Data["firstMenuItem"] = "auditing" diff --git a/internal/web/actions/default/servers/init.go b/internal/web/actions/default/servers/init.go index c95d2e04..542f02e9 100644 --- a/internal/web/actions/default/servers/init.go +++ b/internal/web/actions/default/servers/init.go @@ -20,6 +20,7 @@ func init() { GetPost("/addServerNamePopup", new(AddServerNamePopupAction)). GetPost("/addOriginPopup", new(AddOriginPopupAction)). Get("/serverNamesPopup", new(ServerNamesPopupAction)). + Post("/status", new(StatusAction)). EndAll() }) } diff --git a/internal/web/actions/default/servers/status.go b/internal/web/actions/default/servers/status.go new file mode 100644 index 00000000..66d4deb8 --- /dev/null +++ b/internal/web/actions/default/servers/status.go @@ -0,0 +1,187 @@ +package servers + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAdmin/internal/utils" + "github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/dao" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/iwind/TeaGo/maps" + "net" + "sync" +) + +type StatusAction struct { + actionutils.ParentAction +} + +func (this *StatusAction) RunPost(params struct { + ServerIds []int64 +}) { + status := map[int64]maps.Map{} + statusLocker := sync.Mutex{} + + if len(params.ServerIds) == 0 { + this.Data["status"] = status + this.Success() + } + + // 读取全局配置 + globalConfig, err := dao.SharedSysSettingDAO.ReadGlobalConfig(this.AdminContext()) + if err != nil { + this.ErrorPage(err) + return + } + auditingPrompt := "" + if globalConfig != nil { + auditingPrompt = globalConfig.HTTPAll.DomainAuditingPrompt + } + + wg := sync.WaitGroup{} + wg.Add(len(params.ServerIds)) + + for _, serverId := range params.ServerIds { + go func(serverId int64) { + defer utils.Recover() + defer wg.Done() + + m := maps.Map{ + "isOk": false, + "message": "", + "todo": "", + "type": "", + } + + defer func() { + statusLocker.Lock() + defer statusLocker.Unlock() + + status[serverId] = m + }() + + // 检查cname + serverDNSResp, err := this.RPC().ServerRPC().FindEnabledServerDNS(this.AdminContext(), &pb.FindEnabledServerDNSRequest{ServerId: serverId}) + if err != nil { + this.ErrorPage(err) + + m["type"] = "serverErr" + m["message"] = "服务器错误" + m["todo"] = "错误信息:FindEnabledServerDNS(): " + err.Error() + ",请联系管理员修复此问题" + return + } + + if len(serverDNSResp.DnsName) == 0 { + m["type"] = "dnsNameEmpty" + m["message"] = "CNAME为空" + m["todo"] = "请删除后重新创建服务" + return + } + + if serverDNSResp.Domain == nil { + m["type"] = "clusterDNSEmpty" + m["message"] = "集群配置错误" + m["todo"] = "所属集群没有配置DNS,请联系管理员修复此问题。服务ID:" + numberutils.FormatInt64(serverId) + return + } + + // 检查DNS是否已经设置 + serverNamesResp, err := this.RPC().ServerRPC().FindServerNames(this.AdminContext(), &pb.FindServerNamesRequest{ServerId: serverId}) + if err != nil { + this.ErrorPage(err) + + m["type"] = "serverErr" + m["message"] = "服务器错误" + m["todo"] = "错误信息:FindServerNames(): " + err.Error() + ",请联系管理员修复此问题" + return + } + if serverNamesResp.IsAuditing { + m["type"] = "auditing" + m["message"] = "审核中" + if len(auditingPrompt) > 0 { + m["todo"] = auditingPrompt + } else { + m["todo"] = "域名正在审核中,请耐心等待" + } + return + } + if serverNamesResp.AuditingResult != nil && !serverNamesResp.AuditingResult.IsOk { + m["type"] = "auditingFailed" + m["message"] = "审核不通过" + m["todo"] = "审核不通过,原因:" + serverNamesResp.AuditingResult.Reason + return + } + + serverNames := []*serverconfigs.ServerNameConfig{} + if len(serverNamesResp.ServerNamesJSON) > 0 { + err = json.Unmarshal(serverNamesResp.ServerNamesJSON, &serverNames) + if err != nil { + this.ErrorPage(err) + + m["type"] = "serverErr" + m["message"] = "服务器错误" + m["todo"] = "错误信息:解析域名时出错:" + err.Error() + ",请联系管理员修复此问题" + return + } + + cname := serverDNSResp.DnsName + "." + serverDNSResp.Domain.Name + "." + for _, serverName := range serverNames { + if len(serverName.SubNames) == 0 { + // TODO 可以指定查找解析记录的DNSResolver + result, err := net.LookupCNAME(serverName.Name) + if err != nil { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:解析域名'" + serverName.Name + "' CNAME记录时出错:" + err.Error() + ",请修复此问题。如果已经修改,请等待一个小时后再试。" + return + } + if result == serverName.Name+"." { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:找不到域名'" + serverName.Name + "'的CNAME记录,请设置为'" + cname + "'。如果已经设置,请等待一个小时后再试。" + return + } + if result != cname { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:解析域名'" + serverName.Name + "' CNAME记录时出错:当前的CNAME值为" + result + ",请修改为" + cname + "。如果已经修改,请等待一个小时后再试。" + return + } + } else { + for _, subName := range serverName.SubNames { + // TODO 可以指定查找解析记录的DNSResolver + result, err := net.LookupCNAME(subName) + if err != nil { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:解析域名'" + subName + "' CNAME记录时出错:" + err.Error() + ",请修复此问题。如果已经修改,请等待一个小时后再试。" + return + } + if result == cname+"." { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:找不到域名'" + serverName.Name + "'的CNAME记录,请设置为'" + cname + "'。如果已经设置,请等待一个小时后再试。" + return + } + if result != cname { + m["type"] = "dnsResolveErr" + m["message"] = "域名解析错误" + m["todo"] = "错误信息:解析域名'" + subName + "' CNAME记录时出错:当前的CNAME值为" + result + ",请修改为" + cname + "。如果已经修改,请等待一个小时后再试。" + return + } + } + } + } + } + + m["isOk"] = true + }(serverId) + } + + wg.Wait() + + this.Data["status"] = status + + this.Success() +} diff --git a/web/views/@default/servers/index.html b/web/views/@default/servers/index.html index 5ec01cf5..e8c6b21b 100644 --- a/web/views/@default/servers/index.html +++ b/web/views/@default/servers/index.html @@ -4,26 +4,33 @@
-
-
- + +
+ 检查域名解析 +
+

暂时还没有服务。

@@ -76,7 +83,17 @@
- +
+ +
+
+ 停用中 + 正常 + 检查中 + {{server.status.message}} + + +
详情 diff --git a/web/views/@default/servers/index.js b/web/views/@default/servers/index.js index d078408b..c56a7b0f 100644 --- a/web/views/@default/servers/index.js +++ b/web/views/@default/servers/index.js @@ -1,3 +1,40 @@ Tea.context(function () { + this.servers.forEach(function (v) { + v["status"] = { + isOk: false, + message: "", + todo: "" + } + }) + this.$delay(function () { + if (this.checkDNS) { + this.loadStatus() + } + + let that = this + this.$watch("checkDNS", function (v) { + if (v) { + that.loadStatus() + } + }) + }) + + this.loadStatus = function () { + let serverIds = this.servers.map(function (v) { + return v.id + }) + this.$post(".status") + .params({ + serverIds: serverIds + }) + .success(function (resp) { + let status = resp.data.status + this.servers.forEach(function (server) { + if (typeof status[server.id] === "object") { + server.status = status[server.id] + } + }) + }) + } }); \ No newline at end of file