mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	实现监控节点管理
This commit is contained in:
		@@ -139,6 +139,10 @@ func (this *RPCClient) DBNodeRPC() pb.DBNodeServiceClient {
 | 
			
		||||
	return pb.NewDBNodeServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) MonitorNodeRPC() pb.MonitorNodeServiceClient {
 | 
			
		||||
	return pb.NewMonitorNodeServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *RPCClient) DBRPC() pb.DBServiceClient {
 | 
			
		||||
	return pb.NewDBServiceClient(this.pickConn())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,28 @@
 | 
			
		||||
package monitornodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type DeleteAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *DeleteAction) RunPost(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// TODO 检查权限
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().MonitorNodeRPC().DeleteMonitorNode(this.AdminContext(), &pb.DeleteMonitorNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 创建日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "删除监控节点 %d", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
package monitornodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHelper() *Helper {
 | 
			
		||||
	return &Helper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Helper) BeforeAction(action *actions.ActionObject) {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								internal/web/actions/default/settings/monitor-nodes/index.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								internal/web/actions/default/settings/monitor-nodes/index.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
package monitornodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/logs"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct{}) {
 | 
			
		||||
	countResp, err := this.RPC().MonitorNodeRPC().CountAllEnabledMonitorNodes(this.AdminContext(), &pb.CountAllEnabledMonitorNodesRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	count := countResp.Count
 | 
			
		||||
	page := this.NewPage(count)
 | 
			
		||||
	this.Data["page"] = page.AsHTML()
 | 
			
		||||
 | 
			
		||||
	nodeMaps := []maps.Map{}
 | 
			
		||||
	if count > 0 {
 | 
			
		||||
		nodesResp, err := this.RPC().MonitorNodeRPC().ListEnabledMonitorNodes(this.AdminContext(), &pb.ListEnabledMonitorNodesRequest{
 | 
			
		||||
			Offset: page.Offset,
 | 
			
		||||
			Size:   page.Size,
 | 
			
		||||
		})
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, node := range nodesResp.Nodes {
 | 
			
		||||
			// 状态
 | 
			
		||||
			status := &nodeconfigs.NodeStatus{}
 | 
			
		||||
			if len(node.StatusJSON) > 0 {
 | 
			
		||||
				err = json.Unmarshal(node.StatusJSON, &status)
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					logs.Error(err)
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
				status.IsActive = status.IsActive && time.Now().Unix()-status.UpdatedAt <= 60 // N秒之内认为活跃
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			nodeMaps = append(nodeMaps, maps.Map{
 | 
			
		||||
				"id":   node.Id,
 | 
			
		||||
				"isOn": node.IsOn,
 | 
			
		||||
				"name": node.Name,
 | 
			
		||||
				"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),
 | 
			
		||||
					"buildVersion": status.BuildVersion,
 | 
			
		||||
				},
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["nodes"] = nodeMaps
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								internal/web/actions/default/settings/monitor-nodes/init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								internal/web/actions/default/settings/monitor-nodes/init.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
package monitornodes
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/monitor-nodes/node"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Helper(settingutils.NewAdvancedHelper("monitorNodes")).
 | 
			
		||||
			Prefix("/settings/monitorNodes").
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
			GetPost("/node/createPopup", new(node.CreatePopupAction)).
 | 
			
		||||
			Post("/delete", new(DeleteAction)).
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,47 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type CreatePopupAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "create")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunGet(params struct{}) {
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
			
		||||
	Name        string
 | 
			
		||||
	Description string
 | 
			
		||||
	IsOn        bool
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入监控节点名称")
 | 
			
		||||
 | 
			
		||||
	createResp, err := this.RPC().MonitorNodeRPC().CreateMonitorNode(this.AdminContext(), &pb.CreateMonitorNodeRequest{
 | 
			
		||||
		Name:        params.Name,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
		IsOn:        params.IsOn,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 创建日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "创建监控节点 %d", createResp.NodeId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helper struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHelper() *Helper {
 | 
			
		||||
	return &Helper{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *Helper) BeforeAction(action *actions.ActionObject) (goNext bool) {
 | 
			
		||||
	if action.Request.Method != http.MethodGet {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"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("", "", "index")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	nodeResp, err := this.RPC().MonitorNodeRPC().FindEnabledMonitorNode(this.AdminContext(), &pb.FindEnabledMonitorNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.NotFound("monitorNode", params.NodeId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":          node.Id,
 | 
			
		||||
		"name":        node.Name,
 | 
			
		||||
		"description": node.Description,
 | 
			
		||||
		"isOn":        node.IsOn,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,25 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/settingutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	TeaGo.BeforeStart(func(server *TeaGo.Server) {
 | 
			
		||||
		server.
 | 
			
		||||
			Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeSetting)).
 | 
			
		||||
			Helper(settingutils.NewAdvancedHelper("monitorNodes")).
 | 
			
		||||
			Prefix("/settings/monitorNodes/node").
 | 
			
		||||
 | 
			
		||||
			// 节点相关
 | 
			
		||||
			Helper(NewHelper()).
 | 
			
		||||
			Get("", new(IndexAction)).
 | 
			
		||||
			GetPost("/update", new(UpdateAction)).
 | 
			
		||||
			Get("/install", new(InstallAction)).
 | 
			
		||||
 | 
			
		||||
			EndAll()
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,57 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type InstallAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *InstallAction) Init() {
 | 
			
		||||
	this.Nav("", "", "install")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *InstallAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	// 监控节点信息
 | 
			
		||||
	nodeResp, err := this.RPC().MonitorNodeRPC().FindEnabledMonitorNode(this.AdminContext(), &pb.FindEnabledMonitorNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.NotFound("monitorNode", params.NodeId)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":       node.Id,
 | 
			
		||||
		"name":     node.Name,
 | 
			
		||||
		"uniqueId": node.UniqueId,
 | 
			
		||||
		"secret":   node.Secret,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// API节点列表
 | 
			
		||||
	apiNodesResp, err := this.RPC().APINodeRPC().FindAllEnabledAPINodes(this.AdminContext(), &pb.FindAllEnabledAPINodesRequest{})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	apiNodes := apiNodesResp.Nodes
 | 
			
		||||
	apiEndpoints := []string{}
 | 
			
		||||
	for _, apiNode := range apiNodes {
 | 
			
		||||
		if !apiNode.IsOn {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		apiEndpoints = append(apiEndpoints, apiNode.AccessAddrs...)
 | 
			
		||||
	}
 | 
			
		||||
	this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\""
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,73 @@
 | 
			
		||||
package node
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type UpdateAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) Init() {
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	nodeResp, err := this.RPC().MonitorNodeRPC().FindEnabledMonitorNode(this.AdminContext(), &pb.FindEnabledMonitorNodeRequest{
 | 
			
		||||
		NodeId: params.NodeId,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	node := nodeResp.Node
 | 
			
		||||
	if node == nil {
 | 
			
		||||
		this.WriteString("要操作的节点不存在")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["node"] = maps.Map{
 | 
			
		||||
		"id":          node.Id,
 | 
			
		||||
		"name":        node.Name,
 | 
			
		||||
		"description": node.Description,
 | 
			
		||||
		"isOn":        node.IsOn,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 保存基础设置
 | 
			
		||||
func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
	NodeId      int64
 | 
			
		||||
	Name        string
 | 
			
		||||
	Description string
 | 
			
		||||
	IsOn        bool
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
	params.Must.
 | 
			
		||||
		Field("name", params.Name).
 | 
			
		||||
		Require("请输入监控节点名称")
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().MonitorNodeRPC().UpdateMonitorNode(this.AdminContext(), &pb.UpdateMonitorNodeRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		Name:        params.Name,
 | 
			
		||||
		Description: params.Description,
 | 
			
		||||
		IsOn:        params.IsOn,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 创建日志
 | 
			
		||||
	defer this.CreateLog(oplogs.LevelInfo, "修改监控节点 %d", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -34,6 +34,8 @@ func (this *AdvancedHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNex
 | 
			
		||||
		tabbar.Add("API节点", "", "/api", "", this.tab == "apiNodes")
 | 
			
		||||
		tabbar.Add("用户节点", "", "/settings/userNodes", "", this.tab == "userNodes")
 | 
			
		||||
		tabbar.Add("日志数据库", "", "/db", "", this.tab == "dbNodes")
 | 
			
		||||
		tabbar.Add("监控节点", "", "/settings/monitorNodes", "", this.tab == "monitorNodes")
 | 
			
		||||
 | 
			
		||||
		//tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
 | 
			
		||||
	}
 | 
			
		||||
	actionutils.SetTabbar(actionPtr, tabbar)
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,8 @@ import (
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/database"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/ip-library"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/login"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/monitor-nodes"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/monitor-nodes/node"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/profile"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/security"
 | 
			
		||||
	_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/settings/server"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								web/views/@default/settings/monitor-nodes/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								web/views/@default/settings/monitor-nodes/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
<first-menu>
 | 
			
		||||
	<a href="" class="item" @click.prevent="createNode()">[添加节点]</a>
 | 
			
		||||
</first-menu>
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="nodes.length == 0">暂时还没有节点。</p>
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable celled" v-if="nodes.length > 0">
 | 
			
		||||
	<thead>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<th>节点名称</th>
 | 
			
		||||
            <th class="width6 center">版本号</th>
 | 
			
		||||
            <th class="width5 center">CPU</th>
 | 
			
		||||
            <th class="width5 center">内存</th>
 | 
			
		||||
            <th class="center width10">状态</th>
 | 
			
		||||
			<th class="two op">操作</th>
 | 
			
		||||
		</tr>
 | 
			
		||||
	</thead>
 | 
			
		||||
	<tr v-for="node in nodes">
 | 
			
		||||
		<td>{{node.name}}</td>
 | 
			
		||||
        <td class="center">
 | 
			
		||||
            <span v-if="node.status.buildVersion.length > 0">v{{node.status.buildVersion}}</span>
 | 
			
		||||
            <span v-else class="disabled">-</span>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td class="center">
 | 
			
		||||
            <span v-if="node.status.isActive" :class="{red:node.status.cpuUsage > 0.80}">{{node.status.cpuUsageText}}</span>
 | 
			
		||||
            <span v-else class="disabled">-</span>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td class="center">
 | 
			
		||||
            <span v-if="node.status.isActive" :class="{red:node.status.memUsage > 0.80}">{{node.status.memUsageText}}</span>
 | 
			
		||||
            <span v-else class="disabled">-</span>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td class="center">
 | 
			
		||||
            <span v-if="!node.isOn"><label-on :v-is-on="node.isOn"></label-on></span>
 | 
			
		||||
            <div v-else-if="node.status.isActive">
 | 
			
		||||
                <span class="green">运行中</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <span v-else-if="node.status.updatedAt > 0" class="red">已断开</span>
 | 
			
		||||
            <span v-else-if="node.status.updatedAt == 0" class="red">未连接</span>
 | 
			
		||||
        </td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<a :href="'/settings/monitorNodes/node?nodeId=' + node.id">详情</a>  
 | 
			
		||||
			<a href="" @click.prevent="deleteNode(node.id)">删除</a>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
 | 
			
		||||
<div class="page" v-html="page"></div>
 | 
			
		||||
							
								
								
									
										26
									
								
								web/views/@default/settings/monitor-nodes/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								web/views/@default/settings/monitor-nodes/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	// 创建节点
 | 
			
		||||
	this.createNode = function () {
 | 
			
		||||
		teaweb.popup("/settings/monitorNodes/node/createPopup", {
 | 
			
		||||
			width: "50em",
 | 
			
		||||
			height: "30em",
 | 
			
		||||
			callback: function () {
 | 
			
		||||
				teaweb.success("保存成功", function () {
 | 
			
		||||
					teaweb.reload()
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 删除节点
 | 
			
		||||
	this.deleteNode = function (nodeId) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.confirm("确定要删除此节点吗?", function () {
 | 
			
		||||
			that.$post("/settings/monitorNodes/delete")
 | 
			
		||||
				.params({
 | 
			
		||||
					nodeId: nodeId
 | 
			
		||||
				})
 | 
			
		||||
				.refresh()
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
<first-menu>
 | 
			
		||||
	<menu-item href="/settings/monitorNodes">节点列表</menu-item>
 | 
			
		||||
	<span class="item">|</span>
 | 
			
		||||
	<menu-item :href="'/settings/monitorNodes/node?nodeId=' + node.id" code="index">"{{node.name}}"详情</menu-item>
 | 
			
		||||
	<menu-item :href="'/settings/monitorNodes/node/install?nodeId=' + node.id" code="install">安装节点</menu-item>
 | 
			
		||||
	<menu-item :href="'/settings/monitorNodes/node/update?nodeId=' + node.id" code="update">修改节点</menu-item>
 | 
			
		||||
</first-menu>
 | 
			
		||||
@@ -0,0 +1,34 @@
 | 
			
		||||
{$layout "layout_popup"}
 | 
			
		||||
 | 
			
		||||
<h3>添加监控节点</h3>
 | 
			
		||||
<form class="ui form" method="post" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<table class="ui table selectable definition">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="100" ref="focus"/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>描述</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<textarea name="description" maxlength="200" rows="3"></textarea>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>是否启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" checked="checked"/>
 | 
			
		||||
						<label></label>
 | 
			
		||||
					</div>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										24
									
								
								web/views/@default/settings/monitor-nodes/node/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								web/views/@default/settings/monitor-nodes/node/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<table class="ui table selectable definition">
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td class="title">节点名称</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			{{node.name}}
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>状态</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<label-on :v-is-on="node.isOn"></label-on>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td>描述</td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<span v-if="node.description.length > 0">{{node.description}}</span>
 | 
			
		||||
			<span v-else class="disabled">暂时还没有描述。</span>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
							
								
								
									
										23
									
								
								web/views/@default/settings/monitor-nodes/node/install.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								web/views/@default/settings/monitor-nodes/node/install.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<h3>安装步骤</h3>
 | 
			
		||||
<ol class="ui list">
 | 
			
		||||
	<li>按照下面的配置信息替换<code-label>configs/api.yaml</code-label>内容</li>
 | 
			
		||||
	<li>使用<code-label>bin/edge-monitor start</code-label>启动节点</li>
 | 
			
		||||
	<li>可以在<code-label>logs/run.log</code-label>中查看启动是否有异常</li>
 | 
			
		||||
</ol>
 | 
			
		||||
 | 
			
		||||
<div class="ui divider"></div>
 | 
			
		||||
<h3>配置信息</h3>
 | 
			
		||||
<table class="ui table definition selectable">
 | 
			
		||||
	<tr>
 | 
			
		||||
		<td class="title">configs/api.yaml<em><br/><download-link :v-element="'api-code'" :v-file="'api.yaml'">[下载]</download-link></em></td>
 | 
			
		||||
		<td>
 | 
			
		||||
			<pre id="api-code">rpc:
 | 
			
		||||
  endpoints: [ {{apiEndpoints}} ]
 | 
			
		||||
nodeId: "{{node.uniqueId}}"
 | 
			
		||||
secret: "{{node.secret}}"</pre>
 | 
			
		||||
		</td>
 | 
			
		||||
	</tr>
 | 
			
		||||
</table>
 | 
			
		||||
							
								
								
									
										37
									
								
								web/views/@default/settings/monitor-nodes/node/update.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								web/views/@default/settings/monitor-nodes/node/update.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
{$template "menu"}
 | 
			
		||||
 | 
			
		||||
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
	<input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
	<input type="hidden" name="sslPolicyId" :value="node.sslPolicyId"/>
 | 
			
		||||
	<table class="ui table selectable definition">
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td class="title">节点名称 *</td>
 | 
			
		||||
			<td>
 | 
			
		||||
				<input type="text" name="name" maxlength="100" ref="focus" v-model="node.name"/>
 | 
			
		||||
			</td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tr>
 | 
			
		||||
			<td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
		</tr>
 | 
			
		||||
		<tbody v-show="moreOptionsVisible">
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>描述</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<textarea name="description" maxlength="200" rows="3" v-model="node.description"></textarea>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
			<tr>
 | 
			
		||||
				<td>是否启用</td>
 | 
			
		||||
				<td>
 | 
			
		||||
					<div class="ui checkbox">
 | 
			
		||||
						<input type="checkbox" name="isOn" value="1" v-model="node.isOn"/>
 | 
			
		||||
						<label></label>
 | 
			
		||||
					</div>
 | 
			
		||||
				</td>
 | 
			
		||||
			</tr>
 | 
			
		||||
		</tbody>
 | 
			
		||||
	</table>
 | 
			
		||||
	<submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/settings/monitor-nodes/node/update.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/settings/monitor-nodes/node/update.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifySuccess("保存成功", "/settings/monitorNodes/node?nodeId=" + this.node.id)
 | 
			
		||||
})
 | 
			
		||||
		Reference in New Issue
	
	Block a user