单个节点支持多个DNS线路

This commit is contained in:
刘祥超
2020-11-16 13:03:45 +08:00
parent 8abf806ce9
commit b466868da1
43 changed files with 348 additions and 124 deletions

View File

@@ -77,7 +77,7 @@ func (this *CreateNodeAction) RunPost(params struct {
SshPort int SshPort int
DnsDomainId int64 DnsDomainId int64
DnsRoute string DnsRoutesJSON []byte
Must *actions.Must Must *actions.Must
}) { }) {
@@ -94,6 +94,13 @@ func (this *CreateNodeAction) RunPost(params struct {
this.Fail("请选择所在集群") this.Fail("请选择所在集群")
} }
dnsRouteCodes := []string{}
err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
if err != nil {
this.ErrorPage(err)
return
}
// TODO 检查登录授权 // TODO 检查登录授权
loginInfo := &pb.NodeLogin{ loginInfo := &pb.NodeLogin{
Id: 0, Id: 0,
@@ -113,7 +120,7 @@ func (this *CreateNodeAction) RunPost(params struct {
GroupId: params.GroupId, GroupId: params.GroupId,
Login: loginInfo, Login: loginInfo,
DnsDomainId: params.DnsDomainId, DnsDomainId: params.DnsDomainId,
DnsRoute: params.DnsRoute, DnsRoutes: dnsRouteCodes,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -97,6 +97,12 @@ func (this *IndexAction) RunGet(params struct {
} }
} }
// DNS
dnsRouteNames := []string{}
for _, route := range node.DnsRoutes {
dnsRouteNames = append(dnsRouteNames, route.Name)
}
nodeMaps = append(nodeMaps, maps.Map{ nodeMaps = append(nodeMaps, maps.Map{
"id": node.Id, "id": node.Id,
"name": node.Name, "name": node.Name,
@@ -125,6 +131,7 @@ func (this *IndexAction) RunGet(params struct {
"isSynced": isSynced, "isSynced": isSynced,
"ipAddresses": ipAddresses, "ipAddresses": ipAddresses,
"group": groupMap, "group": groupMap,
"dnsRouteNames": dnsRouteNames,
}) })
} }
this.Data["nodes"] = nodeMaps this.Data["nodes"] = nodeMaps

View File

@@ -70,6 +70,21 @@ func (this *NodeAction) RunGet(params struct {
}) })
} }
// DNS相关
dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
dnsRouteMaps := []maps.Map{}
for _, dnsInfo := range dnsInfoResp.Node.Routes {
dnsRouteMaps = append(dnsRouteMaps, maps.Map{
"name": dnsInfo.Name,
"code": dnsInfo.Code,
})
}
this.Data["dnsRoutes"] = dnsRouteMaps
// 登录信息 // 登录信息
var loginMap maps.Map = nil var loginMap maps.Map = nil
if node.Login != nil { if node.Login != nil {

View File

@@ -60,6 +60,38 @@ func (this *UpdateAction) RunGet(params struct {
}) })
} }
// DNS相关
dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId})
if err != nil {
this.ErrorPage(err)
return
}
dnsRouteMaps := []maps.Map{}
for _, dnsInfo := range dnsInfoResp.Node.Routes {
dnsRouteMaps = append(dnsRouteMaps, maps.Map{
"name": dnsInfo.Name,
"code": dnsInfo.Code,
})
}
this.Data["dnsRoutes"] = dnsRouteMaps
this.Data["allDNSRoutes"] = []maps.Map{}
this.Data["dnsDomainId"] = dnsInfoResp.Node.DnsDomainId
if dnsInfoResp.Node.DnsDomainId > 0 {
routesMaps := []maps.Map{}
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfoResp.Node.DnsDomainId})
if err != nil {
this.ErrorPage(err)
return
}
for _, route := range routesResp.Routes {
routesMaps = append(routesMaps, maps.Map{
"name": route.Name,
"code": route.Code,
})
}
this.Data["allDNSRoutes"] = routesMaps
}
// 登录信息 // 登录信息
var loginMap maps.Map = nil var loginMap maps.Map = nil
if node.Login != nil { if node.Login != nil {
@@ -152,6 +184,9 @@ func (this *UpdateAction) RunPost(params struct {
MaxCPU int32 MaxCPU int32
IsOn bool IsOn bool
DnsDomainId int64
DnsRoutesJSON []byte
Must *actions.Must Must *actions.Must
}) { }) {
// 创建日志 // 创建日志
@@ -170,6 +205,13 @@ func (this *UpdateAction) RunPost(params struct {
this.Fail("请选择所在集群") this.Fail("请选择所在集群")
} }
dnsRouteCodes := []string{}
err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
if err != nil {
this.ErrorPage(err)
return
}
// TODO 检查登录授权 // TODO 检查登录授权
loginInfo := &pb.NodeLogin{ loginInfo := &pb.NodeLogin{
Id: params.LoginId, Id: params.LoginId,
@@ -183,7 +225,7 @@ func (this *UpdateAction) RunPost(params struct {
} }
// 保存 // 保存
_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{ _, err = this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
NodeId: params.NodeId, NodeId: params.NodeId,
GroupId: params.GroupId, GroupId: params.GroupId,
Name: params.Name, Name: params.Name,
@@ -191,6 +233,8 @@ func (this *UpdateAction) RunPost(params struct {
Login: loginInfo, Login: loginInfo,
MaxCPU: params.MaxCPU, MaxCPU: params.MaxCPU,
IsOn: params.IsOn, IsOn: params.IsOn,
DnsDomainId: params.DnsDomainId,
DnsRoutes: dnsRouteCodes,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -2,7 +2,6 @@ package clusters
import ( import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils" "github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
@@ -55,20 +54,16 @@ func (this *IndexAction) RunGet(params struct{}) {
return return
} }
// grant // DNS
var grantMap maps.Map = nil dnsDomainName := ""
if cluster.GrantId > 0 { if cluster.DnsDomainId > 0 {
grantResp, err := this.RPC().NodeGrantRPC().FindEnabledGrant(this.AdminContext(), &pb.FindEnabledGrantRequest{GrantId: cluster.GrantId}) dnsInfoResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: cluster.Id})
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)
return return
} }
if grantResp.Grant != nil { if dnsInfoResp.Domain != nil {
grantMap = maps.Map{ dnsDomainName = dnsInfoResp.Domain.Name
"id": grantResp.Grant.Id,
"name": grantResp.Grant.Name,
"methodName": grantutils.FindGrantMethodName(grantResp.Grant.Method),
}
} }
} }
@@ -76,9 +71,11 @@ func (this *IndexAction) RunGet(params struct{}) {
"id": cluster.Id, "id": cluster.Id,
"name": cluster.Name, "name": cluster.Name,
"installDir": cluster.InstallDir, "installDir": cluster.InstallDir,
"grant": grantMap,
"countAllNodes": countNodesResp.Count, "countAllNodes": countNodesResp.Count,
"countActiveNodes": countActiveNodesResp.Count, "countActiveNodes": countActiveNodesResp.Count,
"dnsDomainId": cluster.DnsDomainId,
"dnsName": cluster.DnsName,
"dnsDomainName": dnsDomainName,
}) })
} }
} }

