mirror of
				https://github.com/TeaOSLab/EdgeAdmin.git
				synced 2025-11-04 13:10:26 +08:00 
			
		
		
		
	实现健康检查配置、立即执行健康检查
This commit is contained in:
		@@ -73,9 +73,10 @@ func (this *IndexAction) RunGet(params struct {
 | 
				
			|||||||
		ipAddresses := []maps.Map{}
 | 
							ipAddresses := []maps.Map{}
 | 
				
			||||||
		for _, addr := range ipAddressesResp.Addresses {
 | 
							for _, addr := range ipAddressesResp.Addresses {
 | 
				
			||||||
			ipAddresses = append(ipAddresses, maps.Map{
 | 
								ipAddresses = append(ipAddresses, maps.Map{
 | 
				
			||||||
				"id":   addr.Id,
 | 
									"id":        addr.Id,
 | 
				
			||||||
				"name": addr.Name,
 | 
									"name":      addr.Name,
 | 
				
			||||||
				"ip":   addr.Ip,
 | 
									"ip":        addr.Ip,
 | 
				
			||||||
 | 
									"canAccess": addr.CanAccess,
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,9 +60,10 @@ func (this *NodeAction) RunGet(params struct {
 | 
				
			|||||||
	ipAddressMaps := []maps.Map{}
 | 
						ipAddressMaps := []maps.Map{}
 | 
				
			||||||
	for _, addr := range ipAddressesResp.Addresses {
 | 
						for _, addr := range ipAddressesResp.Addresses {
 | 
				
			||||||
		ipAddressMaps = append(ipAddressMaps, maps.Map{
 | 
							ipAddressMaps = append(ipAddressMaps, maps.Map{
 | 
				
			||||||
			"id":   addr.Id,
 | 
								"id":        addr.Id,
 | 
				
			||||||
			"name": addr.Name,
 | 
								"name":      addr.Name,
 | 
				
			||||||
			"ip":   addr.Ip,
 | 
								"ip":        addr.Ip,
 | 
				
			||||||
 | 
								"canAccess": addr.CanAccess,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/grants/grantutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/grants/grantutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/ipAddresses/ipaddressutils"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
@@ -51,9 +52,10 @@ func (this *UpdateAction) RunGet(params struct {
 | 
				
			|||||||
	ipAddressMaps := []maps.Map{}
 | 
						ipAddressMaps := []maps.Map{}
 | 
				
			||||||
	for _, addr := range ipAddressesResp.Addresses {
 | 
						for _, addr := range ipAddressesResp.Addresses {
 | 
				
			||||||
		ipAddressMaps = append(ipAddressMaps, maps.Map{
 | 
							ipAddressMaps = append(ipAddressMaps, maps.Map{
 | 
				
			||||||
			"id":   addr.Id,
 | 
								"id":        addr.Id,
 | 
				
			||||||
			"name": addr.Name,
 | 
								"name":      addr.Name,
 | 
				
			||||||
			"ip":   addr.Ip,
 | 
								"ip":        addr.Ip,
 | 
				
			||||||
 | 
								"canAccess": addr.CanAccess,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -128,16 +130,16 @@ func (this *UpdateAction) RunGet(params struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *UpdateAction) RunPost(params struct {
 | 
					func (this *UpdateAction) RunPost(params struct {
 | 
				
			||||||
	LoginId     int64
 | 
						LoginId         int64
 | 
				
			||||||
	NodeId      int64
 | 
						NodeId          int64
 | 
				
			||||||
	Name        string
 | 
						Name            string
 | 
				
			||||||
	IPAddresses string `alias:"ipAddresses"`
 | 
						IPAddressesJSON []byte `alias:"ipAddressesJSON"`
 | 
				
			||||||
	ClusterId   int64
 | 
						ClusterId       int64
 | 
				
			||||||
	GrantId     int64
 | 
						GrantId         int64
 | 
				
			||||||
	SshHost     string
 | 
						SshHost         string
 | 
				
			||||||
	SshPort     int
 | 
						SshPort         int
 | 
				
			||||||
	MaxCPU      int32
 | 
						MaxCPU          int32
 | 
				
			||||||
	IsOn        bool
 | 
						IsOn            bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Must *actions.Must
 | 
						Must *actions.Must
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
@@ -188,23 +190,11 @@ func (this *UpdateAction) RunPost(params struct {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 添加新的IP地址
 | 
						// 添加新的IP地址
 | 
				
			||||||
	ipAddresses := []maps.Map{}
 | 
						err = ipaddressutils.UpdateNodeIPAddresses(this.Parent(), params.NodeId, params.IPAddressesJSON)
 | 
				
			||||||
	err = json.Unmarshal([]byte(params.IPAddresses), &ipAddresses)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		this.ErrorPage(err)
 | 
							this.ErrorPage(err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, address := range ipAddresses {
 | 
					 | 
				
			||||||
		addressId := address.GetInt64("id")
 | 
					 | 
				
			||||||
		_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
 | 
					 | 
				
			||||||
			AddressId: addressId,
 | 
					 | 
				
			||||||
			NodeId:    params.NodeId,
 | 
					 | 
				
			||||||
		})
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			this.ErrorPage(err)
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Success()
 | 
						this.Success()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					package settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HealthAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "setting", "")
 | 
				
			||||||
 | 
						this.SecondMenu("health")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthAction) RunGet(params struct {
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						configResp, err := this.RPC().NodeClusterRPC().FindNodeClusterHealthCheckConfig(this.AdminContext(), &pb.FindNodeClusterHealthCheckConfigRequest{ClusterId: params.ClusterId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var config *serverconfigs.HealthCheckConfig = nil
 | 
				
			||||||
 | 
						if len(configResp.HealthCheckConfig) > 0 {
 | 
				
			||||||
 | 
							config = &serverconfigs.HealthCheckConfig{}
 | 
				
			||||||
 | 
							err = json.Unmarshal(configResp.HealthCheckConfig, config)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								this.ErrorPage(err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["healthCheckConfig"] = config
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthAction) RunPost(params struct {
 | 
				
			||||||
 | 
						ClusterId       int64
 | 
				
			||||||
 | 
						HealthCheckJSON []byte
 | 
				
			||||||
 | 
						Must            *actions.Must
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						config := &serverconfigs.HealthCheckConfig{}
 | 
				
			||||||
 | 
						err := json.Unmarshal(params.HealthCheckJSON, config)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err = this.RPC().NodeClusterRPC().UpdateNodeClusterHealthCheck(this.AdminContext(), &pb.UpdateNodeClusterHealthCheckRequest{
 | 
				
			||||||
 | 
							ClusterId:       params.ClusterId,
 | 
				
			||||||
 | 
							HealthCheckJSON: params.HealthCheckJSON,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.ErrorPage(err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					package settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HealthRunAction struct {
 | 
				
			||||||
 | 
						actionutils.ParentAction
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthRunAction) Init() {
 | 
				
			||||||
 | 
						this.Nav("", "", "")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthRunAction) RunGet(params struct{}) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Show()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (this *HealthRunAction) RunPost(params struct {
 | 
				
			||||||
 | 
						ClusterId int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Must *actions.Must
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
						resp, err := this.RPC().NodeClusterRPC().ExecuteNodeClusterHealthCheck(this.AdminContext(), &pb.ExecuteNodeClusterHealthCheckRequest{ClusterId: params.ClusterId})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							this.Fail(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.Data["results"] = resp.Results
 | 
				
			||||||
 | 
						this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -13,6 +13,8 @@ func init() {
 | 
				
			|||||||
			Helper(clusters.NewClusterHelper()).
 | 
								Helper(clusters.NewClusterHelper()).
 | 
				
			||||||
			Prefix("/clusters/cluster/settings").
 | 
								Prefix("/clusters/cluster/settings").
 | 
				
			||||||
			GetPost("", new(IndexAction)).
 | 
								GetPost("", new(IndexAction)).
 | 
				
			||||||
 | 
								GetPost("/health", new(HealthAction)).
 | 
				
			||||||
 | 
								GetPost("/healthRun", new(HealthRunAction)).
 | 
				
			||||||
			EndAll()
 | 
								EndAll()
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,5 +84,10 @@ func (this *ClusterHelper) createSettingMenu(clusterId string, selectedItem stri
 | 
				
			|||||||
		"url":      "/clusters/cluster/settings?clusterId=" + clusterId,
 | 
							"url":      "/clusters/cluster/settings?clusterId=" + clusterId,
 | 
				
			||||||
		"isActive": selectedItem == "basic",
 | 
							"isActive": selectedItem == "basic",
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						items = append(items, maps.Map{
 | 
				
			||||||
 | 
							"name":     "健康检查",
 | 
				
			||||||
 | 
							"url":      "/clusters/cluster/settings/health?clusterId=" + clusterId,
 | 
				
			||||||
 | 
							"isActive": selectedItem == "health",
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
package ipAddresses
 | 
					package ipAddresses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreatePopupAction struct {
 | 
					type CreatePopupAction struct {
 | 
				
			||||||
@@ -20,31 +20,28 @@ func (this *CreatePopupAction) RunGet(params struct{}) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (this *CreatePopupAction) RunPost(params struct {
 | 
					func (this *CreatePopupAction) RunPost(params struct {
 | 
				
			||||||
	IP   string `alias:"ip"`
 | 
						IP        string `alias:"ip"`
 | 
				
			||||||
	Name string
 | 
						CanAccess bool
 | 
				
			||||||
 | 
						Name      string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Must *actions.Must
 | 
						Must *actions.Must
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
	// TODO 严格校验IP地址
 | 
						// TODO 严格校验IP地址
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ip := net.ParseIP(params.IP)
 | 
				
			||||||
 | 
						if len(ip) == 0 {
 | 
				
			||||||
 | 
							this.Fail("请输入正确的IP")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	params.Must.
 | 
						params.Must.
 | 
				
			||||||
		Field("ip", params.IP).
 | 
							Field("ip", params.IP).
 | 
				
			||||||
		Require("请输入IP地址")
 | 
							Require("请输入IP地址")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
 | 
					 | 
				
			||||||
		NodeId: 0,
 | 
					 | 
				
			||||||
		Name:   params.Name,
 | 
					 | 
				
			||||||
		Ip:     params.IP,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		this.ErrorPage(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this.Data["ipAddress"] = maps.Map{
 | 
						this.Data["ipAddress"] = maps.Map{
 | 
				
			||||||
		"name": params.Name,
 | 
							"name":      params.Name,
 | 
				
			||||||
		"ip":   params.IP,
 | 
							"canAccess": params.CanAccess,
 | 
				
			||||||
		"id":   resp.AddressId,
 | 
							"ip":        params.IP,
 | 
				
			||||||
 | 
							"id":        0,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	this.Success()
 | 
						this.Success()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					package ipaddressutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 保存一组IP地址
 | 
				
			||||||
 | 
					func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64, ipAddressesJSON []byte) error {
 | 
				
			||||||
 | 
						addresses := []maps.Map{}
 | 
				
			||||||
 | 
						err := json.Unmarshal(ipAddressesJSON, &addresses)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, addr := range addresses {
 | 
				
			||||||
 | 
							addrId := addr.GetInt64("id")
 | 
				
			||||||
 | 
							if addrId > 0 {
 | 
				
			||||||
 | 
								_, err = parentAction.RPC().NodeIPAddressRPC().UpdateNodeIPAddress(parentAction.AdminContext(), &pb.UpdateNodeIPAddressRequest{
 | 
				
			||||||
 | 
									AddressId: addrId,
 | 
				
			||||||
 | 
									Ip:        addr.GetString("ip"),
 | 
				
			||||||
 | 
									Name:      addr.GetString("name"),
 | 
				
			||||||
 | 
									CanAccess: addr.GetBool("canAccess"),
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								_, err = parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
 | 
				
			||||||
 | 
									NodeId:    nodeId,
 | 
				
			||||||
 | 
									Name:      addr.GetString("name"),
 | 
				
			||||||
 | 
									Ip:        addr.GetString("ip"),
 | 
				
			||||||
 | 
									CanAccess: addr.GetBool("canAccess"),
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,10 +1,10 @@
 | 
				
			|||||||
package ipAddresses
 | 
					package ipAddresses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
						"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
 | 
				
			||||||
	"github.com/iwind/TeaGo/actions"
 | 
						"github.com/iwind/TeaGo/actions"
 | 
				
			||||||
	"github.com/iwind/TeaGo/maps"
 | 
						"github.com/iwind/TeaGo/maps"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type UpdatePopupAction struct {
 | 
					type UpdatePopupAction struct {
 | 
				
			||||||
@@ -18,23 +18,6 @@ func (this *UpdatePopupAction) Init() {
 | 
				
			|||||||
func (this *UpdatePopupAction) RunGet(params struct {
 | 
					func (this *UpdatePopupAction) RunGet(params struct {
 | 
				
			||||||
	AddressId int64
 | 
						AddressId int64
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
	addressResp, err := this.RPC().NodeIPAddressRPC().FindEnabledNodeIPAddress(this.AdminContext(), &pb.FindEnabledNodeIPAddressRequest{AddressId: params.AddressId})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		this.ErrorPage(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	address := addressResp.IpAddress
 | 
					 | 
				
			||||||
	if address == nil {
 | 
					 | 
				
			||||||
		this.WriteString("找不到要修改的IP地址")
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this.Data["address"] = maps.Map{
 | 
					 | 
				
			||||||
		"id":   address.Id,
 | 
					 | 
				
			||||||
		"name": address.Name,
 | 
					 | 
				
			||||||
		"ip":   address.Ip,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this.Show()
 | 
						this.Show()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,6 +25,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
 | 
				
			|||||||
	AddressId int64
 | 
						AddressId int64
 | 
				
			||||||
	IP        string `alias:"ip"`
 | 
						IP        string `alias:"ip"`
 | 
				
			||||||
	Name      string
 | 
						Name      string
 | 
				
			||||||
 | 
						CanAccess bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Must *actions.Must
 | 
						Must *actions.Must
 | 
				
			||||||
}) {
 | 
					}) {
 | 
				
			||||||
@@ -51,20 +35,16 @@ func (this *UpdatePopupAction) RunPost(params struct {
 | 
				
			|||||||
		Field("ip", params.IP).
 | 
							Field("ip", params.IP).
 | 
				
			||||||
		Require("请输入IP地址")
 | 
							Require("请输入IP地址")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := this.RPC().NodeIPAddressRPC().UpdateNodeIPAddress(this.AdminContext(), &pb.UpdateNodeIPAddressRequest{
 | 
						ip := net.ParseIP(params.IP)
 | 
				
			||||||
		AddressId: params.AddressId,
 | 
						if len(ip) == 0 {
 | 
				
			||||||
		Name:      params.Name,
 | 
							this.Fail("请输入正确的IP")
 | 
				
			||||||
		Ip:        params.IP,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		this.ErrorPage(err)
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Data["ipAddress"] = maps.Map{
 | 
						this.Data["ipAddress"] = maps.Map{
 | 
				
			||||||
		"name": params.Name,
 | 
							"name":      params.Name,
 | 
				
			||||||
		"ip":   params.IP,
 | 
							"ip":        params.IP,
 | 
				
			||||||
		"id":   params.AddressId,
 | 
							"id":        params.AddressId,
 | 
				
			||||||
 | 
							"canAccess": params.CanAccess,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this.Success()
 | 
						this.Success()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										168
									
								
								web/public/js/components/common/health-check-config-box.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								web/public/js/components/common/health-check-config-box.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
				
			|||||||
 | 
					Vue.component("health-check-config-box", {
 | 
				
			||||||
 | 
						props: ["v-health-check-config"],
 | 
				
			||||||
 | 
						data: function () {
 | 
				
			||||||
 | 
							let healthCheckConfig = this.vHealthCheckConfig
 | 
				
			||||||
 | 
							let urlProtocol = "http"
 | 
				
			||||||
 | 
							let urlPort = ""
 | 
				
			||||||
 | 
							let urlRequestURI = "/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (healthCheckConfig == null) {
 | 
				
			||||||
 | 
								healthCheckConfig = {
 | 
				
			||||||
 | 
									isOn: false,
 | 
				
			||||||
 | 
									url: "",
 | 
				
			||||||
 | 
									interval: {count: 60, unit: "second"},
 | 
				
			||||||
 | 
									statusCodes: [200],
 | 
				
			||||||
 | 
									timeout: {count: 10, unit: "second"},
 | 
				
			||||||
 | 
									countTries: 3,
 | 
				
			||||||
 | 
									tryDelay: {count: 100, unit: "ms"}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								let that = this
 | 
				
			||||||
 | 
								setTimeout(function () {
 | 
				
			||||||
 | 
									that.changeURL()
 | 
				
			||||||
 | 
								}, 500)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								let url = new URL(healthCheckConfig.url)
 | 
				
			||||||
 | 
								urlProtocol = url.protocol.substring(0, url.protocol.length - 1)
 | 
				
			||||||
 | 
								urlPort = url.port
 | 
				
			||||||
 | 
								urlRequestURI = url.pathname
 | 
				
			||||||
 | 
								if (url.search.length > 0) {
 | 
				
			||||||
 | 
									urlRequestURI += url.search
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								healthCheck: healthCheckConfig,
 | 
				
			||||||
 | 
								advancedVisible: false,
 | 
				
			||||||
 | 
								urlProtocol: urlProtocol,
 | 
				
			||||||
 | 
								urlPort: urlPort,
 | 
				
			||||||
 | 
								urlRequestURI: urlRequestURI
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						watch: {
 | 
				
			||||||
 | 
							urlRequestURI: function () {
 | 
				
			||||||
 | 
								if (this.urlRequestURI.length > 0 && this.urlRequestURI[0] != "/") {
 | 
				
			||||||
 | 
									this.urlRequestURI = "/" + this.urlRequestURI
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.changeURL()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							urlPort: function (v) {
 | 
				
			||||||
 | 
								let port = parseInt(v)
 | 
				
			||||||
 | 
								if (!isNaN(port)) {
 | 
				
			||||||
 | 
									this.urlPort = port.toString()
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									this.urlPort = ""
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								this.changeURL()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							urlProtocol: function () {
 | 
				
			||||||
 | 
								this.changeURL()
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"healthCheck.countTries": function (v) {
 | 
				
			||||||
 | 
								let count = parseInt(v)
 | 
				
			||||||
 | 
								if (!isNaN(count)) {
 | 
				
			||||||
 | 
									this.healthCheck.countTries = count
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									this.healthCheck.countTries = 0
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						methods: {
 | 
				
			||||||
 | 
							showAdvanced: function () {
 | 
				
			||||||
 | 
								this.advancedVisible = !this.advancedVisible
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							changeURL: function () {
 | 
				
			||||||
 | 
								this.healthCheck.url = this.urlProtocol + "://${host}" + ((this.urlPort.length > 0) ? ":" + this.urlPort : "") + this.urlRequestURI
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							changeStatus: function (values) {
 | 
				
			||||||
 | 
								this.healthCheck.statusCodes = values.$map(function (k, v) {
 | 
				
			||||||
 | 
									let status = parseInt(v)
 | 
				
			||||||
 | 
									if (isNaN(status)) {
 | 
				
			||||||
 | 
										return 0
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										return status
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								console.log(this.healthCheck.statusCodes)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						template: `<div>
 | 
				
			||||||
 | 
					<input type="hidden" name="healthCheckJSON" :value="JSON.stringify(healthCheck)"/>
 | 
				
			||||||
 | 
					<table class="ui table definition selectable">
 | 
				
			||||||
 | 
						<tbody>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td class="title">是否启用</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input type="checkbox" value="1" v-model="healthCheck.isOn"/>
 | 
				
			||||||
 | 
										<label></label>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</tbody>
 | 
				
			||||||
 | 
						<tbody v-show="healthCheck.isOn">
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>URL *</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<div class="ui fields inline">
 | 
				
			||||||
 | 
										<div class="ui field">
 | 
				
			||||||
 | 
											<select class="ui dropdown" v-model="urlProtocol">
 | 
				
			||||||
 | 
												<option value="http">http://</option>
 | 
				
			||||||
 | 
												<option value="https">https://</option>
 | 
				
			||||||
 | 
											</select>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div class="ui field">
 | 
				
			||||||
 | 
											<var style="color:grey">\${host}</var>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div class="ui field">:</div>
 | 
				
			||||||
 | 
										<div class="ui field">
 | 
				
			||||||
 | 
											<input type="text" maxlength="5" style="width:5.4em" placeholder="端口" v-model="urlPort"/>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
										<div class="ui field">
 | 
				
			||||||
 | 
											<input type="text" v-model="urlRequestURI" placeholder="/" style="width:23em"/>
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<div class="ui divider"></div>
 | 
				
			||||||
 | 
									<p class="comment" v-if="healthCheck.url.length > 0">拼接后的URL:<code-label>{{healthCheck.url}}</code-label>,其中\${host}指的是节点地址。</p>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>检测时间间隔</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<time-duration-box :v-value="healthCheck.interval"></time-duration-box>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</tbody>	
 | 
				
			||||||
 | 
						<tbody v-show="healthCheck.isOn">
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td colspan="2"><more-options-angle @change="showAdvanced"></more-options-angle></td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</tbody>
 | 
				
			||||||
 | 
						<tbody v-show="advancedVisible && healthCheck.isOn">
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>允许的状态码</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<values-box :values="healthCheck.statusCodes" maxlength="3" @change="changeStatus"></values-box>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>超时时间</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<time-duration-box :v-value="healthCheck.timeout"></time-duration-box>
 | 
				
			||||||
 | 
								</td>	
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>连续尝试次数</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<input type="text" v-model="healthCheck.countTries" style="width: 5em" maxlength="2"/>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>每次尝试间隔</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<time-duration-box :v-value="healthCheck.tryDelay"></time-duration-box>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
							</tbody>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
 | 
					<div class="margin"></div>
 | 
				
			||||||
 | 
					</div>`
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -37,10 +37,12 @@ Vue.component("values-box", {
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				this.vValues.push(this.value);
 | 
									this.vValues.push(this.value);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			this.cancel();
 | 
								this.cancel()
 | 
				
			||||||
 | 
								this.$emit("change", this.vValues)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		remove: function (index) {
 | 
							remove: function (index) {
 | 
				
			||||||
			this.vValues.$remove(index);
 | 
								this.vValues.$remove(index)
 | 
				
			||||||
 | 
								this.$emit("change", this.vValues)
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cancel: function () {
 | 
							cancel: function () {
 | 
				
			||||||
			this.isUpdating = false;
 | 
								this.isUpdating = false;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,8 @@ Vue.component("node-ip-addresses-box", {
 | 
				
			|||||||
	methods: {
 | 
						methods: {
 | 
				
			||||||
		// 添加IP地址
 | 
							// 添加IP地址
 | 
				
			||||||
		addIPAddress: function () {
 | 
							addIPAddress: function () {
 | 
				
			||||||
 | 
								window.UPDATING_NODE_IP_ADDRESS = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let that = this;
 | 
								let that = this;
 | 
				
			||||||
			teaweb.popup("/nodes/ipAddresses/createPopup", {
 | 
								teaweb.popup("/nodes/ipAddresses/createPopup", {
 | 
				
			||||||
				callback: function (resp) {
 | 
									callback: function (resp) {
 | 
				
			||||||
@@ -18,8 +20,10 @@ Vue.component("node-ip-addresses-box", {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// 修改地址
 | 
							// 修改地址
 | 
				
			||||||
		updateIPAddress: function (index, address) {
 | 
							updateIPAddress: function (index, address) {
 | 
				
			||||||
 | 
								window.UPDATING_NODE_IP_ADDRESS = address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let that = this;
 | 
								let that = this;
 | 
				
			||||||
			teaweb.popup("/nodes/ipAddresses/updatePopup?addressId=" + address.id, {
 | 
								teaweb.popup("/nodes/ipAddresses/updatePopup", {
 | 
				
			||||||
				callback: function (resp) {
 | 
									callback: function (resp) {
 | 
				
			||||||
					Vue.set(that.ipAddresses, index, resp.data.ipAddress);
 | 
										Vue.set(that.ipAddresses, index, resp.data.ipAddress);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -32,11 +36,13 @@ Vue.component("node-ip-addresses-box", {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	template: `<div>
 | 
						template: `<div>
 | 
				
			||||||
	<input type="hidden" name="ipAddresses" :value="JSON.stringify(ipAddresses)"/>
 | 
						<input type="hidden" name="ipAddressesJSON" :value="JSON.stringify(ipAddresses)"/>
 | 
				
			||||||
	<div v-if="ipAddresses.length > 0">
 | 
						<div v-if="ipAddresses.length > 0">
 | 
				
			||||||
		<div>
 | 
							<div>
 | 
				
			||||||
			<div v-for="(address, index) in ipAddresses" class="ui label small">
 | 
								<div v-for="(address, index) in ipAddresses" class="ui label small">
 | 
				
			||||||
				{{address.ip}}<span class="small" v-if="address.name.length > 0">({{address.name}})</span>
 | 
									{{address.ip}}
 | 
				
			||||||
 | 
									<span class="small" v-if="address.name.length > 0">({{address.name}}<span v-if="!address.canAccess">,不可访问</span>)</span>
 | 
				
			||||||
 | 
									<span class="small" v-if="address.name.length == 0 && !address.canAccess">(不可访问)</span>
 | 
				
			||||||
				<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
 | 
									<a href="" title="修改" @click.prevent="updateIPAddress(index, address)"><i class="icon pencil small"></i></a>
 | 
				
			||||||
				<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
 | 
									<a href="" title="删除" @click.prevent="removeIPAddress(index)"><i class="icon remove"></i></a>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
@@ -46,6 +52,5 @@ Vue.component("node-ip-addresses-box", {
 | 
				
			|||||||
	<div>
 | 
						<div>
 | 
				
			||||||
		<button class="ui button small" type="button" @click.prevent="addIPAddress()">+</button>
 | 
							<button class="ui button small" type="button" @click.prevent="addIPAddress()">+</button>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	<p class="comment">添加已经绑定的IP地址,仅做记录用。</p>
 | 
					 | 
				
			||||||
</div>`
 | 
					</div>`
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "menu"}
 | 
						{$template "menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<form class="ui form segment" action="/clusters/cluster">
 | 
						<form class="ui form segment" action="/clusters/cluster">
 | 
				
			||||||
@@ -61,7 +59,10 @@
 | 
				
			|||||||
				<span v-if="node.ipAddresses.length == 0">-</span>
 | 
									<span v-if="node.ipAddresses.length == 0">-</span>
 | 
				
			||||||
				<div v-else class="address-box">
 | 
									<div v-else class="address-box">
 | 
				
			||||||
					<div v-for="addr in node.ipAddresses" style="margin-bottom:0.3em">
 | 
										<div v-for="addr in node.ipAddresses" style="margin-bottom:0.3em">
 | 
				
			||||||
						<div class="ui label tiny">{{addr.ip}} <span class="small">({{addr.name}})</span></div>
 | 
											<div class="ui label tiny">{{addr.ip}}
 | 
				
			||||||
 | 
												<span class="small" v-if="addr.name.length > 0">({{addr.name}}<span v-if="!addr.canAccess">,不可访问</span>)</span>
 | 
				
			||||||
 | 
												<span class="small" v-if="addr.name.length == 0 && !addr.canAccess">(不可访问)</span>
 | 
				
			||||||
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
@@ -98,5 +99,4 @@
 | 
				
			|||||||
	</table>
 | 
						</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<div class="page" v-html="page"></div>
 | 
						<div class="page" v-html="page"></div>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "menu"}
 | 
						{$template "menu"}
 | 
				
			||||||
	<p>可以通过节点安装包中的<code-label>configs/cluster.yaml</code-label>直接自动注册节点。</p>
 | 
						<p>可以通过节点安装包中的<code-label>configs/cluster.yaml</code-label>直接自动注册节点。</p>
 | 
				
			||||||
	<table class="ui table definition selectable">
 | 
						<table class="ui table definition selectable">
 | 
				
			||||||
@@ -16,5 +14,4 @@ clusterId: "{{cluster.uniqueId}}"
 | 
				
			|||||||
secret: "{{cluster.secret}}"</pre>
 | 
					secret: "{{cluster.secret}}"</pre>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
	</table>
 | 
						</table>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
<second-menu>
 | 
					<second-menu>
 | 
				
			||||||
 | 
						<menu-item :href="'/clusters/cluster?clusterId=' + clusterId">节点列表</menu-item>
 | 
				
			||||||
 | 
						<span class="item">|</span>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + nodeId" code="node">节点详情</menu-item>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + nodeId" code="log">运行日志</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/node/logs?clusterId=' + clusterId + '&nodeId=' + nodeId" code="log">运行日志</menu-item>
 | 
				
			||||||
	<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改设置</menu-item>
 | 
						<menu-item :href="'/clusters/cluster/node/update?clusterId=' + clusterId + '&nodeId=' + nodeId" code="update">修改设置</menu-item>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "/clusters/cluster/menu"}
 | 
						{$template "/clusters/cluster/menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
						<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
@@ -41,5 +39,4 @@
 | 
				
			|||||||
			</tr>
 | 
								</tr>
 | 
				
			||||||
		</table>
 | 
							</table>
 | 
				
			||||||
		<submit-btn></submit-btn>
 | 
							<submit-btn></submit-btn>
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "node_menu"}
 | 
						{$template "node_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<!-- 已安装 -->
 | 
						<!-- 已安装 -->
 | 
				
			||||||
@@ -53,5 +51,4 @@ secret: "{{node.secret}}"</pre>
 | 
				
			|||||||
		</table>
 | 
							</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		<a href="" @click.prevent="updateNodeIsInstalled(true)">[修改为已安装状态]</a>
 | 
							<a href="" @click.prevent="updateNodeIsInstalled(true)">[修改为已安装状态]</a>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "node_menu"}
 | 
						{$template "node_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
 | 
						<p class="comment" v-if="logs.length == 0">暂时还没有日志。</p>
 | 
				
			||||||
@@ -19,5 +17,4 @@
 | 
				
			|||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
	</table>
 | 
						</table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<div class="page" v-html="page"></div>
 | 
						<div class="page" v-html="page"></div>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "node_menu"}
 | 
						{$template "node_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<h3>节点详情</h3>
 | 
						<h3>节点详情</h3>
 | 
				
			||||||
@@ -19,8 +17,10 @@
 | 
				
			|||||||
			<td>
 | 
								<td>
 | 
				
			||||||
				<div v-if="node.ipAddresses.length > 0">
 | 
									<div v-if="node.ipAddresses.length > 0">
 | 
				
			||||||
					<div>
 | 
										<div>
 | 
				
			||||||
						<div v-for="(address, index) in node.ipAddresses" class="ui label small">
 | 
											<div v-for="(address, index) in node.ipAddresses" class="ui label tiny">
 | 
				
			||||||
                            {{address.ip}}<span class="small">({{address.name}})</span>
 | 
					                            {{address.ip}}
 | 
				
			||||||
 | 
												<span class="small" v-if="address.name.length > 0">({{address.name}}<span v-if="!address.canAccess">,不可访问</span>)</span>
 | 
				
			||||||
 | 
												<span class="small" v-if="address.name.length == 0 && !address.canAccess">(不可访问)</span>
 | 
				
			||||||
						</div>
 | 
											</div>
 | 
				
			||||||
					</div>
 | 
										</div>
 | 
				
			||||||
				</div>
 | 
									</div>
 | 
				
			||||||
@@ -97,5 +97,4 @@
 | 
				
			|||||||
				<a v-else :href="'/clusters/cluster/installNode?clusterId=' + clusterId + '&nodeId=' + nodeId" class="underline" title="点击进入安装界面"><span class="red">未安装</span></a>
 | 
									<a v-else :href="'/clusters/cluster/installNode?clusterId=' + clusterId + '&nodeId=' + nodeId" class="underline" title="点击进入安装界面"><span class="red">未安装</span></a>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
	</table>
 | 
						</table>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
{$layout}
 | 
					{$layout}
 | 
				
			||||||
{$template "/left_menu"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="right-box">
 | 
					 | 
				
			||||||
	{$template "node_menu"}
 | 
						{$template "node_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<h3>修改节点</h3>
 | 
						<h3>修改节点</h3>
 | 
				
			||||||
@@ -76,5 +74,4 @@
 | 
				
			|||||||
			</tbody>
 | 
								</tbody>
 | 
				
			||||||
		</table>
 | 
							</table>
 | 
				
			||||||
		<submit-btn></submit-btn>
 | 
							<submit-btn></submit-btn>
 | 
				
			||||||
	</form>
 | 
						</form>
 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
							
								
								
									
										10
									
								
								web/views/@default/clusters/cluster/settings/health.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								web/views/@default/clusters/cluster/settings/health.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					{$layout}
 | 
				
			||||||
 | 
					{$template "/left_menu"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="right-box">
 | 
				
			||||||
 | 
						<form class="ui form" data-tea-action="$" data-tea-success="success">
 | 
				
			||||||
 | 
							<input type="hidden" name="clusterId" :value="clusterId"/>
 | 
				
			||||||
 | 
							<health-check-config-box :v-health-check-config="healthCheckConfig"></health-check-config-box>
 | 
				
			||||||
 | 
							<submit-btn></submit-btn>   <a href="" @click.prevent="run()">立即检查</a>
 | 
				
			||||||
 | 
						</form>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										11
									
								
								web/views/@default/clusters/cluster/settings/health.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								web/views/@default/clusters/cluster/settings/health.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifyReloadSuccess("保存成功")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.run = function () {
 | 
				
			||||||
 | 
							teaweb.confirm("确定要对当前集群下的所有节点进行健康检查吗?", function () {
 | 
				
			||||||
 | 
								teaweb.popup("/clusters/cluster/settings/healthRun?clusterId=" + this.clusterId, {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										27
									
								
								web/views/@default/clusters/cluster/settings/healthRun.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								web/views/@default/clusters/cluster/settings/healthRun.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					{$layout "layout_popup"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<h3>健康检查</h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<span class="red" v-if="isRequesting">正在执行中,请等待执行完毕...</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="ui form" v-if="!isRequesting">
 | 
				
			||||||
 | 
						<p>成功节点:<span class="green">{{countSuccess}}</span>   失败节点:<span class="red">{{countFail}}</span></p>
 | 
				
			||||||
 | 
						<table class="ui table selectable">
 | 
				
			||||||
 | 
							<thead>
 | 
				
			||||||
 | 
								<tr>
 | 
				
			||||||
 | 
									<th>节点</th>
 | 
				
			||||||
 | 
									<th>结果</th>
 | 
				
			||||||
 | 
									<th>耗时</th>
 | 
				
			||||||
 | 
								</tr>
 | 
				
			||||||
 | 
							</thead>
 | 
				
			||||||
 | 
							<tr v-for="result in results">
 | 
				
			||||||
 | 
								<td>{{result.node.name}}<span class="small" v-if="result.nodeAddr != null && result.nodeAddr.length > 0">({{result.nodeAddr}})</span></td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<span v-if="!result.isOk" class="red">失败:{{result.error}}</span>
 | 
				
			||||||
 | 
									<span v-else class="green">成功</span>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
								<td>{{result.costMs}}ms</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
 | 
						</table>
 | 
				
			||||||
 | 
						<button class="ui button primary" type="button" @click.prevent="success">完成</button>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										39
									
								
								web/views/@default/clusters/cluster/settings/healthRun.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								web/views/@default/clusters/cluster/settings/healthRun.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					Tea.context(function () {
 | 
				
			||||||
 | 
						this.success = NotifyPopup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.isRequesting = false
 | 
				
			||||||
 | 
						this.results = []
 | 
				
			||||||
 | 
						this.countSuccess = 0
 | 
				
			||||||
 | 
						this.countFail = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.$delay(function () {
 | 
				
			||||||
 | 
							this.run()
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.run = function () {
 | 
				
			||||||
 | 
							this.isRequesting = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.$post("$")
 | 
				
			||||||
 | 
								.params({
 | 
				
			||||||
 | 
									clusterId: this.clusterId
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								.success(function (resp) {
 | 
				
			||||||
 | 
									this.results = resp.data.results
 | 
				
			||||||
 | 
									let that = this
 | 
				
			||||||
 | 
									this.results.forEach(function (v) {
 | 
				
			||||||
 | 
										v.costMs = Math.ceil(v.costMs)
 | 
				
			||||||
 | 
										if (isNaN(v.costMs)) {
 | 
				
			||||||
 | 
											v.costMs = 0
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (v.isOk) {
 | 
				
			||||||
 | 
											that.countSuccess++
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											that.countFail++
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									})
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
								.done(function () {
 | 
				
			||||||
 | 
									this.isRequesting = false
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -10,6 +10,16 @@
 | 
				
			|||||||
				<input type="text" name="ip" maxlength="128" ref="focus"/>
 | 
									<input type="text" name="ip" maxlength="128" ref="focus"/>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>是否可以访问</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input type="checkbox" name="canAccess" value="1" checked="checked"/>
 | 
				
			||||||
 | 
										<label></label>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<p class="comment">是否为可以公开访问的IP。</p>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
			<td class="title">备注</td>
 | 
								<td class="title">备注</td>
 | 
				
			||||||
			<td>
 | 
								<td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,16 @@
 | 
				
			|||||||
				<input type="text" name="ip" maxlength="128" ref="focus" v-model="address.ip"/>
 | 
									<input type="text" name="ip" maxlength="128" ref="focus" v-model="address.ip"/>
 | 
				
			||||||
			</td>
 | 
								</td>
 | 
				
			||||||
		</tr>
 | 
							</tr>
 | 
				
			||||||
 | 
							<tr>
 | 
				
			||||||
 | 
								<td>是否可以访问</td>
 | 
				
			||||||
 | 
								<td>
 | 
				
			||||||
 | 
									<div class="ui checkbox">
 | 
				
			||||||
 | 
										<input type="checkbox" name="canAccess" value="1" v-model="address.canAccess"/>
 | 
				
			||||||
 | 
										<label></label>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
 | 
									<p class="comment">是否为可以公开访问的IP。</p>
 | 
				
			||||||
 | 
								</td>
 | 
				
			||||||
 | 
							</tr>
 | 
				
			||||||
		<tr>
 | 
							<tr>
 | 
				
			||||||
			<td class="title">备注</td>
 | 
								<td class="title">备注</td>
 | 
				
			||||||
			<td>
 | 
								<td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
Tea.context(function (){
 | 
					Tea.context(function () {
 | 
				
			||||||
	this.success = NotifyPopup;
 | 
						this.success = NotifyPopup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this.address = window.parent.UPDATING_NODE_IP_ADDRESS
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
		Reference in New Issue
	
	Block a user