mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-04 04:54:32 +08:00
281 lines
7.5 KiB
Go
281 lines
7.5 KiB
Go
package clusters
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
"github.com/iwind/TeaGo/maps"
|
|
"github.com/iwind/TeaGo/types"
|
|
"time"
|
|
)
|
|
|
|
type IndexAction struct {
|
|
actionutils.ParentAction
|
|
}
|
|
|
|
func (this *IndexAction) Init() {
|
|
this.Nav("", "cluster", "index")
|
|
}
|
|
|
|
func (this *IndexAction) RunGet(params struct {
|
|
Keyword string
|
|
SearchType string
|
|
}) {
|
|
isSearching := len(params.Keyword) > 0
|
|
this.Data["keyword"] = params.Keyword
|
|
this.Data["searchType"] = params.SearchType
|
|
this.Data["isSearching"] = isSearching
|
|
|
|
// 常用的集群
|
|
latestClusterMaps := []maps.Map{}
|
|
if !isSearching {
|
|
clustersResp, err := this.RPC().NodeClusterRPC().FindLatestNodeClusters(this.AdminContext(), &pb.FindLatestNodeClustersRequest{Size: 6})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
for _, cluster := range clustersResp.NodeClusters {
|
|
latestClusterMaps = append(latestClusterMaps, maps.Map{
|
|
"id": cluster.Id,
|
|
"name": cluster.Name,
|
|
})
|
|
}
|
|
}
|
|
this.Data["latestClusters"] = latestClusterMaps
|
|
|
|
// 搜索节点
|
|
if params.SearchType == "node" && len(params.Keyword) > 0 {
|
|
this.searchNodes(params.Keyword)
|
|
return
|
|
}
|
|
|
|
// 搜索集群
|
|
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{
|
|
Keyword: params.Keyword,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
this.Data["countClusters"] = countResp.Count
|
|
|
|
count := countResp.Count
|
|
page := this.NewPage(count)
|
|
this.Data["page"] = page.AsHTML()
|
|
|
|
clusterMaps := []maps.Map{}
|
|
if count > 0 {
|
|
clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{
|
|
Keyword: params.Keyword,
|
|
Offset: page.Offset,
|
|
Size: page.Size,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
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
|
|
}
|
|
|
|
// 在线节点
|
|
countActiveNodesResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
|
NodeClusterId: cluster.Id,
|
|
ActiveState: types.Int32(configutils.BoolStateYes),
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
|
|
// 需要升级的节点
|
|
countUpgradeNodesResp, err := this.RPC().NodeRPC().CountAllUpgradeNodesWithNodeClusterId(this.AdminContext(), &pb.CountAllUpgradeNodesWithNodeClusterIdRequest{NodeClusterId: cluster.Id})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
|
|
// DNS
|
|
dnsDomainName := ""
|
|
if cluster.DnsDomainId > 0 {
|
|
dnsInfoResp, err := this.RPC().NodeClusterRPC().FindEnabledNodeClusterDNS(this.AdminContext(), &pb.FindEnabledNodeClusterDNSRequest{NodeClusterId: cluster.Id})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
if dnsInfoResp.Domain != nil {
|
|
dnsDomainName = dnsInfoResp.Domain.Name
|
|
}
|
|
}
|
|
|
|
clusterMaps = append(clusterMaps, maps.Map{
|
|
"id": cluster.Id,
|
|
"name": cluster.Name,
|
|
"installDir": cluster.InstallDir,
|
|
"countAllNodes": countNodesResp.Count,
|
|
"countActiveNodes": countActiveNodesResp.Count,
|
|
"countUpgradeNodes": countUpgradeNodesResp.Count,
|
|
"dnsDomainId": cluster.DnsDomainId,
|
|
"dnsName": cluster.DnsName,
|
|
"dnsDomainName": dnsDomainName,
|
|
})
|
|
}
|
|
}
|
|
this.Data["clusters"] = clusterMaps
|
|
this.Data["nodes"] = []maps.Map{}
|
|
|
|
if len(params.Keyword) > 0 {
|
|
// 搜索节点
|
|
countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
|
Keyword: params.Keyword,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
this.Data["countNodes"] = countResp.Count
|
|
}
|
|
|
|
this.Show()
|
|
}
|
|
|
|
func (this *IndexAction) searchNodes(keyword string) {
|
|
// 搜索节点
|
|
countResp, err := this.RPC().NodeRPC().CountAllEnabledNodesMatch(this.AdminContext(), &pb.CountAllEnabledNodesMatchRequest{
|
|
Keyword: keyword,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
count := countResp.Count
|
|
page := this.NewPage(count)
|
|
this.Data["page"] = page.AsHTML()
|
|
this.Data["countNodes"] = count
|
|
|
|
nodesResp, err := this.RPC().NodeRPC().ListEnabledNodesMatch(this.AdminContext(), &pb.ListEnabledNodesMatchRequest{
|
|
Offset: page.Offset,
|
|
Size: page.Size,
|
|
Keyword: keyword,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
|
|
nodeMaps := []maps.Map{}
|
|
for _, node := range nodesResp.Nodes {
|
|
// 状态
|
|
isSynced := false
|
|
status := &nodeconfigs.NodeStatus{}
|
|
if len(node.StatusJSON) > 0 {
|
|
err = json.Unmarshal(node.StatusJSON, &status)
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
|
|
isSynced = status.ConfigVersion == node.Version
|
|
}
|
|
|
|
// IP
|
|
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
|
NodeId: node.Id,
|
|
Role: nodeconfigs.NodeRoleNode,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
ipAddresses := []maps.Map{}
|
|
for _, addr := range ipAddressesResp.Addresses {
|
|
ipAddresses = append(ipAddresses, maps.Map{
|
|
"id": addr.Id,
|
|
"name": addr.Name,
|
|
"ip": addr.Ip,
|
|
"canAccess": addr.CanAccess,
|
|
})
|
|
}
|
|
|
|
// 分组
|
|
var groupMap maps.Map = nil
|
|
if node.NodeGroup != nil {
|
|
groupMap = maps.Map{
|
|
"id": node.NodeGroup.Id,
|
|
"name": node.NodeGroup.Name,
|
|
}
|
|
}
|
|
|
|
// 区域
|
|
var regionMap maps.Map = nil
|
|
if node.NodeRegion != nil {
|
|
regionMap = maps.Map{
|
|
"id": node.NodeRegion.Id,
|
|
"name": node.NodeRegion.Name,
|
|
}
|
|
}
|
|
|
|
// DNS
|
|
dnsRouteNames := []string{}
|
|
for _, route := range node.DnsRoutes {
|
|
dnsRouteNames = append(dnsRouteNames, route.Name)
|
|
}
|
|
|
|
nodeMaps = append(nodeMaps, maps.Map{
|
|
"id": node.Id,
|
|
"name": node.Name,
|
|
"isInstalled": node.IsInstalled,
|
|
"isOn": node.IsOn,
|
|
"isUp": node.IsUp,
|
|
"installStatus": maps.Map{
|
|
"isRunning": node.InstallStatus.IsRunning,
|
|
"isFinished": node.InstallStatus.IsFinished,
|
|
"isOk": node.InstallStatus.IsOk,
|
|
"error": node.InstallStatus.Error,
|
|
},
|
|
"status": maps.Map{
|
|
"isActive": status.IsActive,
|
|
"updatedAt": status.UpdatedAt,
|
|
"hostname": status.Hostname,
|
|
"cpuUsage": status.CPUUsage,
|
|
"cpuUsageText": fmt.Sprintf("%.2f%%", status.CPUUsage*100),
|
|
"memUsage": status.MemoryUsage,
|
|
"memUsageText": fmt.Sprintf("%.2f%%", status.MemoryUsage*100),
|
|
},
|
|
"cluster": maps.Map{
|
|
"id": node.NodeCluster.Id,
|
|
"name": node.NodeCluster.Name,
|
|
},
|
|
"isSynced": isSynced,
|
|
"ipAddresses": ipAddresses,
|
|
"group": groupMap,
|
|
"region": regionMap,
|
|
"dnsRouteNames": dnsRouteNames,
|
|
})
|
|
}
|
|
this.Data["nodes"] = nodeMaps
|
|
|
|
this.Data["clusters"] = []maps.Map{}
|
|
|
|
// 搜索集群
|
|
{
|
|
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClusters(this.AdminContext(), &pb.CountAllEnabledNodeClustersRequest{
|
|
Keyword: keyword,
|
|
})
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
this.Data["countClusters"] = countResp.Count
|
|
}
|
|
|
|
this.Show()
|
|
}
|