阶段性提交

This commit is contained in:
刘祥超
2020-09-06 16:19:34 +08:00
parent d7e3cefa4d
commit 9093019c73
185 changed files with 5306 additions and 1832 deletions

View File

@@ -0,0 +1,4 @@
.table .label {
margin-bottom: 0.5em;
}
/*# sourceMappingURL=index.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,MAAO;EACN,oBAAA","file":"index.css"}

View File

@@ -0,0 +1,87 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
<second-menu>
<menu-item :href="'/clusters/cluster/node/create?clusterId=' + clusterId">添加节点</menu-item>
<menu-item>安装节点</menu-item>
</second-menu>
<h3>节点列表</h3>
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
<div v-show="nodes.length > 0">
<form class="ui form segment" action="/clusters/cluster">
<input type="hidden" name="clusterId" :value="clusterId"/>
<div class="ui fields inline">
<div class="ui field">
安装状态:
</div>
<div class="ui field">
<select class="ui dropdown" name="installedState">
<option value="0">[全部]</option>
<option value="1">已安装</option>
<option value="2">未安装</option>
</select>
</div>
<div class="ui field">
<button class="ui button" type="submit">搜索</button>
</div>
</div>
</form>
</div>
<table class="ui table selectable" v-if="nodes.length > 0">
<thead>
<tr>
<th>ID</th>
<th>节点名称</th>
<th>主机名</th>
<th>IP</th>
<th>CPU</th>
<th>内存</th>
<!--<th>流量</th>
<th>连接数</th>-->
<th>状态</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="node in nodes">
<td>{{node.id}}</td>
<td>{{node.name}}</td>
<td>
<span v-if="node.status.hostname != null && node.status.hostname.length > 0">{{node.status.hostname}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="node.ipAddresses.length == 0">-</span>
<div v-else class="address-box">
<div v-for="addr in node.ipAddresses" class="ui label small">{{addr.ip}} <span class="small">{{addr.name}}</span></div>
</div>
</td>
<td>
<span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
<span v-else>-</span>
</td>
<td>
<div v-if="node.isInstalled">
<span v-if="node.status.isActive"><span class="green">运行中</span></span>
<span v-else-if="node.status.updatedAt > 0" class="red">已断开</span>
<span v-else-if="node.status.updatedAt == 0" class="red">未连接</span>
</div>
<span v-else class="red">未安装</span>
</td>
<td>
<a :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + node.id">详情</a> &nbsp; <a href="" @click.prevent="deleteNode(node.id)">删除</a>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>
</div>

View File

@@ -0,0 +1,11 @@
Tea.context(function () {
this.deleteNode = function (nodeId) {
teaweb.confirm("确定要删除这个节点吗?", function () {
this.$post("/nodes/delete")
.params({
nodeId: nodeId
})
.refresh();
});
};
});

View File

@@ -0,0 +1,3 @@
.table .label {
margin-bottom: 0.5em;
}

View File

@@ -0,0 +1,5 @@
<second-menu>
<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改节点</menu-item>
<menu-item :href="'/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
</second-menu>

View File

@@ -0,0 +1,45 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
<h3>添加节点</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="clusterId" :value="clusterId"/>
<table class="ui table definition selectable">
<tr>
<td class="title">节点名称 *</td>
<td>
<input type="text" name="name" maxlength="50" ref="focus"/>
</td>
</tr>
<tr>
<td>IP地址</td>
<td>
<node-ip-addresses-box></node-ip-addresses-box>
</td>
</tr>
<tr>
<td>SSH主机地址</td>
<td>
<input type="text" name="sshHost" maxlength="64"/>
<p class="comment">比如192.168.1.100</p>
</td>
</tr>
<tr>
<td>SSH主机端口</td>
<td>
<input type="text" name="sshPort" maxlength="5"/>
<p class="comment">常见的比如22。</p>
</td>
</tr>
<tr>
<td>SSH登录认证</td>
<td>
<grant-selector></grant-selector>
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</div>

View File

@@ -0,0 +1,3 @@
Tea.context(function () {
this.success = NotifySuccess("保存成功", "/clusters/cluster?clusterId=" + this.clusterId);
});

View File

@@ -0,0 +1,37 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
{$template "node_menu"}
<!-- 已安装 -->
<div v-if="node.isInstalled">
<div class="ui message green">当前节点为已安装状态。</div>
<a href="" @click.prevent="updateNodeIsInstalled(false)">[修改为未安装状态]</a>
</div>
<!-- 未安装 -->
<div v-if="!node.isInstalled">
<h3>方法1自动安装</h3>
<h3>方法2手动安装</h3>
<table class="ui table definition selectable">
<tr>
<td>配置文件<em>configs/api.yaml</em></td>
<td>
<pre>rpc:
endpoints: [ "${endpoint}" ]
nodeId: "{{node.uniqueId}}"
secret: "{{node.secret}}"</pre>
</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>
<span v-else>{{node.installDir}}</span>
</td>
</tr>
</table>
</div>
</div>

View File

@@ -0,0 +1,12 @@
Tea.context(function () {
this.updateNodeIsInstalled = function (isInstalled) {
teaweb.confirm("确定要将当前节点修改为未安装状态?", function () {
this.$post("/clusters/cluster/node/updateInstallStatus")
.params({
nodeId: this.nodeId,
isInstalled: isInstalled ? 1 : 0
})
.refresh()
})
}
})

View File

@@ -0,0 +1,4 @@
a.underline {
border-bottom: 1px #db2828 dashed;
}
/*# sourceMappingURL=node.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["node.less"],"names":[],"mappings":"AAAA,CAAC;EACA,iCAAA","file":"node.css"}

View File

@@ -0,0 +1,90 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
{$template "node_menu"}
<h3>节点详情</h3>
<table class="ui table definition selectable">
<tr>
<td class="title">节点名称</td>
<td>{{node.name}}</td>
</tr>
<tr>
<td>IP地址</td>
<td>
<div v-if="node.ipAddresses.length > 0">
<div>
<div v-for="(address, index) in node.ipAddresses" class="ui label small">
{{address.ip}}<span class="small">{{address.name}}</span>
</div>
</div>
</div>
<div v-else>
<span class="disabled">暂时还没有填写IP地址。</span>
</div>
</td>
</tr>
<tr>
<td>SSH主机地址</td>
<td>
<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
<span v-if="node.login.params.host.length > 0">{{node.login.params.host}}</span>
<span v-else class="disabled">尚未设置</span>
</div>
<div v-else class="disabled">
尚未设置
</div>
</td>
</tr>
<tr>
<td>SSH主机端口</td>
<td>
<div v-if="node.login != null && node.login.params != null && node.login.params.host != null">
<span v-if="node.login.params.port > 0">{{node.login.params.port}}</span>
<span v-else class="disabled">尚未设置</span>
</div>
<span v-else class="disabled">
尚未设置
</span>
</td>
</tr>
<tr>
<td>SSH登录认证</td>
<td>
<div v-if="node.login != null && node.login.grant != null && node.login.grant.id > 0">
{{node.login.grant.name}}<span class="small">{{node.login.grant.methodName}}</span>
</div>
<span v-else class="disabled">
尚未设置
</span>
</td>
</tr>
</table>
<h3>安装信息</h3>
<table class="ui table definition selectable">
<tr>
<td>节点ID<em>id</em></td>
<td>{{node.uniqueId}}</td>
</tr>
<tr>
<td>密钥<em>secret</em></td>
<td>{{node.secret}}</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>
<span v-else>{{node.installDir}}</span>
</td>
</tr>
<tr>
<td>是否已安装</td>
<td>
<span v-if="node.isInstalled" class="green">已安装</span>
<a v-else :href="'/clusters/cluster/installNode?clusterId=' + clusterId + '&nodeId=' + nodeId" class="underline" title="点击进入安装界面"><span class="red">未安装</span></a>
</td>
</tr>
</table>
</div>

View File

@@ -0,0 +1,3 @@
a.underline {
border-bottom: 1px #db2828 dashed;
}

View File

@@ -0,0 +1,55 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
{$template "node_menu"}
<h3>修改节点</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<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>
<td>
<input type="text" name="name" maxlength="50" ref="focus" v-model="node.name"/>
</td>
</tr>
<tr>
<td>IP地址</td>
<td>
<node-ip-addresses-box :v-ip-addresses="ipAddresses"></node-ip-addresses-box>
</td>
</tr>
<tr>
<td>所属集群</td>
<td>
<select class="ui dropdown" name="clusterId" style="width:10em" v-model="clusterId">
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
</td>
</tr>
<tr>
<td>SSH主机地址</td>
<td>
<input type="text" name="sshHost" maxlength="64" v-model="sshHost"/>
<p class="comment">比如192.168.1.100</p>
</td>
</tr>
<tr>
<td>SSH主机端口</td>
<td>
<input type="text" name="sshPort" maxlength="5" v-model="sshPort"/>
<p class="comment">比如22。</p>
</td>
</tr>
<tr>
<td>SSH登录认证</td>
<td>
<grant-selector :v-grant="grant"></grant-selector>
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</div>

View File

@@ -0,0 +1,60 @@
Tea.context(function () {
this.clusterId = 0;
if (this.node.cluster != null && this.node.cluster.id > 0) {
this.clusterId = this.node.cluster.id;
}
this.success = NotifySuccess("保存成功", "/clusters/cluster/node?clusterId=" + this.clusterId + "&nodeId=" + this.node.id);
// IP地址相关
this.ipAddresses = this.node.ipAddresses;
// 添加IP地址
this.addIPAddress = function () {
teaweb.popup("/nodes/ipAddresses/createPopup", {
callback: function (resp) {
this.ipAddresses.push(resp.data.ipAddress);
}
})
};
// 修改地址
this.updateIPAddress = function (index, address) {
teaweb.popup("/nodes/ipAddresses/updatePopup?addressId=" + address.id, {
callback: function (resp) {
Vue.set(this.ipAddresses, index, resp.data.ipAddress);
}
})
}
// 删除IP地址
this.removeIPAddress = function (index) {
this.ipAddresses.$remove(index);
};
// 认证相关
this.grant = null;
this.sshHost = "";
this.sshPort = "";
this.loginId = 0;
if (this.node.login != null) {
this.loginId = this.node.login.id;
if (this.node.login.params != null) {
this.sshHost = this.node.login.params.host;
if (this.node.login.params.port > 0) {
this.sshPort = this.node.login.params.port;
}
}
if (this.node.login.grant != null && typeof this.node.login.grant.id != "undefined") {
this.grant = {
id: this.node.login.grant.id,
name: this.node.login.grant.name,
method: this.node.login.grant.method,
methodName: this.node.login.grant.methodName
};
}
}
});

View File

@@ -0,0 +1,30 @@
{$layout}
{$template "/left_menu"}
<div class="right-box">
<h3>基础设置</h3>
<form class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="clusterId" :value="cluster.id"/>
<table class="ui table selectable definition">
<tr>
<td class="title">集群名称 *</td>
<td><input type="text" name="name" maxlength="50" ref="focus" v-model="cluster.name"/></td>
</tr>
<tr>
<td>默认SSH登录方式</td>
<td>
<grant-selector :v-grant="grant"></grant-selector>
<p class="comment">当节点没有单独设置SSH登录方式时默认使用此设置。</p>
</td>
</tr>
<tr>
<td>默认安装目录</td>
<td>
<input type="text" name="installDir" maxlength="100" v-model="cluster.installDir"/>
<p class="comment">当节点没有单独设置安装目录时,默认使用此设置。如果集群和节点都没有设置安装目录,则使用<span class="ui label tiny">/$登录用户/edge-node</span> 目录。</p>
</td>
</tr>
</table>
<submit-btn></submit-btn>
</form>
</div>

View File

@@ -0,0 +1,3 @@
Tea.context(function () {
this.success = NotifyReloadSuccess("保存成功")
})