View File

@@ -67,17 +67,32 @@ func (this *ClusterAction) RunGet(params struct {
} }
nodeMaps := []maps.Map{} nodeMaps := []maps.Map{}
for _, node := range nodesResp.Nodes { for _, node := range nodesResp.Nodes {
if len(node.Routes) > 0 {
for _, route := range node.Routes {
nodeMaps = append(nodeMaps, maps.Map{ nodeMaps = append(nodeMaps, maps.Map{
"id": node.Id, "id": node.Id,
"name": node.Name, "name": node.Name,
"ipAddr": node.IpAddr, "ipAddr": node.IpAddr,
"route": maps.Map{ "route": maps.Map{
"name": node.Route.Name, "name": route.Name,
"code": node.Route.Code, "code": route.Code,
}, },
"clusterId": node.ClusterId, "clusterId": node.ClusterId,
}) })
} }
} else {
nodeMaps = append(nodeMaps, maps.Map{
"id": node.Id,
"name": node.Name,
"ipAddr": node.IpAddr,
"route": maps.Map{
"name": "",
"code": "",
},
"clusterId": node.ClusterId,
})
}
}
this.Data["nodes"] = nodeMaps this.Data["nodes"] = nodeMaps
// 代理服务解析记录 // 代理服务解析记录

View File

@@ -1,6 +1,9 @@
package domainutils package domainutils
import ( import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"regexp" "regexp"
"strings" "strings"
) )
@@ -16,3 +19,30 @@ func ValidateDomainFormat(domain string) bool {
return true return true
} }
// 转换线路列表
func ConvertRoutesToMaps(routes []*pb.DNSRoute) []maps.Map {
result := []maps.Map{}
for _, route := range routes {
result = append(result, maps.Map{
"name": route.Name,
"code": route.Code,
})
}
return result
}
// 筛选线路
func FilterRoutes(routes []*pb.DNSRoute, allRoutes []*pb.DNSRoute) []*pb.DNSRoute {
routeCodes := []string{}
for _, route := range allRoutes {
routeCodes = append(routeCodes, route.Code)
}
result := []*pb.DNSRoute{}
for _, route := range routes {
if lists.ContainsString(routeCodes, route.Code) {
result = append(result, route)
}
}
return result
}

View File

