mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-06 14:50:25 +08:00
节点根据健康检查自动上下线
This commit is contained in:
@@ -37,6 +37,33 @@ func (this *CreateNodeAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["leftMenuItems"] = leftMenuItems
|
||||
|
||||
// DNS线路
|
||||
clusterDNSResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: params.ClusterId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
dnsRouteMaps := []maps.Map{}
|
||||
this.Data["dnsDomainId"] = 0
|
||||
if clusterDNSResp.Domain != nil {
|
||||
domainId := clusterDNSResp.Domain.Id
|
||||
this.Data["dnsDomainId"] = domainId
|
||||
if domainId > 0 {
|
||||
routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: domainId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, route := range routesResp.Routes {
|
||||
dnsRouteMaps = append(dnsRouteMaps, maps.Map{
|
||||
"name": route.Name,
|
||||
"code": route.Code,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
this.Data["dnsRoutes"] = dnsRouteMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -49,6 +76,9 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
SshHost string
|
||||
SshPort int
|
||||
|
||||
DnsDomainId int64
|
||||
DnsRoute string
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
params.Must.
|
||||
@@ -82,6 +112,8 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
ClusterId: params.ClusterId,
|
||||
GroupId: params.GroupId,
|
||||
Login: loginInfo,
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
DnsRoute: params.DnsRoute,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -102,6 +102,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
"name": node.Name,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"installStatus": maps.Map{
|
||||
"isRunning": node.InstallStatus.IsRunning,
|
||||
"isFinished": node.InstallStatus.IsFinished,
|
||||
|
||||
@@ -39,6 +39,8 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
this.Data["dnsName"] = dnsInfoResp.Name
|
||||
this.Data["nodesAutoSync"] = dnsInfoResp.NodesAutoSync
|
||||
this.Data["serversAutoSync"] = dnsInfoResp.ServersAutoSync
|
||||
if dnsInfoResp.Domain != nil {
|
||||
this.Data["domainId"] = dnsInfoResp.Domain.Id
|
||||
this.Data["domainName"] = dnsInfoResp.Domain.Name
|
||||
@@ -52,6 +54,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
|
||||
DnsDomainId int64
|
||||
DnsName string
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -83,6 +87,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -51,9 +51,9 @@ func (this *ClusterHelper) BeforeAction(action *actions.ActionObject) {
|
||||
|
||||
tabbar := actionutils.NewTabbar()
|
||||
tabbar.Add("集群列表", "", "/clusters", "", false)
|
||||
tabbar.Add("节点", "", "/clusters/cluster?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
||||
tabbar.Add("设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
||||
tabbar.Add("删除", "", "/clusters/cluster/delete?clusterId="+clusterIdString, "trash", selectedTabbar == "delete")
|
||||
tabbar.Add("集群节点", "", "/clusters/cluster?clusterId="+clusterIdString, "server", selectedTabbar == "node")
|
||||
tabbar.Add("集群设置", "", "/clusters/cluster/settings?clusterId="+clusterIdString, "setting", selectedTabbar == "setting")
|
||||
tabbar.Add("删除集群", "", "/clusters/cluster/delete?clusterId="+clusterIdString, "trash", selectedTabbar == "delete")
|
||||
|
||||
{
|
||||
m := tabbar.Add("当前集群:"+cluster.Name, "", "/clusters/cluster?clusterId="+clusterIdString, "", false)
|
||||
|
||||
@@ -29,6 +29,8 @@ func (this *UpdateClusterPopupAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
this.Data["dnsName"] = dnsResp.Name
|
||||
this.Data["nodesAutoSync"] = dnsResp.NodesAutoSync
|
||||
this.Data["serversAutoSync"] = dnsResp.ServersAutoSync
|
||||
if dnsResp.Domain != nil {
|
||||
this.Data["domainId"] = dnsResp.Domain.Id
|
||||
this.Data["domain"] = dnsResp.Domain.Name
|
||||
@@ -66,6 +68,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
DnsName string
|
||||
DomainId int64
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -97,6 +101,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
NodeClusterId: params.ClusterId,
|
||||
DnsName: params.DnsName,
|
||||
DnsDomainId: params.DomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -13,7 +13,7 @@ type DeleteAction struct {
|
||||
func (this *DeleteAction) RunPost(params struct {
|
||||
NodeId int64
|
||||
}) {
|
||||
_, err := this.RPC().NodeRPC().DisableNode(this.AdminContext(), &pb.DisableNodeRequest{NodeId: params.NodeId})
|
||||
_, err := this.RPC().NodeRPC().DeleteNode(this.AdminContext(), &pb.DeleteNodeRequest{NodeId: params.NodeId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
@@ -14,7 +14,10 @@ Vue.component("health-check-config-box", {
|
||||
statusCodes: [200],
|
||||
timeout: {count: 10, unit: "second"},
|
||||
countTries: 3,
|
||||
tryDelay: {count: 100, unit: "ms"}
|
||||
tryDelay: {count: 100, unit: "ms"},
|
||||
autoDown: true,
|
||||
countUp: 1,
|
||||
countDown: 1
|
||||
}
|
||||
let that = this
|
||||
setTimeout(function () {
|
||||
@@ -44,7 +47,14 @@ Vue.component("health-check-config-box", {
|
||||
if (healthCheckConfig.tryDelay == null) {
|
||||
healthCheckConfig.tryDelay = {count: 100, unit: "ms"}
|
||||
}
|
||||
if (healthCheckConfig.countUp == null || healthCheckConfig.countUp < 1) {
|
||||
healthCheckConfig.countUp = 1
|
||||
}
|
||||
if (healthCheckConfig.countDown == null || healthCheckConfig.countDown < 1) {
|
||||
healthCheckConfig.countDown = 1
|
||||
}
|
||||
}
|
||||
console.log(healthCheckConfig.countUp, healthCheckConfig.countDown)
|
||||
return {
|
||||
healthCheck: healthCheckConfig,
|
||||
advancedVisible: false,
|
||||
@@ -79,6 +89,22 @@ Vue.component("health-check-config-box", {
|
||||
} else {
|
||||
this.healthCheck.countTries = 0
|
||||
}
|
||||
},
|
||||
"healthCheck.countUp": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (!isNaN(count)) {
|
||||
this.healthCheck.countUp = count
|
||||
} else {
|
||||
this.healthCheck.countUp = 0
|
||||
}
|
||||
},
|
||||
"healthCheck.countDown": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (!isNaN(count)) {
|
||||
this.healthCheck.countDown = count
|
||||
} else {
|
||||
this.healthCheck.countDown = 0
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -145,6 +171,30 @@ Vue.component("health-check-config-box", {
|
||||
<time-duration-box :v-value="healthCheck.interval"></time-duration-box>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否自动下线</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" value="1" v-model="healthCheck.autoDown"/>
|
||||
<label></label>
|
||||
</div>
|
||||
<p class="comment">选中后系统会根据健康检查的结果自动标记节点的上线/下线状态。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="healthCheck.autoDown">
|
||||
<td>连续上线次数</td>
|
||||
<td>
|
||||
<input type="text" v-model="healthCheck.countUp" style="width:5em" maxlength="6"/>
|
||||
<p class="comment">连续N次检查成功后自动恢复上线。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="healthCheck.autoDown">
|
||||
<td>连续下线次数</td>
|
||||
<td>
|
||||
<input type="text" v-model="healthCheck.countDown" style="width:5em" maxlength="6"/>
|
||||
<p class="comment">连续N次检查失败后自动下线。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody v-show="healthCheck.isOn">
|
||||
<tr>
|
||||
|
||||
@@ -31,9 +31,15 @@ Vue.component("message-row", {
|
||||
<td>
|
||||
{{message.body}}
|
||||
|
||||
<div v-if="message.type == 'HealthCheckFail'" style="margin-top: 0.8em">
|
||||
<!-- 健康检查 -->
|
||||
<div v-if="message.type == 'HealthCheckFailed'" style="margin-top: 0.8em">
|
||||
<a :href="'/clusters/cluster/node?clusterId=' + message.cluster.id + '&nodeId=' + param.node.id" v-for="param in params" class="ui label tiny" style="margin-bottom: 0.5em">{{param.node.name}}: {{param.error}}</a>
|
||||
</div>
|
||||
|
||||
<!-- 集群DNS设置 -->
|
||||
<div v-if="message.type == 'ClusterDNSSyncFailed'" style="margin-top: 0.8em">
|
||||
<a :href="'/dns/clusters/cluster?clusterId=' + message.cluster.id">查看问题 »</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -16,6 +16,18 @@
|
||||
<td>IP地址</td>
|
||||
<td>
|
||||
<node-ip-addresses-box></node-ip-addresses-box>
|
||||
<p class="comment">用于访问节点和域名解析等。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="dnsRoutes.length > 0">
|
||||
<td>DNS线路</td>
|
||||
<td>
|
||||
<input type="hidden" name="dnsDomainId" :value="dnsDomainId"/>
|
||||
<select class="ui dropdown auto-width" name="dnsRoute">
|
||||
<option value="">[请选择]</option>
|
||||
<option v-for="route in dnsRoutes" :value="route.code">{{route.name}}</option>
|
||||
</select>
|
||||
<p class="comment">可用线路是根据集群设置的域名获取的,注意DNS服务商可能对这些线路有所限制。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -25,7 +37,9 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
<td colspan="2">
|
||||
<more-options-indicator></more-options-indicator>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
|
||||
@@ -87,7 +87,10 @@
|
||||
<span v-else class="disabled">-</span>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="!node.isOn">
|
||||
<div v-if="!node.isUp">
|
||||
<span class="red">健康问题</span>
|
||||
</div>
|
||||
<div v-else-if="!node.isOn">
|
||||
<label-on :v-is-on="node.isOn"></label-on>
|
||||
</div>
|
||||
<div v-else-if="node.isInstalled">
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<td>IP地址</td>
|
||||
<td>
|
||||
<node-ip-addresses-box :v-ip-addresses="ipAddresses"></node-ip-addresses-box>
|
||||
<p class="comment">用于访问节点和域名解析等。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -25,6 +25,29 @@
|
||||
<p class="comment">和主域名一起组成子域名。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>是否同步节点DNS状态</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="nodesAutoSync" value="1" v-model="nodesAutoSync"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否同步网站服务DNS状态</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="serversAutoSync" value="1" v-model="serversAutoSync"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">集群</td>
|
||||
<td>{{cluster.name}}</td>
|
||||
<td><link-icon :href="'/clusters/cluster?clusterId=' + cluster.id">{{cluster.name}}</link-icon></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>子域名</td>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Tea.context(function () {
|
||||
this.updateCluster = function (clusterId) {
|
||||
teaweb.popup("/dns/updateClusterPopup?clusterId=" + clusterId, {
|
||||
height: "22em",
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Tea.context(function () {
|
||||
this.updateCluster = function (clusterId) {
|
||||
teaweb.popup("/dns/updateClusterPopup?clusterId=" + clusterId, {
|
||||
height: "22em",
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
|
||||
@@ -8,7 +8,7 @@ Tea.context(function () {
|
||||
this.updateCluster = function (clusterId) {
|
||||
let that = this
|
||||
teaweb.popup("/dns/updateClusterPopup?clusterId=" + clusterId, {
|
||||
height: "22em",
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
that.reload()
|
||||
|
||||
@@ -43,6 +43,29 @@
|
||||
<p class="comment">子域名和主域名共同组成集群的域名。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>是否同步节点DNS状态</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="nodesAutoSync" value="1" v-model="nodesAutoSync"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>是否同步网站服务DNS状态</td>
|
||||
<td>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" name="serversAutoSync" value="1" v-model="serversAutoSync"/>
|
||||
<label></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
|
||||
Reference in New Issue
Block a user