Initial commit (code only without large binaries)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<second-menu>
|
||||
<menu-item :href="'/clusters/cluster?clusterId=' + clusterId">{{currentClusterName}}</menu-item>
|
||||
<raquo-item></raquo-item>
|
||||
<menu-item :href="'/clusters/cluster/settings?clusterId=' + clusterId">集群设置</menu-item>
|
||||
<raquo-item></raquo-item>
|
||||
<a class="item active" v-if="leftMenuActiveItem != null" :href="leftMenuActiveItem.url">"{{leftMenuActiveItem.name}}"设置</a>
|
||||
</second-menu>
|
||||
20
EdgeAdmin/web/views/@default/clusters/cluster/settings/cache/index.html
vendored
Normal file
20
EdgeAdmin/web/views/@default/clusters/cluster/settings/cache/index.html
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">选择缓存策略 *</td>
|
||||
<td>
|
||||
<http-cache-policy-selector :v-cache-policy="cachePolicy"></http-cache-policy-selector>
|
||||
<p class="comment">部署在当前集群上的所有网站都会自动使用此策略,只是服务可以自定义是否开启。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
3
EdgeAdmin/web/views/@default/clusters/cluster/settings/cache/index.js
vendored
Normal file
3
EdgeAdmin/web/views/@default/clusters/cluster/settings/cache/index.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,109 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用CC防护功能</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="httpCCPolicy.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示当前集群下的网站可以使用CC防护功能。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="httpCCPolicy.isOn">
|
||||
<tr v-for="(defaultThreshold, index) in defaultThresholds">
|
||||
<td>检测阈值{{index+1}}</td>
|
||||
<td>
|
||||
<table class="ui table">
|
||||
<tr>
|
||||
<td class="title">计算周期</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="thresholdPeriodSeconds" style="width: 5em" maxlength="4" v-model="thresholds[index].periodSeconds"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">0表示默认,默认{{defaultThreshold.periodSeconds}}秒。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>最大请求数</td>
|
||||
<td>
|
||||
<input type="text" name="thresholdMaxRequests" style="width: 6em" maxlength="5" v-model="thresholds[index].maxRequests"/>
|
||||
<p class="comment">0表示默认,默认{{defaultThreshold.maxRequests}}。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>拦截时间</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="thresholdBlockSeconds" style="width: 5em" maxlength="4" v-model="thresholds[index].blockSeconds"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">0表示默认,默认{{defaultThreshold.blockSeconds}}秒。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="comment"><pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>单IP最大并发连接数</td>
|
||||
<td>
|
||||
<input type="text" name="maxConnectionsPerIP" v-model="httpCCPolicy.maxConnectionsPerIP" maxlength="6" style="width: 6em"/>
|
||||
<p class="comment">如果为0表示使用默认,默认为{{defaultHTTPCCPolicyMaxConnectionsPerIP}}。<pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳转检测路径</td>
|
||||
<td>
|
||||
<input type="text" name="redirectsCheckingValidatePath" v-model="httpCCPolicy.redirectsChecking.validatePath"/>
|
||||
<p class="comment">如果不填表示使用默认,默认为{{defaultHTTPCCPolicyRedirectsCheckingValidatePath}};必须是一个特殊的URL以避免用户访问异常。<pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳转检测周期</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" maxlength="4" style="width: 5em" name="redirectsCheckingDurationSeconds" v-model="httpCCPolicy.redirectsChecking.durationSeconds"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">如果为0表示使用默认,默认为{{defaultHTTPCCPolicyRedirectsCheckingDurationSeconds}}。<pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳转检测最多次数</td>
|
||||
<td>
|
||||
<input type="text" maxlength="4" style="width: 5em" name="redirectsCheckingMaxRedirects" v-model="httpCCPolicy.redirectsChecking.maxRedirects"/>
|
||||
<p class="comment">如果为0表示使用默认,默认为{{defaultHTTPCCPolicyRedirectsCheckingMaxRedirects}}。<pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>跳转检测拦截时间</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" maxlength="6" style="width: 6em" name="redirectsCheckingBlockSeconds" v-model="httpCCPolicy.redirectsChecking.blockSeconds"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">如果为0表示使用默认,默认为{{defaultHTTPCCPolicyRedirectsCheckingBlockSeconds}}。<pro-warning-label></pro-warning-label></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>防火墙拦截范围</td>
|
||||
<td>
|
||||
<select name="firewallScope" v-model="httpCCPolicy.firewall.scope" class="ui dropdown auto-width">
|
||||
<option value="global">所有网站</option>
|
||||
<option value="service">当前网站</option>
|
||||
</select>
|
||||
<p class="comment" v-if="httpCCPolicy.firewall.scope == 'global'">“所有网站”表示IP被拦截时,将被阻止访问所有网站;此时系统可以自动尝试利用本地防火墙提升拦截效率。</p>
|
||||
<p class="comment" v-if="httpCCPolicy.firewall.scope == 'service'">“当前网站”表示IP被拦截时,只会阻止访问当前网站;选择此选项会严重影响拦截效率,建议只有特殊情况下才使用。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,19 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item :href="'.?clusterId=' + clusterId" class="active">设置</menu-item>
|
||||
<menu-item :href="'.status?clusterId=' + clusterId" >状态</menu-item>
|
||||
</first-menu>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
|
||||
<node-ddos-protection-config-box :v-ddos-protection-config="config" :v-default-configs="defaultConfigs"></node-ddos-protection-config-box>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item :href="'.?clusterId=' + clusterId">设置</menu-item>
|
||||
<menu-item :href="'.status?clusterId=' + clusterId" class="active">状态</menu-item>
|
||||
</first-menu>
|
||||
|
||||
<loading-message v-if="isLoading">检查中,请耐心等待完成...</loading-message>
|
||||
|
||||
<p class="comment" v-if="!isLoading && results.length == 0">当前集群下暂时还没有节点。</p>
|
||||
|
||||
<table class="ui table selectable" v-if="results.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="three wide">节点名称</th>
|
||||
<th>检查结果</th>
|
||||
<th class="two op">独立设置</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-for="result in results">
|
||||
<tr>
|
||||
<td>
|
||||
<a :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + result.nodeId">{{result.nodeName}}</a>
|
||||
<div v-if="result.isPrior">
|
||||
<a :href="'/clusters/cluster/node/settings/ddos-protection?clusterId=' + clusterId + '&nodeId=' + result.nodeId"><grey-label>定制</grey-label></a>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span class="green" v-if="result.isOk">{{result.message}}</span>
|
||||
<span class="red" v-if="!result.isOk">{{result.message}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<a :href="'/clusters/cluster/node/settings/ddos-protection?clusterId=' + clusterId + '&nodeId=' + result.nodeId">设置</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="margin"></div>
|
||||
<a href="" @click.prevent="reload">[刷新]</a>
|
||||
</div>
|
||||
@@ -0,0 +1,20 @@
|
||||
Tea.context(function () {
|
||||
this.isLoading = true
|
||||
this.results = []
|
||||
|
||||
this.$delay(function () {
|
||||
this.reload()
|
||||
})
|
||||
|
||||
this.reload = function () {
|
||||
this.isLoading = true
|
||||
this.$post("$")
|
||||
.params({ clusterId: this.clusterId })
|
||||
.success(function (resp) {
|
||||
this.results = resp.data.results
|
||||
})
|
||||
.done(function () {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
<first-menu>
|
||||
<menu-item :href="'.?clusterId=' + clusterId" code="index">DNS设置</menu-item>
|
||||
<menu-item :href="'.records?clusterId=' + clusterId" code="records">解析记录</menu-item>
|
||||
</first-menu>
|
||||
@@ -0,0 +1,101 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td>选择主域名 *</td>
|
||||
<td>
|
||||
<div v-if="hasDomains">
|
||||
<dns-domain-selector :v-domain-id="domainId" :v-domain-name="domainName" :v-provider-name="domainProvider.name" @change="changeDomain"></dns-domain-selector>
|
||||
<p class="comment">用于生成集群节点和网站的CNAME和DNS解析记录<span v-if="domainId > 0">,修改后将自动删除旧域名中的相关记录</span>。</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
没有可用的域名,请在 <a href="/dns/providers" target="_blank">[域名解析]</a> 中添加。
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="oldDomain.id > 0 && domain.id == 0">
|
||||
<td>不使用主域名</td>
|
||||
<td>
|
||||
<checkbox name="confirmResetDomain"></checkbox>
|
||||
<p class="comment">选中后,表示确认当前集群不使用主域名;否则必须选择一个主域名。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">DNS子域名 *</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="dnsName" maxlength="64" style="width:12em" v-model="dnsName"/>
|
||||
<span class="ui label" v-if="domain != null && domain.name != null && domain.name.length > 0">.{{domain.name}}</span>
|
||||
<span class="ui label" v-else>.主域名</span>
|
||||
</div>
|
||||
<p class="comment">当前集群的子域名,和主域名一起组成集群节点的子域名,修改后将自动删除旧域名中的相关记录。<a href="" @click.prevent="generateRandName()">[随机生成]</a>。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动设置CNAME记录<optional-label></optional-label></td>
|
||||
<td>
|
||||
<values-box :values="cnameRecords" name="cnameRecords" placeholder="记录名" ref="cnameRecords"></values-box>
|
||||
<p class="comment">除集群已创建的网站之外,自动解析到集群的CNAME记录,比如<code-label @click.prevent="addCnameRecord('www')">www</code-label>。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>允许通过CNAME访问网站</td>
|
||||
<td>
|
||||
<checkbox name="cnameAsDomain" v-model="cnameAsDomain"></checkbox>
|
||||
<p class="comment">选中后,表示允许使用CNAME直接访问网站;如果取消选中,则表示CNAME只作为DNS解析记录使用。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="teaIsPlus">
|
||||
<td>包含Ln节点</td>
|
||||
<td>
|
||||
<checkbox name="includingLnNodes" v-model="includingLnNodes"></checkbox>
|
||||
<p class="comment">选中后,表示域名解析中包含L2及以上级别节点,也就意味着用户请求可能会被分配到这些节点。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>解析记录TTL</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="ttl" maxlength="6" style="width: 6em" v-model="ttl"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">每个DNS服务商或者账号的TTL限制各有不同,请注意取值范围;修改后,只对新的解析记录生效。0表示使用默认。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<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>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
|
||||
this.domain = {id: this.domainId, name: this.domainName}
|
||||
this.oldDomain = {id: this.domainId, name: this.domainName}
|
||||
this.changeDomain = function (domain) {
|
||||
this.domain.id = domain.id
|
||||
this.domain.name = domain.name
|
||||
}
|
||||
|
||||
this.addCnameRecord = function (name) {
|
||||
this.$refs.cnameRecords.addValue(name)
|
||||
}
|
||||
|
||||
this.generateRandName = function () {
|
||||
this.$post(".randomName")
|
||||
.success(function (resp) {
|
||||
this.dnsName = resp.data.name
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,203 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">DNS子域名</td>
|
||||
<td>
|
||||
<span v-if="dnsInfo.domainName.length > 0"><var>{{dnsInfo.dnsName}}</var>.{{dnsInfo.domainName}}</span>
|
||||
<span v-else class="disabled">没有设置</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DNS服务商</td>
|
||||
<td>
|
||||
<div v-if="dnsInfo.providerName.length > 0">
|
||||
<link-icon :href="'/dns/providers/provider?providerId=' + dnsInfo.providerId">{{dnsInfo.providerTypeName}} - {{dnsInfo.providerName}}</link-icon>
|
||||
</div>
|
||||
<span v-else-if="dnsInfo.domainName.length == 0" class="disabled">请先设置域名</span>
|
||||
<span v-else class="disabled">没有设置</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动设置CNAME记录</td>
|
||||
<td>
|
||||
<span v-if="dnsInfo.cnameRecords.length == 0" class="disabled">暂时还没有设置。</span>
|
||||
<div v-else>
|
||||
<span v-for="record in dnsInfo.cnameRecords" class="ui label basic small">{{record}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="dnsInfo.domainName.length > 0">
|
||||
<td>操作</td>
|
||||
<td>
|
||||
<div v-if="!isSyncing">
|
||||
<link-red v-if="dnsHasChanges" @click.prevent="syncCluster(cluster.id)">检测到解析记录有变化,需要同步</link-red>
|
||||
<a href="" @click.prevent="syncCluster(cluster.id)" v-else>DNS服务商同步</a>
|
||||
</div>
|
||||
<span v-else>DNS服务商同步中...</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 当前任务 -->
|
||||
<div v-if="tasks.length > 0">
|
||||
<h3>正在执行的任务</h3>
|
||||
<table class="ui table selectable celled">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>对象</th>
|
||||
<th>任务</th>
|
||||
<th>状态</th>
|
||||
<th>触发时间</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="task in tasks">
|
||||
<td>
|
||||
<span v-if="(task.type == 'clusterChange' || task.type == 'clusterNodesChange') && task.cluster != null">{{task.cluster.name}}
|
||||
<link-icon :href="'/dns/clusters/cluster?clusterId=' + task.cluster.id" target="_top"></link-icon>
|
||||
</span>
|
||||
<span v-if="task.type == 'nodeChange'">{{task.node.name}}</span>
|
||||
<span v-if="task.type == 'serverChange'">{{task.server.name}}</span>
|
||||
<span v-if="task.type == 'domainChange'">{{task.domain.name}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="task.type == 'clusterChange' || task.type == 'clusterNodesChange'">集群</span>
|
||||
<span v-if="task.type == 'nodeChange'">节点</span>
|
||||
<span v-if="task.type == 'serverChange'">网站</span>
|
||||
<span v-if="task.type == 'domainChange'">域名</span>
|
||||
</td>
|
||||
<td style="word-break: break-word; width: 26em">
|
||||
<span v-if="task.isDone" class="red">{{task.error}}</span>
|
||||
<span v-else>正在同步...</span>
|
||||
</td>
|
||||
<td>{{task.updatedTime}}</td>
|
||||
<td>
|
||||
<a href="" title="删除" class="remove-btn" @click.prevent="deleteTask(task.id)"><i class="icon remove small grey"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 问题合集 -->
|
||||
<div v-if="issues.length > 0">
|
||||
<h3>需要修复的问题</h3>
|
||||
<table class="ui table selectable celled" v-if="issues.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 50%">问题对象</th>
|
||||
<th>问题描述</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="issue in issues">
|
||||
<td>
|
||||
<div v-if="issue.type == 'cluster'">
|
||||
集群 "{{issue.target}}" <link-icon :href="'/clusters/cluster?clusterId=' + issue.targetId"></link-icon>
|
||||
</div>
|
||||
<div v-if="issue.type == 'node'">
|
||||
集群 "{{issue.params.clusterName}}" 节点 "{{issue.target}}" <link-icon :href="'/clusters/cluster/node?clusterId=' + issue.params.clusterId + '&nodeId=' + issue.targetId"></link-icon>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span>{{issue.description}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="issue.type == 'cluster'">
|
||||
<link-red @click.prevent="updateCluster(issue.targetId)">修复</link-red>
|
||||
</div>
|
||||
<div v-if="issue.type == 'node'">
|
||||
<link-red @click.prevent="updateNode(issue.params.clusterId, issue.targetId)">修复</link-red>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="margin"></div>
|
||||
</div>
|
||||
|
||||
<p class="comment">下面的DNS解析记录也可以手工在DNS服务商提供的管理平台添加。</p>
|
||||
|
||||
<!-- 节点DNS解析记录 -->
|
||||
<h3>节点DNS解析记录 <span> ({{nodes.length}}个)</span></h3>
|
||||
<p class="comment" v-if="nodes.length == 0">暂时没有需要设置的DNS记录。</p>
|
||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点</th>
|
||||
<th>子域名</th>
|
||||
<th>记录类型</th>
|
||||
<th>记录值</th>
|
||||
<th>线路</th>
|
||||
<th>状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="node in nodes">
|
||||
<td><link-icon :href="'/clusters/cluster/node?clusterId=' + node.clusterId + '&nodeId=' + node.id">{{node.name}}</link-icon></td>
|
||||
<td>
|
||||
<span v-if="dnsInfo.dnsName.length > 0">{{dnsInfo.dnsName}}</span>
|
||||
<link-red v-else @click.prevent="updateCluster(cluster.id)">没有设置</link-red>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.ipAddr.indexOf(':') > -1">AAAA</span>
|
||||
<span v-else>A</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.ipAddr.length > 0">{{node.ipAddr}}</span>
|
||||
<link-red title="点击设置" v-else @click.prevent="updateNode(node.clusterId, node.id, node.ipAddrId)">没有设置</link-red>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.route.code.length > 0">{{node.route.name}}</span>
|
||||
<link-red v-else title="点击设置" @click.prevent="updateNode(node.clusterId, node.id, node.ipAddrId)">没有设置</link-red>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.isBackup" class="red">备用节点</span>
|
||||
<span v-else-if="node.isOffline" class="red">已下线</span>
|
||||
<div v-else="">
|
||||
<span v-if="node.isInstalled">
|
||||
<span class="green" v-if="node.isResolved">已解析</span>
|
||||
<span v-else class="red">未解析</span>
|
||||
</span>
|
||||
<link-red :href="'/clusters/cluster/node/install?clusterId=' + cluster.id + '&nodeId=' + node.id" v-if="!node.isInstalled" title="节点未安装"><span class="red">未安装</span></link-red>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<link-popup @click.prevent="updateNode(node.clusterId, node.id, node.ipAddrId)">修改</link-popup>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 网站解析记录 -->
|
||||
<h3>网站解析记录 <span> ({{servers.length}}个)</span></h3>
|
||||
<p class="comment" v-if="servers.length == 0">暂时没有需要设置的DNS记录。</p>
|
||||
<table class="ui table selectable celled" v-if="servers.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>网站</th>
|
||||
<th>子域名</th>
|
||||
<th>记录类型</th>
|
||||
<th>记录值</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="server in servers">
|
||||
<td><link-icon :href="'/servers/server?serverId=' + server.id">{{server.name}}</link-icon> </td>
|
||||
<td>{{server.dnsName}}</td>
|
||||
<td>CNAME</td>
|
||||
<td>
|
||||
<span v-if="dnsInfo.domainName.length > 0"><var>{{dnsInfo.dnsName}}</var>.{{dnsInfo.domainName}}.</span>
|
||||
<link-red title="点击设置" v-else @click.prevent="updateCluster(cluster.id)">没有设置</link-red>
|
||||
</td>
|
||||
<td>
|
||||
<span class="green" v-if="server.isResolved">已解析</span>
|
||||
<span v-else class="red">未解析</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,56 @@
|
||||
Tea.context(function () {
|
||||
this.updateCluster = function (clusterId) {
|
||||
teaweb.popup("/dns/updateClusterPopup?clusterId=" + clusterId, {
|
||||
height: "25em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.updateNode = function (clusterId, nodeId, ipAddrId) {
|
||||
teaweb.popup("/dns/issues/updateNodePopup?clusterId=" + clusterId + "&nodeId=" + nodeId + "&ipAddrId=" + (ipAddrId ? ipAddrId : 0), {
|
||||
width: "46em",
|
||||
height: "26em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.isSyncing = false
|
||||
this.syncCluster = function (clusterId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要执行数据同步吗?", function () {
|
||||
that.isSyncing = true
|
||||
that.$post("/dns/clusters/sync")
|
||||
.params({clusterId: clusterId})
|
||||
.done(function () {
|
||||
that.isSyncing = false
|
||||
that.dnsHasChanges = false
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.success("同步成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteTask = function (taskId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个任务吗?", function () {
|
||||
that.$post("/dns/tasks/delete")
|
||||
.params({
|
||||
taskId: taskId
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,5 @@
|
||||
.white-span {
|
||||
background: white;
|
||||
border: 1px;
|
||||
}
|
||||
/*# sourceMappingURL=createPopup.css.map */
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["createPopup.less"],"names":[],"mappings":"AAAA;EACC,iBAAA;EACA,WAAA","file":"createPopup.css"}
|
||||
@@ -0,0 +1,130 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>添加动作</h3>
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="name" maxlength="50" ref="focus"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>级别</td>
|
||||
<td>
|
||||
<firewall-event-level-options :v-value="'critical'"></firewall-event-level-options>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>类型</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="type" v-model="type">
|
||||
<option value="">[请选择]</option>
|
||||
<option v-for="type in actionTypes" :value="type.code">{{type.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{typeDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- IPSet -->
|
||||
<tbody v-if="type == 'ipset'">
|
||||
<tr>
|
||||
<td>IPv4白名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetWhiteName" value="edge_white_list" maxlength="64"/>
|
||||
<p class="comment"><span class="ui label basic grey tiny">白名单</span> 用来存放<span class="red">IPv4地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv6白名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetWhiteNameIPv6" value="edge_white_list_ipv6" maxlength="64"/>
|
||||
<p class="comment"><span class="ui label basic grey tiny">白名单</span> 用来存放<span class="red">IPv6地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv4黑名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetBlackName" value="edge_black_list" maxlength="64"/>
|
||||
<p class="comment"><span class="ui label black tiny">黑名单</span> 用来存放<span class="red">IPv4地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv6 黑名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetBlackNameIPv6" value="edge_black_list_ipv6" maxlength="64"/>
|
||||
<p class="comment"><span class="ui label black tiny">黑名单</span> 用来存放<span class="red">IPv6地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>创建IPTables规则</td>
|
||||
<td>
|
||||
<checkbox name="ipsetAutoAddToIPTables" :value="true"></checkbox>
|
||||
<p class="comment">是否尝试自动创建包含有此IPSet的IPTables规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>创建Firewalld规则</td>
|
||||
<td>
|
||||
<checkbox name="ipsetAutoAddToFirewalld" :value="true"></checkbox>
|
||||
<p class="comment">是否尝试自动创建包含有此IPSet的Firewalld规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- Firewalld -->
|
||||
<tbody v-if="type == 'firewalld'">
|
||||
|
||||
</tbody>
|
||||
|
||||
<!-- IPTables -->
|
||||
<tbody v-if="type == 'iptables'">
|
||||
|
||||
</tbody>
|
||||
|
||||
<!-- 脚本 -->
|
||||
<tbody v-if="type == 'script'">
|
||||
<tr>
|
||||
<td>脚本路径 *</td>
|
||||
<td>
|
||||
<input type="text" name="scriptPath" maxlength="200"/>
|
||||
<p class="comment">可执行脚本文件的完整路径。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- HTTP API -->
|
||||
<tbody v-if="type == 'httpAPI'">
|
||||
<tr>
|
||||
<td>API URL *</td>
|
||||
<td>
|
||||
<input type="text" name="httpAPIURL" maxlength="200" placeholder="http|https://..."/>
|
||||
<p class="comment">完整的API地址。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- HTML -->
|
||||
<tbody v-if="type == 'html'">
|
||||
<tr>
|
||||
<td>HTML内容 *</td>
|
||||
<td>
|
||||
<textarea name="htmlContent" maxlength="128000" placeholder="完整的HTML内容"><!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 这里写提示文字 -->
|
||||
|
||||
</body>
|
||||
</html></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -0,0 +1,30 @@
|
||||
Tea.context(function () {
|
||||
this.$delay(function () {
|
||||
let that = this
|
||||
|
||||
// 类型
|
||||
this.$watch("type", function () {
|
||||
that.changeType()
|
||||
})
|
||||
|
||||
this.changeType()
|
||||
})
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
this.type = ""
|
||||
this.typeDescription = ""
|
||||
|
||||
this.changeType = function () {
|
||||
let that = this
|
||||
let t = this.actionTypes.$find(function (k, v) {
|
||||
return v.code == that.type
|
||||
})
|
||||
if (t != null) {
|
||||
this.typeDescription = t.description
|
||||
} else {
|
||||
this.typeDescription = ""
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,37 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item @click.prevent="createAction">添加动作</menu-item>
|
||||
<span class="item disabled">|</span>
|
||||
<span class="item"><tip-icon content="可以设置WAF中的规则集和IP名单中的IP级别,从而在匹配时触发对应的动作。"></tip-icon></span>
|
||||
</first-menu>
|
||||
|
||||
<div class="margin"></div>
|
||||
<div v-if="!hasActions">
|
||||
<p class="comment">暂时还没有自定义动作。</p>
|
||||
</div>
|
||||
<div v-for="level in levels" v-if="level.actions.length > 0">
|
||||
<h4 style="margin-bottom: 0">{{level.name}}级别</h4>
|
||||
<p class="comment" v-if="level.actions.length == 0">暂时还没有定义动作。</p>
|
||||
<table class="ui table selectable" v-if="level.actions.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>名称</th>
|
||||
<th class="four wide">类型</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="action in level.actions">
|
||||
<td>{{action.name}}</td>
|
||||
<td>{{action.typeName}}</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="updateAction(action.id)">修改</a> <a href="" @click.prevent="deleteAction(action.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
Tea.context(function () {
|
||||
this.createAction = function () {
|
||||
teaweb.popup(Tea.url(".createPopup", {clusterId: this.clusterId}), {
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.updateAction = function (actionId) {
|
||||
teaweb.popup(Tea.url(".updatePopup", {actionId: actionId}), {
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteAction = function (actionId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除此动作吗?", function () {
|
||||
that.$post(".delete")
|
||||
.params({
|
||||
actionId: actionId
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.success("删除成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,121 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改动作</h3>
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="actionId" :value="action.id"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="name" maxlength="50" ref="focus" v-model="action.name"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>级别</td>
|
||||
<td>
|
||||
<firewall-event-level-options :v-value="eventLevel"></firewall-event-level-options>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>类型</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="type" v-model="type">
|
||||
<option value="">[请选择]</option>
|
||||
<option v-for="type in actionTypes" :value="type.code">{{type.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{typeDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- IPSet -->
|
||||
<tbody v-if="type == 'ipset'">
|
||||
<tr>
|
||||
<td>IPv4白名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetWhiteName" value="edge_white_list" maxlength="64" v-model="action.params.whiteName"/>
|
||||
<p class="comment"><span class="ui label basic grey tiny">白名单</span> 用来存放<span class="red">IPv4地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv6白名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetWhiteNameIPv6" value="edge_white_list_ipv6" maxlength="64" v-model="action.params.whiteNameIPv6"/>
|
||||
<p class="comment"><span class="ui label basic grey tiny">白名单</span> 用来存放<span class="red">IPv6地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv4黑名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetBlackName" value="edge_black_list" maxlength="64" v-model="action.params.blackName"/>
|
||||
<p class="comment"><span class="ui label black tiny">黑名单</span> 用来存放<span class="red">IPv4地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IPv6 黑名单名称 *</td>
|
||||
<td>
|
||||
<input type="text" name="ipsetBlackNameIPv6" value="edge_black_list_ipv6" maxlength="64" v-model="action.params.blackNameIPv6"/>
|
||||
<p class="comment"><span class="ui label black tiny">黑名单</span> 用来存放<span class="red">IPv6地址</span>。只能是英文、数字、下划线的组合。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>创建IPTables规则</td>
|
||||
<td>
|
||||
<checkbox name="ipsetAutoAddToIPTables" v-model="action.params.autoAddToIPTables"></checkbox>
|
||||
<p class="comment">是否尝试自动创建包含有此IPSet的IPTables规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>创建Firewalld规则</td>
|
||||
<td>
|
||||
<checkbox name="ipsetAutoAddToFirewalld" v-model="action.params.autoAddToFirewalld"></checkbox>
|
||||
<p class="comment">是否尝试自动创建包含有此IPSet的Firewalld规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- Firewalld -->
|
||||
<tbody v-if="type == 'firewalld'">
|
||||
|
||||
</tbody>
|
||||
|
||||
<!-- IPTables -->
|
||||
<tbody v-if="type == 'iptables'">
|
||||
|
||||
</tbody>
|
||||
|
||||
<!-- 脚本 -->
|
||||
<tbody v-if="type == 'script'">
|
||||
<tr>
|
||||
<td>脚本路径 *</td>
|
||||
<td>
|
||||
<input type="text" name="scriptPath" maxlength="200" v-model="action.params.path"/>
|
||||
<p class="comment">可执行脚本文件的完整路径。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- HTTP API -->
|
||||
<tbody v-if="type == 'httpAPI'">
|
||||
<tr>
|
||||
<td>API URL *</td>
|
||||
<td>
|
||||
<input type="text" name="httpAPIURL" maxlength="200" placeholder="http|https://..." v-model="action.params.url"/>
|
||||
<p class="comment">完整的API地址。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<!-- HTML -->
|
||||
<tbody v-if="type == 'html'">
|
||||
<tr>
|
||||
<td>HTML内容 *</td>
|
||||
<td>
|
||||
<textarea name="htmlContent" maxlength="128000" placeholder="完整的HTML内容" v-model="action.params.content"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -0,0 +1,35 @@
|
||||
Tea.context(function () {
|
||||
this.$delay(function () {
|
||||
let that = this
|
||||
|
||||
// 类型
|
||||
this.$watch("type", function () {
|
||||
that.changeType()
|
||||
})
|
||||
|
||||
this.changeType()
|
||||
})
|
||||
|
||||
/**
|
||||
* 级别
|
||||
*/
|
||||
this.eventLevel = this.action.eventLevel
|
||||
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
this.type = this.action.type
|
||||
this.typeDescription = ""
|
||||
|
||||
this.changeType = function () {
|
||||
let that = this
|
||||
let t = this.actionTypes.$find(function (k, v) {
|
||||
return v.code == that.type
|
||||
})
|
||||
if (t != null) {
|
||||
this.typeDescription = t.description
|
||||
} else {
|
||||
this.typeDescription = ""
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,313 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<second-menu>
|
||||
<a v-for="item in titleMenus" :class="{active: item.id == currentItem}" :href="'#' + item.id" class="item" @click="selectItem(item)">{{item.name}}</a>
|
||||
</second-menu>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success" id="global-config-form">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
|
||||
<div v-show="currentItem == 'title-server-name-bind'">
|
||||
<h4 id="title-server-name-bind">域名绑定</h4>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">禁止未绑定域名访问</td>
|
||||
<td>
|
||||
<checkbox name="httpAllMatchDomainStrictly" v-model="config.httpAll.matchDomainStrictly"></checkbox>
|
||||
<p class="comment">选中后,表示禁止未在网站绑定的域名和IP访问。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="config.httpAll.matchDomainStrictly">
|
||||
<td class="color-border">处理未绑定域名方式</td>
|
||||
<td>
|
||||
<radio name="httpAllDomainMismatchActionCode" :v-value="'page'" v-model="httpAllDomainMismatchActionCode">显示提示页面</radio>
|
||||
<radio name="httpAllDomainMismatchActionCode" :v-value="'redirect'" v-model="httpAllDomainMismatchActionCode">跳转到网址</radio>
|
||||
<radio name="httpAllDomainMismatchActionCode" :v-value="'close'" v-model="httpAllDomainMismatchActionCode">关闭连接</radio>
|
||||
|
||||
<p class="comment" v-if="httpAllDomainMismatchActionCode == 'page'">显示提示内容。</p>
|
||||
<p class="comment" v-if="httpAllDomainMismatchActionCode == 'redirect'">跳转到一个特定URL。</p>
|
||||
<p class="comment" v-if="httpAllDomainMismatchActionCode == 'close'">直接关闭网络连接,不提示任何内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="config.httpAll.matchDomainStrictly && httpAllDomainMismatchActionCode == 'page'">
|
||||
<td class="color-border">提示页面状态码</td>
|
||||
<td>
|
||||
<input type="text" name="httpAllDomainMismatchActionStatusCode" v-model="httpAllDomainMismatchActionStatusCode" style="width: 4em" maxlength="3"/>
|
||||
<p class="comment">访问未绑定域名时的提示页面状态码,默认404。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="config.httpAll.matchDomainStrictly && httpAllDomainMismatchActionCode == 'page'">
|
||||
<td class="color-border">提示页面内容</td>
|
||||
<td>
|
||||
<textarea rows="3" name="httpAllDomainMismatchActionContentHTML" v-model="httpAllDomainMismatchActionContentHTML"></textarea>
|
||||
<p class="comment">访问未绑定的域名时提示页面内容,可以使用HTML;仅限于HTTP请求,不适于用HTTPS(HTTPS会提示证书错误)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="config.httpAll.matchDomainStrictly && httpAllDomainMismatchActionCode == 'redirect'">
|
||||
<td class="color-border">跳转目标网址URL *</td>
|
||||
<td>
|
||||
<input type="text" placeholder="https://..." name="httpAllDomainMismatchActionRedirectURL" v-model="httpAllDomainMismatchActionRedirectURL"/>
|
||||
<p class="comment">必须以http://或者https://开头,支持使用变量。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="config.httpAll.matchDomainStrictly">
|
||||
<td>允许例外的域名</td>
|
||||
<td>
|
||||
<domains-box name="httpAllAllowMismatchDomainsJSON" :v-domains="config.httpAll.allowMismatchDomains"></domains-box>
|
||||
<p class="comment">允许这些域名不经过绑定就可以直接访问网站。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="config.httpAll.matchDomainStrictly">
|
||||
<td>默认域名</td>
|
||||
<td>
|
||||
<input type="text" name="httpAllDefaultDomain" v-model="config.httpAll.defaultDomain"/>
|
||||
<p class="comment">例外域名或使用节点IP访问时使用的默认域名;如果指定的域名在集群里已经绑定到某个网站,则相当于直接访问该网站。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr v-show="config.httpAll.matchDomainStrictly">
|
||||
<td class="color-border">允许使用节点IP访问</td>
|
||||
<td>
|
||||
<checkbox name="httpAllAllowNodeIP" v-model="config.httpAll.allowNodeIP"></checkbox>
|
||||
<p class="comment">选中后,表示允许直接使用节点IP访问网站。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="config.httpAll.matchDomainStrictly && config.httpAll.allowNodeIP">
|
||||
<td class="color-border">访问节点IP显示自定义内容</td>
|
||||
<td>
|
||||
<checkbox name="httpAllNodeIPShowPage" v-model="config.httpAll.nodeIPShowPage"></checkbox>
|
||||
<p class="comment">选中后,表示用户访问节点IP时显示自定义内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="config.httpAll.matchDomainStrictly && config.httpAll.nodeIPShowPage">
|
||||
<td class="color-border">访问节点IP自定义内容</td>
|
||||
<td>
|
||||
<textarea name="httpAllNodeIPPageHTML" v-model="config.httpAll.nodeIPPageHTML" rows="3" placeholder="访问节点IP时要显示的自定义内容"></textarea>
|
||||
<p class="comment">访问节点IP时要显示的自定义内容,支持HTML。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="teaIsPlus && currentItem == 'title-server-name-auditing'">
|
||||
<h4 id="title-server-name-auditing" v-if="teaIsPlus">域名审核</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">域名变更时需要审核</td>
|
||||
<td>
|
||||
<checkbox name="httpAllDomainAuditingIsOn" v-model="config.httpAll.domainAuditingIsOn"></checkbox>
|
||||
<p class="comment">选中后,用户在创建和修改域名时需要管理员审核通过才能生效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="config.httpAll.domainAuditingIsOn">
|
||||
<td>审核提示</td>
|
||||
<td>
|
||||
<input name="httpAllDomainAuditingPrompt" type="text" v-model="config.httpAll.domainAuditingPrompt" maxlength="200"/>
|
||||
<p class="comment">提示用户需要审核的文字说明。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="currentItem == 'title-access-log'">
|
||||
<h4 id="title-access-log">访问日志</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td>允许记录访问日志</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogIsOn" v-model="config.httpAccessLog.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示允许当前集群下的网站记录访问日志,否则当前集群下的所有网站都不会记录访问日志。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>记录请求报头</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogEnableRequestHeaders" v-model="config.httpAccessLog.enableRequestHeaders"></checkbox>
|
||||
<p class="comment">选中后,表示在访问日志中记录请求报头。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">只记录通用请求报头</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogCommonRequestHeadersOnly" v-model="config.httpAccessLog.commonRequestHeadersOnly"></checkbox>
|
||||
<p class="comment">选中后,表示访问日志中只记录通用的HTTP请求报头(比如<code-label>User-Agent</code-label>),其他自定义或非标准的(比如<code-label>Test-Header</code-label>)将不记录。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>记录响应报头</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogEnableResponseHeaders" v-model="config.httpAccessLog.enableResponseHeaders"></checkbox>
|
||||
<p class="comment">选中后,表示在访问日志中记录响应报头。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>记录Cookie</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogEnableCookies" v-model="config.httpAccessLog.enableCookies"></checkbox>
|
||||
<p class="comment">选中后,表示访问日志中记录Cookie内容。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>记录找不到网站日志</td>
|
||||
<td>
|
||||
<checkbox name="httpAccessLogEnableServerNotFound" v-model="config.httpAccessLog.enableServerNotFound"></checkbox>
|
||||
<p class="comment">选中后,表示如果访客访问的域名对应的网站不存在也会记录日志。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="currentItem == 'title-server-log'">
|
||||
<h4 id="title-server-log">运行日志</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">记录网站错误</td>
|
||||
<td>
|
||||
<checkbox name="logRecordServerError" v-model="config.log.recordServerError"></checkbox>
|
||||
<p class="comment">在节点运行日志中记录网站相关错误详细信息,比如无法连接源站等,建议仅用于调试。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="currentItem == 'title-performance'">
|
||||
<h4 id="title-performance">性能</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">自动读数据超时</td>
|
||||
<td>
|
||||
<checkbox name="performanceAutoReadTimeout" v-model="config.performance.autoReadTimeout"></checkbox>
|
||||
<p class="comment">从客户端读取数据时自动设置超时时间,如果超时,则自动视为慢连接,并关闭网络连接;此为专业选项,请在专家指导下进行修改。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">自动写数据超时</td>
|
||||
<td>
|
||||
<checkbox name="performanceAutoWriteTimeout" v-model="config.performance.autoWriteTimeout"></checkbox>
|
||||
<p class="comment">向客户端发送数据时自动设置超时时间,如果超时,则自动视为慢连接,并关闭网络连接;此为专业选项,请在专家指导下进行修改。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>调试模式</td>
|
||||
<td>
|
||||
<checkbox name="performanceDebug" v-model="config.performance.debug"></checkbox>
|
||||
<p class="comment">开启调试模式后,将在某些信息中包含调试信息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="teaIsPlus && currentItem == 'title-ln'">
|
||||
<h4 id="title-ln" v-if="teaIsPlus">Ln节点</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td>强制Ln请求</td>
|
||||
<td>
|
||||
<checkbox name="httpAllForceLnRequest" v-model="config.httpAll.forceLnRequest"></checkbox>
|
||||
<p class="comment">选中后,所有请求优先发送到L2或者更高级别节点。默认不开启的情况下,只有可以缓存的内容请求才会发送到L2或者更高级别节点。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ln请求负载均衡方法</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="httpAllLnRequestSchedulingMethod" v-model="config.httpAll.lnRequestSchedulingMethod">
|
||||
<option value="urlMapping">URL映射</option>
|
||||
<option value="random">随机</option>
|
||||
</select>
|
||||
<p class="comment" v-if="config.httpAll.lnRequestSchedulingMethod == 'urlMapping'">当存在多个Ln节点时,将请求根据URL自动映射到某个固定的Ln节点。</p>
|
||||
<p class="comment" v-if="config.httpAll.lnRequestSchedulingMethod == 'random'">当存在多个Ln节点时,将请求随机发送到某个Ln节点。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="currentItem == 'title-tcp-udp'">
|
||||
<h4 id="title-tcp-udp">TCP/UDP相关</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">允许的端口范围</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" name="tcpAllPortRangeMin" maxlength="5" size="6" v-model="tcpAllPortRangeMin"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
-
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<input type="text" name="tcpAllPortRangeMax" maxlength="5" size="6" v-model="tcpAllPortRangeMax"/>
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">用户创建TCP/TLS负载均衡服务时可以随机选择的端口范围,最小不能小于1024,最大不能大于65534。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>排除的端口</td>
|
||||
<td>
|
||||
<values-box placeholder="端口" size="6" name="tcpAllDenyPorts" :values="tcpAllDenyPorts"></values-box>
|
||||
<p class="comment">当为用户随机分配端口时要排除的端口。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-show="currentItem == 'title-others'">
|
||||
<h4 id="title-others">其他</h4>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">服务器旗标</td>
|
||||
<td>
|
||||
<input type="text" name="httpAllServerName" v-model="config.httpAll.serverName" maxlength="60"/>
|
||||
<p class="comment">服务器旗标会以<code-label>Server: 旗标</code-label>的形式出现在响应报头中。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支持低版本HTTP</td>
|
||||
<td>
|
||||
<checkbox name="httpAllSupportsLowVersionHTTP" v-model="config.httpAll.supportsLowVersionHTTP"></checkbox>
|
||||
<p class="comment">选中后,表示支持HTTP/1.0、HTTP/0.9等低于HTTP/1.1版本的HTTP协议。低版本HTTP协议不支持分段传输内容,且无法保持连接,对系统性能有严重的负面影响。建议只有在你的用户正在使用非常老旧的设备时才启用此选项。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动匹配证书</td>
|
||||
<td>
|
||||
<checkbox name="httpAllMatchCertFromAllServers" v-model="config.httpAll.matchCertFromAllServers"></checkbox>
|
||||
<p class="comment">选中后,表示找不到证书时自动查找其他网站设置的证书。此功能仅仅为了兼容以往系统版本,可能会导致用户访问的网站混乱,所以请不要轻易启用。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支持${serverAddr}变量</td>
|
||||
<td>
|
||||
<checkbox name="httpAllEnableServerAddrVariable" v-model="config.httpAll.enableServerAddrVariable"></checkbox>
|
||||
<p class="comment">选中后,表示支持在自定义页面中使用<code-label>${serverAddr}</code-label>变量,用来表示访客当前正在访问的服务器地址。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动gzip回源</td>
|
||||
<td>
|
||||
<checkbox name="httpAllRequestOriginsWithEncodings" v-model="config.httpAll.requestOriginsWithEncodings"></checkbox>
|
||||
<p class="comment">选中后,表示自动使用<code-label>Accept-Encoding: gzip, ...</code-label>回源,可以用来节约源站流量。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XFF中最多地址数</td>
|
||||
<td>
|
||||
<input type="text" name="httpAllXFFMaxAddresses" v-model="config.httpAll.xffMaxAddresses"/>
|
||||
<p class="comment">可以转发的X-Forwarded-For中最多的地址数,如果为0表示不限制;不要轻易修改此选项,避免无法获取真实的客户端地址。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="margin"></div>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,47 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
|
||||
// Menu
|
||||
this.currentItem = ""
|
||||
|
||||
this.titleMenus = []
|
||||
this.$delay(function () {
|
||||
let elements = document.querySelectorAll("#global-config-form h4")
|
||||
this.currentItem = elements[0].getAttribute("id")
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let textContent = elements[i].textContent
|
||||
if (textContent == null || textContent.length == 0) {
|
||||
textContent = elements[i].innerText
|
||||
}
|
||||
let itemId = elements[i].getAttribute("id")
|
||||
if (window.location.hash == "#" + itemId) {
|
||||
this.currentItem = itemId
|
||||
}
|
||||
this.titleMenus.push({
|
||||
name: textContent,
|
||||
id: itemId
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.selectItem = function (item) {
|
||||
this.currentItem = item.id
|
||||
}
|
||||
|
||||
/**
|
||||
* TCP端口
|
||||
*/
|
||||
this.tcpAllPortRangeMin = 10000
|
||||
this.tcpAllPortRangeMax = 40000
|
||||
if (this.config.tcpAll.portRangeMin > 0) {
|
||||
this.tcpAllPortRangeMin = this.config.tcpAll.portRangeMin
|
||||
}
|
||||
if (this.config.tcpAll.portRangeMax > 0) {
|
||||
this.tcpAllPortRangeMax = this.config.tcpAll.portRangeMax
|
||||
}
|
||||
|
||||
this.tcpAllDenyPorts = []
|
||||
if (this.config.tcpAll.denyPorts != null) {
|
||||
this.tcpAllDenyPorts = this.config.tcpAll.denyPorts
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<health-check-config-box :v-health-check-config="healthCheckConfig" :v-check-domain-url="'/clusters/cluster/settings/health/checkDomain?clusterId=' + clusterId" :v-is-plus="teaIsPlus"></health-check-config-box>
|
||||
<submit-btn></submit-btn> <a href="" @click.prevent="run()" v-if="healthCheckConfig != null && healthCheckConfig.isOn">立即检查</a>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
|
||||
this.run = function () {
|
||||
teaweb.confirm("确定要对当前集群下的所有节点进行健康检查吗?", function () {
|
||||
teaweb.popup("/clusters/cluster/settings/health/runPopup?clusterId=" + this.clusterId, {
|
||||
height: "30em"
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,33 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>健康检查</h3>
|
||||
|
||||
<div v-show="!hasServers">
|
||||
<span class="red">当前集群尚未部署网站,无法进行健康检查;请至少部署至少一个网站后再试。</span>
|
||||
</div>
|
||||
<div v-show="hasServers">
|
||||
<span class="red" v-if="isRequesting">正在执行中,请等待执行完毕...</span>
|
||||
<span class="red" v-if="!isRequesting && errorString.length > 0">{{errorString}}</span>
|
||||
|
||||
<form method="post" class="ui form" v-if="!isRequesting && errorString.length == 0">
|
||||
<p>成功节点:<span class="green">{{countSuccess}}</span> 失败节点:<span class="red">{{countFail}}</span></p>
|
||||
<table class="ui table selectable celled" v-if="results.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点</th>
|
||||
<th>结果</th>
|
||||
<th nowrap="">耗时</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="result in results">
|
||||
<td>{{result.node.name}}<span class="small" v-if="result.nodeAddr != null && result.nodeAddr.length > 0">({{result.nodeAddr}})</span></td>
|
||||
<td>
|
||||
<span v-if="!result.isOk" class="red">失败:{{result.error}}</span>
|
||||
<span v-else class="green">成功</span>
|
||||
</td>
|
||||
<td>{{result.costMs}}ms</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button class="ui button primary" type="button" @click.prevent="success">完成</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,47 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
|
||||
this.isRequesting = true
|
||||
this.results = []
|
||||
this.countSuccess = 0
|
||||
this.countFail = 0
|
||||
this.errorString = ""
|
||||
|
||||
this.$delay(function () {
|
||||
if (this.hasServers) {
|
||||
this.run()
|
||||
}
|
||||
})
|
||||
|
||||
this.run = function () {
|
||||
this.isRequesting = true
|
||||
this.errorString = ""
|
||||
|
||||
this.$post("$")
|
||||
.params({
|
||||
clusterId: this.clusterId
|
||||
})
|
||||
.timeout(60)
|
||||
.success(function (resp) {
|
||||
this.results = resp.data.results
|
||||
let that = this
|
||||
this.results.forEach(function (v) {
|
||||
v.costMs = Math.ceil(v.costMs)
|
||||
if (isNaN(v.costMs)) {
|
||||
v.costMs = 0
|
||||
}
|
||||
if (v.isOk) {
|
||||
that.countSuccess++
|
||||
} else {
|
||||
that.countFail++
|
||||
}
|
||||
})
|
||||
})
|
||||
.error(function () {
|
||||
this.errorString = "执行健康检查超时,请重试"
|
||||
})
|
||||
.done(function () {
|
||||
this.isRequesting = false
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,4 @@
|
||||
<first-menu>
|
||||
<menu-item :href="'.?clusterId=' + clusterId" code="index">设置</menu-item>
|
||||
<menu-item :href="'.test?clusterId=' + clusterId" code="test">测试</menu-item>
|
||||
</first-menu>
|
||||
@@ -0,0 +1,38 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用HTTP/3功能</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="http3Policy.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示当前集群下的网站可以使用HTTP/3功能;单个网站可以在HTTPS设置页面里启用HTTP/3。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="http3Policy.isOn">
|
||||
<tr>
|
||||
<td>UDP端口</td>
|
||||
<td>
|
||||
<input type="text" style="width: 5em" maxlength="4" name="port" v-model="http3Policy.port"/>
|
||||
<p class="comment">HTTP/3通讯使用的UDP端口,范围在1-1024,请在服务器安全策略或者防火墙中设置此端口为通过。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>支持手机浏览器</td>
|
||||
<td>
|
||||
<checkbox name="supportMobileBrowsers" v-model="http3Policy.supportMobileBrowsers"></checkbox>
|
||||
<p class="comment">在手机浏览器上也尝试开启HTTP/3;当下部分手机浏览器对HTTP/3支持的并不完善,请根据自己的需要决定是否启用。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,59 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<div v-show="!http3Policy.isOn">
|
||||
<div class="margin"></div>
|
||||
<p class="ui message">当前集群尚未启用HTTP/3功能,不需要做任何测试。</p>
|
||||
</div>
|
||||
|
||||
<div v-show="http3Policy.isOn">
|
||||
<div class="margin"></div>
|
||||
<form class="ui form" data-tea-action="$" data-tea-before="before" data-tea-done="done" data-tea-success="success" data-tea-timeout="1800">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<input type="hidden" name="port" :value="http3Policy.port"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">测试网址 *</td>
|
||||
<td>
|
||||
<input type="text" name="url" ref="focus" placeholder="https://..."/>
|
||||
<p class="comment">即待测试的网址,<strong>需要确保对应的网站已经启用了HTTP/3功能</strong>;系统会自动访问每个节点上的网址内容,以便确定HTTP/3是否在此节点上工作正常。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn v-if="!isRequesting">开始测试</submit-btn>
|
||||
<button class="ui button disabled" type="button" v-if="isRequesting">测试中,请耐心等待...</button>
|
||||
</form>
|
||||
|
||||
<!-- 测试结果 -->
|
||||
<div v-if="isTested">
|
||||
<h4>测试结果 <a href="" @click.prevent="resetResults" style="font-size: 0.8em">[清除]</a> </h4>
|
||||
<p class="comment" v-if="results.length == 0">暂时还没有任何可以测试的节点。</p>
|
||||
<div v-if="results.length > 0">
|
||||
<table class="ui table celled selectable" style="width: 40em">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 18em">节点</th>
|
||||
<th style="width: 18em">IP</th>
|
||||
<th>测试结果</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="result in results">
|
||||
<td>{{result.nodeName}} <link-icon :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + result.nodeId"></link-icon></td>
|
||||
<td>{{result.ip}}</td>
|
||||
<td>
|
||||
<span class="green" v-if="result.isOk">成功</span>
|
||||
<span v-else class="red">失败 <tip-icon :content="result.error"></tip-icon></span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
Tea.context(function () {
|
||||
this.isRequesting = false
|
||||
|
||||
this.isTested = false
|
||||
this.results = []
|
||||
|
||||
this.before = function () {
|
||||
this.isRequesting = true
|
||||
this.isTested = false
|
||||
this.results = []
|
||||
}
|
||||
|
||||
this.success = function (resp) {
|
||||
this.isTested = true
|
||||
this.results = resp.data.results
|
||||
}
|
||||
|
||||
this.done = function () {
|
||||
this.isRequesting = false
|
||||
}
|
||||
|
||||
this.resetResults = function () {
|
||||
this.isTested = false
|
||||
this.results = []
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,147 @@
|
||||
{$layout}
|
||||
{$template "menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form method="post" 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 v-if="cluster.domainName.length > 0">
|
||||
<td>域名</td>
|
||||
<td>
|
||||
{{cluster.domainName}}<link-icon :href="'/clusters/cluster/settings/dns?clusterId=' + cluster.id"></link-icon>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>默认SSH认证</td>
|
||||
<td>
|
||||
<grant-selector :v-grant="grant"></grant-selector>
|
||||
<p class="comment">当节点没有单独设置SSH认证时,默认使用此设置。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>默认SSH端口</td>
|
||||
<td>
|
||||
<input type="text" name="sshParamsPort" v-model="cluster.sshParams.port" maxlength="5" style="width: 5em"/>
|
||||
<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">$登录用户HOME路径/edge-node</span> 目录。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>时区</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" v-model="timeZoneGroupCode">
|
||||
<option v-for="timeZoneGroup in timeZoneGroups" :value="timeZoneGroup.code">{{timeZoneGroup.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<select class="ui dropdown" name="timeZone" v-model="cluster.timeZone">
|
||||
<option v-for="timeZoneLocation in timeZoneLocations" :value="timeZoneLocation.name" v-if="timeZoneLocation.group == timeZoneGroupCode">{{timeZoneLocation.name}} ({{timeZoneLocation.offset}})</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">节点记录日志使用的时区。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>单节点最大线程数</td>
|
||||
<td>
|
||||
<input type="text" name="nodeMaxThreads" maxlength="6" v-model="cluster.nodeMaxThreads"/>
|
||||
<p class="comment">取值在{{defaultNodeMaxThreadsMin}}和{{defaultNodeMaxThreadsMax}}之间;如果为0,则默认为{{defaultNodeMaxThreads}}。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动开放端口</td>
|
||||
<td>
|
||||
<checkbox name="autoOpenPorts" v-model="cluster.autoOpenPorts"></checkbox>
|
||||
<p class="comment">选中后会自动尝试在边缘节点正在运行的firewalld中开放所需端口;如果有别的防火墙或者安全策略,仍然需要手工操作。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="color-border">自动同步节点时钟</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<checkbox name="clockAutoSync" v-model="cluster.clock.autoSync"></checkbox>
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">选中后表示尝试自动同步节点时钟。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="cluster.clock.autoSync">
|
||||
<td class="color-border">NTP时钟服务器</td>
|
||||
<td>
|
||||
<input type="text" name="clockServer" v-model="cluster.clock.server" maxlength="100"/>
|
||||
<p class="comment">可选项。默认使用<code-label>pool.ntp.org</code-label>。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-show="cluster.clock.autoSync">
|
||||
<td class="color-border">检查Chrony</td>
|
||||
<td>
|
||||
<checkbox name="clockCheckChrony" v-model="cluster.clock.checkChrony"></checkbox>
|
||||
<p class="comment">选中后,表示如果chrony(另一款时间同步软件)正在运行,则不重复执行时间同步。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动远程启动</td>
|
||||
<td>
|
||||
<checkbox name="autoRemoteStart" v-model="cluster.autoRemoteStart"></checkbox>
|
||||
<p class="comment">当检测到节点离线时,自动尝试远程启动(前提是节点已经设置了SSH登录认证)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动安装nftables</td>
|
||||
<td>
|
||||
<checkbox name="autoInstallNftables" v-model="cluster.autoInstallNftables"></checkbox>
|
||||
<p class="comment">选中后,表示在Linux系统中自动尝试安装<code-label>nftables</code-label>用于安全防御;此功能需要联网从Ubuntu、CentOS等软件库中下载安装包。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动调节系统参数</td>
|
||||
<td>
|
||||
<checkbox name="autoSystemTuning" v-model="cluster.autoSystemTuning"></checkbox>
|
||||
<p class="comment">选中后,表示自动调整Linux内核等参数,以便提升性能;启用后,以往安装的边缘节点需要重启进程后才能生效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>自动执行硬盘<br/>TRIM</td>
|
||||
<td>
|
||||
<checkbox name="autoTrimDisks" value="1" v-model="cluster.autoTrimDisks"></checkbox>
|
||||
<p class="comment">执行TRIM后可以移除SSD硬盘中无效的数据,从而显著提升SSD硬盘写入性能。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>节点I/O最大读并发数</td>
|
||||
<td>
|
||||
<input name="maxConcurrentReads" v-model="cluster.maxConcurrentReads" type="text" style="width: 5em" maxlength="4"/>
|
||||
<p class="comment">0表示根据系统资源自动计算;通常不需要修改,请在专业人士指导下操作。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>节点I/O最大写并发数</td>
|
||||
<td>
|
||||
<input name="maxConcurrentWrites" v-model="cluster.maxConcurrentWrites" type="text" style="width: 5em" maxlength="4"/>
|
||||
<p class="comment">0表示根据系统资源自动计算;通常不需要修改,请在专业人士指导下操作。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
|
||||
this.timeZoneGroupCode = "asia"
|
||||
if (this.timeZoneLocation != null) {
|
||||
this.timeZoneGroupCode = this.timeZoneLocation.group
|
||||
}
|
||||
|
||||
let oldTimeZoneGroupCode = this.timeZoneGroupCode
|
||||
let oldTimeZoneName = ""
|
||||
if (this.timeZoneLocation != null) {
|
||||
oldTimeZoneName = this.timeZoneLocation.name
|
||||
}
|
||||
|
||||
this.$delay(function () {
|
||||
this.$watch("timeZoneGroupCode", function (groupCode) {
|
||||
if (groupCode == oldTimeZoneGroupCode && oldTimeZoneName.length > 0) {
|
||||
this.cluster.timeZone = oldTimeZoneName
|
||||
return
|
||||
}
|
||||
let firstLocation = null
|
||||
this.timeZoneLocations.forEach(function (v) {
|
||||
if (firstLocation != null) {
|
||||
return
|
||||
}
|
||||
if (v.group == groupCode) {
|
||||
firstLocation = v
|
||||
}
|
||||
})
|
||||
if (firstLocation != null) {
|
||||
this.cluster.timeZone = firstLocation.name
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,21 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">消息接收人</td>
|
||||
<td>
|
||||
<message-receivers-box :v-node-cluster-id="clusterId"></message-receivers-box>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,36 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>选择接收人</h3>
|
||||
|
||||
|
||||
<form class="ui form">
|
||||
<table class="ui table definition">
|
||||
<tr>
|
||||
<td class="title">选择接收人</td>
|
||||
<td>
|
||||
<div v-if="recipients.length == 0">
|
||||
<span class="disabled">暂时没有接收人。</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a class="ui label small basic" :class="{blue: selectedRecipient != null && recipient.id == selectedRecipient.id}" v-for="recipient in recipients" @click.prevent="selectRecipient(recipient)">
|
||||
{{recipient.name}} <span class="small grey">({{recipient.instanceName}})</span>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>选择接收人分组</td>
|
||||
<td>
|
||||
<div v-if="groups.length == 0">
|
||||
<span class="disabled">暂时没有接收人分组。</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a class="ui label small basic" :class="{blue: selectedGroup != null && group.id == selectedGroup.id}" v-for="group in groups" @click.prevent="selectGroup(group)">
|
||||
分组:{{group.name}}
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="ui button primary" @click.prevent="confirm">确定</button>
|
||||
</form>
|
||||
@@ -0,0 +1,40 @@
|
||||
Tea.context(function () {
|
||||
this.selectedRecipient = null
|
||||
this.selectedGroup = null
|
||||
|
||||
|
||||
this.selectRecipient = function (recipient) {
|
||||
this.selectedRecipient = recipient
|
||||
this.selectedGroup = null
|
||||
}
|
||||
|
||||
this.selectGroup = function (group) {
|
||||
this.selectedRecipient = null
|
||||
this.selectedGroup = group
|
||||
}
|
||||
|
||||
this.confirm = function () {
|
||||
if (this.selectedRecipient != null) {
|
||||
NotifyPopup({
|
||||
code: 200,
|
||||
data: {
|
||||
id: this.selectedRecipient.id,
|
||||
name: this.selectedRecipient.name,
|
||||
subName: this.selectedRecipient.instanceName,
|
||||
type: "recipient"
|
||||
}
|
||||
})
|
||||
} else if (this.selectedGroup != null) {
|
||||
NotifyPopup({
|
||||
code: 200,
|
||||
data: {
|
||||
id: this.selectedGroup.id,
|
||||
name: this.selectedGroup.name,
|
||||
type: "group"
|
||||
}
|
||||
})
|
||||
} else {
|
||||
teaweb.closePopup()
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,43 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>可以添加的指标</h3>
|
||||
|
||||
<p class="comment" v-if="items.length == 0">暂时还没有可用的指标。</p>
|
||||
<table class="ui table celled selectable" v-if="items.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>指标名称</th>
|
||||
<th>统计对象</th>
|
||||
<th>统计周期</th>
|
||||
<th class="three wide">统计数值</th>
|
||||
<th class="two wide">状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="item in items">
|
||||
<td>{{item.name}}
|
||||
<div style="margin-top: 0.3em" v-if="item.isPublic || item.code.length > 0">
|
||||
<span class="ui label olive tiny basic" v-if="item.isPublic">公用</span>
|
||||
<span class="ui label olive tiny basic" v-if="item.code.length > 0">内置</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="item.keys != null" v-for="key in item.keys" style="margin-top: 0.2em; margin-bottom: 0.2em"><metric-key-label :v-key="key"></metric-key-label></div>
|
||||
</td>
|
||||
<td>
|
||||
{{item.period}} {{item.periodUnitName}}
|
||||
</td>
|
||||
<td>
|
||||
<span class="ui label small basic">{{item.valueName}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<label-on :v-is-on="item.isOn"></label-on>
|
||||
</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="addItem(item)" v-if="!item.isChecked">添加</a>
|
||||
<a href="" @click.prevent="removeItem(item)" v-if="item.isChecked"><span class="grey">已添加</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="page" v-html="page"></div>
|
||||
@@ -0,0 +1,23 @@
|
||||
Tea.context(function () {
|
||||
this.addItem = function (item) {
|
||||
this.$post("$")
|
||||
.params({
|
||||
clusterId: this.clusterId,
|
||||
itemId: item.id
|
||||
})
|
||||
.success(function () {
|
||||
item.isChecked = true
|
||||
})
|
||||
}
|
||||
|
||||
this.removeItem = function (item) {
|
||||
this.$post(".delete")
|
||||
.params({
|
||||
clusterId: this.clusterId,
|
||||
itemId: item.id
|
||||
})
|
||||
.success(function () {
|
||||
item.isChecked = false
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,53 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item :href="'/clusters/cluster/settings/metrics?category=http&clusterId=' + clusterId" :active="category == 'http'">HTTP</menu-item>
|
||||
<!--<menu-item :href="'/clusters/cluster/settings/metrics?category=tcp&clusterId=' + clusterId" :active="category == 'tcp'">TCP</menu-item>
|
||||
<menu-item :href="'/clusters/cluster/settings/metrics?category=udp&clusterId=' + clusterId" :active="category == 'udp'">UDP</menu-item>-->
|
||||
<span class="item disabled">|</span>
|
||||
<menu-item @click.prevent="createItem">[添加指标]</menu-item>
|
||||
<span class="item disabled">|</span>
|
||||
<span class="item"><tip-icon content="在这里设置的指标,会自动应用到部署在当前集群上的所有网站上。<br/><br/>指标收集和运算通常需要消耗一定量的边缘节点系统资源,所以请谨慎选择。"></tip-icon></span>
|
||||
</first-menu>
|
||||
|
||||
<p class="comment" v-if="items.length == 0">暂时还没有添加指标。</p>
|
||||
|
||||
<table class="ui table celled selectable" v-if="items.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>指标名称</th>
|
||||
<th>统计对象</th>
|
||||
<th>统计周期</th>
|
||||
<th class="three wide">统计数值</th>
|
||||
<th class="two wide">状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="item in items">
|
||||
<td>{{item.name}}
|
||||
<div style="margin-top: 0.3em" v-if="item.isPublic || item.code.length > 0">
|
||||
<span class="ui label olive tiny basic" v-if="item.isPublic">公用</span>
|
||||
<span class="ui label olive tiny basic" v-if="item.code.length > 0">内置</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div v-if="item.keys != null" v-for="key in item.keys" style="margin-top: 0.2em; margin-bottom: 0.2em"><metric-key-label :v-key="key"></metric-key-label></div>
|
||||
</td>
|
||||
<td>
|
||||
{{item.period}} {{item.periodUnitName}}
|
||||
</td>
|
||||
<td>
|
||||
<span class="ui label small basic">{{item.valueName}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<label-on :v-is-on="item.isOn"></label-on>
|
||||
</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="deleteItem(item.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
Tea.context(function () {
|
||||
this.createItem = function () {
|
||||
teaweb.popup(Tea.url(".createPopup", {
|
||||
clusterId: this.clusterId,
|
||||
category: this.category
|
||||
}), {
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
},
|
||||
onClose: function () {
|
||||
teaweb.reload()
|
||||
},
|
||||
width: "50em",
|
||||
height: "25em"
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteItem = function (itemId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个指标吗?", function () {
|
||||
that.$post(".delete")
|
||||
.params({
|
||||
clusterId: that.clusterId,
|
||||
itemId: itemId
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.success("删除成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
{$layout}
|
||||
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<div class="margin"></div>
|
||||
|
||||
<warning-message>此功能为试验功能,目前只能做一些简单的网络数据包统计。</warning-message>
|
||||
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用数据包统计</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="status" v-model="policy.status">
|
||||
<option value="auto">自动</option>
|
||||
<option value="on">启用</option>
|
||||
<option value="off">停用</option>
|
||||
</select>
|
||||
<p class="comment" v-if="policy.status == 'auto'">自动根据服务器硬件配置决定是否启用,避免影响性能。</p>
|
||||
<p class="comment" v-if="policy.status == 'on'">强制启用;如果节点服务器配置较低,可能会严重影响性能,建议仅在8线程以上CPU节点服务器上选择强制启用。</p>
|
||||
<p class="comment" v-if="policy.status == 'off'">完全关闭此功能。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,25 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用自定义页面功能</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="pagesPolicy.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示当前集群下的网站都可以使用当前设置的自定义页面。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div v-show="pagesPolicy.isOn">
|
||||
<http-pages-box :v-pages="pagesPolicy.pages"></http-pages-box>
|
||||
</div>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,52 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
|
||||
|
||||
<div v-if="nodes.length > 0">
|
||||
<div class="margin"></div>
|
||||
<table class="ui table selectable celled">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点</th>
|
||||
<th>租期结束日期</th>
|
||||
<th>所属集群</th>
|
||||
<th class="two wide">是否为<br/>集群备用节点</th>
|
||||
<th>所属分组</th>
|
||||
<th class="two wide">是否为<br/>分组备用节点</th>
|
||||
<th>当前状态</th>
|
||||
<th class="one op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="node in nodes">
|
||||
<td>{{node.nodeName}}</td>
|
||||
<td>
|
||||
<span v-if="node.offlineDay.length > 0" :class="{red: node.isOffline}">{{node.offlineDay.substring(0, 4)}}-{{node.offlineDay.substring(4, 6)}}-{{node.offlineDay.substring(6, 8)}}</span>
|
||||
<span v-else class="disabled">没有设置</span>
|
||||
</td>
|
||||
<td>{{node.clusterName}}</td>
|
||||
<td>
|
||||
<span v-if="node.isBackupForCluster" class="green">备用</span>
|
||||
<span v-else class="disabled">N</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.groupName.length > 0">{{node.groupName}}</span>
|
||||
<span v-else class="disabled">没有设置</span>
|
||||
</td>
|
||||
<td>
|
||||
<span v-if="node.isBackupForGroup" class="green">备用</span>
|
||||
<span v-else class="disabled">N</span>
|
||||
</td>
|
||||
<td>
|
||||
<a v-if="node.actionStatus != null && node.actionStatus.actionId > 0" :href="'/clusters/cluster/node/settings/schedule?clusterId=' + node.clusterId + '&nodeId=' + node.nodeId" target="_blank"><span class="red" style="border-bottom: 1px red dashed">已触发</span></a>
|
||||
<span v-else class="disabled">未触发</span>
|
||||
</td>
|
||||
<td>
|
||||
<a :href="'/clusters/cluster/node/settings/schedule?clusterId=' + node.clusterId + '&nodeId=' + node.nodeId" target="_blank">修改</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,4 @@
|
||||
<first-menu>
|
||||
<menu-item :href="'/clusters/cluster/settings/services?clusterId=' + clusterId" code="setting">设置</menu-item>
|
||||
<menu-item :href="'/clusters/cluster/settings/services/status?clusterId=' + clusterId" code="status">状态</menu-item>
|
||||
</first-menu>
|
||||
@@ -0,0 +1,24 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">自动加入Systemd服务</td>
|
||||
<td>
|
||||
<checkbox name="systemdIsOn" v-model="systemdIsOn"></checkbox>
|
||||
<p class="comment">加入后可以利用systemd对节点进程进行管理,并可自动随开机启动。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,38 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
{$template "menu"}
|
||||
|
||||
<div v-if="isRequesting" class="ui message">正在节点服务状态检测中,请稍候...</div>
|
||||
<div v-if="!isRequesting">
|
||||
<div v-if="results.length == 0">暂时还没有节点。</div>
|
||||
<div v-else>
|
||||
<div class="margin"></div>
|
||||
<table class="ui table selectable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>节点名</th>
|
||||
<th>是否已启用服务</th>
|
||||
<th>提示消息</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="result in results">
|
||||
<td>{{result.nodeName}}</td>
|
||||
<td>
|
||||
<span v-if="result.isOk" class="green">Y</span>
|
||||
<span v-else class="red">N</span>
|
||||
</td>
|
||||
<td>
|
||||
<span :class="{red: !result.isOk}">{{result.message}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="comment">
|
||||
<a href="" @click.prevent="reload()">[刷新]</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,22 @@
|
||||
Tea.context(function () {
|
||||
this.isRequesting = true
|
||||
this.results = []
|
||||
|
||||
this.$delay(function () {
|
||||
this.reload()
|
||||
}, 2000)
|
||||
|
||||
this.reload = function () {
|
||||
this.isRequesting = true
|
||||
this.$post("$")
|
||||
.params({
|
||||
clusterId: this.clusterId
|
||||
})
|
||||
.success(function (resp) {
|
||||
this.results = resp.data.results
|
||||
})
|
||||
.done(function () {
|
||||
this.isRequesting = false
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,90 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>添加阈值</h3>
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId" />
|
||||
<input type="hidden" name="nodeId" :value="nodeId"/>
|
||||
<input type="hidden" name="sumMethod" value="avg"/>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">监控项 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="item" v-model="threshold.item" @change="changeItem">
|
||||
<option v-for="item in items" :value="item.code">{{item.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{itemDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>参数 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="param" v-model="threshold.param" @change="changeParam">
|
||||
<option v-for="param in itemParams" :value="param.code">{{param.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{paramDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>操作符 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="operator" v-model="threshold.operator">
|
||||
<option v-for="operator in operators" :value="operator.code">{{operator.name}}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>对比值 *</td>
|
||||
<td>
|
||||
<div class="ui input" :class="{'right labeled': paramIsPercent}">
|
||||
<input type="text" name="value" style="width: 6em" maxlength="10"/>
|
||||
<span class="ui label" v-if="paramIsPercent">%</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>统计时间段 *</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" name="duration" value="5" style="width: 5em"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
分钟
|
||||
<!-- TODO 将来支持更多时间范围 -->
|
||||
<input type="hidden" name="durationUnit" value="minute"/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>消息</td>
|
||||
<td>
|
||||
<textarea rows="2" maxlength="100" name="message"></textarea>
|
||||
<p class="comment">触发阈值时的消息提示。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>消息通知间隔</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" name="notifyDuration" value="10" style="width: 5em"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
分钟
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">在此间隔内将不会重复发送跟此阈值相关的消息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -0,0 +1,46 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
this.threshold = {
|
||||
item: this.items[0].code,
|
||||
param: "",
|
||||
operator: this.operators[0].code
|
||||
}
|
||||
this.$delay(function () {
|
||||
this.changeItem()
|
||||
this.changeParam()
|
||||
})
|
||||
|
||||
this.itemDescription = ""
|
||||
this.itemParams = []
|
||||
|
||||
this.changeItem = function () {
|
||||
let that = this
|
||||
this.threshold.param = ""
|
||||
this.items.forEach(function (v) {
|
||||
if (v.code == that.threshold.item) {
|
||||
that.itemDescription = v.description
|
||||
that.itemParams = v.params
|
||||
that.threshold.param = v.params[0].code
|
||||
that.paramDescription = v.params[0].description
|
||||
that.paramIsPercent = v.params[0].isPercent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.paramDescription = ""
|
||||
this.paramIsPercent = false
|
||||
|
||||
this.changeParam = function () {
|
||||
let that = this
|
||||
this.items.forEach(function (v) {
|
||||
if (v.code == that.threshold.item) {
|
||||
v.params.forEach(function (param) {
|
||||
if (param.code == that.threshold.param) {
|
||||
that.paramDescription = param.description
|
||||
that.paramIsPercent = param.isPercent
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,42 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item @click.prevent="createThreshold">[添加阈值]</menu-item>
|
||||
</first-menu>
|
||||
|
||||
<p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p>
|
||||
<table class="ui table selectable celled" v-if="thresholds.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>监控项</th>
|
||||
<th>参数</th>
|
||||
<th>操作符</th>
|
||||
<th>对比值</th>
|
||||
<th>统计时间段</th>
|
||||
<th class="two wide">状态</th>
|
||||
<th class="two op">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="threshold in thresholds">
|
||||
<td>{{threshold.itemName}}
|
||||
<div v-if="threshold.node != null" style="margin-top: 0.3em">
|
||||
<a :href="'/clusters/cluster/node/settings/thresholds?clusterId=' + clusterId + '&nodeId=' + threshold.node.id" class="ui label basic tiny" title="节点专属阈值设置"><span class="small">节点:{{threshold.node.name}}</span></a>
|
||||
</div>
|
||||
</td>
|
||||
<td>{{threshold.paramName}}</td>
|
||||
<td>{{threshold.operatorName}}</td>
|
||||
<td>{{threshold.value}}<span v-if="threshold.paramIsPercent">%</span></td>
|
||||
<td>{{threshold.duration}}{{threshold.durationUnitName}}</td>
|
||||
<td>
|
||||
<label-on :v-is-on="threshold.isOn"></label-on>
|
||||
</td>
|
||||
<td>
|
||||
<a href="" @click.prevent="updateThreshold(threshold.id)">修改</a>
|
||||
<a href="" @click.prevent="deleteThreshold(threshold.id)">删除</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,42 @@
|
||||
Tea.context(function () {
|
||||
this.createThreshold = function () {
|
||||
teaweb.popup(Tea.url(".createPopup", {
|
||||
clusterId: this.clusterId
|
||||
}), {
|
||||
height: "30em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.updateThreshold = function (thresholdId) {
|
||||
teaweb.popup(Tea.url(".updatePopup", {
|
||||
thresholdId: thresholdId
|
||||
}), {
|
||||
height: "30em",
|
||||
callback: function () {
|
||||
teaweb.success("保存成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.deleteThreshold = function (thresholdId) {
|
||||
let that = this
|
||||
teaweb.confirm("确定要删除这个阈值吗?", function () {
|
||||
that.$post(".delete")
|
||||
.params({
|
||||
thresholdId: thresholdId
|
||||
})
|
||||
.success(function () {
|
||||
teaweb.success("删除成功", function () {
|
||||
teaweb.reload()
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,95 @@
|
||||
{$layout "layout_popup"}
|
||||
|
||||
<h3>修改阈值</h3>
|
||||
<form class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="thresholdId" :value="threshold.id"/>
|
||||
<input type="hidden" name="sumMethod" value="avg"/>
|
||||
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">监控项 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="item" v-model="threshold.item" @change="changeItem">
|
||||
<option v-for="item in items" :value="item.code">{{item.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{itemDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>参数 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="param" v-model="threshold.param" @change="changeParam">
|
||||
<option v-for="param in itemParams" :value="param.code">{{param.name}}</option>
|
||||
</select>
|
||||
<p class="comment">{{paramDescription}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>操作符 *</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" name="operator" v-model="threshold.operator">
|
||||
<option v-for="operator in operators" :value="operator.code">{{operator.name}}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>对比值 *</td>
|
||||
<td>
|
||||
<div class="ui input" :class="{'right labeled': paramIsPercent}">
|
||||
<input type="text" name="value" style="width: 6em" maxlength="10" v-model="threshold.value"/>
|
||||
<span class="ui label" v-if="paramIsPercent">%</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>统计时间段 *</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" name="duration" value="5" style="width: 5em" v-model="threshold.duration"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
分钟
|
||||
<!-- TODO 将来支持更多时间范围 -->
|
||||
<input type="hidden" name="durationUnit" value="minute" v-model="threshold.durationUnit"/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>消息</td>
|
||||
<td>
|
||||
<textarea rows="2" maxlength="100" name="message" v-model="threshold.message"></textarea>
|
||||
<p class="comment">触发阈值时的消息提示。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>消息通知间隔</td>
|
||||
<td>
|
||||
<div class="ui fields inline">
|
||||
<div class="ui field">
|
||||
<input type="text" name="notifyDuration" v-model="threshold.notifyDuration" value="10" style="width: 5em"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
分钟
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">在此间隔内将不会重复发送跟此阈值相关的消息。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>启用当前阈值</td>
|
||||
<td>
|
||||
<checkbox name="isOn" value="1" v-model="threshold.isOn"></checkbox>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
@@ -0,0 +1,51 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyPopup
|
||||
this.$delay(function () {
|
||||
this.initItem()
|
||||
this.changeParam()
|
||||
})
|
||||
|
||||
this.itemDescription = ""
|
||||
this.itemParams = []
|
||||
|
||||
this.initItem = function () {
|
||||
let that = this
|
||||
this.items.forEach(function (v) {
|
||||
if (v.code == that.threshold.item) {
|
||||
that.itemDescription = v.description
|
||||
that.itemParams = v.params
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.changeItem = function () {
|
||||
let that = this
|
||||
this.threshold.param = ""
|
||||
this.items.forEach(function (v) {
|
||||
if (v.code == that.threshold.item) {
|
||||
that.itemDescription = v.description
|
||||
that.itemParams = v.params
|
||||
that.threshold.param = v.params[0].code
|
||||
that.paramDescription = v.params[0].description
|
||||
that.paramIsPercent = v.params[0].isPercent
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
this.paramDescription = ""
|
||||
this.paramIsPercent = false
|
||||
|
||||
this.changeParam = function () {
|
||||
let that = this
|
||||
this.items.forEach(function (v) {
|
||||
if (v.code == that.threshold.item) {
|
||||
v.params.forEach(function (param) {
|
||||
if (param.code == that.threshold.param) {
|
||||
that.paramDescription = param.description
|
||||
that.paramIsPercent = param.isPercent
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,61 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<first-menu>
|
||||
<menu-item><tip-icon content="TCP Option Address(TOA)可以在TCP选项中传递客户端IP,多用在TCP负载均衡的源站需要获取客户端真实IP的场景。<br/><br/>注意:HTTP协议通常不需要此设置。<br/><br/>如需修改配置,请在专业人士指导下操作。"></tip-icon></menu-item>
|
||||
<a class="item" href="https://goedge.cn/docs/Node/toa.md" target="_blank">文档 <i class="icon external small"></i></a>
|
||||
</first-menu>
|
||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<csrf-token></csrf-token>
|
||||
|
||||
<table class="ui table selectable definition">
|
||||
<tr>
|
||||
<td class="title">启用TOA</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="toa.isOn"></checkbox>
|
||||
<p class="comment">在启用之前,请确保当前集群下所有节点服务器安装并启用了nftables。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="toa.isOn">
|
||||
<tr>
|
||||
<td class="title">IPv4选项类型数值</td>
|
||||
<td>
|
||||
<input type="text" name="optionTypeV4" v-model="toa.optionTypeV4" style="width:4em" maxlength="3"/>
|
||||
<p class="comment">用来作为附加的IPv4 TCP OPTION值,通常是254(即0xfe),请查阅云服务商文档来确认此值。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">IPv6选项类型数值</td>
|
||||
<td>
|
||||
<input type="text" name="optionTypeV6" v-model="toa.optionTypeV6" style="width:4em" maxlength="3"/>
|
||||
<p class="comment">用来作为附加的IPv6 TCP OPTION值,通常是254(即0xfe),请查阅云服务商文档来确认此值。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody v-show="toa.isOn && moreOptionsVisible">
|
||||
<tr>
|
||||
<td>自动配置</td>
|
||||
<td>
|
||||
<checkbox name="autoSetup" v-model="toa.autoSetup"></checkbox>
|
||||
<p class="comment">TOA功能需要节点服务器安装并开启了nftables,并将网络数据包转发到NFQueue中。如果选中了自动配置,则每次在启动时都会自动尝试配置nftables规则。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>NFQueue队列开始ID</td>
|
||||
<td>
|
||||
<input type="text" name="minQueueId" v-model="toa.minQueueId" style="width:4em" maxlength="3"/>
|
||||
<p class="comment">不能超过255。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,103 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用5秒盾功能</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="uamPolicy.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示当前集群下的网站可以使用5秒盾功能。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="uamPolicy.isOn">
|
||||
<tr>
|
||||
<td>验证有效期</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="keyLife" v-model="uamPolicy.keyLife" maxlength="6" size="6" style="width: 6em"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">单个客户端验证通过后,在这个有效期内不再重复验证;如果为0则表示默认3600秒。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>拦截时长</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="blockSeconds" v-model="uamPolicy.blockSeconds" maxlength="6" size="6" style="width: 6em"/>
|
||||
<span class="ui label">秒</span>
|
||||
</div>
|
||||
<p class="comment">验证失败后,系统拦截的时间。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>最大失败次数</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="maxFails" v-model="uamPolicy.maxFails" maxlength="6" size="6" style="width: 6em"/>
|
||||
<span class="ui label">次</span>
|
||||
</div>
|
||||
<p class="comment">失败尝试达到此数字后,则认为验证失败。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>页面标题</td>
|
||||
<td>
|
||||
<input type="text" maxlength="200" name="uiTitle" v-model="uamPolicy.uiTitle"/>
|
||||
<p class="comment">提示页面的标题。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>页面提示内容</td>
|
||||
<td>
|
||||
<textarea rows="8" name="uiBody" v-model="uamPolicy.uiBody"></textarea>
|
||||
<p class="comment">提示页面的HTML内容,支持请求变量(比如<code-label>${host}</code-label>表示正在访问的域名,<code-label>${product.name}</code-label>表示当前系统产品名称),留空表示使用默认提示内容;用<code-label><span class="ui-counter">5</span></code-label>表示数字倒计时计数器。<a href="" @click.prevent="setTemplateBody">[使用模板]</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tr v-if="uamPolicy.isOn">
|
||||
<td colspan="2"><more-options-indicator></more-options-indicator></td>
|
||||
</tr>
|
||||
<tbody v-show="moreOptionsVisible">
|
||||
<tr>
|
||||
<td>允许常见的搜索引擎</td>
|
||||
<td>
|
||||
<checkbox name="allowSearchEngines" v-model="uamPolicy.allowSearchEngines"></checkbox>
|
||||
<p class="comment">选中表示允许Google、Bing等常见搜索引擎直接跳过检查。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>拦截常见爬虫</td>
|
||||
<td>
|
||||
<checkbox name="denySpiders" v-model="uamPolicy.denySpiders"></checkbox>
|
||||
<p class="comment">选中表示自动拦截Python、Scrapy等常见爬虫。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>包含子域名</td>
|
||||
<td>
|
||||
<checkbox name="includeSubdomains" v-model="uamPolicy.includeSubdomains"></checkbox>
|
||||
<p class="comment">选中后,表示子域名之间只需验证一次。不要轻易修改此选项,防止导致短时间内大量用户验证信息失效。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>防火墙拦截范围</td>
|
||||
<td>
|
||||
<select name="firewallScope" v-model="uamPolicy.firewall.scope" class="ui dropdown auto-width">
|
||||
<option value="global">所有网站</option>
|
||||
<option value="service">当前网站</option>
|
||||
</select>
|
||||
<p class="comment" v-if="uamPolicy.firewall.scope == 'global'">“所有网站”表示IP被拦截时,将被阻止访问所有网站;此时系统可以自动尝试利用本地防火墙提升拦截效率。</p>
|
||||
<p class="comment" v-if="uamPolicy.firewall.scope == 'service'">“当前网站”表示IP被拦截时,只会阻止访问当前网站;选择此选项会严重影响拦截效率,建议只有特殊情况下才使用。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
|
||||
this.setTemplateBody = function () {
|
||||
this.uamPolicy.uiBody = `<div class="ui-uam-box">
|
||||
<h1>Checking your browser before accessing \${host}</h1>
|
||||
<p>Please allow up to <span class="ui-counter">5</span> seconds ...</p>
|
||||
<p> </p>
|
||||
<p>DDoS protection by \${product.name}</p>
|
||||
</div>`
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,20 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">选择WAF策略 *</td>
|
||||
<td>
|
||||
<http-firewall-policy-selector :v-http-firewall-policy="firewallPolicy"></http-firewall-policy-selector>
|
||||
<p class="comment">部署在当前集群上的所有网站都会自动使用此策略,只是网站可以自定义是否开启。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
@@ -0,0 +1,53 @@
|
||||
{$layout}
|
||||
{$template "../menu"}
|
||||
{$template "/left_menu_with_menu"}
|
||||
|
||||
<div class="right-box with-menu">
|
||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
|
||||
<csrf-token></csrf-token>
|
||||
<input type="hidden" name="clusterId" :value="clusterId"/>
|
||||
<table class="ui table definition selectable">
|
||||
<tr>
|
||||
<td class="title">启用WebP功能</td>
|
||||
<td>
|
||||
<checkbox name="isOn" v-model="webpPolicy.isOn"></checkbox>
|
||||
<p class="comment">选中后,表示当前集群下的网站可以使用WebP转换功能。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tbody v-show="webpPolicy.isOn">
|
||||
<tr>
|
||||
<td>图片质量</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" name="quality" v-model="webpPolicy.quality" style="width: 5em" maxlength="4"/>
|
||||
<span class="ui label">%</span>
|
||||
</div>
|
||||
<p class="comment">取值在0到100之间,0表示自动调节;数值越大生成的图像越清晰,文件尺寸也会越大,同时消耗的系统资源越多(在低配置的边缘节点上建议不超过50%)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>需要满足缓存条件</td>
|
||||
<td>
|
||||
<checkbox name="requireCache" v-model="webpPolicy.requireCache"></checkbox>
|
||||
<p class="comment">选中后,表示图片URL需要满足缓存条件后才会转换,防止实时转换消耗巨大的系统资源。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>可转换的最小尺寸</td>
|
||||
<td>
|
||||
<size-capacity-box :v-name="'minLengthJSON'" :v-value="webpPolicy.minLength"></size-capacity-box>
|
||||
<p class="comment">不低于此尺寸的图像文件的才会转换。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>可转换的最大尺寸</td>
|
||||
<td>
|
||||
<size-capacity-box :v-name="'maxLengthJSON'" :v-value="webpPolicy.maxLength"></size-capacity-box>
|
||||
<p class="comment">不高于此尺寸的图像文件的才会转换。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<submit-btn></submit-btn>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
Tea.context(function () {
|
||||
this.success = NotifyReloadSuccess("保存成功")
|
||||
})
|
||||
Reference in New Issue
Block a user