mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	服务列表中增加“检查域名解析”选项
This commit is contained in:
		
							
								
								
									
										12
									
								
								internal/utils/recover.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								internal/utils/recover.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
package utils
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"runtime/debug"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Recover() {
 | 
			
		||||
	e := recover()
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		debug.PrintStack()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ func init() {
 | 
			
		||||
			GetPost("/addServerNamePopup", new(AddServerNamePopupAction)).
 | 
			
		||||
			GetPost("/addOriginPopup", new(AddOriginPopupAction)).
 | 
			
		||||
			Get("/serverNamesPopup", new(ServerNamesPopupAction)).
 | 
			
		||||
			Post("/status", new(StatusAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								internal/web/actions/default/servers/status.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								internal/web/actions/default/servers/status.go
									
									
									
									
									
										Normal file
									
								
							@@ -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()
 | 
			
		||||
}
 | 
			
		||||
@@ -4,26 +4,33 @@
 | 
			
		||||
<form method="get" class="ui form" action="/servers">
 | 
			
		||||
    <input type="hidden" name="auditingFlag" :value="auditingFlag"/>
 | 
			
		||||
	<div class="ui margin"></div>
 | 
			
		||||
	<div class="ui fields inline">
 | 
			
		||||
        <div class="ui field" v-if="clusters.length > 0">
 | 
			
		||||
            <select class="ui dropdown auto-width" name="clusterId" v-model="clusterId">
 | 
			
		||||
                <option value="0">[选择集群]</option>
 | 
			
		||||
                <option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
            </select>
 | 
			
		||||
    <div class="ui menu basic text">
 | 
			
		||||
        <div class="item">
 | 
			
		||||
            <div class="ui fields inline">
 | 
			
		||||
                <div class="ui field" v-if="clusters.length > 0">
 | 
			
		||||
                    <select class="ui dropdown auto-width" name="clusterId" v-model="clusterId">
 | 
			
		||||
                        <option value="0">[选择集群]</option>
 | 
			
		||||
                        <option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="ui field" v-if="groups.length > 0">
 | 
			
		||||
                    <select class="ui dropdown auto-width" name="groupId" v-model="groupId">
 | 
			
		||||
                        <option value="0">[选择分组]</option>
 | 
			
		||||
                        <option v-for="group in groups" :value="group.id">{{group.name}}</option>
 | 
			
		||||
                    </select>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="ui field">
 | 
			
		||||
                    <input type="text" name="keyword" style="width:10em" placeholder="关键词" v-model="keyword"/>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="ui field">
 | 
			
		||||
                    <button type="submit" class="ui button">搜索</button>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
		<div class="ui field" v-if="groups.length > 0">
 | 
			
		||||
			<select class="ui dropdown auto-width" name="groupId" v-model="groupId">
 | 
			
		||||
				<option value="0">[选择分组]</option>
 | 
			
		||||
				<option v-for="group in groups" :value="group.id">{{group.name}}</option>
 | 
			
		||||
			</select>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="ui field">
 | 
			
		||||
			<input type="text" name="keyword" style="width:10em" placeholder="关键词" v-model="keyword"/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="ui field">
 | 
			
		||||
			<button type="submit" class="ui button">搜索</button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
        <div class="item right">
 | 
			
		||||
            <checkbox name="checkDNS" :v-value="1" v-model="checkDNS">检查域名解析</checkbox>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</form>
 | 
			
		||||
 | 
			
		||||
<p class="ui message" v-if="servers.length == 0">暂时还没有服务。</p>
 | 
			
		||||
@@ -76,7 +83,17 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td class="center">
 | 
			
		||||
			<label-on :v-is-on="server.isOn"></label-on>
 | 
			
		||||
            <div v-if="!checkDNS">
 | 
			
		||||
                <label-on :v-is-on="server.isOn"></label-on>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div v-else>
 | 
			
		||||
                <span v-if="!server.isOn" class="grey">停用中</span>
 | 
			
		||||
                <span v-else-if="server.status.isOk" class="green">正常</span>
 | 
			
		||||
                <span v-else-if="server.status.message.length == 0">检查中</span>
 | 
			
		||||
                <span v-else class="red">{{server.status.message}}
 | 
			
		||||
                    <tip-icon :content="server.status.todo"></tip-icon>
 | 
			
		||||
                </span>
 | 
			
		||||
            </div>
 | 
			
		||||
		</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<a :href="'/servers/server?serverId=' + server.id">详情</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -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]
 | 
			
		||||
					}
 | 
			
		||||
				})
 | 
			
		||||
			})
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
		Reference in New Issue
	
	Block a user