feat: sync httpdns sdk/platform updates without large binaries

This commit is contained in:
robin
2026-03-04 17:59:14 +08:00
parent 853897a6f8
commit 532891fad0
700 changed files with 6096 additions and 2712 deletions

View File

@@ -1,6 +1,15 @@
package upgrade
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
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
@@ -11,5 +20,264 @@ func (this *IndexAction) Init() {
}
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
}