diff --git a/internal/web/actions/default/clusters/cluster/createNode.go b/internal/web/actions/default/clusters/cluster/createNode.go index 15f3343a..8d844e14 100644 --- a/internal/web/actions/default/clusters/cluster/createNode.go +++ b/internal/web/actions/default/clusters/cluster/createNode.go @@ -11,7 +11,7 @@ import ( "strconv" ) -// 创建节点 +// CreateNodeAction 创建节点 type CreateNodeAction struct { actionutils.ParentAction } @@ -57,8 +57,10 @@ func (this *CreateNodeAction) RunGet(params struct { } for _, route := range routesResp.Routes { dnsRouteMaps = append(dnsRouteMaps, maps.Map{ - "name": route.Name, - "code": route.Code, + "domainId": domainId, + "domainName": clusterDNSResp.Domain.Name, + "name": route.Name, + "code": route.Code, }) } } diff --git a/internal/web/actions/default/clusters/cluster/node/detail.go b/internal/web/actions/default/clusters/cluster/node/detail.go index d5f7b398..4f49d8b5 100644 --- a/internal/web/actions/default/clusters/cluster/node/detail.go +++ b/internal/web/actions/default/clusters/cluster/node/detail.go @@ -3,6 +3,7 @@ package node import ( "encoding/json" "fmt" + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils" @@ -37,6 +38,7 @@ func (this *DetailAction) RunGet(params struct { return } + // 主集群 var clusterMap maps.Map = nil if node.NodeCluster != nil { clusterId := node.NodeCluster.Id @@ -55,6 +57,16 @@ func (this *DetailAction) RunGet(params struct { } } + // 从集群 + var secondaryClustersMaps = []maps.Map{} + for _, cluster := range node.SecondaryNodeClusters { + secondaryClustersMaps = append(secondaryClustersMaps, maps.Map{ + "id": cluster.Id, + "name": cluster.Name, + "isOn": cluster.IsOn, + }) + } + // IP地址 ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{ NodeId: params.NodeId, @@ -64,6 +76,7 @@ func (this *DetailAction) RunGet(params struct { this.ErrorPage(err) return } + var ipAddresses = ipAddressesResp.Addresses ipAddressMaps := []maps.Map{} for _, addr := range ipAddressesResp.Addresses { ipAddressMaps = append(ipAddressMaps, maps.Map{ @@ -75,33 +88,56 @@ func (this *DetailAction) RunGet(params struct { } // DNS相关 - dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId}) - if err != nil { - this.ErrorPage(err) - return - } - dnsRouteMaps := []maps.Map{} - recordName := "" - recordValue := "" - if dnsInfoResp.Node != nil { - recordName = dnsInfoResp.Node.NodeClusterDNSName + "." + dnsInfoResp.Node.DnsDomainName - recordValue = dnsInfoResp.Node.IpAddr - for _, dnsInfo := range dnsInfoResp.Node.Routes { - dnsRouteMaps = append(dnsRouteMaps, maps.Map{ - "name": dnsInfo.Name, - "code": dnsInfo.Code, - }) + var clusters = []*pb.NodeCluster{node.NodeCluster} + clusters = append(clusters, node.SecondaryNodeClusters...) + var recordMaps = []maps.Map{} + var routeMaps = []maps.Map{} + for _, cluster := range clusters { + dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{ + NodeId: params.NodeId, + NodeClusterId: cluster.Id, + }) + if err != nil { + this.ErrorPage(err) + return + } + var dnsInfo = dnsInfoResp.Node + if len(dnsInfo.DnsDomainName) == 0 || len(dnsInfo.NodeClusterDNSName) == 0 { + continue + } + var domainName = dnsInfo.DnsDomainName + + // 默认线路 + if len(dnsInfo.Routes) == 0 { + dnsInfo.Routes = append(dnsInfo.Routes, &pb.DNSRoute{}) + } else { + for _, route := range dnsInfo.Routes { + routeMaps = append(routeMaps, maps.Map{ + "domainName": domainName, + "code": route.Code, + "name": route.Name, + }) + } + } + + for _, addr := range ipAddresses { + if !addr.CanAccess { + continue + } + for _, route := range dnsInfo.Routes { + var recordType = "A" + if utils.IsIPv6(addr.Ip) { + recordType = "AAAA" + } + recordMaps = append(recordMaps, maps.Map{ + "name": dnsInfo.NodeClusterDNSName + "." + domainName, + "type": recordType, + "route": route.Name, + "value": addr.Ip, + }) + } } } - if len(dnsRouteMaps) == 0 { - dnsRouteMaps = append(dnsRouteMaps, maps.Map{ - "name": "", - "code": "", - }) - } - this.Data["dnsRoutes"] = dnsRouteMaps - this.Data["dnsRecordName"] = recordName - this.Data["dnsRecordValue"] = recordValue // 登录信息 var loginMap maps.Map = nil @@ -217,17 +253,20 @@ func (this *DetailAction) RunGet(params struct { } this.Data["node"] = maps.Map{ - "id": node.Id, - "name": node.Name, - "ipAddresses": ipAddressMaps, - "cluster": clusterMap, - "login": loginMap, - "installDir": node.InstallDir, - "isInstalled": node.IsInstalled, - "uniqueId": node.UniqueId, - "secret": node.Secret, - "maxCPU": node.MaxCPU, - "isOn": node.IsOn, + "id": node.Id, + "name": node.Name, + "ipAddresses": ipAddressMaps, + "cluster": clusterMap, + "secondaryClusters": secondaryClustersMaps, + "login": loginMap, + "installDir": node.InstallDir, + "isInstalled": node.IsInstalled, + "uniqueId": node.UniqueId, + "secret": node.Secret, + "maxCPU": node.MaxCPU, + "isOn": node.IsOn, + "records": recordMaps, + "routes": routeMaps, "status": maps.Map{ "isActive": status.IsActive, diff --git a/internal/web/actions/default/clusters/cluster/node/update.go b/internal/web/actions/default/clusters/cluster/node/update.go index 583b5967..b3bc8e87 100644 --- a/internal/web/actions/default/clusters/cluster/node/update.go +++ b/internal/web/actions/default/clusters/cluster/node/update.go @@ -66,44 +66,64 @@ func (this *UpdateAction) RunGet(params struct { } // DNS相关 - dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId}) - if err != nil { - this.ErrorPage(err) - return - } - nodeDNS := dnsInfoResp.Node - dnsRouteMaps := []maps.Map{} - if nodeDNS != nil { - for _, dnsInfo := range nodeDNS.Routes { - dnsRouteMaps = append(dnsRouteMaps, maps.Map{ - "name": dnsInfo.Name, - "code": dnsInfo.Code, - }) + var clusters = []*pb.NodeCluster{node.NodeCluster} + clusters = append(clusters, node.SecondaryNodeClusters...) + var allDNSRouteMaps = map[int64][]maps.Map{} // domain id => routes + var routeMaps = map[int64][]maps.Map{} // domain id => routes + for _, cluster := range clusters { + dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{ + NodeId: params.NodeId, + NodeClusterId: cluster.Id, + }) + if err != nil { + this.ErrorPage(err) + return } - } - this.Data["dnsRoutes"] = dnsRouteMaps - this.Data["allDNSRoutes"] = []maps.Map{} - if nodeDNS != nil { - this.Data["dnsDomainId"] = nodeDNS.DnsDomainId - } else { - this.Data["dnsDomainId"] = 0 - } - if nodeDNS != nil && nodeDNS.DnsDomainId > 0 { - routesMaps := []maps.Map{} + var dnsInfo = dnsInfoResp.Node + if dnsInfo.DnsDomainId <= 0 || len(dnsInfo.DnsDomainName) == 0 { + continue + } + var domainId = dnsInfo.DnsDomainId + var domainName = dnsInfo.DnsDomainName + if len(dnsInfo.Routes) > 0 { + for _, route := range dnsInfo.Routes { + routeMaps[domainId] = append(routeMaps[domainId], maps.Map{ + "domainId": domainId, + "domainName": domainName, + "code": route.Code, + "name": route.Name, + }) + } + } + + // 所有线路选项 routesResp, err := this.RPC().DNSDomainRPC().FindAllDNSDomainRoutes(this.AdminContext(), &pb.FindAllDNSDomainRoutesRequest{DnsDomainId: dnsInfoResp.Node.DnsDomainId}) if err != nil { this.ErrorPage(err) return } for _, route := range routesResp.Routes { - routesMaps = append(routesMaps, maps.Map{ - "name": route.Name, - "code": route.Code, + allDNSRouteMaps[domainId] = append(allDNSRouteMaps[domainId], maps.Map{ + "domainId": domainId, + "domainName": domainName, + "name": route.Name, + "code": route.Code, }) } - this.Data["allDNSRoutes"] = routesMaps } + var domainRoutes = []maps.Map{} + for _, m := range routeMaps { + domainRoutes = append(domainRoutes, m...) + } + this.Data["dnsRoutes"] = domainRoutes + + var allDomainRoutes = []maps.Map{} + for _, m := range allDNSRouteMaps { + allDomainRoutes = append(allDomainRoutes, m...) + } + this.Data["allDNSRoutes"] = allDomainRoutes + // 登录信息 var loginMap maps.Map = nil if node.Login != nil { @@ -188,7 +208,7 @@ func (this *UpdateAction) RunGet(params struct { } } - this.Data["node"] = maps.Map{ + var m = maps.Map{ "id": node.Id, "name": node.Name, "ipAddresses": ipAddressMaps, @@ -202,23 +222,29 @@ func (this *UpdateAction) RunGet(params struct { "maxCacheMemoryCapacity": maxCacheMemoryCapacity, } - // 所有集群 - resp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClusters(this.AdminContext(), &pb.FindAllEnabledNodeClustersRequest{}) - if err != nil { - this.ErrorPage(err) + if node.NodeCluster != nil { + m["primaryCluster"] = maps.Map{ + "id": node.NodeCluster.Id, + "name": node.NodeCluster.Name, + } + } else { + m["primaryCluster"] = nil } - if err != nil { - this.ErrorPage(err) - return + + if len(node.SecondaryNodeClusters) > 0 { + var secondaryClusterMaps = []maps.Map{} + for _, cluster := range node.SecondaryNodeClusters { + secondaryClusterMaps = append(secondaryClusterMaps, maps.Map{ + "id": cluster.Id, + "name": cluster.Name, + }) + } + m["secondaryClusters"] = secondaryClusterMaps + } else { + m["secondaryClusters"] = []interface{}{} } - clusterMaps := []maps.Map{} - for _, cluster := range resp.NodeClusters { - clusterMaps = append(clusterMaps, maps.Map{ - "id": cluster.Id, - "name": cluster.Name, - }) - } - this.Data["clusters"] = clusterMaps + + this.Data["node"] = m this.Show() } @@ -230,7 +256,8 @@ func (this *UpdateAction) RunPost(params struct { RegionId int64 Name string IPAddressesJSON []byte `alias:"ipAddressesJSON"` - ClusterId int64 + PrimaryClusterId int64 + SecondaryClusterIds []byte GrantId int64 SshHost string SshPort int @@ -256,8 +283,17 @@ func (this *UpdateAction) RunPost(params struct { Require("请输入节点名称") // TODO 检查cluster - if params.ClusterId <= 0 { - this.Fail("请选择所在集群") + if params.PrimaryClusterId <= 0 { + this.Fail("请选择节点所在主集群") + } + + var secondaryClusterIds = []int64{} + if len(params.SecondaryClusterIds) > 0 { + err := json.Unmarshal(params.SecondaryClusterIds, &secondaryClusterIds) + if err != nil { + this.ErrorPage(err) + return + } } // IP地址 @@ -325,18 +361,19 @@ func (this *UpdateAction) RunPost(params struct { // 保存 _, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{ - NodeId: params.NodeId, - NodeGroupId: params.GroupId, - NodeRegionId: params.RegionId, - Name: params.Name, - NodeClusterId: params.ClusterId, - NodeLogin: loginInfo, - MaxCPU: params.MaxCPU, - IsOn: params.IsOn, - DnsDomainId: params.DnsDomainId, - DnsRoutes: dnsRouteCodes, - MaxCacheDiskCapacity: pbMaxCacheDiskCapacity, - MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity, + NodeId: params.NodeId, + NodeGroupId: params.GroupId, + NodeRegionId: params.RegionId, + Name: params.Name, + NodeClusterId: params.PrimaryClusterId, + SecondaryNodeClusterIds: secondaryClusterIds, + NodeLogin: loginInfo, + MaxCPU: params.MaxCPU, + IsOn: params.IsOn, + DnsDomainId: params.DnsDomainId, + DnsRoutes: dnsRouteCodes, + MaxCacheDiskCapacity: pbMaxCacheDiskCapacity, + MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity, }) if err != nil { this.ErrorPage(err) diff --git a/internal/web/actions/default/clusters/cluster/nodes.go b/internal/web/actions/default/clusters/cluster/nodes.go index bf64b49b..9e884f4b 100644 --- a/internal/web/actions/default/clusters/cluster/nodes.go +++ b/internal/web/actions/default/clusters/cluster/nodes.go @@ -156,6 +156,16 @@ func (this *NodesAction) RunGet(params struct { dnsRouteNames = append(dnsRouteNames, route.Name) } + // 从集群 + var secondaryClusterMaps []maps.Map + for _, secondaryCluster := range node.SecondaryNodeClusters { + secondaryClusterMaps = append(secondaryClusterMaps, maps.Map{ + "id": secondaryCluster.Id, + "name": secondaryCluster.Name, + "isOn": secondaryCluster.IsOn, + }) + } + nodeMaps = append(nodeMaps, maps.Map{ "id": node.Id, "name": node.Name, @@ -183,11 +193,12 @@ func (this *NodesAction) RunGet(params struct { "id": node.NodeCluster.Id, "name": node.NodeCluster.Name, }, - "isSynced": isSynced, - "ipAddresses": ipAddresses, - "group": groupMap, - "region": regionMap, - "dnsRouteNames": dnsRouteNames, + "secondaryClusters": secondaryClusterMaps, + "isSynced": isSynced, + "ipAddresses": ipAddresses, + "group": groupMap, + "region": regionMap, + "dnsRouteNames": dnsRouteNames, }) } this.Data["nodes"] = nodeMaps diff --git a/internal/web/actions/default/clusters/cluster/settings/dns/index.go b/internal/web/actions/default/clusters/cluster/settings/dns/index.go index 89625f1d..5069518f 100644 --- a/internal/web/actions/default/clusters/cluster/settings/dns/index.go +++ b/internal/web/actions/default/clusters/cluster/settings/dns/index.go @@ -63,6 +63,14 @@ func (this *IndexAction) RunPost(params struct { // 创建日志 defer this.CreateLog(oplogs.LevelInfo, "修改集群 %d DNS设置", params.ClusterId) + if params.DnsDomainId <= 0 { + this.Fail("请选择集群的主域名") + } + + params.Must. + Field("dnsName", params.DnsName). + Require("请输入DNS子域名") + // 检查DNS名称 if len(params.DnsName) > 0 { if !domainutils.ValidateDomainFormat(params.DnsName) { diff --git a/internal/web/actions/default/clusters/index.go b/internal/web/actions/default/clusters/index.go index 93de9088..f639aa21 100644 --- a/internal/web/actions/default/clusters/index.go +++ b/internal/web/actions/default/clusters/index.go @@ -235,6 +235,16 @@ func (this *IndexAction) searchNodes(keyword string) { dnsRouteNames = append(dnsRouteNames, route.Name) } + // 从集群 + var secondaryClusterMaps []maps.Map + for _, secondaryCluster := range node.SecondaryNodeClusters { + secondaryClusterMaps = append(secondaryClusterMaps, maps.Map{ + "id": secondaryCluster.Id, + "name": secondaryCluster.Name, + "isOn": secondaryCluster.IsOn, + }) + } + nodeMaps = append(nodeMaps, maps.Map{ "id": node.Id, "name": node.Name, @@ -260,11 +270,12 @@ func (this *IndexAction) searchNodes(keyword string) { "id": node.NodeCluster.Id, "name": node.NodeCluster.Name, }, - "isSynced": isSynced, - "ipAddresses": ipAddresses, - "group": groupMap, - "region": regionMap, - "dnsRouteNames": dnsRouteNames, + "secondaryClusters": secondaryClusterMaps, + "isSynced": isSynced, + "ipAddresses": ipAddresses, + "group": groupMap, + "region": regionMap, + "dnsRouteNames": dnsRouteNames, }) } this.Data["nodes"] = nodeMaps diff --git a/internal/web/actions/default/clusters/init.go b/internal/web/actions/default/clusters/init.go index d4fe830b..d42f2332 100644 --- a/internal/web/actions/default/clusters/init.go +++ b/internal/web/actions/default/clusters/init.go @@ -20,6 +20,7 @@ func init() { EndHelpers(). Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeCommon)). Post("/options", new(OptionsAction)). + GetPost("/selectPopup", new(SelectPopupAction)). EndAll() }) diff --git a/internal/web/actions/default/clusters/selectPopup.go b/internal/web/actions/default/clusters/selectPopup.go new file mode 100644 index 00000000..970ed9a5 --- /dev/null +++ b/internal/web/actions/default/clusters/selectPopup.go @@ -0,0 +1,64 @@ +// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. + +package clusters + +import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" + "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/iwind/TeaGo/lists" + "github.com/iwind/TeaGo/maps" +) + +type SelectPopupAction struct { + actionutils.ParentAction +} + +func (this *SelectPopupAction) Init() { + this.Nav("", "", "") +} + +func (this *SelectPopupAction) RunGet(params struct { + SelectedClusterIds string +}) { + var selectedIds = utils.SplitNumbers(params.SelectedClusterIds) + + countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{}) + if err != nil { + this.ErrorPage(err) + return + } + var count = countResp.Count + var page = this.NewPage(count) + this.Data["page"] = page.AsHTML() + + clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{ + Offset: page.Offset, + Size: page.Size, + }) + if err != nil { + this.ErrorPage(err) + return + } + var clusterMaps = []maps.Map{} + for _, cluster := range clustersResp.NodeClusters { + // 节点数 + countNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{NodeClusterId: cluster.Id}) + if err != nil { + this.ErrorPage(err) + return + } + var countNodes = countNodesResp.Count + + clusterMaps = append(clusterMaps, maps.Map{ + "id": cluster.Id, + "name": cluster.Name, + "isOn": cluster.IsOn, + "countNodes": countNodes, + "isSelected": lists.ContainsInt64(selectedIds, cluster.Id), + }) + } + this.Data["clusters"] = clusterMaps + + this.Show() +} diff --git a/internal/web/actions/default/dns/domains/clustersPopup.go b/internal/web/actions/default/dns/domains/clustersPopup.go index 7edfebf6..0699166e 100644 --- a/internal/web/actions/default/dns/domains/clustersPopup.go +++ b/internal/web/actions/default/dns/domains/clustersPopup.go @@ -43,16 +43,21 @@ func (this *ClustersPopupAction) RunGet(params struct { for _, cluster := range clustersResp.NodeClusters { isOk := false if len(cluster.Name) > 0 { - checkResp, err := this.RPC().DNSDomainRPC().ExistDNSDomainRecord(this.AdminContext(), &pb.ExistDNSDomainRecordRequest{ - DnsDomainId: params.DomainId, - Name: cluster.DnsName, - Type: "A", - }) - if err != nil { - this.ErrorPage(err) - return + for _, recordType := range []string{"A", "AAAA"} { + checkResp, err := this.RPC().DNSDomainRPC().ExistDNSDomainRecord(this.AdminContext(), &pb.ExistDNSDomainRecordRequest{ + DnsDomainId: params.DomainId, + Name: cluster.DnsName, + Type: recordType, + }) + if err != nil { + this.ErrorPage(err) + return + } + if checkResp.IsOk { + isOk = true + break + } } - isOk = checkResp.IsOk } clusterMaps = append(clusterMaps, maps.Map{ diff --git a/internal/web/actions/default/dns/domains/domainutils/utils.go b/internal/web/actions/default/dns/domains/domainutils/utils.go index 4660c1a8..de0bb7ca 100644 --- a/internal/web/actions/default/dns/domains/domainutils/utils.go +++ b/internal/web/actions/default/dns/domains/domainutils/utils.go @@ -33,12 +33,17 @@ func ValidateDomainFormat(domain string) bool { } // ConvertRoutesToMaps 转换线路列表 -func ConvertRoutesToMaps(routes []*pb.DNSRoute) []maps.Map { +func ConvertRoutesToMaps(info *pb.NodeDNSInfo) []maps.Map { + if info == nil { + return []maps.Map{} + } result := []maps.Map{} - for _, route := range routes { + for _, route := range info.Routes { result = append(result, maps.Map{ - "name": route.Name, - "code": route.Code, + "name": route.Name, + "code": route.Code, + "domainId": info.DnsDomainId, + "domainName": info.DnsDomainName, }) } return result diff --git a/internal/web/actions/default/dns/domains/nodesPopup.go b/internal/web/actions/default/dns/domains/nodesPopup.go index b0a2cf4f..dd14749b 100644 --- a/internal/web/actions/default/dns/domains/nodesPopup.go +++ b/internal/web/actions/default/dns/domains/nodesPopup.go @@ -1,6 +1,7 @@ package domains import ( + "github.com/TeaOSLab/EdgeAdmin/internal/utils" "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils" "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/iwind/TeaGo/maps" @@ -55,10 +56,14 @@ func (this *NodesPopupAction) RunGet(params struct { // 检查是否有域名解析记录 isOk := false if len(route.Name) > 0 && len(node.IpAddr) > 0 && len(cluster.DnsName) > 0 { + var recordType = "A" + if utils.IsIPv6(node.IpAddr) { + recordType = "AAAA" + } checkResp, err := this.RPC().DNSDomainRPC().ExistDNSDomainRecord(this.AdminContext(), &pb.ExistDNSDomainRecordRequest{ DnsDomainId: params.DomainId, Name: cluster.DnsName, - Type: "A", + Type: recordType, Route: route.Code, Value: node.IpAddr, }) diff --git a/internal/web/actions/default/dns/issues/updateNodePopup.go b/internal/web/actions/default/dns/issues/updateNodePopup.go index d3944f3f..0615bbfe 100644 --- a/internal/web/actions/default/dns/issues/updateNodePopup.go +++ b/internal/web/actions/default/dns/issues/updateNodePopup.go @@ -20,11 +20,15 @@ func (this *UpdateNodePopupAction) Init() { } func (this *UpdateNodePopupAction) RunGet(params struct { - NodeId int64 + ClusterId int64 + NodeId int64 }) { this.Data["nodeId"] = params.NodeId - dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{NodeId: params.NodeId}) + dnsInfoResp, err := this.RPC().NodeRPC().FindEnabledNodeDNS(this.AdminContext(), &pb.FindEnabledNodeDNSRequest{ + NodeId: params.NodeId, + NodeClusterId: params.ClusterId, + }) if err != nil { this.ErrorPage(err) return @@ -35,7 +39,7 @@ func (this *UpdateNodePopupAction) RunGet(params struct { return } this.Data["ipAddr"] = dnsInfo.IpAddr - this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo.Routes) + this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo) this.Data["domainId"] = dnsInfo.DnsDomainId this.Data["domainName"] = dnsInfo.DnsDomainName @@ -50,13 +54,17 @@ func (this *UpdateNodePopupAction) RunGet(params struct { if len(routesResp.Routes) > 0 { for _, route := range routesResp.Routes { allRouteMaps = append(allRouteMaps, maps.Map{ - "name": route.Name, - "code": route.Code, + "name": route.Name, + "code": route.Code, + "domainName": dnsInfo.DnsDomainName, + "domainId": dnsInfo.DnsDomainId, }) } // 筛选 - this.Data["routes"] = domainutils.ConvertRoutesToMaps(domainutils.FilterRoutes(dnsInfo.Routes, routesResp.Routes)) + var routes = domainutils.FilterRoutes(dnsInfo.Routes, routesResp.Routes) + dnsInfo.Routes = routes + this.Data["routes"] = domainutils.ConvertRoutesToMaps(dnsInfo) } } this.Data["allRoutes"] = allRouteMaps diff --git a/internal/web/actions/default/nodes/delete.go b/internal/web/actions/default/nodes/delete.go index b18d1265..1a4422b5 100644 --- a/internal/web/actions/default/nodes/delete.go +++ b/internal/web/actions/default/nodes/delete.go @@ -10,12 +10,16 @@ type DeleteAction struct { } func (this *DeleteAction) RunPost(params struct { - NodeId int64 + ClusterId int64 + NodeId int64 }) { // 创建日志 - defer this.CreateLogInfo("删除节点", params.NodeId) + defer this.CreateLogInfo("从集群 %d 中删除节点 %d", params.ClusterId, params.NodeId) - _, err := this.RPC().NodeRPC().DeleteNode(this.AdminContext(), &pb.DeleteNodeRequest{NodeId: params.NodeId}) + _, err := this.RPC().NodeRPC().DeleteNodeFromNodeCluster(this.AdminContext(), &pb.DeleteNodeFromNodeClusterRequest{ + NodeId: params.NodeId, + NodeClusterId: params.ClusterId, + }) if err != nil { this.ErrorPage(err) return diff --git a/web/public/js/components/cluster/cluster-selector.js b/web/public/js/components/cluster/cluster-selector.js index 17faf648..6aa492f7 100644 --- a/web/public/js/components/cluster/cluster-selector.js +++ b/web/public/js/components/cluster/cluster-selector.js @@ -1,3 +1,4 @@ +// 单个集群选择 Vue.component("cluster-selector", { mounted: function () { let that = this diff --git a/web/public/js/components/cluster/node-clusters-labels.js b/web/public/js/components/cluster/node-clusters-labels.js new file mode 100644 index 00000000..53c233ab --- /dev/null +++ b/web/public/js/components/cluster/node-clusters-labels.js @@ -0,0 +1,28 @@ +// 显示节点的多个集群 +Vue.component("node-clusters-labels", { + props: ["v-primary-cluster", "v-secondary-clusters", "size"], + data: function () { + let cluster = this.vPrimaryCluster + let secondaryClusters = this.vSecondaryClusters + if (secondaryClusters == null) { + secondaryClusters = [] + } + + let labelSize = this.size + if (labelSize == null) { + labelSize = "small" + } + if (labelSize == "tiny") { + labelSize += " olive" + } + return { + cluster: cluster, + secondaryClusters: secondaryClusters, + labelSize: labelSize + } + }, + template: `
| 主集群 | +
+
+
+
+
+ 多个集群配置有冲突时,优先使用主集群配置。 + |
+
| 从集群 | +
+
+
+
+
+ |
+
| 记录名 | -记录类型 | -线路 | -记录值 | -
|---|---|---|---|
| 记录名 | +记录类型 | +线路 | +记录值 | +
| {{dnsRecordName}} | -- AAAA - A - | -- {{route.name}} - 默认 - | -{{address.ip}} | -
| {{record.name}} | +{{record.type}} | ++ {{record.route}} + 默认 + | +{{record.value}} | +
通过设置A记录可以将集群上的服务请求转发到不同线路的节点上。
用于访问节点和域名解析等。
当前节点对应的DNS线路,可用线路是根据集群设置的域名获取的,注意DNS服务商可能对这些线路有其他限制。
| 选择主域名 | +选择主域名 * |
用于生成集群节点和网站服务的DNS解析记录。 |
||
| DNS子域名 | +DNS子域名 * |
diff --git a/web/views/@default/clusters/create.css b/web/views/@default/clusters/create.css
new file mode 100644
index 00000000..b817efb2
--- /dev/null
+++ b/web/views/@default/clusters/create.css
@@ -0,0 +1,4 @@
+h4 span {
+ font-size: 0.8em;
+}
+/*# sourceMappingURL=create.css.map */
\ No newline at end of file
diff --git a/web/views/@default/clusters/create.css.map b/web/views/@default/clusters/create.css.map
new file mode 100644
index 00000000..0c12d393
--- /dev/null
+++ b/web/views/@default/clusters/create.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["create.less"],"names":[],"mappings":"AAAA,EAAG;EACF,gBAAA","file":"create.css"}
\ No newline at end of file
diff --git a/web/views/@default/clusters/create.html b/web/views/@default/clusters/create.html
index b1336370..add5dcd8 100644
--- a/web/views/@default/clusters/create.html
+++ b/web/views/@default/clusters/create.html
@@ -13,17 +13,19 @@
默认缓存设置 * |
|
此全局设置不会强制应用到每个网站服务。 |
| 默认WAF设置 * |
此全局设置不会强制应用到每个网站服务。 |
| 默认SSH登录方式 | @@ -49,7 +51,7 @@
| 选择主域名 | diff --git a/web/views/@default/clusters/create.less b/web/views/@default/clusters/create.less new file mode 100644 index 00000000..a28c88b2 --- /dev/null +++ b/web/views/@default/clusters/create.less @@ -0,0 +1,3 @@ +h4 span { + font-size: 0.8em; +} \ No newline at end of file diff --git a/web/views/@default/clusters/index.html b/web/views/@default/clusters/index.html index 57c4fdc4..676b7c35 100644 --- a/web/views/@default/clusters/index.html +++ b/web/views/@default/clusters/index.html @@ -93,7 +93,7 @@|||||||||
- 集群:{{node.cluster.name}}
+
|
diff --git a/web/views/@default/clusters/selectPopup.html b/web/views/@default/clusters/selectPopup.html
new file mode 100644
index 00000000..1f0c7941
--- /dev/null
+++ b/web/views/@default/clusters/selectPopup.html
@@ -0,0 +1,25 @@
+{$layout "layout_popup"}
+
+选择集群+ +
-
|
{{node.ipAddr}}
- |
{{node.route.name}}
- |
已解析 未解析 |
- |