@@ -1,8 +1,10 @@
package issues package issues
import ( import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs" "github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns/domains/domainutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps" "github.com/iwind/TeaGo/maps"
@@ -33,12 +35,12 @@ func (this *UpdateNodePopupAction) RunGet(params struct {
return return
} }
this.Data["ipAddr"] = dnsInfo.IpAddr this.Data["ipAddr"] = dnsInfo.IpAddr
this.Data["route"] = dnsInfo.Route.Code this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo.Routes)
this.Data["domainId"] = dnsInfo.DnsDomainId this.Data["domainId"] = dnsInfo.DnsDomainId
this.Data["domainName"] = dnsInfo.DnsDomainName this.Data["domainName"] = dnsInfo.DnsDomainName
// 读取所有线路 // 读取所有线路
routeMaps := []maps.Map{} allRouteMaps := []maps.Map{}
if dnsInfo.DnsDomainId > 0 { if dnsInfo.DnsDomainId > 0 {
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfo.DnsDomainId}) routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfo.DnsDomainId})
if err != nil { if err != nil {
@@ -47,28 +49,17 @@ func (this *UpdateNodePopupAction) RunGet(params struct {
} }
if len(routesResp.Routes) > 0 { if len(routesResp.Routes) > 0 {
for _, route := range routesResp.Routes { for _, route := range routesResp.Routes {
routeMaps = append(routeMaps, maps.Map{ allRouteMaps = append(allRouteMaps, maps.Map{
"name": route.Name, "name": route.Name,
"code": route.Code, "code": route.Code,
}) })
} }
}
}
this.Data["routes"] = routeMaps
// 是否包含现有线路 // 筛选
if len(routeMaps) > 0 { this.Data["routes"] = domainutils.ConvertRoutesToMaps(domainutils.FilterRoutes(dnsInfo.Routes, routesResp.Routes))
isRouteValid := false
for _, route := range routeMaps {
if route.GetString("code") == dnsInfo.Route.Code {
isRouteValid = true
break
}
}
if !isRouteValid {
this.Data["route"] = routeMaps[0].GetString("code")
} }
} }
this.Data["allRoutes"] = allRouteMaps
this.Show() this.Show()
} }
@@ -77,7 +68,7 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
NodeId int64 NodeId int64
IpAddr string IpAddr string
DomainId int64 DomainId int64
Route string DnsRoutesJSON []byte
Must *actions.Must Must *actions.Must
CSRF *actionutils.CSRF CSRF *actionutils.CSRF
@@ -85,6 +76,13 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
// 操作日志 // 操作日志
this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId) this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
routes := []string{}
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
if err != nil {
this.ErrorPage(err)
return
}
params.Must. params.Must.
Field("ipAddr", params.IpAddr). Field("ipAddr", params.IpAddr).
Require("请输入IP地址") Require("请输入IP地址")
@@ -94,11 +92,11 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
} }
// 执行修改 // 执行修改
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{ _, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
NodeId: params.NodeId, NodeId: params.NodeId,
IpAddr: params.IpAddr, IpAddr: params.IpAddr,
DnsDomainId: params.DomainId, DnsDomainId: params.DomainId,
Route: params.Route, Routes: routes,
}) })
if err != nil { if err != nil {
this.ErrorPage(err) this.ErrorPage(err)

View File

@@ -0,0 +1,79 @@
Vue.component("dns-route-selector", {
props: ["v-all-routes", "v-routes"],
data: function () {
let routes = this.vRoutes
if (routes == null) {
routes = []
}
return {
routes: routes,
routeCodes: routes.$map(function (k, v) {
return v.code
}),
isAdding: false,
routeCode: ""
}
},
methods: {
add: function () {
this.isAdding = true
},
cancel: function () {
this.isAdding = false
},
confirm: function () {
if (this.routeCode.length == 0) {
return
}
if (this.routeCodes.$contains(this.routeCode)) {
teaweb.warn("已经添加过此线路,不能重复添加")
return
}
let that = this
let route = this.vAllRoutes.$find(function (k, v) {
return v.code == that.routeCode
})
if (route == null) {
return
}
this.routeCodes.push(this.routeCode)
this.routes.push(route)
this.routeCode = ""
this.isAdding = false
},
remove: function (route) {
this.routeCodes.$removeValue(route.code)
this.routes.$removeIf(function (k, v) {
return v.code == route.code
})
}
},
template: `<div>
<input type="hidden" name="dnsRoutesJSON" :value="JSON.stringify(routeCodes)"/>
<div v-if="routes.length > 0">
<tiny-label v-for="route in routes" :key="route.code">
{{route.name}} <a href="" @click.prevent="remove(route)"><i class="icon remove"></i></a>
</tiny-label>
<div class="ui divider"></div>
</div>
<button type="button" class="ui button small" @click.prevent="add" v-if="!isAdding">+</button>
<div v-if="isAdding">
<div class="ui fields inline">
<div class="ui field">
<select class="ui dropdown auto-width" v-model="routeCode">
<option value="">[请选择]</option>
<option v-for="route in vAllRoutes" :value="route.code">{{route.name}}</option>
</select>
</div>
<div class="ui field">
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
</div>
<div class="ui field">
<a href="" @click.prevent="cancel()"><i class="icon remove"></i></a>
</div>
</div>
</div>
</div>`
})

View File

@@ -18,4 +18,8 @@ form .fields {
.link.grey:hover { .link.grey:hover {
color: #4183c4 !important; color: #4183c4 !important;
} }
table th.center,
table td.center {
text-align: center !important;
}
/*# sourceMappingURL=@layout_override.css.map */ /*# sourceMappingURL=@layout_override.css.map */

View File

@@ -1 +1 @@
{"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA","file":"@layout_override.css"} {"version":3,"sources":["@layout_override.less"],"names":[],"mappings":"AACA,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,MAAM,QAAS,QAAO;EACrG,oCAAA;;AAGD,GAAG,OAAO,SAAU,MAAK,QAAS,OAAM;AAAS,GAAG,OAAO,SAAU,MAAK,QAAS,QAAO;EACzF,oCAAA;;AAGD,GAAG,MAAM;EACR,kCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA","file":"@layout_override.css"}

View File

@@ -26,3 +26,10 @@ form {
.link.grey:hover { .link.grey:hover {
color: #4183c4 !important; color: #4183c4 !important;
} }
// table
table {
th.center, td.center {
text-align: center !important;
}
}

View File

@@ -6,7 +6,7 @@
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p> <p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
<table class="ui table selectable" v-if="nodes.length > 0"> <table class="ui table selectable celled" v-if="nodes.length > 0">
<thead> <thead>
<tr> <tr>
<th>节点名称</th> <th>节点名称</th>

View File

@@ -23,10 +23,7 @@
<td>DNS线路</td> <td>DNS线路</td>
<td> <td>
<input type="hidden" name="dnsDomainId" :value="dnsDomainId"/> <input type="hidden" name="dnsDomainId" :value="dnsDomainId"/>
<select class="ui dropdown auto-width" name="dnsRoute"> <dns-route-selector :v-all-routes="dnsRoutes"></dns-route-selector>
<option value="">[请选择]</option>
<option v-for="route in dnsRoutes" :value="route.code">{{route.name}}</option>
</select>
<p class="comment">可用线路是根据集群设置的域名获取的注意DNS服务商可能对这些线路有所限制。</p> <p class="comment">可用线路是根据集群设置的域名获取的注意DNS服务商可能对这些线路有所限制。</p>
</td> </td>
</tr> </tr>

View File

@@ -8,12 +8,12 @@
<p class="comment" v-if="groups.length == 0">暂时还没有分组。</p> <p class="comment" v-if="groups.length == 0">暂时还没有分组。</p>
<div v-show="groups.length > 0"> <div v-show="groups.length > 0">
<div class="margin"></div> <div class="margin"></div>
<table class="ui table selectable" id="sortable-table"> <table class="ui table selectable celled" id="sortable-table">
<thead> <thead>
<tr> <tr>
<th style="width:3em"></th> <th style="width:3em"></th>
<th>分组名称</th> <th>分组名称</th>
<th>节点数</th> <th class="center">节点数</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
</thead> </thead>
@@ -21,7 +21,7 @@
<tr> <tr>
<td style="text-align: center;"><i class="icon bars handle grey"></i> </td> <td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
<td>{{group.name}}</td> <td>{{group.name}}</td>
<td> <td class="center">
<span v-if="group.countNodes.length > 0">{{group.countNodes}}</span> <span v-if="group.countNodes.length > 0">{{group.countNodes}}</span>
<span v-else class="disabled">0</span> <span v-else class="disabled">0</span>
</td> </td>

View File

@@ -45,23 +45,24 @@
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p> <p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
<table class="ui table selectable" v-if="nodes.length > 0"> <table class="ui table selectable celled" v-if="nodes.length > 0">
<thead> <thead>
<tr> <tr>
<th class="one wide">ID</th> <th class="one wide center">ID</th>
<th>节点名称</th> <th>节点名称</th>
<th class="two wide">所属分组</th> <th class="two wide">所属分组</th>
<th class="three wide">IP</th> <th style="width:10em">IP</th>
<th class="two wide">CPU</th> <th>DNS线路</th>
<th class="two wide">内存</th> <th style="width:5em" class="center">CPU</th>
<th style="width:5em" class="center">内存</th>
<!--<th>流量</th> <!--<th>流量</th>
<th>连接数</th>--> <th>连接数</th>-->
<th class="two wide">状态</th> <th class="two wide center">状态</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
</thead> </thead>
<tr v-for="node in nodes"> <tr v-for="node in nodes">
<td nowrap="">{{node.id}}</td> <td nowrap="" class="center">{{node.id}}</td>
<td>{{node.name}}</td> <td>{{node.name}}</td>
<td> <td>
<span v-if="node.group != null" class="ui label tiny">{{node.group.name}}</span> <span v-if="node.group != null" class="ui label tiny">{{node.group.name}}</span>
@@ -79,14 +80,20 @@
</div> </div>
</td> </td>
<td> <td>
<div v-if="node.dnsRouteNames.length > 0">
<div v-for="routeName in node.dnsRouteNames" style="margin-bottom: 0.4em">{{routeName}}</div>
</div>
<span v-else class="disabled">-</span>
</td>
<td class="center">
<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span> <span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
<span v-else class="disabled">-</span> <span v-else class="disabled">-</span>
</td> </td>
<td> <td class="center">
<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span> <span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
<span v-else class="disabled">-</span> <span v-else class="disabled">-</span>
</td> </td>
<td> <td class="center">
<div v-if="!node.isUp"> <div v-if="!node.isUp">
<span class="red">健康问题</span> <span class="red">健康问题</span>
</div> </div>

View File

@@ -7,7 +7,7 @@
<div v-if="nodes.length > 0"> <div v-if="nodes.length > 0">
<h3>所有未安装节点</h3> <h3>所有未安装节点</h3>
<table class="ui table selectable"> <table class="ui table selectable celled">
<thead> <thead>
<tr> <tr>
<th>节点名</th> <th>节点名</th>

View File

@@ -7,7 +7,7 @@
<div v-if="nodes.length > 0"> <div v-if="nodes.length > 0">
<h3>所有未安装节点</h3> <h3>所有未安装节点</h3>
<table class="ui table selectable"> <table class="ui table selectable celled">
<thead> <thead>
<tr> <tr>
<th>节点名</th> <th>节点名</th>

View File

@@ -29,6 +29,12 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr v-if="dnsRoutes.length > 0">
<td>DNS线路</td>
<td>
<span class="ui label tiny" v-for="route in dnsRoutes">{{route.name}}</span>
</td>
</tr>
<tr> <tr>
<td>所属分组</td> <td>所属分组</td>
<td> <td>

View File

@@ -20,6 +20,13 @@
<p class="comment">用于访问节点和域名解析等。</p> <p class="comment">用于访问节点和域名解析等。</p>
</td> </td>
</tr> </tr>
<tr v-if="allDNSRoutes.length > 0">
<td>DNS线路</td>
<td>
<input type="hidden" name="dnsDomainId" :value="dnsDomainId"/>
<dns-route-selector :v-all-routes="allDNSRoutes" :v-routes="dnsRoutes"></dns-route-selector>
</td>
</tr>
<tr> <tr>
<td>所属集群</td> <td>所属集群</td>
<td> <td>

View File

@@ -6,7 +6,7 @@
<form method="post" class="ui form" v-if="!isRequesting"> <form method="post" class="ui form" v-if="!isRequesting">
<p>成功节点:<span class="green">{{countSuccess}}</span> &nbsp; 失败节点:<span class="red">{{countFail}}</span></p> <p>成功节点:<span class="green">{{countSuccess}}</span> &nbsp; 失败节点:<span class="red">{{countFail}}</span></p>
<table class="ui table selectable"> <table class="ui table selectable celled">
<thead> <thead>
<tr> <tr>
<th>节点</th> <th>节点</th>

View File

@@ -7,7 +7,7 @@
<div v-if="nodes.length > 0"> <div v-if="nodes.length > 0">
<h3>所有需要升级的节点</h3> <h3>所有需要升级的节点</h3>
<table class="ui table selectable"> <table class="ui table selectable celled">
<thead> <thead>
<tr> <tr>
<th>节点名</th> <th>节点名</th>

View File

@@ -3,28 +3,28 @@
<div class="ui message" v-if="grants.length == 0">暂时还没有认证信息。</div> <div class="ui message" v-if="grants.length == 0">暂时还没有认证信息。</div>
<table class="ui table selectable" v-if="grants.length > 0"> <table class="ui table selectable celled" v-if="grants.length > 0">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th class="center">ID</th>
<th>名称</th> <th>名称</th>
<th>类型</th> <th>类型</th>
<th>集群数</th> <th class="center">集群数</th>
<th>节点数</th> <th class="center">节点数</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
</thead> </thead>
<tr v-for="grant in grants"> <tr v-for="grant in grants">
<td>{{grant.id}}</td> <td class="center">{{grant.id}}</td>
<td>{{grant.name}}</td> <td>{{grant.name}}</td>
<td> <td>
<span class="ui label tiny">{{grant.method.name}}</span> <span class="ui label tiny">{{grant.method.name}}</span>
</td> </td>
<td> <td class="center">
<span v-if="grant.countClusters > 0">{{grant.countClusters}}</span> <span v-if="grant.countClusters > 0">{{grant.countClusters}}</span>
<span v-else class="disabled">0</span> <span v-else class="disabled">0</span>
</td> </td>
<td> <td class="center">
<span v-if="grant.countNodes > 0">{{grant.countNodes}}</span> <span v-if="grant.countNodes > 0">{{grant.countNodes}}</span>
<span v-else class="disabled">0</span> <span v-else class="disabled">0</span>
</td> </td>

View File

@@ -3,28 +3,31 @@
<p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p> <p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p>
<table class="ui table selectable" v-if="clusters.length > 0"> <table class="ui table selectable celled" v-if="clusters.length > 0">
<thead> <thead>
<tr> <tr>
<th>集群名称</th> <th>集群名称</th>
<th>节点数量</th> <th class="center">节点数量</th>
<th>在线节点数量</th> <th class="center">在线节点数量</th>
<th>默认认证</th> <th>DNS域名</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
</thead> </thead>
<tr v-for="cluster in clusters"> <tr v-for="cluster in clusters">
<td>{{cluster.name}}</td> <td>{{cluster.name}}</td>
<td> <td class="center">
<a :href="'/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0"><span :class="{red:cluster.countAllNodes > cluster.countActiveNodes}">{{cluster.countAllNodes}}</span></a> <a :href="'/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0"><span :class="{red:cluster.countAllNodes > cluster.countActiveNodes}">{{cluster.countAllNodes}}</span></a>
<span class="disabled" v-else="">-</span> <span class="disabled" v-else="">-</span>
</td> </td>
<td> <td class="center">
<a :href="'/clusters/cluster?clusterId=' + cluster.id + '&activeState=1'" v-if="cluster.countActiveNodes > 0"><span class="green">{{cluster.countActiveNodes}}</span></a> <a :href="'/clusters/cluster?clusterId=' + cluster.id + '&activeState=1'" v-if="cluster.countActiveNodes > 0"><span class="green">{{cluster.countActiveNodes}}</span></a>
<span class="disabled" v-else>-</span> <span class="disabled" v-else>-</span>
</td> </td>
<td> <td>
<span v-if="cluster.grant != null">{{cluster.grant.name}}<span class="small">{{cluster.grant.methodName}}</span></span> <span v-if="cluster.dnsName.length > 0">
<var>{{cluster.dnsName}}</var>.<span v-if="cluster.dnsDomainName.length > 0">{{cluster.dnsDomainName}}</span><span v-else class="disabled">主域名</span>
<span v-if="cluster.dnsDomainId > 0"><link-icon :href="'/dns/clusters/cluster?clusterId=' + cluster.id"></link-icon></span>
</span>
<span v-else class="disabled">-</span> <span v-else class="disabled">-</span>
</td> </td>
<td> <td>

View File

@@ -6,7 +6,7 @@
<p class="comment" v-if="nodes.length == 0">暂时还没有数据库节点。</p> <p class="comment" v-if="nodes.length == 0">暂时还没有数据库节点。</p>
<table class="ui table selectable" v-if="nodes.length > 0"> <table class="ui table selectable celled" v-if="nodes.length > 0">
<thead> <thead>
<tr> <tr>
<th>节点名称</th> <th>节点名称</th>

View File

@@ -46,7 +46,7 @@
<h3>节点DNS解析记录 <span>&nbsp; ({{nodes.length}}个)</span></h3> <h3>节点DNS解析记录 <span>&nbsp; ({{nodes.length}}个)</span></h3>
<p class="comment" v-if="nodes.length == 0">暂时没有需要设置的DNS记录。</p> <p class="comment" v-if="nodes.length == 0">暂时没有需要设置的DNS记录。</p>
<table class="ui table selectable" v-if="nodes.length > 0"> <table class="ui table selectable celled" v-if="nodes.length > 0">
<thead> <thead>
<tr> <tr>
<th>节点</th> <th>节点</th>
@@ -80,7 +80,7 @@
<h3>代理服务解析记录 <span>&nbsp; ({{servers.length}}个)</span></h3> <h3>代理服务解析记录 <span>&nbsp; ({{servers.length}}个)</span></h3>
<p class="comment" v-if="servers.length == 0">暂时没有需要设置的DNS记录。</p> <p class="comment" v-if="servers.length == 0">暂时没有需要设置的DNS记录。</p>
<table class="ui table selectable" v-if="servers.length > 0"> <table class="ui table selectable celled" v-if="servers.length > 0">
<thead> <thead>
<tr> <tr>
<th>服务</th> <th>服务</th>

View File

@@ -12,6 +12,7 @@ Tea.context(function () {
this.updateNode = function (nodeId) { this.updateNode = function (nodeId) {
teaweb.popup("/dns/issues/updateNodePopup?nodeId=" + nodeId, { teaweb.popup("/dns/issues/updateNodePopup?nodeId=" + nodeId, {
height: "26em",
callback: function () { callback: function () {
teaweb.success("保存成功", function () { teaweb.success("保存成功", function () {
teaweb.reload() teaweb.reload()

View File

@@ -3,7 +3,7 @@
<div class="margin"></div> <div class="margin"></div>
<p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p> <p class="comment" v-if="clusters.length == 0">暂时还没有集群。</p>
<table class="ui table selectable" v-if="clusters.length > 0"> <table class="ui table selectable celled" v-if="clusters.length > 0">
<thead> <thead>
<tr> <tr>
<th>集群</th> <th>集群</th>

View File

@@ -18,7 +18,7 @@
<p class="comment">暂时没有发现问题。</p> <p class="comment">暂时没有发现问题。</p>
</div> </div>
<table class="ui table selectable" v-if="issues.length > 0"> <table class="ui table selectable celled" v-if="issues.length > 0">
<thead> <thead>
<tr> <tr>
<th style="width: 50%">问题对象</th> <th style="width: 50%">问题对象</th>

View File

@@ -24,11 +24,11 @@
<tr v-if="domainId > 0"> <tr v-if="domainId > 0">
<td>线路</td> <td>线路</td>
<td> <td>
<p class="comment" v-if="routes.length == 0">没有可选的线路。</p> <p class="comment" v-if="allRoutes.length == 0">没有可选的线路。</p>
<select class="ui dropdown auto-width" name="route" v-if="routes.length > 0" v-model="route"> <div v-if="allRoutes.length > 0">
<option v-for="route in routes" :value="route.code">{{route.name}}</option> <dns-route-selector :v-all-routes="allRoutes" :v-routes="routes"></dns-route-selector>
</select> <p class="comment">当前节点IP对应的线路。</p>
<p class="comment" v-if="routes.length > 0">当前节点IP对应的线路。</p> </div>
</td> </td>
</tr> </tr>
</table> </table>

View File

@@ -6,12 +6,12 @@
<p class="comment" v-if="providers.length == 0">暂时还没有第三方DNS服务商。</p> <p class="comment" v-if="providers.length == 0">暂时还没有第三方DNS服务商。</p>
<table class="ui table selectable" v-if="providers.length > 0"> <table class="ui table selectable celled" v-if="providers.length > 0">
<thead> <thead>
<tr> <tr>
<th>账号说明</th> <th>账号说明</th>
<th>服务商</th> <th>服务商</th>
<th>域名</th> <th class="center">域名</th>
<th>数据更新时间</th> <th>数据更新时间</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
@@ -19,9 +19,9 @@
<tr v-for="(provider, index) in providers"> <tr v-for="(provider, index) in providers">
<td>{{provider.name}}</td> <td>{{provider.name}}</td>
<td>{{provider.typeName}}</td> <td>{{provider.typeName}}</td>
<td> <td class="center">
<span v-if="provider.countDomains == 0" class="disabled">0个域名</span> <span v-if="provider.countDomains == 0" class="disabled">0</span>
<span v-else>{{provider.countDomains}}个域名</span> <span v-else>{{provider.countDomains}}</span>
</td> </td>
<td> <td>
<span v-if="provider.dataUpdatedTime.length > 0">{{provider.dataUpdatedTime}}</span> <span v-if="provider.dataUpdatedTime.length > 0">{{provider.dataUpdatedTime}}</span>

View File

@@ -48,7 +48,7 @@
<h3>管理的域名 <a href="" @click.prevent="createDomain()">[添加域名]</a> </h3> <h3>管理的域名 <a href="" @click.prevent="createDomain()">[添加域名]</a> </h3>
<p class="comment" v-if="domains.length == 0">暂时还没有可以管理的域名。</p> <p class="comment" v-if="domains.length == 0">暂时还没有可以管理的域名。</p>
<table class="ui table selectable" v-if="domains.length > 0"> <table class="ui table selectable celled" v-if="domains.length > 0">
<thead> <thead>
<tr> <tr>
<th>域名</th> <th>域名</th>

View File

@@ -9,7 +9,7 @@
</second-menu> </second-menu>
<p class="comment" v-if="cachePolicies == null || cachePolicies.length == 0">暂时还没有缓存策略。</p> <p class="comment" v-if="cachePolicies == null || cachePolicies.length == 0">暂时还没有缓存策略。</p>
<table class="ui table selectable" v-if="cachePolicies != null && cachePolicies.length > 0"> <table class="ui table selectable celled" v-if="cachePolicies != null && cachePolicies.length > 0">
<thead> <thead>
<tr> <tr>
<th>策略名称</th> <th>策略名称</th>

View File

@@ -11,7 +11,7 @@
<p class="comment" v-if="groups.length == 0">暂时还没有分组。</p> <p class="comment" v-if="groups.length == 0">暂时还没有分组。</p>
<div v-show="groups.length > 0"> <div v-show="groups.length > 0">
<div class="margin"></div> <div class="margin"></div>
<table class="ui table selectable" id="sortable-table"> <table class="ui table selectable celled" id="sortable-table">
<thead> <thead>
<tr> <tr>
<th style="width:3em"></th> <th style="width:3em"></th>

View File

@@ -11,7 +11,7 @@
<p class="comment" v-if="libraries.length == 0">暂时还没有IP库。</p> <p class="comment" v-if="libraries.length == 0">暂时还没有IP库。</p>
<div v-if="libraries.length > 0"> <div v-if="libraries.length > 0">
<div class="margin"></div> <div class="margin"></div>
<table class="ui table selectable"> <table class="ui table selectable celled">
<thead> <thead>
<tr> <tr>
<th>文件名</th> <th>文件名</th>

View File

@@ -14,7 +14,7 @@
</second-menu> </second-menu>
<p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p> <p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p>
<table class="ui table selectable" v-if="certs.length > 0"> <table class="ui table selectable celled" v-if="certs.length > 0">
<thead> <thead>
<tr> <tr>
<th>证书说明</th> <th>证书说明</th>

View File

@@ -2,7 +2,7 @@
<h3>选择证书</h3> <h3>选择证书</h3>
<p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p> <p class="comment" v-if="certs.length == 0">暂时还没有相关的证书。</p>
<table class="ui table selectable" v-if="certs.length > 0"> <table class="ui table selectable celled" v-if="certs.length > 0">
<thead> <thead>
<tr> <tr>
<th>证书说明</th> <th>证书说明</th>

View File

@@ -27,7 +27,7 @@
<h3 style="padding-top:0.8em">规则集<a href="" @click.prevent="createSet(group.id)">[添加规则集]</a> </h3> <h3 style="padding-top:0.8em">规则集<a href="" @click.prevent="createSet(group.id)">[添加规则集]</a> </h3>
<p class="comment" v-if="sets == null || sets.length == 0">暂时还没有规则。</p> <p class="comment" v-if="sets == null || sets.length == 0">暂时还没有规则。</p>
<table class="ui table selectable" id="sortable-table" v-if="sets != null && sets.length > 0"> <table class="ui table selectable celled" id="sortable-table" v-if="sets != null && sets.length > 0">
<thead> <thead>
<tr> <tr>
<th style="width:3em"></th> <th style="width:3em"></th>

View File

@@ -10,7 +10,7 @@
<p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p> <p class="comment" v-if="groups.length == 0">暂时还没有规则分组。</p>
<table class="ui table selectable" v-if="groups.length > 0" id="sortable-table"> <table class="ui table selectable celled" v-if="groups.length > 0" id="sortable-table">
<thead> <thead>
<tr> <tr>
<th style="width:3em"></th> <th style="width:3em"></th>

View File

@@ -10,7 +10,7 @@
<p class="comment" v-if="policies.length == 0">暂时还没有WAF策略。</p> <p class="comment" v-if="policies.length == 0">暂时还没有WAF策略。</p>
<table class="ui table selectable" v-if="policies.length > 0"> <table class="ui table selectable celled" v-if="policies.length > 0">
<thead> <thead>
<tr> <tr>
<th>策略名称</th> <th>策略名称</th>

View File

@@ -7,7 +7,7 @@
<p class="comment" v-if="items.length == 0">暂时还没有IP。</p> <p class="comment" v-if="items.length == 0">暂时还没有IP。</p>
<table class="ui table selectable" v-if="items.length > 0"> <table class="ui table selectable celled" v-if="items.length > 0">
<thead> <thead>
<tr> <tr>
<th>IP</th> <th>IP</th>

View File

@@ -24,7 +24,7 @@
<p class="ui message" v-if="servers.length == 0">暂时还没有服务。</p> <p class="ui message" v-if="servers.length == 0">暂时还没有服务。</p>
<table class="ui table selectable" v-if="servers.length > 0"> <table class="ui table selectable celled" v-if="servers.length > 0">
<thead> <thead>
<tr> <tr>
<th>服务名称</th> <th>服务名称</th>
@@ -32,7 +32,7 @@
<th>部署集群</th> <th>部署集群</th>
<th>域名</th> <th>域名</th>
<th>端口</th> <th>端口</th>
<th class="two wide">状态</th> <th class="two wide center">状态</th>
<th class="two op">操作</th> <th class="two op">操作</th>
</tr> </tr>
</thead> </thead>
@@ -65,7 +65,7 @@
<tiny-label>{{port.portRange}}<span class="small">{{port.protocol}}</span></tiny-label> <tiny-label>{{port.portRange}}<span class="small">{{port.protocol}}</span></tiny-label>
</div> </div>
</td> </td>
<td> <td class="center">
<label-on :v-is-on="server.isOn"></label-on> <label-on :v-is-on="server.isOn"></label-on>
</td> </td>
<td> <td>

View File

@@ -10,7 +10,7 @@
<p class="comment" v-if="locations.length == 0">暂时还没有路径规则。</p> <p class="comment" v-if="locations.length == 0">暂时还没有路径规则。</p>
<table class="ui table selectable" v-if="locations.length > 0" id="sortable-table"> <table class="ui table selectable celled" v-if="locations.length > 0" id="sortable-table">
<thead> <thead>
<tr> <tr>
<th style="width:1em"></th> <th style="width:1em"></th>