前端页面
This commit is contained in:
@@ -21,6 +21,10 @@ func (this *ClusterAction) RunGet(params struct {
|
||||
}) {
|
||||
httpdnsutils.AddLeftMenu(this.Parent())
|
||||
cluster := pickCluster(params.ClusterId)
|
||||
|
||||
// 构建顶部 tabbar
|
||||
httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "node")
|
||||
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["cluster"] = cluster
|
||||
this.Data["installState"] = params.InstalledState
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
package clusters
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/policies"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type ClusterSettingsAction struct {
|
||||
@@ -15,35 +24,184 @@ func (this *ClusterSettingsAction) Init() {
|
||||
|
||||
func (this *ClusterSettingsAction) RunGet(params struct {
|
||||
ClusterId int64
|
||||
Section string
|
||||
}) {
|
||||
httpdnsutils.AddLeftMenu(this.Parent())
|
||||
cluster := pickCluster(params.ClusterId)
|
||||
installDir := cluster.GetString("installDir")
|
||||
if len(installDir) == 0 {
|
||||
installDir = "/opt/edge-httpdns"
|
||||
settings := loadClusterSettings(cluster)
|
||||
cluster["name"] = settings.GetString("name")
|
||||
|
||||
// 构建顶部 tabbar
|
||||
httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "setting")
|
||||
|
||||
// 当前选中的 section
|
||||
section := params.Section
|
||||
if len(section) == 0 {
|
||||
section = "basic"
|
||||
}
|
||||
this.Data["activeSection"] = section
|
||||
|
||||
// 左侧菜单
|
||||
cid := strconv.FormatInt(params.ClusterId, 10)
|
||||
this.Data["leftMenuItems"] = []map[string]interface{}{
|
||||
{"name": "基础设置", "url": "/httpdns/clusters/cluster/settings?clusterId=" + cid + "§ion=basic", "isActive": section == "basic"},
|
||||
{"name": "TLS", "url": "/httpdns/clusters/cluster/settings?clusterId=" + cid + "§ion=tls", "isActive": section == "tls"},
|
||||
}
|
||||
|
||||
settings["isDefaultCluster"] = (policies.LoadDefaultClusterID() == cluster.GetInt64("id"))
|
||||
|
||||
this.Data["cluster"] = cluster
|
||||
this.Data["settings"] = map[string]interface{}{
|
||||
"region": cluster.GetString("region"),
|
||||
"gatewayDomain": cluster.GetString("gatewayDomain"),
|
||||
"cacheTtl": cluster.GetInt("cacheTtl"),
|
||||
"fallbackTimeout": cluster.GetInt("fallbackTimeout"),
|
||||
"installDir": installDir,
|
||||
"isOn": cluster.GetBool("isOn"),
|
||||
// 构造前端需要的 tlsConfig 格式
|
||||
var listenAddresses []*serverconfigs.NetworkAddressConfig
|
||||
listenAddrsRaw := settings.GetString("listenAddrsJSON")
|
||||
if len(listenAddrsRaw) > 0 {
|
||||
_ = json.Unmarshal([]byte(listenAddrsRaw), &listenAddresses)
|
||||
} else {
|
||||
// 默认 443 端口
|
||||
listenAddresses = []*serverconfigs.NetworkAddressConfig{
|
||||
{
|
||||
Protocol: serverconfigs.ProtocolHTTPS,
|
||||
Host: "",
|
||||
PortRange: "443",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 构造前端需要的 SSLPolicy
|
||||
var sslPolicy *sslconfigs.SSLPolicy
|
||||
originCertPem := settings.GetString("originCertPem")
|
||||
originKeyPem := settings.GetString("originKeyPem")
|
||||
if len(originCertPem) > 0 && len(originKeyPem) > 0 {
|
||||
sslPolicy = &sslconfigs.SSLPolicy{
|
||||
IsOn: true,
|
||||
MinVersion: settings.GetString("tlsMinVersion"),
|
||||
CipherSuitesIsOn: settings.GetBool("tlsCipherSuitesOn"),
|
||||
OCSPIsOn: settings.GetBool("tlsOcspOn"),
|
||||
ClientAuthType: int(settings.GetInt32("tlsClientAuthType")),
|
||||
Certs: []*sslconfigs.SSLCertConfig{
|
||||
{
|
||||
IsOn: true,
|
||||
CertData: []byte(originCertPem),
|
||||
KeyData: []byte(originKeyPem),
|
||||
},
|
||||
},
|
||||
}
|
||||
} else {
|
||||
sslPolicy = &sslconfigs.SSLPolicy{
|
||||
IsOn: true,
|
||||
}
|
||||
}
|
||||
|
||||
this.Data["tlsConfig"] = maps.Map{
|
||||
"isOn": true,
|
||||
"listen": listenAddresses,
|
||||
"sslPolicy": sslPolicy,
|
||||
}
|
||||
|
||||
this.Data["cluster"] = cluster
|
||||
this.Data["settings"] = settings
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *ClusterSettingsAction) RunPost(params struct {
|
||||
ClusterId int64
|
||||
Name string
|
||||
Region string
|
||||
GatewayDomain string
|
||||
CacheTtl int32
|
||||
FallbackTimeout int32
|
||||
InstallDir string
|
||||
IsOn bool
|
||||
ClusterId int64
|
||||
Name string
|
||||
GatewayDomain string
|
||||
CacheTtl int32
|
||||
FallbackTimeout int32
|
||||
InstallDir string
|
||||
IsOn bool
|
||||
IsDefaultCluster bool
|
||||
|
||||
Addresses []byte
|
||||
SslPolicyJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
// Mock successful save
|
||||
params.Must.Field("clusterId", params.ClusterId).Gt(0, "please select cluster")
|
||||
params.Must.Field("name", params.Name).Require("please input cluster name")
|
||||
params.Must.Field("gatewayDomain", params.GatewayDomain).Require("please input service domain")
|
||||
params.Must.Field("cacheTtl", params.CacheTtl).Gt(0, "cache ttl should be greater than 0")
|
||||
params.Must.Field("fallbackTimeout", params.FallbackTimeout).Gt(0, "fallback timeout should be greater than 0")
|
||||
params.Must.Field("installDir", params.InstallDir).Require("please input install dir")
|
||||
|
||||
|
||||
if params.IsDefaultCluster && !params.IsOn {
|
||||
this.Fail("默认集群必须保持启用状态")
|
||||
return
|
||||
}
|
||||
|
||||
cluster := pickCluster(params.ClusterId)
|
||||
settings := loadClusterSettings(cluster)
|
||||
settings["name"] = strings.TrimSpace(params.Name)
|
||||
settings["gatewayDomain"] = strings.TrimSpace(params.GatewayDomain)
|
||||
settings["cacheTtl"] = int(params.CacheTtl)
|
||||
settings["fallbackTimeout"] = int(params.FallbackTimeout)
|
||||
settings["installDir"] = strings.TrimSpace(params.InstallDir)
|
||||
settings["isOn"] = params.IsOn
|
||||
// 处理地址
|
||||
var addresses = []*serverconfigs.NetworkAddressConfig{}
|
||||
if len(params.Addresses) > 0 {
|
||||
err := json.Unmarshal(params.Addresses, &addresses)
|
||||
if err != nil {
|
||||
this.Fail("端口地址解析失败:" + err.Error())
|
||||
}
|
||||
|
||||
addressesJSON, _ := json.Marshal(addresses)
|
||||
settings["listenAddrsJSON"] = string(addressesJSON)
|
||||
}
|
||||
|
||||
// 处理 SSL 配置
|
||||
var originCertPem = ""
|
||||
var originKeyPem = ""
|
||||
var tlsMinVersion = "TLS 1.1"
|
||||
var tlsCipherSuitesOn = false
|
||||
var tlsOcspOn = false
|
||||
var tlsClientAuthType = sslconfigs.SSLClientAuthType(0)
|
||||
|
||||
if len(params.SslPolicyJSON) > 0 {
|
||||
sslPolicy := &sslconfigs.SSLPolicy{}
|
||||
err := json.Unmarshal(params.SslPolicyJSON, sslPolicy)
|
||||
if err == nil {
|
||||
tlsMinVersion = sslPolicy.MinVersion
|
||||
tlsCipherSuitesOn = sslPolicy.CipherSuitesIsOn
|
||||
tlsOcspOn = sslPolicy.OCSPIsOn
|
||||
tlsClientAuthType = sslconfigs.SSLClientAuthType(sslPolicy.ClientAuthType)
|
||||
|
||||
if len(sslPolicy.Certs) > 0 {
|
||||
cert := sslPolicy.Certs[0]
|
||||
originCertPem = string(cert.CertData)
|
||||
originKeyPem = string(cert.KeyData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(originCertPem) == 0 || len(originKeyPem) == 0 {
|
||||
this.Fail("请上传或选择证书")
|
||||
}
|
||||
|
||||
settings["originHttps"] = true
|
||||
settings["originCertPem"] = originCertPem
|
||||
settings["originKeyPem"] = originKeyPem
|
||||
if len(tlsMinVersion) == 0 {
|
||||
tlsMinVersion = "TLS 1.1"
|
||||
}
|
||||
settings["tlsMinVersion"] = tlsMinVersion
|
||||
settings["tlsCipherSuitesOn"] = tlsCipherSuitesOn
|
||||
settings["tlsOcspOn"] = tlsOcspOn
|
||||
settings["tlsClientAuthType"] = int(tlsClientAuthType)
|
||||
settings["lastModifiedAt"] = nowDateTime()
|
||||
settings["certUpdatedAt"] = nowDateTime()
|
||||
|
||||
saveClusterSettings(params.ClusterId, settings)
|
||||
|
||||
currentDefaultClusterId := policies.LoadDefaultClusterID()
|
||||
if params.IsDefaultCluster {
|
||||
policies.SaveDefaultClusterID(params.ClusterId)
|
||||
} else if currentDefaultClusterId == params.ClusterId {
|
||||
policies.SaveDefaultClusterID(0)
|
||||
}
|
||||
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
package clusters
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
var clusterSettingsStore = struct {
|
||||
sync.RWMutex
|
||||
data map[int64]maps.Map
|
||||
}{
|
||||
data: map[int64]maps.Map{},
|
||||
}
|
||||
|
||||
func defaultClusterSettings(cluster maps.Map) maps.Map {
|
||||
installDir := strings.TrimSpace(cluster.GetString("installDir"))
|
||||
if len(installDir) == 0 {
|
||||
installDir = "/opt/edge-httpdns"
|
||||
}
|
||||
|
||||
return maps.Map{
|
||||
"name": cluster.GetString("name"),
|
||||
"gatewayDomain": strings.TrimSpace(cluster.GetString("gatewayDomain")),
|
||||
"cacheTtl": cluster.GetInt("cacheTtl"),
|
||||
"fallbackTimeout": cluster.GetInt("fallbackTimeout"),
|
||||
"installDir": installDir,
|
||||
"isOn": cluster.GetBool("isOn"),
|
||||
"originHttps": true,
|
||||
"originCertPem": "",
|
||||
"originKeyPem": "",
|
||||
"tlsMinVersion": "TLS 1.1",
|
||||
"tlsCipherSuitesOn": false,
|
||||
"tlsOcspOn": false,
|
||||
"tlsClientAuthType": 0,
|
||||
"certUpdatedAt": "",
|
||||
"lastModifiedAt": "",
|
||||
}
|
||||
}
|
||||
|
||||
func cloneClusterSettings(settings maps.Map) maps.Map {
|
||||
return maps.Map{
|
||||
"name": settings.GetString("name"),
|
||||
"gatewayDomain": settings.GetString("gatewayDomain"),
|
||||
"cacheTtl": settings.GetInt("cacheTtl"),
|
||||
"fallbackTimeout": settings.GetInt("fallbackTimeout"),
|
||||
"installDir": settings.GetString("installDir"),
|
||||
"isOn": settings.GetBool("isOn"),
|
||||
"originHttps": true,
|
||||
"originCertPem": settings.GetString("originCertPem"),
|
||||
"originKeyPem": settings.GetString("originKeyPem"),
|
||||
"tlsMinVersion": settings.GetString("tlsMinVersion"),
|
||||
"tlsCipherSuitesOn": settings.GetBool("tlsCipherSuitesOn"),
|
||||
"tlsOcspOn": settings.GetBool("tlsOcspOn"),
|
||||
"tlsClientAuthType": settings.GetInt("tlsClientAuthType"),
|
||||
"certUpdatedAt": settings.GetString("certUpdatedAt"),
|
||||
"lastModifiedAt": settings.GetString("lastModifiedAt"),
|
||||
}
|
||||
}
|
||||
|
||||
func loadClusterSettings(cluster maps.Map) maps.Map {
|
||||
clusterId := cluster.GetInt64("id")
|
||||
|
||||
clusterSettingsStore.RLock()
|
||||
settings, ok := clusterSettingsStore.data[clusterId]
|
||||
clusterSettingsStore.RUnlock()
|
||||
if ok {
|
||||
if len(settings.GetString("tlsMinVersion")) == 0 {
|
||||
settings["tlsMinVersion"] = "TLS 1.1"
|
||||
}
|
||||
return cloneClusterSettings(settings)
|
||||
}
|
||||
|
||||
settings = defaultClusterSettings(cluster)
|
||||
saveClusterSettings(clusterId, settings)
|
||||
return cloneClusterSettings(settings)
|
||||
}
|
||||
|
||||
func saveClusterSettings(clusterId int64, settings maps.Map) {
|
||||
clusterSettingsStore.Lock()
|
||||
clusterSettingsStore.data[clusterId] = cloneClusterSettings(settings)
|
||||
clusterSettingsStore.Unlock()
|
||||
}
|
||||
|
||||
func applyClusterSettingsOverrides(cluster maps.Map) {
|
||||
clusterId := cluster.GetInt64("id")
|
||||
if clusterId <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
clusterSettingsStore.RLock()
|
||||
settings, ok := clusterSettingsStore.data[clusterId]
|
||||
clusterSettingsStore.RUnlock()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
cluster["name"] = settings.GetString("name")
|
||||
cluster["gatewayDomain"] = settings.GetString("gatewayDomain")
|
||||
cluster["cacheTtl"] = settings.GetInt("cacheTtl")
|
||||
cluster["fallbackTimeout"] = settings.GetInt("fallbackTimeout")
|
||||
cluster["installDir"] = settings.GetString("installDir")
|
||||
cluster["isOn"] = settings.GetBool("isOn")
|
||||
}
|
||||
|
||||
func nowDateTime() string {
|
||||
return time.Now().Format("2006-01-02 15:04:05")
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package clusters
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type CreateNodeAction struct {
|
||||
@@ -11,14 +10,18 @@ type CreateNodeAction struct {
|
||||
}
|
||||
|
||||
func (this *CreateNodeAction) Init() {
|
||||
this.Nav("", "node", "createNode")
|
||||
this.SecondMenu("nodes")
|
||||
this.Nav("httpdns", "cluster", "createNode")
|
||||
}
|
||||
|
||||
func (this *CreateNodeAction) RunGet(params struct{ ClusterId int64 }) {
|
||||
httpdnsutils.AddLeftMenu(this.Parent())
|
||||
cluster := pickCluster(params.ClusterId)
|
||||
|
||||
// 构建顶部 tabbar
|
||||
httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "node")
|
||||
|
||||
this.Data["clusterId"] = params.ClusterId
|
||||
this.Data["cluster"] = maps.Map{"id": params.ClusterId, "name": "Mock Cluster"}
|
||||
this.Data["cluster"] = cluster
|
||||
this.Show()
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ func (this *DeleteAction) RunGet(params struct {
|
||||
}) {
|
||||
httpdnsutils.AddLeftMenu(this.Parent())
|
||||
cluster := pickCluster(params.ClusterId)
|
||||
|
||||
// 构建顶部 tabbar
|
||||
httpdnsutils.AddClusterTabbar(this.Parent(), cluster.GetString("name"), params.ClusterId, "delete")
|
||||
|
||||
this.Data["cluster"] = cluster
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package clusters
|
||||
import "github.com/iwind/TeaGo/maps"
|
||||
|
||||
func mockClusters() []maps.Map {
|
||||
return []maps.Map{
|
||||
clusters := []maps.Map{
|
||||
{
|
||||
"id": int64(1),
|
||||
"name": "gateway-cn-hz",
|
||||
@@ -31,6 +31,12 @@ func mockClusters() []maps.Map {
|
||||
"isOn": true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, cluster := range clusters {
|
||||
applyClusterSettingsOverrides(cluster)
|
||||
}
|
||||
|
||||
return clusters
|
||||
}
|
||||
|
||||
func pickCluster(clusterId int64) maps.Map {
|
||||
|
||||
Reference in New Issue
Block a user