mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-16 13:40:24 +08:00
集群设置中增加服务设置
This commit is contained in:
@@ -0,0 +1,150 @@
|
|||||||
|
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package globalServerConfig
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/actions"
|
||||||
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IndexAction struct {
|
||||||
|
actionutils.ParentAction
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) Init() {
|
||||||
|
this.Nav("", "setting", "")
|
||||||
|
this.SecondMenu("globalServerConfig")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunGet(params struct {
|
||||||
|
ClusterId int64
|
||||||
|
}) {
|
||||||
|
configResp, err := this.RPC().NodeClusterRPC().FindNodeClusterGlobalServerConfig(this.AdminContext(), &pb.FindNodeClusterGlobalServerConfigRequest{NodeClusterId: params.ClusterId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var configJSON = configResp.GlobalServerConfigJSON
|
||||||
|
var config = serverconfigs.DefaultGlobalServerConfig()
|
||||||
|
if len(configJSON) > 0 {
|
||||||
|
err = json.Unmarshal(configJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.Data["config"] = config
|
||||||
|
|
||||||
|
var httpAllDomainMismatchActionContentHTML = ""
|
||||||
|
if config.HTTPAll.DomainMismatchAction != nil {
|
||||||
|
httpAllDomainMismatchActionContentHTML = config.HTTPAll.DomainMismatchAction.Options.GetString("contentHTML")
|
||||||
|
} else {
|
||||||
|
httpAllDomainMismatchActionContentHTML = `<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8"/>
|
||||||
|
<title>404 not found</title>
|
||||||
|
<style>
|
||||||
|
* { font-family: Roboto, system-ui, sans-serif; }
|
||||||
|
h3, p { text-align: center; }
|
||||||
|
p { color: grey; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Error: 404 Page Not Found</h3>
|
||||||
|
<h3>找不到您要访问的页面。</h3>
|
||||||
|
|
||||||
|
<p>原因:找不到当前访问域名对应的网站,请联系网站管理员。</p>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
}
|
||||||
|
this.Data["httpAllDomainMismatchActionContentHTML"] = httpAllDomainMismatchActionContentHTML
|
||||||
|
|
||||||
|
this.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *IndexAction) RunPost(params struct {
|
||||||
|
ClusterId int64
|
||||||
|
|
||||||
|
HttpAllMatchDomainStrictly bool
|
||||||
|
HttpAllDomainMismatchActionContentHTML string
|
||||||
|
HttpAllAllowMismatchDomainsJSON []byte
|
||||||
|
HttpAllAllowNodeIP bool
|
||||||
|
HttpAllDefaultDomain string
|
||||||
|
|
||||||
|
LogRecordServerError bool
|
||||||
|
|
||||||
|
Must *actions.Must
|
||||||
|
CSRF *actionutils.CSRF
|
||||||
|
}) {
|
||||||
|
defer this.CreateLogInfo("修改集群 %d 全局配置", params.ClusterId)
|
||||||
|
|
||||||
|
configResp, err := this.RPC().NodeClusterRPC().FindNodeClusterGlobalServerConfig(this.AdminContext(), &pb.FindNodeClusterGlobalServerConfigRequest{NodeClusterId: params.ClusterId})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var configJSON = configResp.GlobalServerConfigJSON
|
||||||
|
var config = serverconfigs.DefaultGlobalServerConfig()
|
||||||
|
if len(configJSON) > 0 {
|
||||||
|
err = json.Unmarshal(configJSON, config)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.HTTPAll.MatchDomainStrictly = params.HttpAllMatchDomainStrictly
|
||||||
|
config.HTTPAll.DomainMismatchAction = &serverconfigs.DomainMismatchAction{
|
||||||
|
Code: serverconfigs.DomainMismatchActionPage,
|
||||||
|
Options: maps.Map{
|
||||||
|
"statusCode": 404,
|
||||||
|
"contentHTML": params.HttpAllDomainMismatchActionContentHTML,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowMismatchDomains = []string{}
|
||||||
|
if len(params.HttpAllAllowMismatchDomainsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(params.HttpAllAllowMismatchDomainsJSON, &allowMismatchDomains)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.HTTPAll.AllowMismatchDomains = allowMismatchDomains
|
||||||
|
config.HTTPAll.AllowNodeIP = params.HttpAllAllowNodeIP
|
||||||
|
config.HTTPAll.DefaultDomain = params.HttpAllDefaultDomain
|
||||||
|
|
||||||
|
config.Log.RecordServerError = params.LogRecordServerError
|
||||||
|
|
||||||
|
err = config.Init()
|
||||||
|
if err != nil {
|
||||||
|
this.Fail("配置校验失败:" + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
configJSON, err = json.Marshal(config)
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = this.RPC().NodeClusterRPC().UpdateNodeClusterGlobalServerConfig(this.AdminContext(), &pb.UpdateNodeClusterGlobalServerConfigRequest{
|
||||||
|
NodeClusterId: params.ClusterId,
|
||||||
|
GlobalServerConfigJSON: configJSON,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
this.ErrorPage(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Success()
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
ddosProtection "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/ddos-protection"
|
ddosProtection "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/ddos-protection"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/dns"
|
||||||
firewallActions "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/firewall-actions"
|
firewallActions "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/firewall-actions"
|
||||||
|
globalServerConfig "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/global-server-config"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/health"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/health"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/metrics"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/metrics"
|
||||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services"
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/settings/services"
|
||||||
@@ -71,6 +72,10 @@ func init() {
|
|||||||
GetPost("", new(ddosProtection.IndexAction)).
|
GetPost("", new(ddosProtection.IndexAction)).
|
||||||
GetPost("/status", new(ddosProtection.StatusAction)).
|
GetPost("/status", new(ddosProtection.StatusAction)).
|
||||||
|
|
||||||
|
// 全局服务配置
|
||||||
|
Prefix("/clusters/cluster/settings/global-server-config").
|
||||||
|
GetPost("", new(globalServerConfig.IndexAction)).
|
||||||
|
|
||||||
//
|
//
|
||||||
EndAll()
|
EndAll()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ func (this *ClusterHelper) createSettingMenu(cluster *pb.NodeCluster, info *pb.F
|
|||||||
"isActive": selectedItem == "basic",
|
"isActive": selectedItem == "basic",
|
||||||
"isOn": true,
|
"isOn": true,
|
||||||
})
|
})
|
||||||
|
items = append(items, maps.Map{
|
||||||
|
"name": "服务设置",
|
||||||
|
"url": "/clusters/cluster/settings/global-server-config?clusterId=" + clusterId,
|
||||||
|
"isActive": selectedItem == "globalServerConfig",
|
||||||
|
})
|
||||||
items = append(items, maps.Map{
|
items = append(items, maps.Map{
|
||||||
"name": "缓存设置",
|
"name": "缓存设置",
|
||||||
"url": "/clusters/cluster/settings/cache?clusterId=" + clusterId,
|
"url": "/clusters/cluster/settings/cache?clusterId=" + clusterId,
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
// 域名列表
|
// 域名列表
|
||||||
Vue.component("domains-box", {
|
Vue.component("domains-box", {
|
||||||
props: ["v-domains"],
|
props: ["v-domains", "name"],
|
||||||
data: function () {
|
data: function () {
|
||||||
let domains = this.vDomains
|
let domains = this.vDomains
|
||||||
if (domains == null) {
|
if (domains == null) {
|
||||||
domains = []
|
domains = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let realName = "domainsJSON"
|
||||||
|
if (this.name != null && typeof this.name == "string") {
|
||||||
|
realName = this.name
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
domains: domains,
|
domains: domains,
|
||||||
isAdding: false,
|
isAdding: false,
|
||||||
addingDomain: ""
|
addingDomain: "",
|
||||||
|
realName: realName
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -59,7 +65,7 @@ Vue.component("domains-box", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: `<div>
|
template: `<div>
|
||||||
<input type="hidden" name="domainsJSON" :value="JSON.stringify(domains)"/>
|
<input type="hidden" :name="realName" :value="JSON.stringify(domains)"/>
|
||||||
<div v-if="domains.length > 0">
|
<div v-if="domains.length > 0">
|
||||||
<span class="ui label small basic" v-for="(domain, index) in domains">
|
<span class="ui label small basic" v-for="(domain, index) in domains">
|
||||||
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
||||||
|
|||||||
@@ -510,6 +510,9 @@ body.expanded .main {
|
|||||||
.main h4 {
|
.main h4 {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
.main form h4 {
|
||||||
|
margin-top: 0.6em;
|
||||||
|
}
|
||||||
.main td span.small {
|
.main td span.small {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -476,6 +476,10 @@ body.expanded .main {
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main form h4 {
|
||||||
|
margin-top: 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
.main td span.small {
|
.main td span.small {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
{$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"/>
|
||||||
|
|
||||||
|
<h4>域名</h4>
|
||||||
|
|
||||||
|
<table class="ui table definition selectable">
|
||||||
|
<tr>
|
||||||
|
<td class="title color-border">禁止未绑定域名访问</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>
|
||||||
|
<textarea name="httpAllDomainMismatchActionContentHTML" v-model="httpAllDomainMismatchActionContentHTML"></textarea>
|
||||||
|
<p class="comment">访问未绑定的域名时提示的文字,可以使用HTML;仅限于HTTP请求,不适于用HTTPS(HTTPS会提示证书错误)。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr v-show="config.httpAll.matchDomainStrictly">
|
||||||
|
<td class="color-border">允许例外的域名</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 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">
|
||||||
|
<td class="color-border">默认域名</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="httpAllDefaultDomain" v-model="config.httpAll.defaultDomain"/>
|
||||||
|
<p class="comment">例外域名或使用节点IP访问时使用的默认域名。</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h4>日志</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>
|
||||||
|
|
||||||
|
<submit-btn></submit-btn>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Tea.context(function () {
|
||||||
|
this.success = NotifyReloadSuccess("保存成功")
|
||||||
|
})
|
||||||
@@ -11,54 +11,7 @@
|
|||||||
|
|
||||||
<!-- 域名相关配置 -->
|
<!-- 域名相关配置 -->
|
||||||
<div v-show="tab == 'domainMatch'">
|
<div v-show="tab == 'domainMatch'">
|
||||||
<table class="ui table selectable definition">
|
<p class="comment">域名匹配相关配置已经转移到集群设置中,请到对应的集群设置中修改。</p>
|
||||||
<tr>
|
|
||||||
<td class="title">严格匹配域名</td>
|
|
||||||
<td>
|
|
||||||
<checkbox name="matchDomainStrictly" v-model="globalConfig.httpAll.matchDomainStrictly"></checkbox>
|
|
||||||
<p class="comment">如果选择了严格匹配域名,找不到匹配的域名时会采取对应的动作。</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tbody v-show="globalConfig.httpAll.matchDomainStrictly">
|
|
||||||
<tr>
|
|
||||||
<td>默认域名</td>
|
|
||||||
<td>
|
|
||||||
<input type="text" name="defaultDomain" v-model="globalConfig.httpAll.defaultDomain" maxlength="100"/>
|
|
||||||
<p class="comment">当找不到匹配的域名时,自动使用此域名。</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>允许不匹配的域名</td>
|
|
||||||
<td>
|
|
||||||
<values-box :name="'allowMismatchDomains'" :values="globalConfig.httpAll.allowMismatchDomains" :size="40" :maxlength="100" :placeholder="'域名'"></values-box>
|
|
||||||
<p class="comment">允许这些域名即时不匹配也可以访问。</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td class="color-border">域名不匹配时的动作</td>
|
|
||||||
<td>
|
|
||||||
<radio name="domainMismatchAction" :v-value="'close'" v-model="domainMismatchAction">断开连接</radio>
|
|
||||||
|
|
||||||
<radio name="domainMismatchAction" :v-value="'page'" v-model="domainMismatchAction">显示提示页面</radio>
|
|
||||||
|
|
||||||
<p class="comment" v-if="domainMismatchAction == 'close'">当找不到要访问的域名时关闭客户端连接。</p>
|
|
||||||
<p class="comment" v-if="domainMismatchAction == 'page'">当找不到访问的域名时显示一个提示页面。</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-show="domainMismatchAction == 'page'">
|
|
||||||
<td class="color-border">响应代码</td>
|
|
||||||
<td>
|
|
||||||
<input type="text" name="domainMismatchActionPageStatusCode" v-model="domainMismatchActionPageOptions.statusCode" style="width:4em" maxlength="3"/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr v-show="domainMismatchAction == 'page'">
|
|
||||||
<td class="color-border">域名不匹配时显示的页面</td>
|
|
||||||
<td>
|
|
||||||
<textarea name="domainMismatchActionPageContentHTML" v-model="domainMismatchActionPageOptions.contentHTML" rows="15"></textarea>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 域名审核相关配置 -->
|
<!-- 域名审核相关配置 -->
|
||||||
@@ -112,5 +65,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="margin"></div>
|
<div class="margin"></div>
|
||||||
<submit-btn>保存</submit-btn>
|
<submit-btn v-show="tab != 'domainMatch'">保存</submit-btn>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Reference in New Issue
Block a user