换成单集群模式

This commit is contained in:
robin
2026-03-02 20:07:53 +08:00
parent 5d0b7c7e91
commit 2a76d1773d
432 changed files with 5681 additions and 5095 deletions

View File

@@ -2,16 +2,17 @@
{$template "node_menu"}
{$template "/code_editor"}
<!-- 已安装 -->
<div v-if="node.isInstalled">
<div class="ui message green">当前节点为已安装状态。</div>
<a href="" @click.prevent="updateNodeIsInstalled(false)">[修改为未安装]</a>
<a href="" @click.prevent="updateNodeIsInstalled(false)">[重新安装]</a>
<h4>配置文件</h4>
<table class="ui table definition selectable">
<tr>
<td class="title">配置文件</td>
<td>
configs/api_httpdns.yaml
configs/api_httpdns.yaml &nbsp;
<download-link :v-element="'rpc-code'" :v-file="'api_httpdns.yaml'">[下载]</download-link>
</td>
</tr>
@@ -19,27 +20,45 @@
<td>配置内容</td>
<td>
<source-code-box id="rpc-code" type="text/yaml">rpc.endpoints: [ {{apiEndpoints}} ]
nodeId: "{{node.uniqueId}}"
secret: "{{node.secret}}"</source-code-box>
nodeId: "{{node.uniqueId}}"
secret: "{{node.secret}}"</source-code-box>
<p class="comment">每个节点的配置文件内容均不相同,不能混用。</p>
</td>
</tr>
<tr>
<td class="title">安装目录</td>
<td>
<div v-if="node.installDir.length == 0">使用集群设置<span v-if="node.cluster != null && node.cluster.installDir.length > 0">{{node.cluster.installDir}}</span></div>
<div v-if="node.installDir.length == 0">使用集群设置<span
v-if="node.cluster != null && node.cluster.installDir.length > 0">{{node.cluster.installDir}}</span>
</div>
<span v-else>{{node.installDir}}</span>
</td>
</tr>
</table>
</div>
<!-- 未安装 -->
<div v-if="!node.isInstalled">
<h4>通过控制台标记安装</h4>
<div v-if="installStatus != null && (installStatus.isRunning || installStatus.isFinished)" class="ui segment installing-box">
<h4>方法1通过SSH自动安装</h4>
<table class="ui table definition selectable">
<tr>
<td class="title">SSH地址</td>
<td>
<span v-if="sshAddr.length > 0">{{sshAddr}} &nbsp; <a href=""
@click.prevent="showSSHPopup(nodeId)">[修改]</a></span>
<span v-else><span class="red">尚未设置</span> &nbsp; <a href=""
@click.prevent="showSSHPopup(nodeId)">[设置]</a></span>
</td>
</tr>
</table>
<div v-if="installStatus != null && (installStatus.isRunning || installStatus.isFinished)"
class="ui segment installing-box">
<div v-if="installStatus.isRunning" class="blue">安装中...</div>
<div v-if="installStatus.isFinished">
<span v-if="installStatus.isOk" class="green">安装成功</span>
<span v-else class="red">安装失败{{installStatus.error}}</span>
<span v-if="installStatus.isOk" class="green">安装成功</span>
<span v-if="!installStatus.isOk" class="red">安装过程中发生错误{{installStatus.error}}</span>
</div>
</div>
<div v-if="installStatus != null && installStatus.isFinished">
@@ -49,12 +68,12 @@
<button class="ui button small primary" type="button" @click.prevent="install()">开始安装</button>
</div>
<h4>配置文件</h4>
<h4>方法2手动安装</h4>
<table class="ui table definition selectable">
<tr>
<td class="title">配置文件</td>
<td>
configs/api_httpdns.yaml
configs/api_httpdns.yaml &nbsp;
<download-link :v-element="'rpc-code'" :v-file="'api_httpdns.yaml'">[下载]</download-link>
</td>
</tr>
@@ -62,18 +81,21 @@
<td>配置内容</td>
<td>
<source-code-box id="rpc-code" type="text/yaml">rpc.endpoints: [ {{apiEndpoints}} ]
nodeId: "{{node.uniqueId}}"
secret: "{{node.secret}}"</source-code-box>
nodeId: "{{node.uniqueId}}"
secret: "{{node.secret}}"</source-code-box>
<p class="comment">每个节点的配置文件内容均不相同,不能混用。</p>
</td>
</tr>
<tr>
<td class="title">安装目录</td>
<td>
<div v-if="node.installDir.length == 0">使用集群设置<span v-if="node.cluster != null && node.cluster.installDir.length > 0">{{node.cluster.installDir}}</span></div>
<div v-if="node.installDir.length == 0">使用集群设置<span
v-if="node.cluster != null && node.cluster.installDir.length > 0">{{node.cluster.installDir}}</span>
</div>
<span v-else>{{node.installDir}}</span>
</td>
</tr>
</table>
<a href="" @click.prevent="updateNodeIsInstalled(true)">[修改为已安装]</a>
</div>
<a href="" @click.prevent="updateNodeIsInstalled(true)">[修改为已安装状态]</a>
</div>

