mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-07 07:10:27 +08:00
可以在节点列表中直接修改节点所属线路
This commit is contained in:
@@ -47,6 +47,7 @@ func init() {
|
||||
Get("/thresholds", new(thresholds.IndexAction)).
|
||||
Get("/detail", new(node.DetailAction)).
|
||||
GetPost("/boards", new(nodeboards.IndexAction)).
|
||||
GetPost("/updateDNSPopup", new(node.UpdateDNSPopupAction)).
|
||||
|
||||
// 分组相关
|
||||
Prefix("/clusters/cluster/groups").
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"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/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"net"
|
||||
)
|
||||
|
||||
type UpdateDNSPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdateDNSPopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *UpdateDNSPopupAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
NodeId int64
|
||||
}) {
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
dnsInfo := dnsInfoResp.Node
|
||||
if dnsInfo == nil {
|
||||
this.NotFound("node", params.NodeId)
|
||||
return
|
||||
}
|
||||
this.Data["ipAddr"] = dnsInfo.IpAddr
|
||||
this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo)
|
||||
this.Data["domainId"] = dnsInfo.DnsDomainId
|
||||
this.Data["domainName"] = dnsInfo.DnsDomainName
|
||||
|
||||
// 读取所有线路
|
||||
allRouteMaps := []maps.Map{}
|
||||
if dnsInfo.DnsDomainId > 0 {
|
||||
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfo.DnsDomainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
if len(routesResp.Routes) > 0 {
|
||||
for _, route := range routesResp.Routes {
|
||||
allRouteMaps = append(allRouteMaps, maps.Map{
|
||||
"name": route.Name,
|
||||
"code": route.Code,
|
||||
"domainName": dnsInfo.DnsDomainName,
|
||||
"domainId": dnsInfo.DnsDomainId,
|
||||
})
|
||||
}
|
||||
|
||||
// 筛选
|
||||
var routes = domainutils.FilterRoutes(dnsInfo.Routes, routesResp.Routes)
|
||||
dnsInfo.Routes = routes
|
||||
this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo)
|
||||
}
|
||||
}
|
||||
this.Data["allRoutes"] = allRouteMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdateDNSPopupAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
IpAddr string
|
||||
DomainId int64
|
||||
DnsRoutesJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
// 操作日志
|
||||
defer 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.
|
||||
Field("ipAddr", params.IpAddr).
|
||||
Require("请输入IP地址")
|
||||
|
||||
if net.ParseIP(params.IpAddr) == nil {
|
||||
this.FailField("ipAddr", "请输入正确的IP地址")
|
||||
}
|
||||
|
||||
// 执行修改
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: params.IpAddr,
|
||||
DnsDomainId: params.DomainId,
|
||||
Routes: routes,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -41,6 +41,15 @@ func (this *NodesAction) RunGet(params struct {
|
||||
this.Data["activeState"] = params.ActiveState
|
||||
this.Data["keyword"] = params.Keyword
|
||||
|
||||
// 集群是否已经设置了线路
|
||||
clusterDNSResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["hasClusterDNS"] = clusterDNSResp.Domain != nil
|
||||
|
||||
// 数量
|
||||
countAllResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ Vue.component("dns-route-selector", {
|
||||
</select>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<input type="text" placeholder="搜索..." size="10" v-model="keyword" ref="keywordRef"/>
|
||||
<input type="text" placeholder="搜索..." size="10" v-model="keyword" ref="keywordRef" @keyup.enter="confirm" @keypress.enter.prevent="1"/>
|
||||
</div>
|
||||
|
||||
<div class="ui field">
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
{$end}
|
||||
<link rel="stylesheet" type="text/css" href="/_/@default/@layout.css" media="all"/>
|
||||
{$TEA.SEMANTIC}
|
||||
<link rel="stylesheet" type="text/css" href="/_/@default/@layout_override.css" media="all"/>
|
||||
|
||||
{$TEA.VUE}
|
||||
{$echo "header"}
|
||||
@@ -20,6 +19,8 @@
|
||||
<script type="text/javascript" src="/js/utils.js"></script>
|
||||
<script type="text/javascript" src="/js/sweetalert2/dist/sweetalert2.all.min.js"></script>
|
||||
<script type="text/javascript" src="/js/date.tea.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/_/@default/@layout_override.css" media="all"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -45,4 +45,7 @@ select.dropdown {
|
||||
.message .icon.warning {
|
||||
font-size: 2em !important;
|
||||
}
|
||||
body.swal2-shown {
|
||||
overflow: auto !important;
|
||||
}
|
||||
/*# sourceMappingURL=@layout_override.css.map */
|
||||
@@ -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;;AAGD,GAAG,MAAM,MAAM;EACd,iCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA;EACA,0BAAA;EACA,2BAAA;;AAJF,KAOC,GAAE;EACD,WAAA;;AARF,KAWC,GAAE;EACD,UAAA;;AAZF,KAeC,GAAE;EACD,UAAA;;AAKF,QAAQ;EACP,qBAAA;;AAID,MAAM;EACL,uBAAA;;AAID,QACC,MAAK;EACJ,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;;AAGD,GAAG,MAAM,MAAM;EACd,iCAAA;;AAID,IACC;EACC,2BAAA;;AAKF,KAAK;EACJ,sBAAA;;AAGD,KAAK,KAAK;EACT,yBAAA;;AAID,KACC,GAAE;AADH,KACY,GAAE;EACZ,6BAAA;EACA,0BAAA;EACA,2BAAA;;AAJF,KAOC,GAAE;EACD,WAAA;;AARF,KAWC,GAAE;EACD,UAAA;;AAZF,KAeC,GAAE;EACD,UAAA;;AAKF,QAAQ;EACP,qBAAA;;AAID,MAAM;EACL,uBAAA;;AAID,QACC,MAAK;EACJ,yBAAA;;AAKF,IAAI;EACH,yBAAA","file":"@layout_override.css"}
|
||||
@@ -68,3 +68,8 @@ select.dropdown {
|
||||
font-size: 2em !important;
|
||||
}
|
||||
}
|
||||
|
||||
// popup
|
||||
body.swal2-shown {
|
||||
overflow: auto !important;
|
||||
}
|
||||
37
web/views/@default/clusters/cluster/node/updateDNSPopup.html
Normal file
37
web/views/@default/clusters/cluster/node/updateDNSPopup.html
Normal file
@@ -0,0 +1,37 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改节点DNS设置</h3>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="nodeId" :value="nodeId"/>
|
||||
<input type="hidden" name="domainId" :value="domainId"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr v-if="domainName.length > 0">
|
||||
<td>主域名</td>
|
||||
<td>{{domainName}}
|
||||
<p class="comment">由当前节点所属集群设置。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">IP地址 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipAddr" maxlength="64" ref="focus" v-model="ipAddr"/>
|
||||
<p class="comment">用于域名解析的节点IP地址。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="domainId > 0">
|
||||
<td>线路</td>
|
||||
<td>
|
||||
<p class="comment" v-if="allRoutes.length == 0">没有可选的线路。</p>
|
||||
<div v-if="allRoutes.length > 0">
|
||||
<dns-route-selector :v-all-routes="allRoutes" :v-routes="routes"></dns-route-selector>
|
||||
<p class="comment">当前节点IP对应的线路。</p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -4,4 +4,19 @@
|
||||
a .red {
|
||||
border-bottom: 1px #db2828 dashed;
|
||||
}
|
||||
.routes-box a {
|
||||
margin-left: 0.4em;
|
||||
display: none;
|
||||
}
|
||||
.routes-box.show-link a {
|
||||
display: inline;
|
||||
font-size: 1em;
|
||||
}
|
||||
.routes-box:hover a {
|
||||
display: inline;
|
||||
}
|
||||
a.small {
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
}
|
||||
/*# sourceMappingURL=nodes.css.map */
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sources":["nodes.less"],"names":[],"mappings":"AAAA,MAAO;EACN,oBAAA;;AAGD,CACC;EACC,iCAAA","file":"nodes.css"}
|
||||
{"version":3,"sources":["nodes.less"],"names":[],"mappings":"AAAA,MAAO;EACN,oBAAA;;AAGD,CACC;EACC,iCAAA;;AAIF,WACC;EACC,kBAAA;EACA,aAAA;;AAIF,WAAW,UACV;EACC,eAAA;EACA,cAAA;;AAIF,WAAW,MACV;EACC,eAAA;;AAIF,CAAC;EACA,gBAAA;EACA,kBAAA","file":"nodes.css"}
|
||||
@@ -88,12 +88,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<td class="routes-box" :class="{'show-link': node.dnsRouteNames.length == 0 && hasClusterDNS}">
|
||||
<div v-if="node.dnsRouteNames.length > 0">
|
||||
<div v-for="routeName in node.dnsRouteNames">
|
||||
<tiny-basic-label>{{routeName}}</tiny-basic-label>
|
||||
</div>
|
||||
<div>
|
||||
<a href="" @click.prevent="updateNodeDNS(node.id)" class="small">[修改]</a>
|
||||
</div>
|
||||
</div>
|
||||
<span v-else-if="hasClusterDNS">
|
||||
<a href="" @click.prevent="updateNodeDNS(node.id)" class="small">[设置]</a>
|
||||
</span>
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td class="center">
|
||||
|
||||
@@ -21,4 +21,17 @@ Tea.context(function () {
|
||||
.refresh()
|
||||
})
|
||||
}
|
||||
|
||||
this.updateNodeDNS = function (nodeId) {
|
||||
let that = this
|
||||
teaweb.popup("/clusters/cluster/node/updateDNSPopup?clusterId=" + this.clusterId + "&nodeId=" + nodeId, {
|
||||
width: "46em",
|
||||
height: "26em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -7,3 +7,28 @@ a {
|
||||
border-bottom: 1px #db2828 dashed;
|
||||
}
|
||||
}
|
||||
|
||||
.routes-box {
|
||||
a {
|
||||
margin-left: 0.4em;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.routes-box.show-link {
|
||||
a {
|
||||
display: inline;
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.routes-box:hover {
|
||||
a {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
a.small {
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
}
|
||||
Reference in New Issue
Block a user