284 lines
7.1 KiB
Go
284 lines
7.1 KiB
Go
package upgrade
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
|
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
|
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
"github.com/iwind/TeaGo/maps"
|
|
)
|
|
|
|
type IndexAction struct {
|
|
actionutils.ParentAction
|
|
}
|
|
|
|
func (this *IndexAction) Init() {
|
|
this.Nav("", "", "")
|
|
}
|
|
|
|
func (this *IndexAction) RunGet(params struct{}) {
|
|
// 加载升级配置
|
|
config, err := configloaders.LoadUpgradeConfig()
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
this.Data["config"] = config
|
|
|
|
// 模块列表
|
|
modules := []maps.Map{}
|
|
|
|
// 1. 边缘节点 (EdgeNode)
|
|
nodeModule := this.loadEdgeNodeModule()
|
|
if nodeModule != nil {
|
|
modules = append(modules, nodeModule)
|
|
}
|
|
|
|
// 2. DNS节点 (EdgeDNS) — 仅Plus版本
|
|
if teaconst.IsPlus {
|
|
dnsClusters := loadDNSUpgradeModules(&this.ParentAction)
|
|
if len(dnsClusters) > 0 {
|
|
totalCount := 0
|
|
for _, c := range dnsClusters {
|
|
totalCount += c.GetInt("count")
|
|
}
|
|
modules = append(modules, maps.Map{
|
|
"name": "DNS节点",
|
|
"code": "dns",
|
|
"clusters": dnsClusters,
|
|
"count": totalCount,
|
|
})
|
|
}
|
|
}
|
|
|
|
// 3. HTTPDNS节点
|
|
httpdnsModule := this.loadHTTPDNSModule()
|
|
if httpdnsModule != nil {
|
|
modules = append(modules, httpdnsModule)
|
|
}
|
|
|
|
this.Data["modules"] = modules
|
|
|
|
this.Show()
|
|
}
|
|
|
|
func (this *IndexAction) RunPost(params struct {
|
|
AutoUpgrade bool
|
|
}) {
|
|
config, err := configloaders.LoadUpgradeConfig()
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
|
|
config.AutoUpgrade = params.AutoUpgrade
|
|
|
|
err = configloaders.UpdateUpgradeConfig(config)
|
|
if err != nil {
|
|
this.ErrorPage(err)
|
|
return
|
|
}
|
|
|
|
this.Success()
|
|
}
|
|
|
|
// loadEdgeNodeModule 加载边缘节点模块的待升级信息
|
|
func (this *IndexAction) loadEdgeNodeModule() maps.Map {
|
|
// 获取所有集群
|
|
clustersResp, err := this.RPC().NodeClusterRPC().ListEnabledNodeClusters(this.AdminContext(), &pb.ListEnabledNodeClustersRequest{
|
|
Offset: 0,
|
|
Size: 10000,
|
|
})
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var clusterMaps []maps.Map
|
|
totalCount := 0
|
|
for _, cluster := range clustersResp.NodeClusters {
|
|
resp, err := this.RPC().NodeRPC().FindAllUpgradeNodesWithNodeClusterId(this.AdminContext(), &pb.FindAllUpgradeNodesWithNodeClusterIdRequest{
|
|
NodeClusterId: cluster.Id,
|
|
})
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if len(resp.Nodes) == 0 {
|
|
continue
|
|
}
|
|
|
|
var nodeMaps []maps.Map
|
|
for _, nodeUpgrade := range resp.Nodes {
|
|
if nodeUpgrade.Node == nil {
|
|
continue
|
|
}
|
|
installStatusMap := decodeInstallStatusFromPB(nodeUpgrade.Node.InstallStatus)
|
|
accessIP, login, loginParams := decodeNodeAccessInfo(nodeUpgrade.Node.StatusJSON, nodeUpgrade.Node.NodeLogin, nodeUpgrade.Node.Name)
|
|
|
|
nodeMaps = append(nodeMaps, maps.Map{
|
|
"id": nodeUpgrade.Node.Id,
|
|
"name": nodeUpgrade.Node.Name,
|
|
"os": nodeUpgrade.Os,
|
|
"arch": nodeUpgrade.Arch,
|
|
"oldVersion": nodeUpgrade.OldVersion,
|
|
"newVersion": nodeUpgrade.NewVersion,
|
|
"isOn": nodeUpgrade.Node.IsOn,
|
|
"isUp": nodeUpgrade.Node.IsUp,
|
|
"accessIP": accessIP,
|
|
"login": login,
|
|
"loginParams": loginParams,
|
|
"installStatus": installStatusMap,
|
|
})
|
|
}
|
|
totalCount += len(nodeMaps)
|
|
clusterMaps = append(clusterMaps, maps.Map{
|
|
"id": cluster.Id,
|
|
"name": cluster.Name,
|
|
"nodes": nodeMaps,
|
|
"count": len(nodeMaps),
|
|
})
|
|
}
|
|
|
|
if len(clusterMaps) == 0 {
|
|
return nil
|
|
}
|
|
|
|
return maps.Map{
|
|
"name": "边缘节点",
|
|
"code": "node",
|
|
"clusters": clusterMaps,
|
|
"count": totalCount,
|
|
}
|
|
}
|
|
|
|
// loadHTTPDNSModule 加载HTTPDNS模块的待升级信息
|
|
func (this *IndexAction) loadHTTPDNSModule() maps.Map {
|
|
clustersResp, err := this.RPC().HTTPDNSClusterRPC().ListHTTPDNSClusters(this.AdminContext(), &pb.ListHTTPDNSClustersRequest{
|
|
Offset: 0,
|
|
Size: 10000,
|
|
})
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var clusterMaps []maps.Map
|
|
totalCount := 0
|
|
for _, cluster := range clustersResp.Clusters {
|
|
resp, err := this.RPC().HTTPDNSNodeRPC().FindAllUpgradeHTTPDNSNodesWithClusterId(this.AdminContext(), &pb.FindAllUpgradeHTTPDNSNodesWithClusterIdRequest{
|
|
ClusterId: cluster.Id,
|
|
})
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if len(resp.Nodes) == 0 {
|
|
continue
|
|
}
|
|
|
|
var nodeMaps []maps.Map
|
|
for _, nodeUpgrade := range resp.Nodes {
|
|
if nodeUpgrade.Node == nil {
|
|
continue
|
|
}
|
|
installStatusMap := decodeInstallStatusFromJSON(nodeUpgrade.Node.InstallStatusJSON)
|
|
accessIP, login, loginParams := decodeNodeAccessInfo(nodeUpgrade.Node.StatusJSON, nodeUpgrade.Node.NodeLogin, nodeUpgrade.Node.Name)
|
|
|
|
nodeMaps = append(nodeMaps, maps.Map{
|
|
"id": nodeUpgrade.Node.Id,
|
|
"name": nodeUpgrade.Node.Name,
|
|
"os": nodeUpgrade.Os,
|
|
"arch": nodeUpgrade.Arch,
|
|
"oldVersion": nodeUpgrade.OldVersion,
|
|
"newVersion": nodeUpgrade.NewVersion,
|
|
"isOn": nodeUpgrade.Node.IsOn,
|
|
"isUp": nodeUpgrade.Node.IsUp,
|
|
"accessIP": accessIP,
|
|
"login": login,
|
|
"loginParams": loginParams,
|
|
"installStatus": installStatusMap,
|
|
})
|
|
}
|
|
totalCount += len(nodeMaps)
|
|
clusterMaps = append(clusterMaps, maps.Map{
|
|
"id": cluster.Id,
|
|
"name": cluster.Name,
|
|
"nodes": nodeMaps,
|
|
"count": len(nodeMaps),
|
|
})
|
|
}
|
|
|
|
if len(clusterMaps) == 0 {
|
|
return nil
|
|
}
|
|
|
|
return maps.Map{
|
|
"name": "HTTPDNS节点",
|
|
"code": "httpdns",
|
|
"clusters": clusterMaps,
|
|
"count": totalCount,
|
|
}
|
|
}
|
|
|
|
// decodeInstallStatusFromPB 从 protobuf InstallStatus 解码安装状态
|
|
func decodeInstallStatusFromPB(status *pb.NodeInstallStatus) maps.Map {
|
|
if status == nil {
|
|
return nil
|
|
}
|
|
// 历史成功状态,在待升级列表中忽略
|
|
if status.IsFinished && status.IsOk {
|
|
return nil
|
|
}
|
|
return maps.Map{
|
|
"isRunning": status.IsRunning,
|
|
"isFinished": status.IsFinished,
|
|
"isOk": status.IsOk,
|
|
"error": status.Error,
|
|
"errorCode": status.ErrorCode,
|
|
"updatedAt": status.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
// decodeInstallStatusFromJSON 从 JSON 字节解码安装状态
|
|
func decodeInstallStatusFromJSON(raw []byte) maps.Map {
|
|
if len(raw) == 0 {
|
|
return nil
|
|
}
|
|
result := maps.Map{}
|
|
_ = json.Unmarshal(raw, &result)
|
|
|
|
isFinished, _ := result["isFinished"].(bool)
|
|
isOk, _ := result["isOk"].(bool)
|
|
if isFinished && isOk {
|
|
return nil
|
|
}
|
|
return result
|
|
}
|
|
|
|
// decodeNodeAccessInfo 从节点状态和登录信息中提取 accessIP、login、loginParams
|
|
func decodeNodeAccessInfo(statusJSON []byte, nodeLogin *pb.NodeLogin, nodeName string) (accessIP string, login maps.Map, loginParams maps.Map) {
|
|
// 从 statusJSON 中提取 hostIP 作为 accessIP
|
|
if len(statusJSON) > 0 {
|
|
statusMap := maps.Map{}
|
|
_ = json.Unmarshal(statusJSON, &statusMap)
|
|
accessIP = strings.TrimSpace(statusMap.GetString("hostIP"))
|
|
}
|
|
if len(accessIP) == 0 {
|
|
accessIP = strings.TrimSpace(nodeName)
|
|
}
|
|
|
|
// 解码 login 信息
|
|
if nodeLogin != nil {
|
|
login = maps.Map{
|
|
"id": nodeLogin.Id,
|
|
"name": nodeLogin.Name,
|
|
"type": nodeLogin.Type,
|
|
}
|
|
if len(nodeLogin.Params) > 0 {
|
|
loginParams = maps.Map{}
|
|
_ = json.Unmarshal(nodeLogin.Params, &loginParams)
|
|
}
|
|
}
|
|
return
|
|
}
|