换成单集群模式

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

View File

@@ -1,15 +1,14 @@
package apps
import (
"encoding/json"
"strconv"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/httpdns/httpdnsutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
)
type AppSettingsAction struct {
@@ -60,55 +59,70 @@ func (this *AppSettingsAction) RunGet(params struct {
return
}
clusters := make([]maps.Map, 0, len(clusterResp.GetClusters()))
clusterDomainMap := map[int64]string{}
clusterApiAddressMap := map[int64]string{}
clusterNameMap := map[int64]string{}
defaultPrimaryClusterId := int64(0)
for _, cluster := range clusterResp.GetClusters() {
clusterId := cluster.GetId()
clusterName := cluster.GetName()
port := "443"
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
var tlsConfig map[string]interface{}
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
if listenRaw, ok := tlsConfig["listen"]; ok && listenRaw != nil {
if data, err := json.Marshal(listenRaw); err == nil {
var listenAddresses []map[string]interface{}
if err := json.Unmarshal(data, &listenAddresses); err == nil {
if len(listenAddresses) > 0 {
if portRange, ok := listenAddresses[0]["portRange"].(string); ok && len(portRange) > 0 {
port = portRange
}
}
}
}
}
}
}
apiAddress := "https://" + cluster.GetServiceDomain() + ":" + port
clusters = append(clusters, maps.Map{
"id": clusterId,
"name": clusterName,
"serviceDomain": cluster.GetServiceDomain(),
"isDefault": cluster.GetIsDefault(),
"id": clusterId,
"name": clusterName,
})
clusterDomainMap[clusterId] = cluster.GetServiceDomain()
clusterApiAddressMap[clusterId] = apiAddress
clusterNameMap[clusterId] = clusterName
if defaultPrimaryClusterId <= 0 && cluster.GetIsDefault() {
defaultPrimaryClusterId = clusterId
}
// 读取应用绑定的集群列表,取第一个作为当前选中。
var selectedClusterId int64
if raw := app.Get("clusterIds"); raw != nil {
if ids, ok := raw.([]int64); ok && len(ids) > 0 {
selectedClusterId = ids[0]
}
}
defaultBackupClusterId := int64(0)
defaultBackupResp, err := this.RPC().SysSettingRPC().ReadSysSetting(this.AdminContext(), &pb.ReadSysSettingRequest{
Code: string(systemconfigs.SettingCodeHTTPDNSDefaultBackupClusterId),
})
if err != nil {
this.ErrorPage(err)
return
// 构建服务地址列表。
serviceAddresses := make([]maps.Map, 0)
if selectedClusterId > 0 {
addr := clusterApiAddressMap[selectedClusterId]
name := clusterNameMap[selectedClusterId]
if len(addr) > 0 {
serviceAddresses = append(serviceAddresses, maps.Map{
"address": addr,
"clusterName": name,
})
}
}
if defaultBackupResp != nil && len(defaultBackupResp.GetValueJSON()) > 0 {
defaultBackupClusterId = types.Int64(string(defaultBackupResp.GetValueJSON()))
}
primaryClusterId := app.GetInt64("primaryClusterId")
backupClusterId := app.GetInt64("backupClusterId")
settings := maps.Map{
"appId": app.GetString("appId"),
"appStatus": app.GetBool("isOn"),
"primaryClusterId": primaryClusterId,
"backupClusterId": backupClusterId,
"defaultPrimaryClusterId": defaultPrimaryClusterId,
"defaultPrimaryClusterName": clusterNameMap[defaultPrimaryClusterId],
"defaultBackupClusterId": defaultBackupClusterId,
"defaultBackupClusterName": clusterNameMap[defaultBackupClusterId],
"primaryServiceDomain": clusterDomainMap[primaryClusterId],
"backupServiceDomain": clusterDomainMap[backupClusterId],
"signEnabled": app.GetBool("signEnabled"),
"signSecretPlain": app.GetString("signSecretPlain"),
"signSecretMasked": app.GetString("signSecretMasked"),
"signSecretUpdatedAt": app.GetString("signSecretUpdated"),
"appId": app.GetString("appId"),
"appStatus": app.GetBool("isOn"),
"selectedClusterId": selectedClusterId,
"serviceAddresses": serviceAddresses,
"signEnabled": app.GetBool("signEnabled"),
"signSecretPlain": app.GetString("signSecretPlain"),
"signSecretMasked": app.GetString("signSecretMasked"),
"signSecretUpdatedAt": app.GetString("signSecretUpdated"),
}
this.Data["app"] = app
this.Data["settings"] = settings
@@ -119,18 +133,13 @@ func (this *AppSettingsAction) RunGet(params struct {
func (this *AppSettingsAction) RunPost(params struct {
AppId int64
AppStatus bool
PrimaryClusterId int64
BackupClusterId int64
AppStatus bool
ClusterId int64
Must *actions.Must
CSRF *actionutils.CSRF
}) {
params.Must.Field("appId", params.AppId).Gt(0, "请选择应用")
if params.PrimaryClusterId > 0 && params.BackupClusterId > 0 && params.PrimaryClusterId == params.BackupClusterId {
this.FailField("backupClusterId", "备用集群不能与主集群相同")
return
}
appResp, err := this.RPC().HTTPDNSAppRPC().FindHTTPDNSApp(this.AdminContext(), &pb.FindHTTPDNSAppRequest{
AppDbId: params.AppId,
@@ -144,13 +153,18 @@ func (this *AppSettingsAction) RunPost(params struct {
return
}
var clusterIds []int64
if params.ClusterId > 0 {
clusterIds = []int64{params.ClusterId}
}
clusterIdsJSON, _ := json.Marshal(clusterIds)
_, err = this.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(this.AdminContext(), &pb.UpdateHTTPDNSAppRequest{
AppDbId: params.AppId,
Name: appResp.GetApp().GetName(),
PrimaryClusterId: params.PrimaryClusterId,
BackupClusterId: params.BackupClusterId,
IsOn: params.AppStatus,
UserId: appResp.GetApp().GetUserId(),
AppDbId: params.AppId,
Name: appResp.GetApp().GetName(),
ClusterIdsJSON: clusterIdsJSON,
IsOn: params.AppStatus,
UserId: appResp.GetApp().GetUserId(),
})
if err != nil {
this.ErrorPage(err)

View File

@@ -1,6 +1,7 @@
package apps
import (
"encoding/json"
"strconv"
"time"
@@ -33,28 +34,6 @@ func (this *CreateAction) RunGet(params struct{}) {
}
this.Data["clusters"] = clusters
defaultPrimaryClusterId := int64(0)
for _, cluster := range clusterResp.GetClusters() {
if cluster.GetIsDefault() {
defaultPrimaryClusterId = cluster.GetId()
break
}
}
if defaultPrimaryClusterId <= 0 && len(clusters) > 0 {
defaultPrimaryClusterId = clusters[0].GetInt64("id")
}
this.Data["defaultPrimaryClusterId"] = defaultPrimaryClusterId
defaultBackupClusterId := int64(0)
for _, cluster := range clusters {
clusterId := cluster.GetInt64("id")
if clusterId > 0 && clusterId != defaultPrimaryClusterId {
defaultBackupClusterId = clusterId
break
}
}
this.Data["defaultBackupClusterId"] = defaultBackupClusterId
usersResp, err := this.RPC().UserRPC().ListEnabledUsers(this.AdminContext(), &pb.ListEnabledUsersRequest{
Offset: 0,
Size: 10_000,
@@ -77,28 +56,28 @@ func (this *CreateAction) RunGet(params struct{}) {
}
func (this *CreateAction) RunPost(params struct {
Name string
PrimaryClusterId int64
BackupClusterId int64
UserId int64
Name string
ClusterId int64
UserId int64
Must *actions.Must
CSRF *actionutils.CSRF
}) {
params.Must.Field("name", params.Name).Require("请输入应用名称")
params.Must.Field("primaryClusterId", params.PrimaryClusterId).Gt(0, "请输入主服务集群")
if params.BackupClusterId > 0 && params.BackupClusterId == params.PrimaryClusterId {
this.FailField("backupClusterId", "备用服务集群必须和主服务集群不一致")
if params.ClusterId <= 0 {
this.FailField("clusterId", "请选择集群")
return
}
clusterIdsJSON, _ := json.Marshal([]int64{params.ClusterId})
createResp, err := this.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(this.AdminContext(), &pb.CreateHTTPDNSAppRequest{
Name: params.Name,
AppId: "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36),
PrimaryClusterId: params.PrimaryClusterId,
BackupClusterId: params.BackupClusterId,
IsOn: true,
SignEnabled: true,
UserId: params.UserId,
Name: params.Name,
AppId: "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36),
ClusterIdsJSON: clusterIdsJSON,
IsOn: true,
SignEnabled: true,
UserId: params.UserId,
})
if err != nil {
this.ErrorPage(err)

View File

@@ -24,5 +24,6 @@ func (this *IndexAction) RunGet(params struct {
return
}
this.Data["apps"] = apps
this.Data["page"] = ""
this.Show()
}

View File

@@ -1,6 +1,7 @@
package apps
import (
"encoding/json"
"strconv"
"strings"
"time"
@@ -87,15 +88,14 @@ func findAppMap(parent *actionutils.ParentAction, appDbId int64) (maps.Map, erro
return apps[0], nil
}
func createApp(parent *actionutils.ParentAction, name string, primaryClusterId int64, backupClusterId int64) (int64, error) {
func createApp(parent *actionutils.ParentAction, name string, clusterIdsJSON []byte) (int64, error) {
newAppId := "app" + strconv.FormatInt(time.Now().UnixNano()%1_000_000_000_000, 36)
resp, err := parent.RPC().HTTPDNSAppRPC().CreateHTTPDNSApp(parent.AdminContext(), &pb.CreateHTTPDNSAppRequest{
Name: strings.TrimSpace(name),
AppId: newAppId,
PrimaryClusterId: primaryClusterId,
BackupClusterId: backupClusterId,
IsOn: true,
SignEnabled: true,
Name: strings.TrimSpace(name),
AppId: newAppId,
ClusterIdsJSON: clusterIdsJSON,
IsOn: true,
SignEnabled: true,
})
if err != nil {
return 0, err
@@ -110,14 +110,13 @@ func deleteAppByID(parent *actionutils.ParentAction, appDbId int64) error {
return err
}
func updateAppSettings(parent *actionutils.ParentAction, appDbId int64, name string, primaryClusterId int64, backupClusterId int64, isOn bool, userId int64) error {
func updateAppSettings(parent *actionutils.ParentAction, appDbId int64, name string, clusterIdsJSON []byte, isOn bool, userId int64) error {
_, err := parent.RPC().HTTPDNSAppRPC().UpdateHTTPDNSApp(parent.AdminContext(), &pb.UpdateHTTPDNSAppRequest{
AppDbId: appDbId,
Name: strings.TrimSpace(name),
PrimaryClusterId: primaryClusterId,
BackupClusterId: backupClusterId,
IsOn: isOn,
UserId: userId,
AppDbId: appDbId,
Name: strings.TrimSpace(name),
ClusterIdsJSON: clusterIdsJSON,
IsOn: isOn,
UserId: userId,
})
return err
}
@@ -277,13 +276,24 @@ func toggleCustomRule(parent *actionutils.ParentAction, ruleId int64, isOn bool)
return err
}
func appPBToMap(app *pb.HTTPDNSApp, domainCount int64, clusterNameMap map[int64]string, userMapByID map[int64]maps.Map) maps.Map {
func appPBToMap(app *pb.HTTPDNSApp, domainCount int64, clusterMapByID map[int64]maps.Map, userMapByID map[int64]maps.Map) maps.Map {
signSecret := app.GetSignSecret()
primaryClusterID := app.GetPrimaryClusterId()
backupClusterID := app.GetBackupClusterId()
primaryClusterMap := maps.Map{"id": primaryClusterID, "name": clusterNameMap[primaryClusterID]}
backupClusterMap := maps.Map{"id": backupClusterID, "name": clusterNameMap[backupClusterID]}
// 读取集群 ID 列表
var clusterIds []int64
if len(app.GetClusterIdsJSON()) > 0 {
_ = json.Unmarshal(app.GetClusterIdsJSON(), &clusterIds)
}
// 构建集群映射列表
var clusterMaps []maps.Map
for _, cid := range clusterIds {
cm := clusterMapByID[cid]
if cm == nil {
cm = maps.Map{"id": cid, "name": "", "apiAddress": ""}
}
clusterMaps = append(clusterMaps, cm)
}
var userMap maps.Map
if app.GetUserId() > 0 {
@@ -301,11 +311,8 @@ func appPBToMap(app *pb.HTTPDNSApp, domainCount int64, clusterNameMap map[int64]
"id": app.GetId(),
"name": app.GetName(),
"appId": app.GetAppId(),
"clusterId": primaryClusterID,
"primaryClusterId": primaryClusterID,
"backupClusterId": backupClusterID,
"primaryCluster": primaryClusterMap,
"backupCluster": backupClusterMap,
"clusterIds": clusterIds,
"clusters": clusterMaps,
"userId": app.GetUserId(),
"user": userMap,
"isOn": app.GetIsOn(),
@@ -318,15 +325,37 @@ func appPBToMap(app *pb.HTTPDNSApp, domainCount int64, clusterNameMap map[int64]
}
}
func loadHTTPDNSClusterNameMap(parent *actionutils.ParentAction) (map[int64]string, error) {
func loadHTTPDNSClusterNameMap(parent *actionutils.ParentAction) (map[int64]maps.Map, error) {
resp, err := parent.RPC().HTTPDNSClusterRPC().FindAllHTTPDNSClusters(parent.AdminContext(), &pb.FindAllHTTPDNSClustersRequest{})
if err != nil {
return nil, err
}
result := map[int64]string{}
result := map[int64]maps.Map{}
for _, cluster := range resp.GetClusters() {
result[cluster.GetId()] = cluster.GetName()
port := "443"
if rawTLS := cluster.GetTlsPolicyJSON(); len(rawTLS) > 0 {
tlsConfig := maps.Map{}
if err := json.Unmarshal(rawTLS, &tlsConfig); err == nil {
if listenRaw := tlsConfig.Get("listen"); listenRaw != nil {
var listenAddresses []maps.Map
if data, err := json.Marshal(listenRaw); err == nil {
if err := json.Unmarshal(data, &listenAddresses); err == nil {
if len(listenAddresses) > 0 && len(listenAddresses[0].GetString("portRange")) > 0 {
port = listenAddresses[0].GetString("portRange")
}
}
}
}
}
}
apiAddress := "https://" + cluster.GetServiceDomain() + ":" + port
result[cluster.GetId()] = maps.Map{
"id": cluster.GetId(),
"name": cluster.GetName(),
"apiAddress": apiAddress,
}
}
return result, nil
}