View File

@@ -28,6 +28,7 @@ Tea.context(function () {
})
}
// 刷新状态
this.reloadStatus = function (nodeId) {
let that = this
@@ -44,10 +45,50 @@ Tea.context(function () {
}
let installStatus = this.installStatus || {}
let errorCode = installStatus.errorCode || ""
if (errorCode.length > 0) {
let errMsg = installStatus.error || ""
if (installStatus.errorCode != null && installStatus.errorCode.length > 0) {
isInstalling = false
teaweb.warn("安装失败:" + (installStatus.error || "未知错误"))
}
switch (installStatus.errorCode) {
case "EMPTY_LOGIN":
case "EMPTY_SSH_HOST":
case "EMPTY_SSH_PORT":
case "EMPTY_GRANT":
teaweb.warn("需要填写SSH登录信息", function () {
teaweb.popup("/httpdns/clusters/updateNodeSSH?nodeId=" + nodeId, {
height: "20em",
callback: function () {
that.install()
}
})
})
return
case "SSH_LOGIN_FAILED":
teaweb.warn("SSH登录失败请检查设置", function () {
teaweb.popup("/httpdns/clusters/updateNodeSSH?nodeId=" + nodeId, {
height: "20em",
callback: function () {
that.install()
}
})
})
return
case "CREATE_ROOT_DIRECTORY_FAILED":
teaweb.warn("创建根目录失败,请检查目录权限或者手工创建:" + errMsg)
return
case "INSTALL_HELPER_FAILED":
teaweb.warn("安装助手失败:" + errMsg)
return
case "TEST_FAILED":
teaweb.warn("环境测试失败:" + errMsg)
return
case "RPC_TEST_FAILED":
teaweb.confirm("html:要安装的节点到API服务之间的RPC通讯测试失败具体错误" + errMsg + "<br/>现在修改API信息", function () {
window.location = "/settings/api"
})
return
}
})
.done(function () {
@@ -59,7 +100,7 @@ Tea.context(function () {
this.showSSHPopup = function (nodeId) {
teaweb.popup("/httpdns/clusters/updateNodeSSH?nodeId=" + nodeId, {
height: "30em",
height: "20em",
callback: function () {
teaweb.success("保存成功", function () {
teaweb.reload()

View File

@@ -4,8 +4,8 @@
<h3>修改节点</h3>
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<csrf-token></csrf-token>
<input type="hidden" name="nodeId" :value="node.id" />
<input type="hidden" name="loginId" :value="loginId" />
<table class="ui table definition selectable">
<tr>
<td class="title">节点名称 *</td>

View File

@@ -65,40 +65,12 @@
<td>启用当前集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" v-model="settings.isOn" @change="syncDefaultCluster" />
<input type="checkbox" name="isOn" value="1" v-model="settings.isOn" />
<label></label>
</div>
<p class="comment">取消启用后,该集群不会参与 HTTPDNS 服务。</p>
</td>
</tr>
<tr>
<td>默认集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" value="1" v-model="settings.defaultClusterEnabled" @change="syncDefaultClusterSelection" />
<label>设为默认集群</label>
</div>
<div class="ui form" style="margin-top: .8em;" v-if="settings.defaultClusterEnabled">
<div class="grouped fields" style="margin:0;">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="settings.defaultClusterRole" value="primary" @change="syncDefaultClusterSelection" />
<label>主集群</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="settings.defaultClusterRole" value="backup" @change="syncDefaultClusterSelection" />
<label>备用集群</label>
</div>
</div>
</div>
</div>
<input type="hidden" name="isDefaultCluster" value="1" v-if="settings.defaultClusterEnabled && settings.defaultClusterRole == 'primary'" />
<input type="hidden" name="isDefaultBackupCluster" value="1" v-if="settings.defaultClusterEnabled && settings.defaultClusterRole == 'backup'" />
<p class="comment">同一时刻最多 1 个默认集群角色,新设置会自动取消旧设置。</p>
</td>
</tr>
</table>
<table class="ui table selectable definition" v-show="activeSection == 'tls'">

View File

@@ -1,4 +1,4 @@
Tea.context(function () {
Tea.context(function () {
this.success = NotifyReloadSuccess("保存成功")
this.activeSection = this.activeSection || "basic"
@@ -7,39 +7,4 @@
if (!this.settings) {
this.settings = {}
}
// 兼容旧字段,转换成统一“默认集群 + 角色”表现
let isDefaultPrimary = !!this.settings.isDefaultCluster
let isDefaultBackup = !!this.settings.isDefaultBackupCluster
this.settings.defaultClusterEnabled = isDefaultPrimary || isDefaultBackup
this.settings.defaultClusterRole = isDefaultBackup ? "backup" : "primary"
this.syncDefaultCluster = function () {
if (!this.settings.isOn) {
this.settings.defaultClusterEnabled = false
this.settings.defaultClusterRole = "primary"
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = false
return
}
this.syncDefaultClusterSelection()
}
this.syncDefaultClusterSelection = function () {
if (!this.settings.defaultClusterEnabled) {
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = false
return
}
if (this.settings.defaultClusterRole === "backup") {
this.settings.isDefaultCluster = false
this.settings.isDefaultBackupCluster = true
} else {
this.settings.defaultClusterRole = "primary"
this.settings.isDefaultCluster = true
this.settings.isDefaultBackupCluster = false
}
}
})

View File

@@ -24,7 +24,7 @@
<td>默认解析 TTL</td>
<td>
<div class="ui input right labeled">
<input type="text" name="cacheTtl" maxlength="5" value="30" style="width: 6em" />
<input type="text" name="cacheTtl" maxlength="5" value="60" style="width: 6em" />
<span class="ui label"></span>
</div>
<p class="comment">SDK 通过 HTTPDNS 解析域名时返回的默认 TTL。</p>
@@ -51,38 +51,12 @@
<td>启用当前集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" v-model="isOn" @change="syncDefaultClusterEnabled" checked />
<input type="checkbox" name="isOn" value="1" v-model="isOn" @change="syncDefaultClusterEnabled"
checked />
<label></label>
</div>
</td>
</tr>
<tr>
<td>默认集群</td>
<td>
<div class="ui checkbox">
<input type="checkbox" value="1" v-model="defaultClusterEnabled" @change="syncDefaultClusterEnabled" />
<label>设为默认集群</label>
</div>
<div class="ui form" style="margin-top: .8em;" v-if="defaultClusterEnabled">
<div class="grouped fields" style="margin:0;">
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="defaultClusterRole" value="primary" />
<label>主集群</label>
</div>
</div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" v-model="defaultClusterRole" value="backup" />
<label>备用集群</label>
</div>
</div>
</div>
</div>
<input type="hidden" name="isDefaultPrimary" value="1" v-if="defaultClusterEnabled && defaultClusterRole == 'primary'" />
<input type="hidden" name="isDefaultBackup" value="1" v-if="defaultClusterEnabled && defaultClusterRole == 'backup'" />
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</form>

View File

@@ -1,14 +1,5 @@
Tea.context(function () {
Tea.context(function () {
this.isOn = true
this.defaultClusterEnabled = false
this.defaultClusterRole = "primary"
this.syncDefaultClusterEnabled = function () {
if (!this.isOn) {
this.defaultClusterEnabled = false
this.defaultClusterRole = "primary"
}
}
this.success = function (resp) {
let clusterId = 0

View File

@@ -28,7 +28,7 @@
<thead>
<tr>
<th>集群名称</th>
<th>服务域名</th>
<th>API服务地址</th>
<th class="center width10">节点数</th>
<th class="center width10">在线节点数</th>
<th class="width5">状态</th>
@@ -43,7 +43,7 @@
</a>
</td>
<td>
<code>{{cluster.gatewayDomain}}</code>
<code>{{cluster.apiAddress}}</code>
</td>
<td class="center">
<a :href="'/httpdns/clusters/cluster?clusterId=' + cluster.id" v-if="cluster.countAllNodes > 0">
@@ -67,5 +67,4 @@
</table>
<div class="page" v-html="page"></div>
</div>
</div>

View File

@@ -3,7 +3,6 @@
<h3>修改节点"{{node.name}}"的SSH登录信息</h3>
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<csrf-token></csrf-token>
<input type="hidden" name="nodeId" :value="node.id" />
<input type="hidden" name="loginId" :value="loginId" />
<table class="ui table definition">