mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 05:00:25 +08:00 
			
		
		
		
	优化节点设置交互
This commit is contained in:
		@@ -4,7 +4,11 @@ import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/groups"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/thresholds"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/cache"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/dns"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/ssh"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/system"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/settings/thresholds"
 | 
			
		||||
	clusters "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/clusterutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
 | 
			
		||||
	"github.com/iwind/TeaGo"
 | 
			
		||||
@@ -42,10 +46,14 @@ func init() {
 | 
			
		||||
			Post("/start", new(node.StartAction)).
 | 
			
		||||
			Post("/stop", new(node.StopAction)).
 | 
			
		||||
			Post("/up", new(node.UpAction)).
 | 
			
		||||
			Get("/thresholds", new(thresholds.IndexAction)).
 | 
			
		||||
			Get("/detail", new(node.DetailAction)).
 | 
			
		||||
			GetPost("/updateDNSPopup", new(node.UpdateDNSPopupAction)).
 | 
			
		||||
			Post("/syncDomain", new(node.SyncDomainAction)).
 | 
			
		||||
			GetPost("/settings/cache", new(cache.IndexAction)).
 | 
			
		||||
			GetPost("/settings/dns", new(dns.IndexAction)).
 | 
			
		||||
			GetPost("/settings/system", new(system.IndexAction)).
 | 
			
		||||
			GetPost("/settings/ssh", new(ssh.IndexAction)).
 | 
			
		||||
			GetPost("/settings/thresholds", new(thresholds.IndexAction)).
 | 
			
		||||
 | 
			
		||||
			// 分组相关
 | 
			
		||||
			Prefix("/clusters/cluster/groups").
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ func (this *IndexAction) Init() {
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	err := nodeutils.InitNodeInfo(this, params.NodeId)
 | 
			
		||||
	_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ func (this *LogsAction) RunGet(params struct {
 | 
			
		||||
	Level   string
 | 
			
		||||
}) {
 | 
			
		||||
	// 初始化节点信息(用于菜单)
 | 
			
		||||
	err := nodeutils.InitNodeInfo(this, params.NodeId)
 | 
			
		||||
	_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
 
 | 
			
		||||
@@ -7,28 +7,70 @@ import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
	"github.com/iwind/TeaGo/types"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// InitNodeInfo 初始化节点信息
 | 
			
		||||
func InitNodeInfo(action actionutils.ActionInterface, nodeId int64) error {
 | 
			
		||||
func InitNodeInfo(parentAction *actionutils.ParentAction, nodeId int64) (*pb.Node, error) {
 | 
			
		||||
	// 节点信息(用于菜单)
 | 
			
		||||
	nodeResp, err := action.RPC().NodeRPC().FindEnabledNode(action.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: nodeId})
 | 
			
		||||
	nodeResp, err := parentAction.RPC().NodeRPC().FindEnabledNode(parentAction.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: nodeId})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if nodeResp.Node == nil {
 | 
			
		||||
		return errors.New("node '" + strconv.FormatInt(nodeId, 10) + "' not found")
 | 
			
		||||
		return nil, errors.New("node '" + strconv.FormatInt(nodeId, 10) + "' not found")
 | 
			
		||||
	}
 | 
			
		||||
	var node = nodeResp.Node
 | 
			
		||||
	action.ViewData()["node"] = maps.Map{
 | 
			
		||||
	parentAction.Data["node"] = maps.Map{
 | 
			
		||||
		"id":   node.Id,
 | 
			
		||||
		"name": node.Name,
 | 
			
		||||
		"isOn": node.IsOn,
 | 
			
		||||
		"isUp": node.IsUp,
 | 
			
		||||
	}
 | 
			
		||||
	var clusterId int64 = 0
 | 
			
		||||
	if node.NodeCluster != nil {
 | 
			
		||||
		action.ViewData()["clusterId"] = node.NodeCluster.Id
 | 
			
		||||
		parentAction.Data["clusterId"] = node.NodeCluster.Id
 | 
			
		||||
		clusterId = node.NodeCluster.Id
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
	// 左侧菜单
 | 
			
		||||
	var prefix = "/clusters/cluster/node"
 | 
			
		||||
	var query = "clusterId=" + types.String(clusterId) + "&nodeId=" + types.String(nodeId)
 | 
			
		||||
	var menuItem = parentAction.Data.GetString("secondMenuItem")
 | 
			
		||||
 | 
			
		||||
	parentAction.Data["leftMenuItems"] = []maps.Map{
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "基础设置",
 | 
			
		||||
			"url":      prefix + "/update?" + query,
 | 
			
		||||
			"isActive": menuItem == "basic",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "DNS设置",
 | 
			
		||||
			"url":      prefix + "/settings/dns?" + query,
 | 
			
		||||
			"isActive": menuItem == "dns",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "缓存设置",
 | 
			
		||||
			"url":      prefix + "/settings/cache?" + query,
 | 
			
		||||
			"isActive": menuItem == "cache",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "阈值设置",
 | 
			
		||||
			"url":      prefix + "/settings/thresholds?" + query,
 | 
			
		||||
			"isActive": menuItem == "threshold",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "SSH设置",
 | 
			
		||||
			"url":      prefix + "/settings/ssh?" + query,
 | 
			
		||||
			"isActive": menuItem == "ssh",
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"name":     "系统设置",
 | 
			
		||||
			"url":      prefix + "/settings/system?" + query,
 | 
			
		||||
			"isActive": menuItem == "system",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nodeResp.Node, nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										117
									
								
								internal/web/actions/default/clusters/cluster/node/settings/cache/index.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								internal/web/actions/default/clusters/cluster/node/settings/cache/index.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
	this.SecondMenu("cache")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 缓存硬盘 & 内存容量
 | 
			
		||||
	var maxCacheDiskCapacity maps.Map = nil
 | 
			
		||||
	if node.MaxCacheDiskCapacity != nil {
 | 
			
		||||
		maxCacheDiskCapacity = maps.Map{
 | 
			
		||||
			"count": node.MaxCacheDiskCapacity.Count,
 | 
			
		||||
			"unit":  node.MaxCacheDiskCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		maxCacheDiskCapacity = maps.Map{
 | 
			
		||||
			"count": 0,
 | 
			
		||||
			"unit":  "gb",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var maxCacheMemoryCapacity maps.Map = nil
 | 
			
		||||
	if node.MaxCacheMemoryCapacity != nil {
 | 
			
		||||
		maxCacheMemoryCapacity = maps.Map{
 | 
			
		||||
			"count": node.MaxCacheMemoryCapacity.Count,
 | 
			
		||||
			"unit":  node.MaxCacheMemoryCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		maxCacheMemoryCapacity = maps.Map{
 | 
			
		||||
			"count": 0,
 | 
			
		||||
			"unit":  "gb",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var nodeMap = this.Data["node"].(maps.Map)
 | 
			
		||||
	nodeMap["maxCacheDiskCapacity"] = maxCacheDiskCapacity
 | 
			
		||||
	nodeMap["maxCacheMemoryCapacity"] = maxCacheMemoryCapacity
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	NodeId                     int64
 | 
			
		||||
	MaxCacheDiskCapacityJSON   []byte
 | 
			
		||||
	MaxCacheMemoryCapacityJSON []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改节点 %d 缓存设置", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	// 缓存硬盘 & 内存容量
 | 
			
		||||
	var pbMaxCacheDiskCapacity *pb.SizeCapacity
 | 
			
		||||
	if len(params.MaxCacheDiskCapacityJSON) > 0 {
 | 
			
		||||
		var sizeCapacity = &shared.SizeCapacity{}
 | 
			
		||||
		err := json.Unmarshal(params.MaxCacheDiskCapacityJSON, sizeCapacity)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		pbMaxCacheDiskCapacity = &pb.SizeCapacity{
 | 
			
		||||
			Count: sizeCapacity.Count,
 | 
			
		||||
			Unit:  sizeCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var pbMaxCacheMemoryCapacity *pb.SizeCapacity
 | 
			
		||||
	if len(params.MaxCacheMemoryCapacityJSON) > 0 {
 | 
			
		||||
		var sizeCapacity = &shared.SizeCapacity{}
 | 
			
		||||
		err := json.Unmarshal(params.MaxCacheMemoryCapacityJSON, sizeCapacity)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		pbMaxCacheMemoryCapacity = &pb.SizeCapacity{
 | 
			
		||||
			Count: sizeCapacity.Count,
 | 
			
		||||
			Unit:  sizeCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeCache(this.AdminContext(), &pb.UpdateNodeCacheRequest{
 | 
			
		||||
		NodeId:                 params.NodeId,
 | 
			
		||||
		MaxCacheDiskCapacity:   pbMaxCacheDiskCapacity,
 | 
			
		||||
		MaxCacheMemoryCapacity: pbMaxCacheMemoryCapacity,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,125 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package dns
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
	this.SecondMenu("dns")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// DNS相关
 | 
			
		||||
	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
 | 
			
		||||
		}
 | 
			
		||||
		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 {
 | 
			
		||||
			allDNSRouteMaps[domainId] = append(allDNSRouteMaps[domainId], maps.Map{
 | 
			
		||||
				"domainId":   domainId,
 | 
			
		||||
				"domainName": domainName,
 | 
			
		||||
				"name":       route.Name,
 | 
			
		||||
				"code":       route.Code,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	NodeId        int64
 | 
			
		||||
	DnsDomainId   int64
 | 
			
		||||
	DnsRoutesJSON []byte
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改节点 %d DNS设置", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	dnsRouteCodes := []string{}
 | 
			
		||||
	if len(params.DnsRoutesJSON) > 0 {
 | 
			
		||||
		err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
 | 
			
		||||
		NodeId:      params.NodeId,
 | 
			
		||||
		IpAddr:      "",
 | 
			
		||||
		DnsDomainId: 0,
 | 
			
		||||
		Routes:      dnsRouteCodes,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,114 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package ssh
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
	this.SecondMenu("ssh")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 登录信息
 | 
			
		||||
	var loginMap maps.Map = nil
 | 
			
		||||
	if node.NodeLogin != nil {
 | 
			
		||||
		loginParams := maps.Map{}
 | 
			
		||||
		if len(node.NodeLogin.Params) > 0 {
 | 
			
		||||
			err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		grantMap := maps.Map{}
 | 
			
		||||
		grantId := loginParams.GetInt64("grantId")
 | 
			
		||||
		if grantId > 0 {
 | 
			
		||||
			grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if grantResp.NodeGrant != nil {
 | 
			
		||||
				grantMap = maps.Map{
 | 
			
		||||
					"id":         grantResp.NodeGrant.Id,
 | 
			
		||||
					"name":       grantResp.NodeGrant.Name,
 | 
			
		||||
					"method":     grantResp.NodeGrant.Method,
 | 
			
		||||
					"methodName": grantutils.FindGrantMethodName(grantResp.NodeGrant.Method),
 | 
			
		||||
					"username":   grantResp.NodeGrant.Username,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		loginMap = maps.Map{
 | 
			
		||||
			"id":     node.NodeLogin.Id,
 | 
			
		||||
			"name":   node.NodeLogin.Name,
 | 
			
		||||
			"type":   node.NodeLogin.Type,
 | 
			
		||||
			"params": loginParams,
 | 
			
		||||
			"grant":  grantMap,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var nodeMap = this.Data["node"].(maps.Map)
 | 
			
		||||
	nodeMap["login"] = loginMap
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
 | 
			
		||||
	LoginId int64
 | 
			
		||||
	GrantId int64
 | 
			
		||||
	SshHost string
 | 
			
		||||
	SshPort int
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改节点 %d SSH登录信息", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	// TODO 检查登录授权
 | 
			
		||||
	loginInfo := &pb.NodeLogin{
 | 
			
		||||
		Id:   params.LoginId,
 | 
			
		||||
		Name: "SSH",
 | 
			
		||||
		Type: "ssh",
 | 
			
		||||
		Params: maps.Map{
 | 
			
		||||
			"grantId": params.GrantId,
 | 
			
		||||
			"host":    params.SshHost,
 | 
			
		||||
			"port":    params.SshPort,
 | 
			
		||||
		}.AsJSON(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeLogin(this.AdminContext(), &pb.UpdateNodeLoginRequest{
 | 
			
		||||
		NodeId:    params.NodeId,
 | 
			
		||||
		NodeLogin: loginInfo,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,61 @@
 | 
			
		||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
 | 
			
		||||
 | 
			
		||||
package system
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type IndexAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
	this.SecondMenu("system")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 获取节点信息
 | 
			
		||||
	var nodeMap = this.Data["node"].(maps.Map)
 | 
			
		||||
	nodeMap["maxCPU"] = node.MaxCPU
 | 
			
		||||
 | 
			
		||||
	this.Show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunPost(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
	MaxCPU int32
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
	CSRF *actionutils.CSRF
 | 
			
		||||
}) {
 | 
			
		||||
	defer this.CreateLogInfo("修改节点 %d 系统信息", params.NodeId)
 | 
			
		||||
 | 
			
		||||
	if params.MaxCPU < 0 {
 | 
			
		||||
		this.Fail("CPU线程数不能小于0")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNodeSystem(this.AdminContext(), &pb.UpdateNodeSystemRequest{
 | 
			
		||||
		NodeId: params.NodeId,
 | 
			
		||||
		MaxCPU: params.MaxCPU,
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Success()
 | 
			
		||||
}
 | 
			
		||||
@@ -15,22 +15,22 @@ type IndexAction struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "threshold")
 | 
			
		||||
	this.Nav("", "", "update")
 | 
			
		||||
	this.SecondMenu("threshold")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *IndexAction) RunGet(params struct {
 | 
			
		||||
	ClusterId int64
 | 
			
		||||
	NodeId    int64
 | 
			
		||||
}) {
 | 
			
		||||
	this.Data["nodeId"] = params.NodeId
 | 
			
		||||
 | 
			
		||||
	// 初始化节点信息(用于菜单)
 | 
			
		||||
	err := nodeutils.InitNodeInfo(this, params.NodeId)
 | 
			
		||||
	_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["nodeId"] = params.NodeId
 | 
			
		||||
 | 
			
		||||
	// 列出所有阈值
 | 
			
		||||
	thresholdsResp, err := this.RPC().NodeThresholdRPC().FindAllEnabledNodeThresholds(this.AdminContext(), &pb.FindAllEnabledNodeThresholdsRequest{
 | 
			
		||||
		Role:          "node",
 | 
			
		||||
@@ -6,7 +6,7 @@ import (
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 节点状态
 | 
			
		||||
// StatusAction 节点状态
 | 
			
		||||
type StatusAction struct {
 | 
			
		||||
	actionutils.ParentAction
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,11 +4,10 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/cluster/node/nodeutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/ipAddresses/ipaddressutils"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
			
		||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
 | 
			
		||||
	"github.com/iwind/TeaGo/actions"
 | 
			
		||||
	"github.com/iwind/TeaGo/maps"
 | 
			
		||||
)
 | 
			
		||||
@@ -19,12 +18,18 @@ type UpdateAction struct {
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) Init() {
 | 
			
		||||
	this.Nav("", "node", "update")
 | 
			
		||||
	this.SecondMenu("nodes")
 | 
			
		||||
	this.SecondMenu("basic")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
	NodeId int64
 | 
			
		||||
}) {
 | 
			
		||||
	_, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		this.ErrorPage(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.Data["nodeId"] = params.NodeId
 | 
			
		||||
 | 
			
		||||
	nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
 | 
			
		||||
@@ -74,105 +79,6 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// DNS相关
 | 
			
		||||
	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
 | 
			
		||||
		}
 | 
			
		||||
		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 {
 | 
			
		||||
			allDNSRouteMaps[domainId] = append(allDNSRouteMaps[domainId], maps.Map{
 | 
			
		||||
				"domainId":   domainId,
 | 
			
		||||
				"domainName": domainName,
 | 
			
		||||
				"name":       route.Name,
 | 
			
		||||
				"code":       route.Code,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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.NodeLogin != nil {
 | 
			
		||||
		loginParams := maps.Map{}
 | 
			
		||||
		if len(node.NodeLogin.Params) > 0 {
 | 
			
		||||
			err = json.Unmarshal(node.NodeLogin.Params, &loginParams)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		grantMap := maps.Map{}
 | 
			
		||||
		grantId := loginParams.GetInt64("grantId")
 | 
			
		||||
		if grantId > 0 {
 | 
			
		||||
			grantResp, err := this.RPC().NodeGrantRPC().FindEnabledNodeGrant(this.AdminContext(), &pb.FindEnabledNodeGrantRequest{NodeGrantId: grantId})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				this.ErrorPage(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if grantResp.NodeGrant != nil {
 | 
			
		||||
				grantMap = maps.Map{
 | 
			
		||||
					"id":         grantResp.NodeGrant.Id,
 | 
			
		||||
					"name":       grantResp.NodeGrant.Name,
 | 
			
		||||
					"method":     grantResp.NodeGrant.Method,
 | 
			
		||||
					"methodName": grantutils.FindGrantMethodName(grantResp.NodeGrant.Method),
 | 
			
		||||
					"username":   grantResp.NodeGrant.Username,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		loginMap = maps.Map{
 | 
			
		||||
			"id":     node.NodeLogin.Id,
 | 
			
		||||
			"name":   node.NodeLogin.Name,
 | 
			
		||||
			"type":   node.NodeLogin.Type,
 | 
			
		||||
			"params": loginParams,
 | 
			
		||||
			"grant":  grantMap,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 分组
 | 
			
		||||
	var groupMap maps.Map = nil
 | 
			
		||||
	if node.NodeGroup != nil {
 | 
			
		||||
@@ -191,45 +97,14 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 缓存硬盘 & 内存容量
 | 
			
		||||
	var maxCacheDiskCapacity maps.Map = nil
 | 
			
		||||
	if node.MaxCacheDiskCapacity != nil {
 | 
			
		||||
		maxCacheDiskCapacity = maps.Map{
 | 
			
		||||
			"count": node.MaxCacheDiskCapacity.Count,
 | 
			
		||||
			"unit":  node.MaxCacheDiskCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		maxCacheDiskCapacity = maps.Map{
 | 
			
		||||
			"count": 0,
 | 
			
		||||
			"unit":  "gb",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var maxCacheMemoryCapacity maps.Map = nil
 | 
			
		||||
	if node.MaxCacheMemoryCapacity != nil {
 | 
			
		||||
		maxCacheMemoryCapacity = maps.Map{
 | 
			
		||||
			"count": node.MaxCacheMemoryCapacity.Count,
 | 
			
		||||
			"unit":  node.MaxCacheMemoryCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		maxCacheMemoryCapacity = maps.Map{
 | 
			
		||||
			"count": 0,
 | 
			
		||||
			"unit":  "gb",
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var m = maps.Map{
 | 
			
		||||
		"id":                     node.Id,
 | 
			
		||||
		"name":                   node.Name,
 | 
			
		||||
		"ipAddresses":            ipAddressMaps,
 | 
			
		||||
		"cluster":                clusterMap,
 | 
			
		||||
		"login":                  loginMap,
 | 
			
		||||
		"maxCPU":                 node.MaxCPU,
 | 
			
		||||
		"isOn":                   node.IsOn,
 | 
			
		||||
		"group":                  groupMap,
 | 
			
		||||
		"region":                 regionMap,
 | 
			
		||||
		"maxCacheDiskCapacity":   maxCacheDiskCapacity,
 | 
			
		||||
		"maxCacheMemoryCapacity": maxCacheMemoryCapacity,
 | 
			
		||||
		"id":          node.Id,
 | 
			
		||||
		"name":        node.Name,
 | 
			
		||||
		"ipAddresses": ipAddressMaps,
 | 
			
		||||
		"cluster":     clusterMap,
 | 
			
		||||
		"isOn":        node.IsOn,
 | 
			
		||||
		"group":       groupMap,
 | 
			
		||||
		"region":      regionMap,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if node.NodeCluster != nil {
 | 
			
		||||
@@ -260,24 +135,15 @@ func (this *UpdateAction) RunGet(params struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
	LoginId                    int64
 | 
			
		||||
	NodeId                     int64
 | 
			
		||||
	GroupId                    int64
 | 
			
		||||
	RegionId                   int64
 | 
			
		||||
	Name                       string
 | 
			
		||||
	IPAddressesJSON            []byte `alias:"ipAddressesJSON"`
 | 
			
		||||
	PrimaryClusterId           int64
 | 
			
		||||
	SecondaryClusterIds        []byte
 | 
			
		||||
	GrantId                    int64
 | 
			
		||||
	SshHost                    string
 | 
			
		||||
	SshPort                    int
 | 
			
		||||
	MaxCPU                     int32
 | 
			
		||||
	IsOn                       bool
 | 
			
		||||
	MaxCacheDiskCapacityJSON   []byte
 | 
			
		||||
	MaxCacheMemoryCapacityJSON []byte
 | 
			
		||||
 | 
			
		||||
	DnsDomainId   int64
 | 
			
		||||
	DnsRoutesJSON []byte
 | 
			
		||||
	LoginId             int64
 | 
			
		||||
	NodeId              int64
 | 
			
		||||
	GroupId             int64
 | 
			
		||||
	RegionId            int64
 | 
			
		||||
	Name                string
 | 
			
		||||
	IPAddressesJSON     []byte `alias:"ipAddressesJSON"`
 | 
			
		||||
	PrimaryClusterId    int64
 | 
			
		||||
	SecondaryClusterIds []byte
 | 
			
		||||
	IsOn                bool
 | 
			
		||||
 | 
			
		||||
	Must *actions.Must
 | 
			
		||||
}) {
 | 
			
		||||
@@ -319,56 +185,6 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
		this.Fail("请至少输入一个IP地址")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dnsRouteCodes := []string{}
 | 
			
		||||
	if len(params.DnsRoutesJSON) > 0 {
 | 
			
		||||
		err := json.Unmarshal(params.DnsRoutesJSON, &dnsRouteCodes)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// TODO 检查登录授权
 | 
			
		||||
	loginInfo := &pb.NodeLogin{
 | 
			
		||||
		Id:   params.LoginId,
 | 
			
		||||
		Name: "SSH",
 | 
			
		||||
		Type: "ssh",
 | 
			
		||||
		Params: maps.Map{
 | 
			
		||||
			"grantId": params.GrantId,
 | 
			
		||||
			"host":    params.SshHost,
 | 
			
		||||
			"port":    params.SshPort,
 | 
			
		||||
		}.AsJSON(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 缓存硬盘 & 内存容量
 | 
			
		||||
	var pbMaxCacheDiskCapacity *pb.SizeCapacity
 | 
			
		||||
	if len(params.MaxCacheDiskCapacityJSON) > 0 {
 | 
			
		||||
		var sizeCapacity = &shared.SizeCapacity{}
 | 
			
		||||
		err := json.Unmarshal(params.MaxCacheDiskCapacityJSON, sizeCapacity)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		pbMaxCacheDiskCapacity = &pb.SizeCapacity{
 | 
			
		||||
			Count: sizeCapacity.Count,
 | 
			
		||||
			Unit:  sizeCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var pbMaxCacheMemoryCapacity *pb.SizeCapacity
 | 
			
		||||
	if len(params.MaxCacheMemoryCapacityJSON) > 0 {
 | 
			
		||||
		var sizeCapacity = &shared.SizeCapacity{}
 | 
			
		||||
		err := json.Unmarshal(params.MaxCacheMemoryCapacityJSON, sizeCapacity)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			this.ErrorPage(err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		pbMaxCacheMemoryCapacity = &pb.SizeCapacity{
 | 
			
		||||
			Count: sizeCapacity.Count,
 | 
			
		||||
			Unit:  sizeCapacity.Unit,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 保存
 | 
			
		||||
	_, err := this.RPC().NodeRPC().UpdateNode(this.AdminContext(), &pb.UpdateNodeRequest{
 | 
			
		||||
		NodeId:                  params.NodeId,
 | 
			
		||||
@@ -377,13 +193,7 @@ func (this *UpdateAction) RunPost(params struct {
 | 
			
		||||
		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)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,12 @@ Vue.component("dns-route-selector", {
 | 
			
		||||
		if (routes == null) {
 | 
			
		||||
			routes = []
 | 
			
		||||
		}
 | 
			
		||||
		routes.$sort(function (v1, v2) {
 | 
			
		||||
			if (v1.domainId == v2.domainId) {
 | 
			
		||||
				return v1.code < v2.code
 | 
			
		||||
			}
 | 
			
		||||
			return (v1.domainId < v2.domainId) ? 1 : -1
 | 
			
		||||
		})
 | 
			
		||||
		return {
 | 
			
		||||
			routes: routes,
 | 
			
		||||
			routeCodes: routes.$map(function (k, v) {
 | 
			
		||||
@@ -49,6 +55,13 @@ Vue.component("dns-route-selector", {
 | 
			
		||||
			this.routeCodes.push(this.routeCode)
 | 
			
		||||
			this.routes.push(route)
 | 
			
		||||
 | 
			
		||||
			this.routes.$sort(function (v1, v2) {
 | 
			
		||||
				if (v1.domainId == v2.domainId) {
 | 
			
		||||
					return v1.code < v2.code
 | 
			
		||||
				}
 | 
			
		||||
				return (v1.domainId < v2.domainId) ? 1 : -1
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
			this.routeCode = ""
 | 
			
		||||
			this.isAdding = false
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -57,6 +57,9 @@
 | 
			
		||||
.left-box.without-tabbar {
 | 
			
		||||
  top: 3em;
 | 
			
		||||
}
 | 
			
		||||
.left-box.with-menu {
 | 
			
		||||
  top: 10em;
 | 
			
		||||
}
 | 
			
		||||
.right-box {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 7.5em;
 | 
			
		||||
@@ -80,6 +83,9 @@ body.expanded .right-box {
 | 
			
		||||
.right-box.without-tabbar {
 | 
			
		||||
  top: 3em;
 | 
			
		||||
}
 | 
			
		||||
.right-box.with-menu {
 | 
			
		||||
  top: 10em;
 | 
			
		||||
}
 | 
			
		||||
.main.without-footer .left-box {
 | 
			
		||||
  bottom: 0.2em;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -79,6 +79,10 @@
 | 
			
		||||
	top: 3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.left-box.with-menu {
 | 
			
		||||
	top: 10em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.right-box {
 | 
			
		||||
	position: fixed;
 | 
			
		||||
	top: 7.5em;
 | 
			
		||||
@@ -107,6 +111,9 @@ body.expanded .right-box {
 | 
			
		||||
	top: 3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.right-box.with-menu {
 | 
			
		||||
	top: 10em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// main
 | 
			
		||||
.main.without-footer .left-box {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								web/views/@default/@left_menu_with_menu.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								web/views/@default/@left_menu_with_menu.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<div class="margin"></div>
 | 
			
		||||
 | 
			
		||||
<div class="left-box with-menu" :class="{disabled:leftMenuItemIsDisabled}">
 | 
			
		||||
	<div class="ui menu text blue vertical small">
 | 
			
		||||
		<a class="item" v-for="item in leftMenuItems" :href="item.url" :class="{active:item.isActive, separator:item.name == '-', on:item.isOn, off:item.isOff}">
 | 
			
		||||
			<span v-if="item.name != '-'"><i class="icon play tiny" :style="{'visibility':item.isActive ? 'visible' : 'hidden'}"></i>{{item.name}}<var v-if="item.isOff">关</var></span>
 | 
			
		||||
		</a>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -5,7 +5,6 @@
 | 
			
		||||
               v-if="!teaIsPlus">"{{node.name}}"节点详情</menu-item>
 | 
			
		||||
    <menu-item :href="'/clusters/cluster/node/boards?clusterId=' + clusterId + '&nodeId=' + node.id" code="board" v-if="teaIsPlus">"{{node.name}}" 节点看板</menu-item>
 | 
			
		||||
    <menu-item :href="'/clusters/cluster/node/detail?clusterId=' + clusterId + '&nodeId=' + node.id" code="node" v-if="teaIsPlus">节点详情</menu-item>
 | 
			
		||||
    <menu-item :href="'/clusters/cluster/node/thresholds?clusterId=' + clusterId + '&nodeId=' + node.id" code="threshold" v-if="teaIsPlus">阈值设置</menu-item>
 | 
			
		||||
    <menu-item :href="'/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + node.id" code="log">运行日志</menu-item>
 | 
			
		||||
    <menu-item :href="'/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + node.id" code="install">安装节点</menu-item>
 | 
			
		||||
	<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + node.id" code="update">修改设置</menu-item>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								web/views/@default/clusters/cluster/node/settings/cache/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								web/views/@default/clusters/cluster/node/settings/cache/index.html
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/clusters/cluster/node/node_menu"}
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
    <form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
        <csrf-token></csrf-token>
 | 
			
		||||
        <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
        <table class="ui table definition selectable">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td class="title">缓存磁盘容量</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <size-capacity-box :v-value="node.maxCacheDiskCapacity" :v-name="'maxCacheDiskCapacityJSON'"></size-capacity-box>
 | 
			
		||||
                    <p class="comment">缓存能使用的磁盘的最大容量,0表示不限制。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>缓存内存容量</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <size-capacity-box :v-value="node.maxCacheMemoryCapacity" :v-name="'maxCacheMemoryCapacityJSON'"></size-capacity-box>
 | 
			
		||||
                    <p class="comment">缓存能使用的内存的最大容量,0表示不限制。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
        <submit-btn></submit-btn>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										3
									
								
								web/views/@default/clusters/cluster/node/settings/cache/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/views/@default/clusters/cluster/node/settings/cache/index.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifyReloadSuccess("保存成功")
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,23 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/clusters/cluster/node/node_menu"}
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
    <form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
        <csrf-token></csrf-token>
 | 
			
		||||
        <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
 | 
			
		||||
        <table class="ui table definition selectable">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td class="title">DNS线路</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <div v-if="allDNSRoutes.length > 0">
 | 
			
		||||
                        <dns-route-selector :v-all-routes="allDNSRoutes" :v-routes="dnsRoutes"></dns-route-selector>
 | 
			
		||||
                        <p class="comment">当前节点对应的DNS线路,可用线路是根据集群设置的域名获取的,注意DNS服务商可能对这些线路有其他限制。</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
        <submit-btn></submit-btn>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifyReloadSuccess("保存成功")
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,35 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/clusters/cluster/node/node_menu"}
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
    <form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
        <csrf-token></csrf-token>
 | 
			
		||||
        <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
        <input type="hidden" name="loginId" :value="loginId"/>
 | 
			
		||||
 | 
			
		||||
        <table class="ui table definition selectable">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td class="title">SSH主机地址</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="sshHost" maxlength="64" v-model="sshHost"/>
 | 
			
		||||
                    <p class="comment">比如192.168.1.100</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SSH主机端口</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="sshPort" maxlength="5" v-model="sshPort"/>
 | 
			
		||||
                    <p class="comment">比如22。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SSH登录认证</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <grant-selector :v-grant="grant" :v-node-cluster-id="clusterId"></grant-selector>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
        <submit-btn></submit-btn>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifyReloadSuccess("保存成功")
 | 
			
		||||
 | 
			
		||||
	// 认证相关
 | 
			
		||||
	this.grant = null
 | 
			
		||||
 | 
			
		||||
	this.sshHost = ""
 | 
			
		||||
	this.sshPort = ""
 | 
			
		||||
	this.loginId = 0
 | 
			
		||||
	if (this.node.login != null) {
 | 
			
		||||
		this.loginId = this.node.login.id
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.params != null) {
 | 
			
		||||
			this.sshHost = this.node.login.params.host
 | 
			
		||||
			if (this.node.login.params.port > 0) {
 | 
			
		||||
				this.sshPort = this.node.login.params.port
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.grant != null && typeof this.node.login.grant.id != "undefined") {
 | 
			
		||||
			this.grant = {
 | 
			
		||||
				id: this.node.login.grant.id,
 | 
			
		||||
				name: this.node.login.grant.name,
 | 
			
		||||
				method: this.node.login.grant.method,
 | 
			
		||||
				methodName: this.node.login.grant.methodName,
 | 
			
		||||
				username: this.node.login.grant.username
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,20 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/clusters/cluster/node/node_menu"}
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
    <form class="ui form" data-tea-success="success" data-tea-action="$">
 | 
			
		||||
        <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
        <csrf-token></csrf-token>
 | 
			
		||||
        <table class="ui table definition selectable">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td class="title">CPU线程数</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="maxCPU" v-model="node.maxCPU" style="width:5em" maxlength="5em"/>
 | 
			
		||||
                    <p class="comment">当前节点可以使用的最多的CPU线程数,如果为0表示可以使用全部CPU。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </table>
 | 
			
		||||
        <submit-btn></submit-btn>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
Tea.context(function () {
 | 
			
		||||
	this.success = NotifyReloadSuccess("保存成功")
 | 
			
		||||
})
 | 
			
		||||
@@ -0,0 +1,41 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "/clusters/cluster/node/node_menu"}
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
 | 
			
		||||
    <div>
 | 
			
		||||
        <second-menu>
 | 
			
		||||
            <menu-item @click.prevent="createThreshold">添加阈值</menu-item>
 | 
			
		||||
        </second-menu>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p>
 | 
			
		||||
    <table class="ui table selectable celled" v-if="thresholds.length > 0">
 | 
			
		||||
        <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>监控项</th>
 | 
			
		||||
            <th>参数</th>
 | 
			
		||||
            <th>操作符</th>
 | 
			
		||||
            <th>对比值</th>
 | 
			
		||||
            <th>统计时间段</th>
 | 
			
		||||
            <th class="two wide">状态</th>
 | 
			
		||||
            <th class="two op">操作</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tr v-for="threshold in thresholds">
 | 
			
		||||
            <td>{{threshold.itemName}}</td>
 | 
			
		||||
            <td>{{threshold.paramName}}</td>
 | 
			
		||||
            <td>{{threshold.operatorName}}</td>
 | 
			
		||||
            <td>{{threshold.value}}</td>
 | 
			
		||||
            <td>{{threshold.duration}}{{threshold.durationUnitName}}</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <label-on :v-is-on="threshold.isOn"></label-on>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <a href="" @click.prevent="updateThreshold(threshold.id)">修改</a>  
 | 
			
		||||
                <a href="" @click.prevent="deleteThreshold(threshold.id)">删除</a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -27,7 +27,7 @@ Tea.context(function () {
 | 
			
		||||
	this.deleteThreshold = function (thresholdId) {
 | 
			
		||||
		let that = this
 | 
			
		||||
		teaweb.confirm("确定要删除这个阈值吗?", function () {
 | 
			
		||||
			that.$post(".delete")
 | 
			
		||||
			that.$post("/clusters/cluster/settings/thresholds/delete")
 | 
			
		||||
				.params({
 | 
			
		||||
					thresholdId: thresholdId
 | 
			
		||||
				})
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
{$template "../node_menu"}
 | 
			
		||||
 | 
			
		||||
<div style="margin-top: -1em">
 | 
			
		||||
    <second-menu>
 | 
			
		||||
        <menu-item @click.prevent="createThreshold">添加阈值</menu-item>
 | 
			
		||||
    </second-menu>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<p class="comment" v-if="thresholds.length == 0">暂时还没有设置阈值。</p>
 | 
			
		||||
<table class="ui table selectable celled" v-if="thresholds.length > 0">
 | 
			
		||||
    <thead>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <th>监控项</th>
 | 
			
		||||
            <th>参数</th>
 | 
			
		||||
            <th>操作符</th>
 | 
			
		||||
            <th>对比值</th>
 | 
			
		||||
            <th>统计时间段</th>
 | 
			
		||||
            <th class="two wide">状态</th>
 | 
			
		||||
            <th class="two op">操作</th>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tr v-for="threshold in thresholds">
 | 
			
		||||
        <td>{{threshold.itemName}}</td>
 | 
			
		||||
        <td>{{threshold.paramName}}</td>
 | 
			
		||||
        <td>{{threshold.operatorName}}</td>
 | 
			
		||||
        <td>{{threshold.value}}</td>
 | 
			
		||||
        <td>{{threshold.duration}}{{threshold.durationUnitName}}</td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <label-on :v-is-on="threshold.isOn"></label-on>
 | 
			
		||||
        </td>
 | 
			
		||||
        <td>
 | 
			
		||||
            <a href="" @click.prevent="updateThreshold(threshold.id)">修改</a>  
 | 
			
		||||
            <a href="" @click.prevent="deleteThreshold(threshold.id)">删除</a>
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
</table>
 | 
			
		||||
@@ -1,108 +1,65 @@
 | 
			
		||||
{$layout}
 | 
			
		||||
 | 
			
		||||
{$template "node_menu"}
 | 
			
		||||
 | 
			
		||||
<h3>修改节点</h3>
 | 
			
		||||
<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="loginId" :value="loginId"/>
 | 
			
		||||
    <table class="ui table definition selectable">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="title">节点名称 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <input type="text" name="name" maxlength="50" ref="focus" v-model="node.name"/>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>所属集群</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <node-clusters-selector :v-primary-cluster="node.primaryCluster" :v-secondary-clusters="node.secondaryClusters" @change="changeClusters"></node-clusters-selector>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>IP地址 *</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <node-ip-addresses-box :v-ip-addresses="ipAddresses"></node-ip-addresses-box>
 | 
			
		||||
                <p class="comment">用于访问节点和域名解析等。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
       <tr v-if="allDNSRoutes.length > 0">
 | 
			
		||||
            <td>DNS线路</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <dns-route-selector :v-all-routes="allDNSRoutes" :v-routes="dnsRoutes"></dns-route-selector>
 | 
			
		||||
                <p class="comment">当前节点对应的DNS线路,可用线路是根据集群设置的域名获取的,注意DNS服务商可能对这些线路有其他限制。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>所属区域</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <node-region-selector :v-region="node.region"></node-region-selector>
 | 
			
		||||
                <p class="comment">设置区域后才能根据区域进行流量统计和计费。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td>所属分组</td>
 | 
			
		||||
            <td>
 | 
			
		||||
                <node-group-selector :v-cluster-id="clusterId" :v-group="node.group"></node-group-selector>
 | 
			
		||||
                <p class="comment">仅用来筛选服务。</p>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tbody v-show="moreOptionsVisible">
 | 
			
		||||
{$template "/left_menu_with_menu"}
 | 
			
		||||
 | 
			
		||||
<div class="right-box with-menu">
 | 
			
		||||
    <form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
 | 
			
		||||
        <input type="hidden" name="nodeId" :value="node.id"/>
 | 
			
		||||
        <table class="ui table definition selectable">
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SSH主机地址</td>
 | 
			
		||||
                <td class="title">节点名称 *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="sshHost" maxlength="64" v-model="sshHost"/>
 | 
			
		||||
                    <p class="comment">比如192.168.1.100</p>
 | 
			
		||||
                    <input type="text" name="name" maxlength="50" ref="focus" v-model="node.name"/>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SSH主机端口</td>
 | 
			
		||||
                <td>所属集群</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="sshPort" maxlength="5" v-model="sshPort"/>
 | 
			
		||||
                    <p class="comment">比如22。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>SSH登录认证</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <grant-selector :v-grant="grant" :v-node-cluster-id="clusterId"></grant-selector>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>CPU线程数</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <input type="text" name="maxCPU" v-model="node.maxCPU" style="width:5em" maxlength="5em"/>
 | 
			
		||||
                    <p class="comment">当前节点可以使用的最多的CPU线程数,如果为0表示可以使用全部CPU。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>缓存磁盘容量</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <size-capacity-box :v-value="node.maxCacheDiskCapacity" :v-name="'maxCacheDiskCapacityJSON'"></size-capacity-box>
 | 
			
		||||
                    <p class="comment">缓存能使用的磁盘的最大容量,0表示不限制。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>缓存内存容量</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <size-capacity-box :v-value="node.maxCacheMemoryCapacity" :v-name="'maxCacheMemoryCapacityJSON'"></size-capacity-box>
 | 
			
		||||
                    <p class="comment">缓存能使用的内存的最大容量,0表示不限制。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>是否启用</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <div class="ui checkbox">
 | 
			
		||||
                        <input type="checkbox" name="isOn" value="1" v-model="node.isOn"/>
 | 
			
		||||
                        <label></label>
 | 
			
		||||
                    <span v-if="node.primaryCluster != null" class="ui label basic small">{{node.primaryCluster.name}}</span>
 | 
			
		||||
                    <span v-if="node.secondaryClusters.length > 0"  v-for="cluster in node.secondaryClusters" class="ui label basic small grey">{{cluster.name}}</span>   <a href="" @click.prevent="updateClusters">[修改]</a>
 | 
			
		||||
                    <div v-show="showClustersBox">
 | 
			
		||||
                        <node-clusters-selector :v-primary-cluster="node.primaryCluster" :v-secondary-clusters="node.secondaryClusters" @change="changeClusters"></node-clusters-selector>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <p class="comment">如果不启用此节点,此节点上的所有服务将不能访问。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
    <submit-btn></submit-btn>
 | 
			
		||||
</form>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>IP地址 *</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <node-ip-addresses-box :v-ip-addresses="ipAddresses"></node-ip-addresses-box>
 | 
			
		||||
                    <p class="comment">用于访问节点和域名解析等。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>所属区域</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <node-region-selector :v-region="node.region"></node-region-selector>
 | 
			
		||||
                    <p class="comment">设置区域后才能根据区域进行流量统计和计费。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>所属分组</td>
 | 
			
		||||
                <td>
 | 
			
		||||
                    <node-group-selector :v-cluster-id="clusterId" :v-group="node.group"></node-group-selector>
 | 
			
		||||
                    <p class="comment">仅用来筛选服务。</p>
 | 
			
		||||
                </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td colspan="2"><more-options-indicator></more-options-indicator></td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tbody v-show="moreOptionsVisible">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>是否启用</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <div class="ui checkbox">
 | 
			
		||||
                            <input type="checkbox" name="isOn" value="1" v-model="node.isOn"/>
 | 
			
		||||
                            <label></label>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <p class="comment">如果不启用此节点,此节点上的所有服务将不能访问。</p>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
        <submit-btn></submit-btn>
 | 
			
		||||
    </form>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -14,34 +14,16 @@ Tea.context(function () {
 | 
			
		||||
	// IP地址相关
 | 
			
		||||
	this.ipAddresses = this.node.ipAddresses
 | 
			
		||||
 | 
			
		||||
	// 认证相关
 | 
			
		||||
	this.grant = null
 | 
			
		||||
 | 
			
		||||
	this.sshHost = ""
 | 
			
		||||
	this.sshPort = ""
 | 
			
		||||
	this.loginId = 0
 | 
			
		||||
	if (this.node.login != null) {
 | 
			
		||||
		this.loginId = this.node.login.id
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.params != null) {
 | 
			
		||||
			this.sshHost = this.node.login.params.host
 | 
			
		||||
			if (this.node.login.params.port > 0) {
 | 
			
		||||
				this.sshPort = this.node.login.params.port
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (this.node.login.grant != null && typeof this.node.login.grant.id != "undefined") {
 | 
			
		||||
			this.grant = {
 | 
			
		||||
				id: this.node.login.grant.id,
 | 
			
		||||
				name: this.node.login.grant.name,
 | 
			
		||||
				method: this.node.login.grant.method,
 | 
			
		||||
				methodName: this.node.login.grant.methodName,
 | 
			
		||||
				username: this.node.login.grant.username
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	this.changeClusters = function (info) {
 | 
			
		||||
		this.clusterId = info.clusterId
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 集群相关
 | 
			
		||||
	 */
 | 
			
		||||
	this.showClustersBox = false
 | 
			
		||||
 | 
			
		||||
	this.updateClusters = function () {
 | 
			
		||||
		this.showClustersBox = !this.showClustersBox
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
        <tr v-for="threshold in thresholds">
 | 
			
		||||
            <td>{{threshold.itemName}}
 | 
			
		||||
                <div v-if="threshold.node != null" style="margin-top: 0.3em">
 | 
			
		||||
                    <a :href="'/clusters/cluster/node/thresholds?clusterId=' + clusterId + '&nodeId=' + threshold.node.id" class="ui label basic tiny" title="节点专属阈值设置"><span class="small">节点:{{threshold.node.name}}</span></a>
 | 
			
		||||
                    <a :href="'/clusters/cluster/node/settings/thresholds?clusterId=' + clusterId + '&nodeId=' + threshold.node.id" class="ui label basic tiny" title="节点专属阈值设置"><span class="small">节点:{{threshold.node.name}}</span></a>
 | 
			
		||||
                </div>
 | 
			
		||||
            </td>
 | 
			
		||||
            <td>{{threshold.paramName}}</td>
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,6 @@
 | 
			
		||||
	<menu-item :href="'/ns/clusters/cluster?clusterId=' + clusterId">节点列表</menu-item>
 | 
			
		||||
	<span class="item">|</span>
 | 
			
		||||
	<menu-item :href="'/ns/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
 | 
			
		||||
    <!--<menu-item :href="'/ns/clusters/cluster/node/monitor?clusterId=' + clusterId + '&nodeId=' + nodeId" code="monitor">监控图表</menu-item>
 | 
			
		||||
    <menu-item :href="'/ns/clusters/cluster/node/thresholds?clusterId=' + clusterId + '&nodeId=' + nodeId" code="threshold">阈值设置</menu-item>-->
 | 
			
		||||
    <menu-item :href="'/ns/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + nodeId" code="log">运行日志</menu-item>
 | 
			
		||||
	<menu-item :href="'/ns/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改设置</menu-item>
 | 
			
		||||
	<menu-item :href="'/ns/clusters/cluster/node/install?clusterId=' + clusterId + '&nodeId=' + nodeId" code="install">安装节点</menu-item>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user