Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4e3591413 | ||
|
|
3f847d7c7f | ||
|
|
67a10994a4 | ||
|
|
4016296e0b | ||
|
|
92777366ec | ||
|
|
beb34f8264 | ||
|
|
f6f8c5c858 | ||
|
|
a19c4dffcd | ||
|
|
a5754971f6 | ||
|
|
dbe6435809 | ||
|
|
7e5b980600 | ||
|
|
a6c3b70ee7 | ||
|
|
0a23e7951a | ||
|
|
e0e3fc8fef | ||
|
|
a8b947f5ca | ||
|
|
0f28df51f1 | ||
|
|
6e36528f35 | ||
|
|
a885fdbea7 | ||
|
|
713de74abb | ||
|
|
8db6a33e15 | ||
|
|
ed2d577be0 | ||
|
|
084eddecbf | ||
|
|
5e09ba302a | ||
|
|
fa37b40435 | ||
|
|
c95dde5187 | ||
|
|
4d5a4d501a | ||
|
|
ce97f20826 | ||
|
|
ab9cd13abc |
@@ -1,9 +1,9 @@
|
||||
package teaconst
|
||||
|
||||
const (
|
||||
Version = "0.3.0"
|
||||
Version = "0.3.1"
|
||||
|
||||
APINodeVersion = "0.3.0"
|
||||
APINodeVersion = "0.3.1"
|
||||
|
||||
ProductName = "Edge Admin"
|
||||
ProcessName = "edge-admin"
|
||||
|
||||
@@ -103,6 +103,10 @@ func (this *RPCClient) NodeIPAddressLogRPC() pb.NodeIPAddressLogServiceClient {
|
||||
return pb.NewNodeIPAddressLogServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeIPAddressThresholdRPC() pb.NodeIPAddressThresholdServiceClient {
|
||||
return pb.NewNodeIPAddressThresholdServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) NodeValueRPC() pb.NodeValueServiceClient {
|
||||
return pb.NewNodeValueServiceClient(this.pickConn())
|
||||
}
|
||||
@@ -304,6 +308,10 @@ func (this *RPCClient) ReportNodeRPC() pb.ReportNodeServiceClient {
|
||||
return pb.NewReportNodeServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ReportNodeGroupRPC() pb.ReportNodeGroupServiceClient {
|
||||
return pb.NewReportNodeGroupServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
func (this *RPCClient) ReportResultRPC() pb.ReportResultServiceClient {
|
||||
return pb.NewReportResultServiceClient(this.pickConn())
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ func (this *CreateBatchAction) RunPost(params struct {
|
||||
Name: "IP地址",
|
||||
Ip: ip,
|
||||
CanAccess: true,
|
||||
IsUp: true,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -167,32 +167,49 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
nodeId := createResp.NodeId
|
||||
|
||||
// IP地址
|
||||
for _, address := range ipAddresses {
|
||||
addressId := address.GetInt64("id")
|
||||
if addressId > 0 {
|
||||
for _, addr := range ipAddresses {
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
|
||||
NodeIPAddressId: addressId,
|
||||
NodeIPAddressId: addrId,
|
||||
NodeId: nodeId,
|
||||
})
|
||||
} else {
|
||||
var thresholdsJSON = []byte{}
|
||||
var thresholds = address.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, _ = json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: address.GetString("name"),
|
||||
Ip: address.GetString("ip"),
|
||||
CanAccess: address.GetBool("canAccess"),
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
} else {
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
}
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
// 阈值
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, err := json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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").
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils/numberutils"
|
||||
"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/nodes/ipAddresses/ipaddressutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
@@ -68,7 +69,7 @@ func (this *DetailAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -76,17 +77,15 @@ func (this *DetailAction) RunGet(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var ipAddresses = ipAddressesResp.Addresses
|
||||
var ipAddresses = ipAddressesResp.NodeIPAddresses
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
if len(addr.ThresholdsJSON) > 0 {
|
||||
err = json.Unmarshal(addr.ThresholdsJSON, &thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
thresholds, err := ipaddressutils.InitNodeIPAddressThresholds(this.Parent(), addr.Id)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -3,6 +3,7 @@ package node
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"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"
|
||||
@@ -25,16 +26,11 @@ func (this *InstallAction) RunGet(params struct {
|
||||
this.Data["nodeId"] = params.NodeId
|
||||
|
||||
// 节点
|
||||
nodeResp, err := this.RPC().NodeRPC().FindEnabledNode(this.AdminContext(), &pb.FindEnabledNodeRequest{NodeId: params.NodeId})
|
||||
node, err := nodeutils.InitNodeInfo(this.Parent(), params.NodeId)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
node := nodeResp.Node
|
||||
if node == nil {
|
||||
this.WriteString("找不到要操作的节点")
|
||||
return
|
||||
}
|
||||
|
||||
// 安装信息
|
||||
if node.InstallStatus != nil {
|
||||
@@ -84,15 +80,12 @@ func (this *InstallAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["apiEndpoints"] = "\"" + strings.Join(apiEndpoints, "\", \"") + "\""
|
||||
|
||||
this.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"installDir": node.InstallDir,
|
||||
"isInstalled": node.IsInstalled,
|
||||
"uniqueId": node.UniqueId,
|
||||
"secret": node.Secret,
|
||||
"cluster": clusterMap,
|
||||
}
|
||||
var nodeMap = this.Data["node"].(maps.Map)
|
||||
nodeMap["installDir"] = node.InstallDir
|
||||
nodeMap["isInstalled"] = node.IsInstalled
|
||||
nodeMap["uniqueId"] = node.UniqueId
|
||||
nodeMap["secret"] = node.Secret
|
||||
nodeMap["cluster"] = clusterMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -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,80 @@ 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{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
|
||||
var groupMap maps.Map
|
||||
if node.NodeGroup != nil {
|
||||
groupMap = maps.Map{
|
||||
"id": node.NodeGroup.Id,
|
||||
"name": node.NodeGroup.Name,
|
||||
}
|
||||
}
|
||||
|
||||
parentAction.Data["node"] = maps.Map{
|
||||
"id": node.Id,
|
||||
"name": node.Name,
|
||||
"isOn": node.IsOn,
|
||||
"isUp": node.IsUp,
|
||||
"group": groupMap,
|
||||
}
|
||||
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})
|
||||
@@ -47,7 +52,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -56,14 +61,11 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
if len(addr.ThresholdsJSON) > 0 {
|
||||
err = json.Unmarshal(addr.ThresholdsJSON, &thresholds)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
thresholds, err := ipaddressutils.InitNodeIPAddressThresholds(this.Parent(), addr.Id)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
@@ -77,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 {
|
||||
@@ -194,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 {
|
||||
@@ -263,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
|
||||
}) {
|
||||
@@ -322,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,
|
||||
@@ -380,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)
|
||||
@@ -394,7 +201,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 禁用老的IP地址
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllIPAddressesWithNodeIdRequest{
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllNodeIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
|
||||
@@ -85,10 +85,12 @@ func (this *UpdateDNSPopupAction) RunPost(params struct {
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
|
||||
|
||||
routes := []string{}
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params.Must.
|
||||
@@ -100,7 +102,7 @@ func (this *UpdateDNSPopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 执行修改
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: params.IpAddr,
|
||||
DnsDomainId: params.DomainId,
|
||||
|
||||
@@ -123,7 +123,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -132,7 +132,7 @@ func (this *NodesAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -46,6 +46,13 @@ func (this *IndexAction) RunGet(params struct {
|
||||
this.Data["domainName"] = dnsInfoResp.Domain.Name
|
||||
}
|
||||
|
||||
if len(dnsInfoResp.CnameRecords) == 0 {
|
||||
this.Data["cnameRecords"] = []string{}
|
||||
} else {
|
||||
this.Data["cnameRecords"] = dnsInfoResp.CnameRecords
|
||||
}
|
||||
this.Data["ttl"] = dnsInfoResp.Ttl
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -56,6 +63,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
DnsName string
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -97,6 +106,8 @@ func (this *IndexAction) RunPost(params struct {
|
||||
DnsDomainId: params.DnsDomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -45,6 +45,7 @@ func (this *ClusterHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNext
|
||||
action.WriteString("can not find cluster")
|
||||
return
|
||||
}
|
||||
action.Data["currentClusterName"] = cluster.Name
|
||||
|
||||
clusterInfo, err := dao.SharedNodeClusterDAO.FindEnabledNodeClusterConfigInfo(ctx, clusterId)
|
||||
if err != nil {
|
||||
|
||||
@@ -193,7 +193,7 @@ func (this *IndexAction) searchNodes(keyword string) {
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
})
|
||||
@@ -202,7 +202,7 @@ func (this *IndexAction) searchNodes(keyword string) {
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package groups
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type OptionsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *OptionsAction) RunPost(params struct{}) {
|
||||
resp, err := this.RPC().ReportNodeGroupRPC().FindAllEnabledReportNodeGroups(this.AdminContext(), &pb.FindAllEnabledReportNodeGroupsRequest{})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
var groupMaps = []maps.Map{}
|
||||
for _, group := range resp.ReportNodeGroups {
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
})
|
||||
}
|
||||
this.Data["groups"] = groupMaps
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -40,6 +40,10 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunPost(params struct{}) {
|
||||
// 读取看板数据
|
||||
resp, err := this.RPC().AdminRPC().ComposeAdminDashboard(this.AdminContext(), &pb.ComposeAdminDashboardRequest{
|
||||
ApiVersion: teaconst.APINodeVersion,
|
||||
@@ -50,7 +54,7 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
this.Data["dashboard"] = maps.Map{
|
||||
"defaultClusterId": resp.DefaultNodeClusterId,
|
||||
|
||||
|
||||
"countServers": resp.CountServers,
|
||||
"countNodeClusters": resp.CountNodeClusters,
|
||||
"countNodes": resp.CountNodes,
|
||||
@@ -85,8 +89,14 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
statMaps := []maps.Map{}
|
||||
for _, stat := range resp.HourlyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"hour": stat.Hour[8:],
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Hour[4:6] + "月" + stat.Hour[6:8] + "日",
|
||||
"hour": stat.Hour[8:],
|
||||
})
|
||||
}
|
||||
this.Data["hourlyTrafficStats"] = statMaps
|
||||
@@ -97,8 +107,13 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
statMaps := []maps.Map{}
|
||||
for _, stat := range resp.DailyTrafficStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"bytes": stat.Bytes,
|
||||
"day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
|
||||
"bytes": stat.Bytes,
|
||||
"cachedBytes": stat.CachedBytes,
|
||||
"countRequests": stat.CountRequests,
|
||||
"countCachedRequests": stat.CountCachedRequests,
|
||||
"countAttackRequests": stat.CountAttackRequests,
|
||||
"attackBytes": stat.AttackBytes,
|
||||
"day": stat.Day[4:6] + "月" + stat.Day[6:] + "日",
|
||||
})
|
||||
}
|
||||
this.Data["dailyTrafficStats"] = statMaps
|
||||
@@ -172,6 +187,20 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// 域名排行
|
||||
{
|
||||
var statMaps = []maps.Map{}
|
||||
for _, stat := range resp.TopDomainStats {
|
||||
statMaps = append(statMaps, maps.Map{
|
||||
"serverId": stat.ServerId,
|
||||
"domain": stat.Domain,
|
||||
"countRequests": stat.CountRequests,
|
||||
"bytes": stat.Bytes,
|
||||
})
|
||||
}
|
||||
this.Data["topDomainStats"] = statMaps
|
||||
}
|
||||
|
||||
// 指标
|
||||
{
|
||||
var chartMaps = []maps.Map{}
|
||||
@@ -210,5 +239,5 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
this.Data["metricCharts"] = chartMaps
|
||||
}
|
||||
|
||||
this.Show()
|
||||
this.Success()
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
)
|
||||
|
||||
type ClusterAction struct {
|
||||
@@ -61,6 +62,12 @@ func (this *ClusterAction) RunGet(params struct {
|
||||
dnsMap["providerTypeName"] = dnsResp.Provider.TypeName
|
||||
}
|
||||
|
||||
if len(dnsResp.CnameRecords) > 0 {
|
||||
dnsMap["cnameRecords"] = dnsResp.CnameRecords
|
||||
} else {
|
||||
dnsMap["cnameRecords"] = []string{}
|
||||
}
|
||||
|
||||
this.Data["dnsInfo"] = dnsMap
|
||||
|
||||
// 节点DNS解析记录
|
||||
@@ -203,5 +210,60 @@ func (this *ClusterAction) RunGet(params struct {
|
||||
}
|
||||
this.Data["issues"] = issueMaps
|
||||
|
||||
// 当前正在执行的任务
|
||||
resp, err := this.RPC().DNSTaskRPC().FindAllDoingDNSTasks(this.AdminContext(), &pb.FindAllDoingDNSTasksRequest{
|
||||
NodeClusterId: params.ClusterId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
taskMaps := []maps.Map{}
|
||||
for _, task := range resp.DnsTasks {
|
||||
var clusterMap maps.Map = nil
|
||||
var nodeMap maps.Map = nil
|
||||
var serverMap maps.Map = nil
|
||||
var domainMap maps.Map = nil
|
||||
|
||||
if task.NodeCluster != nil {
|
||||
clusterMap = maps.Map{
|
||||
"id": task.NodeCluster.Id,
|
||||
"name": task.NodeCluster.Name,
|
||||
}
|
||||
}
|
||||
if task.Node != nil {
|
||||
nodeMap = maps.Map{
|
||||
"id": task.Node.Id,
|
||||
"name": task.Node.Name,
|
||||
}
|
||||
}
|
||||
if task.Server != nil {
|
||||
serverMap = maps.Map{
|
||||
"id": task.Server.Id,
|
||||
"name": task.Server.Name,
|
||||
}
|
||||
}
|
||||
if task.DnsDomain != nil {
|
||||
domainMap = maps.Map{
|
||||
"id": task.DnsDomain.Id,
|
||||
"name": task.DnsDomain.Name,
|
||||
}
|
||||
}
|
||||
|
||||
taskMaps = append(taskMaps, maps.Map{
|
||||
"id": task.Id,
|
||||
"type": task.Type,
|
||||
"isDone": task.IsDone,
|
||||
"isOk": task.IsOk,
|
||||
"error": task.Error,
|
||||
"updatedTime": timeutil.FormatTime("Y-m-d H:i:s", task.UpdatedAt),
|
||||
"cluster": clusterMap,
|
||||
"node": nodeMap,
|
||||
"server": serverMap,
|
||||
"domain": domainMap,
|
||||
})
|
||||
}
|
||||
this.Data["tasks"] = taskMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
@@ -85,10 +85,12 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
|
||||
defer this.CreateLog(oplogs.LevelInfo, "修改节点 %d 的DNS设置", params.NodeId)
|
||||
|
||||
routes := []string{}
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
if len(params.DnsRoutesJSON) > 0 {
|
||||
err := json.Unmarshal(params.DnsRoutesJSON, &routes)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
params.Must.
|
||||
@@ -100,7 +102,7 @@ func (this *UpdateNodePopupAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 执行修改
|
||||
_, err = this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
_, err := this.RPC().NodeRPC().UpdateNodeDNS(this.AdminContext(), &pb.UpdateNodeDNSRequest{
|
||||
NodeId: params.NodeId,
|
||||
IpAddr: params.IpAddr,
|
||||
DnsDomainId: params.DomainId,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// 修改集群的DNS设置
|
||||
// UpdateClusterPopupAction 修改集群的DNS设置
|
||||
type UpdateClusterPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -46,6 +46,14 @@ func (this *UpdateClusterPopupAction) RunGet(params struct {
|
||||
this.Data["providerId"] = 0
|
||||
}
|
||||
|
||||
if len(dnsResp.CnameRecords) == 0 {
|
||||
this.Data["cnameRecords"] = []string{}
|
||||
} else {
|
||||
this.Data["cnameRecords"] = dnsResp.CnameRecords
|
||||
}
|
||||
|
||||
this.Data["ttl"] = dnsResp.Ttl
|
||||
|
||||
// 所有服务商
|
||||
providerTypesResp, err := this.RPC().DNSProviderRPC().FindAllDNSProviderTypes(this.AdminContext(), &pb.FindAllDNSProviderTypesRequest{})
|
||||
if err != nil {
|
||||
@@ -70,6 +78,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
DomainId int64
|
||||
NodesAutoSync bool
|
||||
ServersAutoSync bool
|
||||
CnameRecords []string
|
||||
Ttl int32
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
@@ -103,6 +113,8 @@ func (this *UpdateClusterPopupAction) RunPost(params struct {
|
||||
DnsDomainId: params.DomainId,
|
||||
NodesAutoSync: params.NodesAutoSync,
|
||||
ServersAutoSync: params.ServersAutoSync,
|
||||
CnameRecords: params.CnameRecords,
|
||||
Ttl: params.Ttl,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -30,20 +30,22 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
IP string `alias:"ip"`
|
||||
CanAccess bool
|
||||
Name string
|
||||
IsUp bool
|
||||
ThresholdsJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
}
|
||||
|
||||
params.Must.
|
||||
Field("ip", params.IP).
|
||||
Require("请输入IP地址")
|
||||
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
}
|
||||
|
||||
// 阈值设置
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if teaconst.IsPlus && len(params.ThresholdsJSON) > 0 {
|
||||
_ = json.Unmarshal(params.ThresholdsJSON, &thresholds)
|
||||
}
|
||||
@@ -54,7 +56,7 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
"ip": params.IP,
|
||||
"id": 0,
|
||||
"isOn": true,
|
||||
"isUp": true,
|
||||
"isUp": params.IsUp,
|
||||
"thresholds": thresholds,
|
||||
}
|
||||
this.Success()
|
||||
|
||||
@@ -16,12 +16,6 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
return err
|
||||
}
|
||||
for _, addr := range addresses {
|
||||
var thresholdsJSON = []byte{}
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, _ = json.Marshal(thresholds)
|
||||
}
|
||||
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
var isOn = false
|
||||
@@ -37,19 +31,36 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
Name: addr.GetString("name"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsOn: isOn,
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
_, err = parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
ThresholdsJSON: thresholdsJSON,
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
}
|
||||
|
||||
// 保存阈值
|
||||
var thresholds = addr.GetSlice("thresholds")
|
||||
if len(thresholds) > 0 {
|
||||
thresholdsJSON, err := json.Marshal(thresholds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -58,3 +69,35 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitNodeIPAddressThresholds 初始化IP阈值
|
||||
func InitNodeIPAddressThresholds(parentAction *actionutils.ParentAction, addrId int64) ([]*nodeconfigs.IPAddressThresholdConfig, error) {
|
||||
thresholdsResp, err := parentAction.RPC().NodeIPAddressThresholdRPC().FindAllEnabledNodeIPAddressThresholds(parentAction.AdminContext(), &pb.FindAllEnabledNodeIPAddressThresholdsRequest{NodeIPAddressId: addrId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if len(thresholdsResp.NodeIPAddressThresholds) > 0 {
|
||||
for _, pbThreshold := range thresholdsResp.NodeIPAddressThresholds {
|
||||
var threshold = &nodeconfigs.IPAddressThresholdConfig{
|
||||
Id: pbThreshold.Id,
|
||||
Items: []*nodeconfigs.IPAddressThresholdItemConfig{},
|
||||
Actions: []*nodeconfigs.IPAddressThresholdActionConfig{},
|
||||
}
|
||||
if len(pbThreshold.ItemsJSON) > 0 {
|
||||
err = json.Unmarshal(pbThreshold.ItemsJSON, &threshold.Items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(pbThreshold.ActionsJSON) > 0 {
|
||||
err = json.Unmarshal(pbThreshold.ActionsJSON, &threshold.Actions)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
thresholds = append(thresholds, threshold)
|
||||
}
|
||||
}
|
||||
return thresholds, nil
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Name string
|
||||
CanAccess bool
|
||||
IsOn bool
|
||||
IsUp bool
|
||||
ThresholdsJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
@@ -43,7 +44,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
Require("请输入IP地址")
|
||||
|
||||
// 获取IP地址信息
|
||||
var isUp = true
|
||||
var isUp = params.IsUp
|
||||
if params.AddressId > 0 {
|
||||
addressResp, err := this.RPC().NodeIPAddressRPC().FindEnabledNodeIPAddress(this.AdminContext(), &pb.FindEnabledNodeIPAddressRequest{NodeIPAddressId: params.AddressId})
|
||||
if err != nil {
|
||||
@@ -54,7 +55,6 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
if address == nil {
|
||||
this.Fail("找不到要修改的地址")
|
||||
}
|
||||
isUp = address.IsUp
|
||||
}
|
||||
|
||||
ip := net.ParseIP(params.IP)
|
||||
@@ -62,7 +62,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
this.Fail("请输入正确的IP")
|
||||
}
|
||||
|
||||
var thresholds = []*nodeconfigs.NodeValueThresholdConfig{}
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
if teaconst.IsPlus && len(params.ThresholdsJSON) > 0 {
|
||||
_ = json.Unmarshal(params.ThresholdsJSON, &thresholds)
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
nodeId := createResp.NsNodeId
|
||||
|
||||
// IP地址
|
||||
for _, address := range ipAddresses {
|
||||
addressId := address.GetInt64("id")
|
||||
for _, addrMap := range ipAddresses {
|
||||
addressId := addrMap.GetInt64("id")
|
||||
if addressId > 0 {
|
||||
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
|
||||
NodeIPAddressId: addressId,
|
||||
@@ -90,9 +90,10 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
Name: address.GetString("name"),
|
||||
Ip: address.GetString("ip"),
|
||||
CanAccess: address.GetBool("canAccess"),
|
||||
Name: addrMap.GetString("name"),
|
||||
Ip: addrMap.GetString("ip"),
|
||||
CanAccess: addrMap.GetBool("canAccess"),
|
||||
IsUp: addrMap.GetBool("isUp"),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -81,7 +81,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
@@ -90,7 +90,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddresses := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddresses = append(ipAddresses, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -56,7 +56,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
@@ -65,7 +65,7 @@ func (this *IndexAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
|
||||
@@ -46,7 +46,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
}
|
||||
|
||||
// IP地址
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
ipAddressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
@@ -55,7 +55,7 @@ func (this *UpdateAction) RunGet(params struct {
|
||||
return
|
||||
}
|
||||
ipAddressMaps := []maps.Map{}
|
||||
for _, addr := range ipAddressesResp.Addresses {
|
||||
for _, addr := range ipAddressesResp.NodeIPAddresses {
|
||||
ipAddressMaps = append(ipAddressMaps, maps.Map{
|
||||
"id": addr.Id,
|
||||
"name": addr.Name,
|
||||
@@ -213,7 +213,7 @@ func (this *UpdateAction) RunPost(params struct {
|
||||
}
|
||||
|
||||
// 禁用老的IP地址
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllIPAddressesWithNodeIdRequest{
|
||||
_, err = this.RPC().NodeIPAddressRPC().DisableAllNodeIPAddressesWithNodeId(this.AdminContext(), &pb.DisableAllNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: params.NodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
|
||||
@@ -28,7 +28,7 @@ func (this *NodeOptionsAction) RunPost(params struct {
|
||||
continue
|
||||
}
|
||||
|
||||
addressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledIPAddressesWithNodeIdRequest{
|
||||
addressesResp, err := this.RPC().NodeIPAddressRPC().FindAllEnabledNodeIPAddressesWithNodeId(this.AdminContext(), &pb.FindAllEnabledNodeIPAddressesWithNodeIdRequest{
|
||||
NodeId: node.Id,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
})
|
||||
@@ -36,7 +36,7 @@ func (this *NodeOptionsAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
var addresses = addressesResp.Addresses
|
||||
var addresses = addressesResp.NodeIPAddresses
|
||||
if len(addresses) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package groups
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
193
internal/web/actions/default/servers/groups/group/index.go
Normal file
193
internal/web/actions/default/servers/groups/group/index.go
Normal file
@@ -0,0 +1,193 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package group
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "group.index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
Keyword string
|
||||
}) {
|
||||
this.Data["keyword"] = params.Keyword
|
||||
|
||||
group, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["group"] = maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
}
|
||||
|
||||
// 是否有用户管理权限
|
||||
this.Data["canVisitUser"] = configloaders.AllowModule(this.AdminId(), configloaders.AdminModuleCodeUser)
|
||||
|
||||
// 服务列表
|
||||
countResp, err := this.RPC().ServerRPC().CountAllEnabledServersMatch(this.AdminContext(), &pb.CountAllEnabledServersMatchRequest{
|
||||
ServerGroupId: params.GroupId,
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
count := countResp.Count
|
||||
page := this.NewPage(count)
|
||||
this.Data["page"] = page.AsHTML()
|
||||
|
||||
// 服务列表
|
||||
serversResp, err := this.RPC().ServerRPC().ListEnabledServersMatch(this.AdminContext(), &pb.ListEnabledServersMatchRequest{
|
||||
Offset: page.Offset,
|
||||
Size: page.Size,
|
||||
ServerGroupId: params.GroupId,
|
||||
Keyword: params.Keyword,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
serverMaps := []maps.Map{}
|
||||
for _, server := range serversResp.Servers {
|
||||
config := &serverconfigs.ServerConfig{}
|
||||
err = json.Unmarshal(server.Config, config)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 端口列表
|
||||
portMaps := []maps.Map{}
|
||||
if len(server.HttpJSON) > 0 && config.HTTP.IsOn {
|
||||
for _, listen := range config.HTTP.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.PortRange,
|
||||
})
|
||||
}
|
||||
}
|
||||
if config.HTTPS != nil && config.HTTPS.IsOn {
|
||||
for _, listen := range config.HTTPS.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.PortRange,
|
||||
})
|
||||
}
|
||||
}
|
||||
if config.TCP != nil && config.TCP.IsOn {
|
||||
for _, listen := range config.TCP.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.PortRange,
|
||||
})
|
||||
}
|
||||
}
|
||||
if config.TLS != nil && config.TLS.IsOn {
|
||||
for _, listen := range config.TLS.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.PortRange,
|
||||
})
|
||||
}
|
||||
}
|
||||
if config.Unix != nil && config.Unix.IsOn {
|
||||
for _, listen := range config.Unix.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.Host,
|
||||
})
|
||||
}
|
||||
}
|
||||
if config.UDP != nil && config.UDP.IsOn {
|
||||
for _, listen := range config.UDP.Listen {
|
||||
portMaps = append(portMaps, maps.Map{
|
||||
"protocol": listen.Protocol,
|
||||
"portRange": listen.PortRange,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 分组
|
||||
groupMaps := []maps.Map{}
|
||||
if len(server.ServerGroups) > 0 {
|
||||
for _, group := range server.ServerGroups {
|
||||
groupMaps = append(groupMaps, maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 域名列表
|
||||
serverNames := []*serverconfigs.ServerNameConfig{}
|
||||
if server.IsAuditing || (server.AuditingResult != nil && !server.AuditingResult.IsOk) {
|
||||
server.ServerNamesJSON = server.AuditingServerNamesJSON
|
||||
}
|
||||
auditingIsOk := true
|
||||
if !server.IsAuditing && server.AuditingResult != nil && !server.AuditingResult.IsOk {
|
||||
auditingIsOk = false
|
||||
}
|
||||
if len(server.ServerNamesJSON) > 0 {
|
||||
err = json.Unmarshal(server.ServerNamesJSON, &serverNames)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
countServerNames := 0
|
||||
for _, serverName := range serverNames {
|
||||
if len(serverName.SubNames) == 0 {
|
||||
countServerNames++
|
||||
} else {
|
||||
countServerNames += len(serverName.SubNames)
|
||||
}
|
||||
}
|
||||
|
||||
// 用户
|
||||
var userMap maps.Map = nil
|
||||
if server.User != nil {
|
||||
userMap = maps.Map{
|
||||
"id": server.User.Id,
|
||||
"fullname": server.User.Fullname,
|
||||
}
|
||||
}
|
||||
|
||||
serverMaps = append(serverMaps, maps.Map{
|
||||
"id": server.Id,
|
||||
"isOn": server.IsOn,
|
||||
"name": server.Name,
|
||||
"cluster": maps.Map{
|
||||
"id": server.NodeCluster.Id,
|
||||
"name": server.NodeCluster.Name,
|
||||
},
|
||||
"ports": portMaps,
|
||||
"serverTypeName": serverconfigs.FindServerType(server.Type).GetString("name"),
|
||||
"groups": groupMaps,
|
||||
"serverNames": serverNames,
|
||||
"countServerNames": countServerNames,
|
||||
"isAuditing": server.IsAuditing,
|
||||
"auditingIsOk": auditingIsOk,
|
||||
"user": userMap,
|
||||
})
|
||||
}
|
||||
this.Data["servers"] = serverMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package servergrouputils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"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"
|
||||
)
|
||||
|
||||
// InitGroup 初始化分组信息
|
||||
func InitGroup(parent *actionutils.ParentAction, groupId int64, menuItem string) (*pb.ServerGroup, error) {
|
||||
groupResp, err := parent.RPC().ServerGroupRPC().FindEnabledServerGroup(parent.AdminContext(), &pb.FindEnabledServerGroupRequest{ServerGroupId: groupId})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var group = groupResp.ServerGroup
|
||||
if group == nil {
|
||||
return nil, errors.New("group with id '" + types.String(groupId) + "' not found")
|
||||
}
|
||||
|
||||
parent.Data["group"] = maps.Map{
|
||||
"id": group.Id,
|
||||
"name": group.Name,
|
||||
}
|
||||
|
||||
// 初始化设置菜单
|
||||
if len(menuItem) > 0 {
|
||||
// 获取设置概要信息
|
||||
configInfoResp, err := parent.RPC().ServerGroupRPC().FindEnabledServerGroupConfigInfo(parent.AdminContext(), &pb.FindEnabledServerGroupConfigInfoRequest{ServerGroupId: groupId})
|
||||
if err != nil {
|
||||
return group, err
|
||||
}
|
||||
|
||||
var urlPrefix = "/servers/groups/group/settings"
|
||||
parent.Data["leftMenuItems"] = []maps.Map{
|
||||
/**{
|
||||
"name": "Web设置",
|
||||
"url": urlPrefix + "/web?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "web",
|
||||
},**/
|
||||
{
|
||||
"name": "HTTP反向代理",
|
||||
"url": urlPrefix + "/httpReverseProxy?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "httpReverseProxy",
|
||||
"isOn": configInfoResp.HasHTTPReverseProxy,
|
||||
},
|
||||
{
|
||||
"name": "TCP反向代理",
|
||||
"url": urlPrefix + "/tcpReverseProxy?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "tcpReverseProxy",
|
||||
"isOn": configInfoResp.HasTCPReverseProxy,
|
||||
},
|
||||
{
|
||||
"name": "UDP反向代理",
|
||||
"url": urlPrefix + "/udpReverseProxy?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "udpReverseProxy",
|
||||
"isOn": configInfoResp.HasUDPReverseProxy,
|
||||
},
|
||||
/**{
|
||||
"name": "-",
|
||||
"url": "",
|
||||
},
|
||||
{
|
||||
"name": "WAF",
|
||||
"url": urlPrefix + "/waf?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "waf",
|
||||
},
|
||||
{
|
||||
"name": "缓存",
|
||||
"url": urlPrefix + "/cache?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "cache",
|
||||
},
|
||||
{
|
||||
"name": "访问日志",
|
||||
"url": urlPrefix + "/accessLog?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "accessLog",
|
||||
},
|
||||
{
|
||||
"name": "统计",
|
||||
"url": urlPrefix + "/stat?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "stat",
|
||||
},
|
||||
{
|
||||
"name": "Gzip压缩",
|
||||
"url": urlPrefix + "/gzip?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "gzip",
|
||||
},
|
||||
{
|
||||
"name": "特殊页面",
|
||||
"url": urlPrefix + "/pages?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "page",
|
||||
},
|
||||
{
|
||||
"name": "HTTP Header",
|
||||
"url": urlPrefix + "/headers?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "header",
|
||||
},
|
||||
{
|
||||
"name": "Websocket",
|
||||
"url": urlPrefix + "/websocket?groupId=" + types.String(groupId),
|
||||
"isActive": menuItem == "websocket",
|
||||
},**/
|
||||
}
|
||||
}
|
||||
|
||||
return group, nil
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package httpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// IndexAction 源站列表
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.FirstMenu("index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "httpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["serverType"] = "httpProxy"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupHTTPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupHTTPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
for _, originConfig := range reverseProxy.BackupOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
this.Data["primaryOrigins"] = primaryOriginMaps
|
||||
this.Data["backupOrigins"] = backupOriginMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package httpReverseProxy
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "group").
|
||||
Prefix("/servers/groups/group/settings/httpReverseProxy").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/scheduling", new(SchedulingAction)).
|
||||
GetPost("/setting", new(SettingAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package httpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
|
||||
)
|
||||
|
||||
type SchedulingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) Init() {
|
||||
this.FirstMenu("scheduling")
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "httpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "http"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupHTTPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupHTTPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyId"] = reverseProxy.Id
|
||||
|
||||
schedulingCode := reverseProxy.FindSchedulingConfig().Code
|
||||
schedulingMap := schedulingconfigs.FindSchedulingType(schedulingCode)
|
||||
if schedulingMap == nil {
|
||||
this.ErrorPage(errors.New("invalid scheduling code '" + schedulingCode + "'"))
|
||||
return
|
||||
}
|
||||
this.Data["scheduling"] = schedulingMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package httpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type SettingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SettingAction) Init() {
|
||||
this.FirstMenu("setting")
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "httpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "http"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupHTTPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupHTTPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunPost(params struct {
|
||||
GroupId int64
|
||||
ReverseProxyRefJSON []byte
|
||||
ReverseProxyJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改分组 %d 的反向代理设置", params.GroupId)
|
||||
|
||||
// TODO 校验配置
|
||||
|
||||
reverseProxyConfig := &serverconfigs.ReverseProxyConfig{}
|
||||
err := json.Unmarshal(params.ReverseProxyJSON, reverseProxyConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = reverseProxyConfig.Init()
|
||||
if err != nil {
|
||||
this.Fail("配置校验失败:" + err.Error())
|
||||
}
|
||||
|
||||
// 设置是否启用
|
||||
_, err = this.RPC().ServerGroupRPC().UpdateServerGroupHTTPReverseProxy(this.AdminContext(), &pb.UpdateServerGroupHTTPReverseProxyRequest{
|
||||
ServerGroupId: params.GroupId,
|
||||
ReverseProxyJSON: params.ReverseProxyRefJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 设置反向代理相关信息
|
||||
_, err = this.RPC().ReverseProxyRPC().UpdateReverseProxy(this.AdminContext(), &pb.UpdateReverseProxyRequest{
|
||||
ReverseProxyId: reverseProxyConfig.Id,
|
||||
RequestHostType: types.Int32(reverseProxyConfig.RequestHostType),
|
||||
RequestHost: reverseProxyConfig.RequestHost,
|
||||
RequestURI: reverseProxyConfig.RequestURI,
|
||||
StripPrefix: reverseProxyConfig.StripPrefix,
|
||||
AutoFlush: reverseProxyConfig.AutoFlush,
|
||||
AddHeaders: reverseProxyConfig.AddHeaders,
|
||||
})
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package reverseProxy
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
this.RedirectURL("/servers/groups/group/settings/httpReverseProxy?groupId=" + types.String(params.GroupId))
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package reverseProxy
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/locations/locationutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/serverutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Helper(locationutils.NewLocationHelper()).
|
||||
Helper(serverutils.NewServerHelper()).
|
||||
Data("mainTab", "setting").
|
||||
Prefix("/servers/groups/group/settings").
|
||||
Get("", new(IndexAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package tcpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// IndexAction 源站列表
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.FirstMenu("index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "tcpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["serverType"] = "tcpProxy"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupTCPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupTCPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
for _, originConfig := range reverseProxy.BackupOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
this.Data["primaryOrigins"] = primaryOriginMaps
|
||||
this.Data["backupOrigins"] = backupOriginMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package tcpReverseProxy
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "group").
|
||||
Prefix("/servers/groups/group/settings/tcpReverseProxy").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/scheduling", new(SchedulingAction)).
|
||||
GetPost("/setting", new(SettingAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package tcpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
|
||||
)
|
||||
|
||||
type SchedulingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) Init() {
|
||||
this.FirstMenu("scheduling")
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "tcpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "tcp"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupTCPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupTCPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyId"] = reverseProxy.Id
|
||||
|
||||
schedulingCode := reverseProxy.FindSchedulingConfig().Code
|
||||
schedulingMap := schedulingconfigs.FindSchedulingType(schedulingCode)
|
||||
if schedulingMap == nil {
|
||||
this.ErrorPage(errors.New("invalid scheduling code '" + schedulingCode + "'"))
|
||||
return
|
||||
}
|
||||
this.Data["scheduling"] = schedulingMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package tcpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type SettingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SettingAction) Init() {
|
||||
this.FirstMenu("setting")
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "tcpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "tcp"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupTCPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupTCPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunPost(params struct {
|
||||
GroupId int64
|
||||
ReverseProxyRefJSON []byte
|
||||
ReverseProxyJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改分组 %d 的反向代理设置", params.GroupId)
|
||||
|
||||
// TODO 校验配置
|
||||
|
||||
reverseProxyConfig := &serverconfigs.ReverseProxyConfig{}
|
||||
err := json.Unmarshal(params.ReverseProxyJSON, reverseProxyConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = reverseProxyConfig.Init()
|
||||
if err != nil {
|
||||
this.Fail("配置校验失败:" + err.Error())
|
||||
}
|
||||
|
||||
// 设置是否启用
|
||||
_, err = this.RPC().ServerGroupRPC().UpdateServerGroupTCPReverseProxy(this.AdminContext(), &pb.UpdateServerGroupTCPReverseProxyRequest{
|
||||
ServerGroupId: params.GroupId,
|
||||
ReverseProxyJSON: params.ReverseProxyRefJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 设置反向代理相关信息
|
||||
_, err = this.RPC().ReverseProxyRPC().UpdateReverseProxy(this.AdminContext(), &pb.UpdateReverseProxyRequest{
|
||||
ReverseProxyId: reverseProxyConfig.Id,
|
||||
RequestHostType: types.Int32(reverseProxyConfig.RequestHostType),
|
||||
RequestHost: reverseProxyConfig.RequestHost,
|
||||
RequestURI: reverseProxyConfig.RequestURI,
|
||||
StripPrefix: reverseProxyConfig.StripPrefix,
|
||||
AutoFlush: reverseProxyConfig.AutoFlush,
|
||||
AddHeaders: reverseProxyConfig.AddHeaders,
|
||||
})
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package udpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
// IndexAction 源站列表
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *IndexAction) Init() {
|
||||
this.FirstMenu("index")
|
||||
}
|
||||
|
||||
func (this *IndexAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "udpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["serverType"] = "udpProxy"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupUDPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupUDPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
for _, originConfig := range reverseProxy.BackupOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
this.Data["primaryOrigins"] = primaryOriginMaps
|
||||
this.Data["backupOrigins"] = backupOriginMaps
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package udpReverseProxy
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
|
||||
func init() {
|
||||
TeaGo.BeforeStart(func(server *TeaGo.Server) {
|
||||
server.
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Data("teaMenu", "servers").
|
||||
Data("teaSubMenu", "group").
|
||||
Prefix("/servers/groups/group/settings/udpReverseProxy").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/scheduling", new(SchedulingAction)).
|
||||
GetPost("/setting", new(SettingAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package udpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/schedulingconfigs"
|
||||
)
|
||||
|
||||
type SchedulingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) Init() {
|
||||
this.FirstMenu("scheduling")
|
||||
}
|
||||
|
||||
func (this *SchedulingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "udpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "udp"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupUDPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupUDPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["reverseProxyId"] = reverseProxy.Id
|
||||
|
||||
schedulingCode := reverseProxy.FindSchedulingConfig().Code
|
||||
schedulingMap := schedulingconfigs.FindSchedulingType(schedulingCode)
|
||||
if schedulingMap == nil {
|
||||
this.ErrorPage(errors.New("invalid scheduling code '" + schedulingCode + "'"))
|
||||
return
|
||||
}
|
||||
this.Data["scheduling"] = schedulingMap
|
||||
|
||||
this.Show()
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package udpReverseProxy
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
type SettingAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *SettingAction) Init() {
|
||||
this.FirstMenu("setting")
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
_, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "udpReverseProxy")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["family"] = "udp"
|
||||
|
||||
reverseProxyResp, err := this.RPC().ServerGroupRPC().FindAndInitServerGroupUDPReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerGroupUDPReverseProxyConfigRequest{ServerGroupId: params.GroupId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
reverseProxyRef := &serverconfigs.ReverseProxyRef{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyRefJSON, reverseProxyRef)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
reverseProxy := &serverconfigs.ReverseProxyConfig{}
|
||||
err = json.Unmarshal(reverseProxyResp.ReverseProxyJSON, reverseProxy)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["reverseProxyRef"] = reverseProxyRef
|
||||
this.Data["reverseProxyConfig"] = reverseProxy
|
||||
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *SettingAction) RunPost(params struct {
|
||||
GroupId int64
|
||||
ReverseProxyRefJSON []byte
|
||||
ReverseProxyJSON []byte
|
||||
|
||||
Must *actions.Must
|
||||
}) {
|
||||
defer this.CreateLogInfo("修改分组 %d 的反向代理设置", params.GroupId)
|
||||
|
||||
// TODO 校验配置
|
||||
|
||||
reverseProxyConfig := &serverconfigs.ReverseProxyConfig{}
|
||||
err := json.Unmarshal(params.ReverseProxyJSON, reverseProxyConfig)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
err = reverseProxyConfig.Init()
|
||||
if err != nil {
|
||||
this.Fail("配置校验失败:" + err.Error())
|
||||
}
|
||||
|
||||
// 设置是否启用
|
||||
_, err = this.RPC().ServerGroupRPC().UpdateServerGroupUDPReverseProxy(this.AdminContext(), &pb.UpdateServerGroupUDPReverseProxyRequest{
|
||||
ServerGroupId: params.GroupId,
|
||||
ReverseProxyJSON: params.ReverseProxyRefJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
// 设置反向代理相关信息
|
||||
_, err = this.RPC().ReverseProxyRPC().UpdateReverseProxy(this.AdminContext(), &pb.UpdateReverseProxyRequest{
|
||||
ReverseProxyId: reverseProxyConfig.Id,
|
||||
RequestHostType: types.Int32(reverseProxyConfig.RequestHostType),
|
||||
RequestHost: reverseProxyConfig.RequestHost,
|
||||
RequestURI: reverseProxyConfig.RequestURI,
|
||||
StripPrefix: reverseProxyConfig.StripPrefix,
|
||||
AutoFlush: reverseProxyConfig.AutoFlush,
|
||||
AddHeaders: reverseProxyConfig.AddHeaders,
|
||||
})
|
||||
|
||||
this.Success()
|
||||
}
|
||||
@@ -1,34 +1,30 @@
|
||||
package groups
|
||||
package group
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/servergrouputils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
)
|
||||
|
||||
type UpdatePopupAction struct {
|
||||
type UpdateAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) Init() {
|
||||
this.Nav("", "", "")
|
||||
func (this *UpdateAction) Init() {
|
||||
this.Nav("", "", "group.update")
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunGet(params struct {
|
||||
func (this *UpdateAction) RunGet(params struct {
|
||||
GroupId int64
|
||||
}) {
|
||||
groupResp, err := this.RPC().ServerGroupRPC().FindEnabledServerGroup(this.AdminContext(), &pb.FindEnabledServerGroupRequest{ServerGroupId: params.GroupId})
|
||||
group, err := servergrouputils.InitGroup(this.Parent(), params.GroupId, "")
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
group := groupResp.ServerGroup
|
||||
if group == nil {
|
||||
this.NotFound("serverGroup", params.GroupId)
|
||||
return
|
||||
}
|
||||
|
||||
this.Data["group"] = maps.Map{
|
||||
"id": group.Id,
|
||||
@@ -38,7 +34,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *UpdatePopupAction) RunPost(params struct {
|
||||
func (this *UpdateAction) RunPost(params struct {
|
||||
GroupId int64
|
||||
Name string
|
||||
|
||||
@@ -2,6 +2,7 @@ package groups
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
|
||||
"github.com/iwind/TeaGo"
|
||||
)
|
||||
@@ -12,13 +13,17 @@ func init() {
|
||||
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
|
||||
Helper(NewHelper()).
|
||||
Data("teaSubMenu", "group").
|
||||
Prefix("/servers/components/groups").
|
||||
Prefix("/servers/groups").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/createPopup", new(CreatePopupAction)).
|
||||
GetPost("/updatePopup", new(UpdatePopupAction)).
|
||||
GetPost("/selectPopup", new(SelectPopupAction)).
|
||||
Post("/delete", new(DeleteAction)).
|
||||
Post("/sort", new(SortAction)).
|
||||
|
||||
// 详情
|
||||
Prefix("/servers/groups/group").
|
||||
Get("", new(group.IndexAction)).
|
||||
Post("/delete", new(group.DeleteAction)).
|
||||
GetPost("/update", new(group.UpdateAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
@@ -54,22 +54,30 @@ func (this *IndexAction) RunGet(params struct {
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
for _, originConfig := range reverseProxy.BackupOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
|
||||
@@ -21,18 +21,24 @@ type AddPopupAction struct {
|
||||
|
||||
func (this *AddPopupAction) RunGet(params struct {
|
||||
ServerId int64
|
||||
ServerType string
|
||||
ReverseProxyId int64
|
||||
OriginType string
|
||||
}) {
|
||||
this.Data["reverseProxyId"] = params.ReverseProxyId
|
||||
this.Data["originType"] = params.OriginType
|
||||
|
||||
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
var serverType = ""
|
||||
if params.ServerId > 0 {
|
||||
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
serverType = serverTypeResp.Type
|
||||
} else {
|
||||
serverType = params.ServerType
|
||||
}
|
||||
serverType := serverTypeResp.Type
|
||||
this.Data["serverType"] = serverType
|
||||
|
||||
// 是否为HTTP
|
||||
@@ -56,6 +62,8 @@ func (this *AddPopupAction) RunPost(params struct {
|
||||
MaxIdleConns int32
|
||||
IdleTimeout int
|
||||
|
||||
DomainsJSON []byte
|
||||
|
||||
Description string
|
||||
IsOn bool
|
||||
|
||||
@@ -121,6 +129,15 @@ func (this *AddPopupAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
var domains = []string{}
|
||||
if len(params.DomainsJSON) > 0 {
|
||||
err = json.Unmarshal(params.DomainsJSON, &domains)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
createResp, err := this.RPC().OriginRPC().CreateOrigin(this.AdminContext(), &pb.CreateOriginRequest{
|
||||
Name: params.Name,
|
||||
Addr: &pb.NetworkAddress{
|
||||
@@ -136,6 +153,7 @@ func (this *AddPopupAction) RunPost(params struct {
|
||||
IdleTimeoutJSON: idleTimeoutJSON,
|
||||
MaxConns: params.MaxConns,
|
||||
MaxIdleConns: params.MaxIdleConns,
|
||||
Domains: domains,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -26,6 +26,7 @@ func (this *UpdatePopupAction) Init() {
|
||||
|
||||
func (this *UpdatePopupAction) RunGet(params struct {
|
||||
ServerId int64
|
||||
ServerType string
|
||||
ReverseProxyId int64
|
||||
OriginType string
|
||||
OriginId int64
|
||||
@@ -34,15 +35,20 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
this.Data["reverseProxyId"] = params.ReverseProxyId
|
||||
this.Data["originId"] = params.OriginId
|
||||
|
||||
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{
|
||||
ServerId: params.ServerId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
var serverType = ""
|
||||
if params.ServerId > 0 {
|
||||
serverTypeResp, err := this.RPC().ServerRPC().FindEnabledServerType(this.AdminContext(), &pb.FindEnabledServerTypeRequest{
|
||||
ServerId: params.ServerId,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
serverType = serverTypeResp.Type
|
||||
} else {
|
||||
serverType = params.ServerType
|
||||
}
|
||||
this.Data["serverType"] = serverTypeResp.Type
|
||||
serverType := serverTypeResp.Type
|
||||
this.Data["serverType"] = serverType
|
||||
|
||||
// 是否为HTTP
|
||||
this.Data["isHTTP"] = serverType == "httpProxy" || serverType == "httpWeb"
|
||||
@@ -76,6 +82,10 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
idleTimeout = types.Int(config.IdleTimeout.Count)
|
||||
}
|
||||
|
||||
if len(config.Domains) == 0 {
|
||||
config.Domains = []string{}
|
||||
}
|
||||
|
||||
this.Data["origin"] = maps.Map{
|
||||
"id": config.Id,
|
||||
"protocol": config.Addr.Protocol,
|
||||
@@ -89,6 +99,7 @@ func (this *UpdatePopupAction) RunGet(params struct {
|
||||
"idleTimeout": idleTimeout,
|
||||
"maxConns": config.MaxConns,
|
||||
"maxIdleConns": config.MaxIdleConns,
|
||||
"domains": config.Domains,
|
||||
}
|
||||
|
||||
this.Show()
|
||||
@@ -110,6 +121,8 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
MaxIdleConns int32
|
||||
IdleTimeout int
|
||||
|
||||
DomainsJSON []byte
|
||||
|
||||
Description string
|
||||
IsOn bool
|
||||
|
||||
@@ -175,6 +188,15 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
|
||||
var domains = []string{}
|
||||
if len(params.DomainsJSON) > 0 {
|
||||
err = json.Unmarshal(params.DomainsJSON, &domains)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
_, err = this.RPC().OriginRPC().UpdateOrigin(this.AdminContext(), &pb.UpdateOriginRequest{
|
||||
OriginId: params.OriginId,
|
||||
Name: params.Name,
|
||||
@@ -191,6 +213,7 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
IdleTimeoutJSON: idleTimeoutJSON,
|
||||
MaxConns: params.MaxConns,
|
||||
MaxIdleConns: params.MaxIdleConns,
|
||||
Domains: domains,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
@@ -6,9 +6,10 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// 源站列表
|
||||
// IndexAction 源站列表
|
||||
type IndexAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -27,6 +28,33 @@ func (this *IndexAction) RunGet(params struct {
|
||||
}
|
||||
serverType := serverTypeResp.Type
|
||||
|
||||
// 当前是否有分组设置
|
||||
groupResp, err := this.RPC().ServerGroupRPC().FindEnabledServerGroupConfigInfo(this.AdminContext(), &pb.FindEnabledServerGroupConfigInfoRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
this.Data["hasGroupConfig"] = false
|
||||
this.Data["groupSettingURL"] = ""
|
||||
switch serverType {
|
||||
case serverconfigs.ServerTypeHTTPWeb, serverconfigs.ServerTypeHTTPProxy:
|
||||
this.Data["hasGroupConfig"] = groupResp.HasHTTPReverseProxy
|
||||
if groupResp.ServerGroupId > 0 {
|
||||
this.Data["groupSettingURL"] = "/servers/groups/group/settings/httpReverseProxy?groupId=" + types.String(groupResp.ServerGroupId)
|
||||
}
|
||||
case serverconfigs.ServerTypeTCPProxy:
|
||||
this.Data["hasGroupConfig"] = groupResp.HasTCPReverseProxy
|
||||
if groupResp.ServerGroupId > 0 {
|
||||
this.Data["groupSettingURL"] = "/servers/groups/group/settings/tcpReverseProxy?groupId=" + types.String(groupResp.ServerGroupId)
|
||||
}
|
||||
case serverconfigs.ServerTypeUDPProxy:
|
||||
this.Data["hasGroupConfig"] = groupResp.HasUDPReverseProxy
|
||||
if groupResp.ServerGroupId > 0 {
|
||||
this.Data["groupSettingURL"] = "/servers/groups/group/settings/udpReverseProxy?groupId=" + types.String(groupResp.ServerGroupId)
|
||||
}
|
||||
}
|
||||
|
||||
// 当前服务的配置
|
||||
reverseProxyResp, err := this.RPC().ServerRPC().FindAndInitServerReverseProxyConfig(this.AdminContext(), &pb.FindAndInitServerReverseProxyConfigRequest{ServerId: params.ServerId})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
@@ -53,22 +81,30 @@ func (this *IndexAction) RunGet(params struct {
|
||||
primaryOriginMaps := []maps.Map{}
|
||||
backupOriginMaps := []maps.Map{}
|
||||
for _, originConfig := range reverseProxy.PrimaryOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
primaryOriginMaps = append(primaryOriginMaps, m)
|
||||
}
|
||||
for _, originConfig := range reverseProxy.BackupOrigins {
|
||||
if len(originConfig.Domains) == 0 {
|
||||
originConfig.Domains = []string{}
|
||||
}
|
||||
m := maps.Map{
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"id": originConfig.Id,
|
||||
"weight": originConfig.Weight,
|
||||
"addr": originConfig.Addr.Protocol.String() + "://" + originConfig.Addr.Host + ":" + originConfig.Addr.PortRange,
|
||||
"name": originConfig.Name,
|
||||
"isOn": originConfig.IsOn,
|
||||
"domains": originConfig.Domains,
|
||||
}
|
||||
backupOriginMaps = append(backupOriginMaps, m)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
// 修改调度算法
|
||||
// UpdateSchedulingPopupAction 修改调度算法
|
||||
type UpdateSchedulingPopupAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
@@ -24,17 +24,15 @@ func (this *UpdateSchedulingPopupAction) Init() {
|
||||
func (this *UpdateSchedulingPopupAction) RunGet(params struct {
|
||||
Type string
|
||||
ServerId int64
|
||||
GroupId int64
|
||||
ReverseProxyId int64
|
||||
Family string
|
||||
}) {
|
||||
this.Data["dataType"] = params.Type
|
||||
this.Data["serverId"] = params.ServerId
|
||||
this.Data["groupId"] = params.GroupId
|
||||
this.Data["reverseProxyId"] = params.ReverseProxyId
|
||||
|
||||
_, serverConfig, isOk := serverutils.FindServer(this.Parent(), params.ServerId)
|
||||
if !isOk {
|
||||
return
|
||||
}
|
||||
|
||||
reverseProxyResp, err := this.RPC().ReverseProxyRPC().FindEnabledReverseProxyConfig(this.AdminContext(), &pb.FindEnabledReverseProxyConfigRequest{
|
||||
ReverseProxyId: params.ReverseProxyId,
|
||||
})
|
||||
@@ -62,6 +60,33 @@ func (this *UpdateSchedulingPopupAction) RunGet(params struct {
|
||||
|
||||
// 调度类型
|
||||
schedulingTypes := []maps.Map{}
|
||||
|
||||
var isHTTPFamily = false
|
||||
var isTCPFamily = false
|
||||
var isUDPFamily = false
|
||||
var isUnixFamily = false
|
||||
if params.ServerId > 0 {
|
||||
_, serverConfig, isOk := serverutils.FindServer(this.Parent(), params.ServerId)
|
||||
if !isOk {
|
||||
return
|
||||
}
|
||||
isHTTPFamily = serverConfig.IsHTTPFamily()
|
||||
isTCPFamily = serverConfig.IsTCPFamily()
|
||||
isUDPFamily = serverConfig.IsUDPFamily()
|
||||
isUnixFamily = serverConfig.IsUnixFamily()
|
||||
} else {
|
||||
switch params.Family {
|
||||
case "http":
|
||||
isHTTPFamily = true
|
||||
case "tcp":
|
||||
isTCPFamily = true
|
||||
case "udp":
|
||||
isUDPFamily = true
|
||||
case "unix":
|
||||
isUnixFamily = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, m := range schedulingconfigs.AllSchedulingTypes() {
|
||||
networks, ok := m["networks"]
|
||||
if !ok {
|
||||
@@ -70,10 +95,10 @@ func (this *UpdateSchedulingPopupAction) RunGet(params struct {
|
||||
if !types.IsSlice(networks) {
|
||||
continue
|
||||
}
|
||||
if (serverConfig.IsHTTPFamily() && lists.Contains(networks, "http")) ||
|
||||
(serverConfig.IsTCPFamily() && lists.Contains(networks, "tcp")) ||
|
||||
(serverConfig.IsUDPFamily() && lists.Contains(networks, "udp")) ||
|
||||
(serverConfig.IsUnixFamily() && lists.Contains(networks, "unix")) {
|
||||
if (isHTTPFamily && lists.Contains(networks, "http")) ||
|
||||
(isTCPFamily && lists.Contains(networks, "tcp")) ||
|
||||
(isUDPFamily && lists.Contains(networks, "udp")) ||
|
||||
(isUnixFamily && lists.Contains(networks, "unix")) {
|
||||
schedulingTypes = append(schedulingTypes, m)
|
||||
}
|
||||
}
|
||||
|
||||
52
internal/web/actions/default/settings/authority/activate.go
Normal file
52
internal/web/actions/default/settings/authority/activate.go
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
)
|
||||
|
||||
type ActivateAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *ActivateAction) Init() {
|
||||
this.Nav("", "", "activate")
|
||||
}
|
||||
|
||||
func (this *ActivateAction) RunGet(params struct{}) {
|
||||
this.Show()
|
||||
}
|
||||
|
||||
func (this *ActivateAction) RunPost(params struct {
|
||||
Key string
|
||||
|
||||
Must *actions.Must
|
||||
CSRF *actionutils.CSRF
|
||||
}) {
|
||||
if len(params.Key) == 0 {
|
||||
this.FailField("key", "请输入激活码")
|
||||
}
|
||||
|
||||
resp, err := this.RPC().AuthorityKeyRPC().ValidateAuthorityKey(this.AdminContext(), &pb.ValidateAuthorityKeyRequest{Key: params.Key})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
if resp.IsOk {
|
||||
_, err := this.RPC().AuthorityKeyRPC().UpdateAuthorityKey(this.AdminContext(), &pb.UpdateAuthorityKeyRequest{
|
||||
Value: params.Key,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
this.Success()
|
||||
} else {
|
||||
this.FailField("key", "无法激活:"+resp.Error)
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
"github.com/iwind/TeaGo/maps"
|
||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IndexAction struct {
|
||||
@@ -26,24 +27,28 @@ func (this *IndexAction) RunGet(params struct{}) {
|
||||
}
|
||||
var keyMap maps.Map = nil
|
||||
teaconst.IsPlus = false
|
||||
if keyResp.AuthorityKey != nil {
|
||||
if len(keyResp.AuthorityKey.MacAddresses) == 0 {
|
||||
keyResp.AuthorityKey.MacAddresses = []string{}
|
||||
var key = keyResp.AuthorityKey
|
||||
if key != nil {
|
||||
if len(key.MacAddresses) == 0 {
|
||||
key.MacAddresses = []string{}
|
||||
}
|
||||
|
||||
isActive := len(keyResp.AuthorityKey.DayTo) > 0 && keyResp.AuthorityKey.DayTo >= timeutil.Format("Y-m-d")
|
||||
isActive := len(key.DayTo) > 0 && key.DayTo >= timeutil.Format("Y-m-d")
|
||||
if isActive {
|
||||
teaconst.IsPlus = true
|
||||
}
|
||||
|
||||
isExpiring := isActive && key.DayTo < timeutil.Format("Y-m-d", time.Now().AddDate(0, 0, 7))
|
||||
|
||||
keyMap = maps.Map{
|
||||
"dayFrom": keyResp.AuthorityKey.DayFrom,
|
||||
"dayTo": keyResp.AuthorityKey.DayTo,
|
||||
"macAddresses": keyResp.AuthorityKey.MacAddresses,
|
||||
"hostname": keyResp.AuthorityKey.Hostname,
|
||||
"company": keyResp.AuthorityKey.Company,
|
||||
"nodes": keyResp.AuthorityKey.Nodes,
|
||||
"dayFrom": key.DayFrom,
|
||||
"dayTo": key.DayTo,
|
||||
"macAddresses": key.MacAddresses,
|
||||
"hostname": key.Hostname,
|
||||
"company": key.Company,
|
||||
"nodes": key.Nodes,
|
||||
"isExpired": !isActive,
|
||||
"isExpiring": isExpiring,
|
||||
"updatedTime": timeutil.FormatTime("Y-m-d H:i:s", keyResp.AuthorityKey.UpdatedAt),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ func init() {
|
||||
Helper(settingutils.NewAdvancedHelper("authority")).
|
||||
Prefix("/settings/authority").
|
||||
Get("", new(IndexAction)).
|
||||
GetPost("/activate", new(ActivateAction)).
|
||||
EndAll()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func (this *AdvancedHelper) BeforeAction(actionPtr actions.ActionWrapper) (goNex
|
||||
tabbar.Add("监控节点", "", "/settings/monitorNodes", "", this.tab == "monitorNodes")
|
||||
}
|
||||
if teaconst.BuildPlus {
|
||||
tabbar.Add("企业版认证", "", "/settings/authority", "", this.tab == "authority")
|
||||
tabbar.Add("商业版认证", "", "/settings/authority", "", this.tab == "authority")
|
||||
}
|
||||
|
||||
//tabbar.Add("备份", "", "/settings/backup", "", this.tab == "backup")
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/server/settings/conds/condutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
@@ -102,6 +103,26 @@ func (this *ComponentsAction) RunGet(params struct{}) {
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// IP地址阈值项目
|
||||
ipAddrThresholdItemsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdItems())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal ip addr threshold items failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.IP_ADDR_THRESHOLD_ITEMS = ")
|
||||
buffer.Write(ipAddrThresholdItemsJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
// IP地址阈值动作
|
||||
ipAddrThresholdActionsJSON, err := json.Marshal(nodeconfigs.FindAllIPAddressThresholdActions())
|
||||
if err != nil {
|
||||
logs.Println("ComponentsAction marshal ip addr threshold actions failed: " + err.Error())
|
||||
} else {
|
||||
buffer.WriteString("window.IP_ADDR_THRESHOLD_ACTIONS = ")
|
||||
buffer.Write(ipAddrThresholdActionsJSON)
|
||||
buffer.Write([]byte{'\n', '\n'})
|
||||
}
|
||||
|
||||
componentsData = buffer.Bytes()
|
||||
|
||||
// ETag
|
||||
|
||||
@@ -30,6 +30,7 @@ func init() {
|
||||
Post("/showTip", new(ShowTipAction)).
|
||||
Post("/hideTip", new(HideTipAction)).
|
||||
Post("/theme", new(ThemeAction)).
|
||||
Post("/validateIPs", new(ValidateIPsAction)).
|
||||
|
||||
EndAll()
|
||||
})
|
||||
|
||||
41
internal/web/actions/default/ui/validateIPs.go
Normal file
41
internal/web/actions/default/ui/validateIPs.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
|
||||
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ValidateIPsAction struct {
|
||||
actionutils.ParentAction
|
||||
}
|
||||
|
||||
func (this *ValidateIPsAction) RunPost(params struct {
|
||||
Ips string
|
||||
}) {
|
||||
var ips = params.Ips
|
||||
if len(ips) == 0 {
|
||||
this.Data["ips"] = []string{}
|
||||
this.Success()
|
||||
}
|
||||
|
||||
var ipSlice = strings.Split(ips, "\n")
|
||||
var result = []string{}
|
||||
for _, ip := range ipSlice {
|
||||
ip = strings.TrimSpace(ip)
|
||||
if len(ip) == 0 {
|
||||
continue
|
||||
}
|
||||
data := net.ParseIP(ip)
|
||||
if len(data) == 0 {
|
||||
this.Data["failIP"] = ip
|
||||
this.Fail()
|
||||
}
|
||||
result = append(result, ip)
|
||||
}
|
||||
|
||||
this.Data["ips"] = result
|
||||
this.Success()
|
||||
}
|
||||
@@ -180,6 +180,11 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
||||
"subtitle": "服务列表",
|
||||
"icon": "clone outsize",
|
||||
"subItems": []maps.Map{
|
||||
{
|
||||
"name": "服务分组",
|
||||
"url": "/servers/groups",
|
||||
"code": "group",
|
||||
},
|
||||
{
|
||||
"name": "证书管理",
|
||||
"url": "/servers/certs",
|
||||
@@ -216,11 +221,6 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
||||
"url": "/servers/metrics",
|
||||
"code": "metric",
|
||||
},
|
||||
{
|
||||
"name": "服务分组",
|
||||
"url": "/servers/components/groups",
|
||||
"code": "group",
|
||||
},
|
||||
{
|
||||
"name": "通用设置",
|
||||
"url": "/servers/components",
|
||||
@@ -246,12 +246,12 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
||||
"code": "ipAddr",
|
||||
"isOn": teaconst.IsPlus,
|
||||
},
|
||||
/**{
|
||||
{
|
||||
"name": "区域监控",
|
||||
"url": "/clusters/monitors",
|
||||
"code": "monitor",
|
||||
"isOn": teaconst.IsPlus,
|
||||
},**/
|
||||
},
|
||||
{
|
||||
"name": "SSH认证",
|
||||
"url": "/clusters/grants",
|
||||
|
||||
@@ -41,9 +41,13 @@ import (
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/certs"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/groups"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/log"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/waf"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/httpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/index"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/tcpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/groups/group/settings/udpReverseProxy"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/logs"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics"
|
||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/metrics/charts"
|
||||
|
||||
@@ -19,7 +19,13 @@ Vue.component("node-clusters-labels", {
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<a v-if="cluster != null" :href="'/clusters/cluster?clusterId=' + cluster.id" class="ui label basic grey" :class="labelSize" title="主集群" style="margin-bottom: 0.3em;">{{cluster.name}}</a>
|
||||
<a v-for="c in secondaryClusters" :href="'/clusters/cluster?clusterId=' + c.id" class="ui label basic grey" :class="labelSize" title="从集群" style="margin-bottom: 0.3em;"><span class="grey" style="text-decoration: none">{{c.name}}</span></a>
|
||||
<a v-if="cluster != null" :href="'/clusters/cluster?clusterId=' + cluster.id" title="主集群" style="margin-bottom: 0.3em;">
|
||||
<span class="ui label basic grey" :class="labelSize" v-if="labelSize != 'tiny'">{{cluster.name}}</span>
|
||||
<grey-label v-if="labelSize == 'tiny'">{{cluster.name}}</grey-label>
|
||||
</a>
|
||||
<a v-for="c in secondaryClusters" :href="'/clusters/cluster?clusterId=' + c.id" :class="labelSize" title="从集群">
|
||||
<span class="ui label basic grey" :class="labelSize" v-if="labelSize != 'tiny'">{{c.name}}</span>
|
||||
<grey-label v-if="labelSize == 'tiny'">{{c.name}}</grey-label>
|
||||
</a>
|
||||
</div>`
|
||||
})
|
||||
@@ -1,150 +1,150 @@
|
||||
Vue.component("datetime-input", {
|
||||
props: ["v-name", "v-timestamp"],
|
||||
mounted: function () {
|
||||
let that = this
|
||||
teaweb.datepicker(this.$refs.dayInput, function (v) {
|
||||
that.day = v
|
||||
that.hour = "23"
|
||||
that.minute = "59"
|
||||
that.second = "59"
|
||||
that.change()
|
||||
})
|
||||
},
|
||||
data: function () {
|
||||
let timestamp = this.vTimestamp
|
||||
if (timestamp != null) {
|
||||
timestamp = parseInt(timestamp)
|
||||
if (isNaN(timestamp)) {
|
||||
timestamp = 0
|
||||
}
|
||||
} else {
|
||||
timestamp = 0
|
||||
}
|
||||
props: ["v-name", "v-timestamp"],
|
||||
mounted: function () {
|
||||
let that = this
|
||||
teaweb.datepicker(this.$refs.dayInput, function (v) {
|
||||
that.day = v
|
||||
that.hour = "23"
|
||||
that.minute = "59"
|
||||
that.second = "59"
|
||||
that.change()
|
||||
})
|
||||
},
|
||||
data: function () {
|
||||
let timestamp = this.vTimestamp
|
||||
if (timestamp != null) {
|
||||
timestamp = parseInt(timestamp)
|
||||
if (isNaN(timestamp)) {
|
||||
timestamp = 0
|
||||
}
|
||||
} else {
|
||||
timestamp = 0
|
||||
}
|
||||
|
||||
let day = ""
|
||||
let hour = ""
|
||||
let minute = ""
|
||||
let second = ""
|
||||
let day = ""
|
||||
let hour = ""
|
||||
let minute = ""
|
||||
let second = ""
|
||||
|
||||
if (timestamp > 0) {
|
||||
let date = new Date()
|
||||
date.setTime(timestamp * 1000)
|
||||
if (timestamp > 0) {
|
||||
let date = new Date()
|
||||
date.setTime(timestamp * 1000)
|
||||
|
||||
let year = date.getFullYear().toString()
|
||||
let month = this.leadingZero((date.getMonth() + 1).toString(), 2)
|
||||
day = year + "-" + month + "-" + this.leadingZero(date.getDate().toString(), 2)
|
||||
let year = date.getFullYear().toString()
|
||||
let month = this.leadingZero((date.getMonth() + 1).toString(), 2)
|
||||
day = year + "-" + month + "-" + this.leadingZero(date.getDate().toString(), 2)
|
||||
|
||||
hour = this.leadingZero(date.getHours().toString(), 2)
|
||||
minute = this.leadingZero(date.getMinutes().toString(), 2)
|
||||
second = this.leadingZero(date.getSeconds().toString(), 2)
|
||||
}
|
||||
hour = this.leadingZero(date.getHours().toString(), 2)
|
||||
minute = this.leadingZero(date.getMinutes().toString(), 2)
|
||||
second = this.leadingZero(date.getSeconds().toString(), 2)
|
||||
}
|
||||
|
||||
return {
|
||||
timestamp: timestamp,
|
||||
day: day,
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
second: second,
|
||||
return {
|
||||
timestamp: timestamp,
|
||||
day: day,
|
||||
hour: hour,
|
||||
minute: minute,
|
||||
second: second,
|
||||
|
||||
hasDayError: false,
|
||||
hasHourError: false,
|
||||
hasMinuteError: false,
|
||||
hasSecondError: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
change: function () {
|
||||
let date = new Date()
|
||||
hasDayError: false,
|
||||
hasHourError: false,
|
||||
hasMinuteError: false,
|
||||
hasSecondError: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
change: function () {
|
||||
let date = new Date()
|
||||
|
||||
// day
|
||||
if (!/^\d{4}-\d{1,2}-\d{1,2}$/.test(this.day)) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
let pieces = this.day.split("-")
|
||||
let year = parseInt(pieces[0])
|
||||
date.setFullYear(year)
|
||||
// day
|
||||
if (!/^\d{4}-\d{1,2}-\d{1,2}$/.test(this.day)) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
let pieces = this.day.split("-")
|
||||
let year = parseInt(pieces[0])
|
||||
date.setFullYear(year)
|
||||
|
||||
let month = parseInt(pieces[1])
|
||||
if (month < 1 || month > 12) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
date.setMonth(month - 1)
|
||||
let month = parseInt(pieces[1])
|
||||
if (month < 1 || month > 12) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
date.setMonth(month - 1)
|
||||
|
||||
let day = parseInt(pieces[2])
|
||||
if (day < 1 || day > 32) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
date.setDate(day)
|
||||
let day = parseInt(pieces[2])
|
||||
if (day < 1 || day > 32) {
|
||||
this.hasDayError = true
|
||||
return
|
||||
}
|
||||
date.setDate(day)
|
||||
|
||||
this.hasDayError = false
|
||||
this.hasDayError = false
|
||||
|
||||
// hour
|
||||
if (!/^\d+$/.test(this.hour)) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
let hour = parseInt(this.hour)
|
||||
if (isNaN(hour)) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
if (hour < 0 || hour >= 24) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
this.hasHourError = false
|
||||
date.setHours(hour)
|
||||
// hour
|
||||
if (!/^\d+$/.test(this.hour)) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
let hour = parseInt(this.hour)
|
||||
if (isNaN(hour)) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
if (hour < 0 || hour >= 24) {
|
||||
this.hasHourError = true
|
||||
return
|
||||
}
|
||||
this.hasHourError = false
|
||||
date.setHours(hour)
|
||||
|
||||
// minute
|
||||
if (!/^\d+$/.test(this.minute)) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
let minute = parseInt(this.minute)
|
||||
if (isNaN(minute)) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
if (minute < 0 || minute >= 60) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
this.hasMinuteError = false
|
||||
date.setMinutes(minute)
|
||||
// minute
|
||||
if (!/^\d+$/.test(this.minute)) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
let minute = parseInt(this.minute)
|
||||
if (isNaN(minute)) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
if (minute < 0 || minute >= 60) {
|
||||
this.hasMinuteError = true
|
||||
return
|
||||
}
|
||||
this.hasMinuteError = false
|
||||
date.setMinutes(minute)
|
||||
|
||||
// second
|
||||
if (!/^\d+$/.test(this.second)) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
let second = parseInt(this.second)
|
||||
if (isNaN(second)) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
if (second < 0 || second >= 60) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
this.hasSecondError = false
|
||||
date.setSeconds(second)
|
||||
// second
|
||||
if (!/^\d+$/.test(this.second)) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
let second = parseInt(this.second)
|
||||
if (isNaN(second)) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
if (second < 0 || second >= 60) {
|
||||
this.hasSecondError = true
|
||||
return
|
||||
}
|
||||
this.hasSecondError = false
|
||||
date.setSeconds(second)
|
||||
|
||||
this.timestamp = parseInt(date.getTime() / 1000)
|
||||
},
|
||||
leadingZero: function (s, l) {
|
||||
if (l <= s.length) {
|
||||
return s
|
||||
}
|
||||
for (let i = 0; i < l - s.length; i++) {
|
||||
s = "0" + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
this.timestamp = Math.ceil(date.getTime() / 1000)
|
||||
},
|
||||
leadingZero: function (s, l) {
|
||||
if (l <= s.length) {
|
||||
return s
|
||||
}
|
||||
for (let i = 0; i < l - s.length; i++) {
|
||||
s = "0" + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" :name="vName" :value="timestamp"/>
|
||||
<div class="ui fields inline" style="padding: 0; margin:0">
|
||||
<div class="ui field" :class="{error: hasDayError}">
|
||||
|
||||
@@ -6,7 +6,12 @@ Vue.component("label-on", {
|
||||
|
||||
// 文字代码标签
|
||||
Vue.component("code-label", {
|
||||
template: `<span class="ui label basic tiny" style="padding: 3px;margin-left:2px;margin-right:2px"><slot></slot></span>`
|
||||
methods: {
|
||||
click: function (args) {
|
||||
this.$emit("click", args)
|
||||
}
|
||||
},
|
||||
template: `<span class="ui label basic tiny" style="padding: 3px;margin-left:2px;margin-right:2px" @click.prevent="click"><slot></slot></span>`
|
||||
})
|
||||
|
||||
// tiny标签
|
||||
@@ -26,5 +31,5 @@ Vue.component("micro-basic-label", {
|
||||
|
||||
// 灰色的Label
|
||||
Vue.component("grey-label", {
|
||||
template: `<span class="grey small"><slot></slot></span>`
|
||||
template: `<span class="ui label basic grey tiny" style="margin-top: 0.4em; font-size: 0.7em; border: 1px solid #ddd!important; font-weight: normal;"><slot></slot></span>`
|
||||
})
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// 使用Icon的链接方式
|
||||
Vue.component("link-icon", {
|
||||
props: ["href", "title"],
|
||||
props: ["href", "title", "target"],
|
||||
data: function () {
|
||||
return {
|
||||
vTitle: (this.title == null) ? "打开链接" : this.title
|
||||
}
|
||||
},
|
||||
template: `<span><slot></slot> <a :href="href" :title="vTitle" class="link grey"><i class="icon linkify small"></i></a></span>`
|
||||
template: `<span><slot></slot> <a :href="href" :title="vTitle" class="link grey" :target="target"><i class="icon linkify small"></i></a></span>`
|
||||
})
|
||||
|
||||
// 带有下划虚线的连接
|
||||
|
||||
@@ -66,7 +66,7 @@ Vue.component("network-addresses-box", {
|
||||
updateAddr: function (index, addr) {
|
||||
let that = this
|
||||
window.UPDATING_ADDR = addr
|
||||
teaweb.popup("/servers/addPortPopup?serverType=" + this.vServerType + "&protocol=" + this.protocol, {
|
||||
teaweb.popup("/servers/addPortPopup?serverType=" + this.vServerType + "&protocol=" + this.protocol + "&from=" + this.from, {
|
||||
height: "16em",
|
||||
callback: function (resp) {
|
||||
var addr = resp.data.address
|
||||
|
||||
@@ -55,6 +55,9 @@ Vue.component("values-box", {
|
||||
},
|
||||
updateAll: function (values) {
|
||||
this.vValeus = values
|
||||
},
|
||||
addValue: function (v) {
|
||||
this.vValues.push(v)
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -1,41 +1,51 @@
|
||||
Vue.component("message-row", {
|
||||
props: ["v-message"],
|
||||
data: function () {
|
||||
let paramsJSON = this.vMessage.params
|
||||
let params = null
|
||||
if (paramsJSON != null && paramsJSON.length > 0) {
|
||||
params = JSON.parse(paramsJSON)
|
||||
}
|
||||
props: ["v-message", "v-can-close"],
|
||||
data: function () {
|
||||
let paramsJSON = this.vMessage.params
|
||||
let params = null
|
||||
if (paramsJSON != null && paramsJSON.length > 0) {
|
||||
params = JSON.parse(paramsJSON)
|
||||
}
|
||||
|
||||
return {
|
||||
message: this.vMessage,
|
||||
params: params
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
viewCert: function (certId) {
|
||||
teaweb.popup("/servers/certs/certPopup?certId=" + certId, {
|
||||
height: "28em",
|
||||
width: "48em"
|
||||
})
|
||||
},
|
||||
readMessage: function (messageId) {
|
||||
Tea.action("/messages/readPage")
|
||||
.params({"messageIds": [messageId]})
|
||||
.post()
|
||||
.success(function () {
|
||||
// 刷新父级页面Badge
|
||||
if (window.parent.Tea != null && window.parent.Tea.Vue != null) {
|
||||
window.parent.Tea.Vue.checkMessagesOnce()
|
||||
}
|
||||
return {
|
||||
message: this.vMessage,
|
||||
params: params,
|
||||
isClosing: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
viewCert: function (certId) {
|
||||
teaweb.popup("/servers/certs/certPopup?certId=" + certId, {
|
||||
height: "28em",
|
||||
width: "48em"
|
||||
})
|
||||
},
|
||||
readMessage: function (messageId) {
|
||||
let that = this
|
||||
|
||||
// 刷新当前页面
|
||||
teaweb.reload()
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<table class="ui table selectable">
|
||||
Tea.action("/messages/readPage")
|
||||
.params({"messageIds": [messageId]})
|
||||
.post()
|
||||
.success(function () {
|
||||
// 刷新父级页面Badge
|
||||
if (window.parent.Tea != null && window.parent.Tea.Vue != null) {
|
||||
window.parent.Tea.Vue.checkMessagesOnce()
|
||||
}
|
||||
|
||||
// 刷新当前页面
|
||||
if (that.vCanClose && typeof (NotifyPopup) != "undefined") {
|
||||
that.isClosing = true
|
||||
setTimeout(function () {
|
||||
NotifyPopup({})
|
||||
}, 1000)
|
||||
} else {
|
||||
teaweb.reload()
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<table class="ui table selectable" v-if="!isClosing">
|
||||
<tr :class="{error: message.level == 'error', positive: message.level == 'success', warning: message.level == 'warning'}">
|
||||
<td style="position: relative">
|
||||
<strong>{{message.datetime}}</strong>
|
||||
|
||||
@@ -5,209 +5,494 @@ Vue.component("node-ip-address-thresholds-box", {
|
||||
let thresholds = this.vThresholds
|
||||
if (thresholds == null) {
|
||||
thresholds = []
|
||||
} else {
|
||||
thresholds.forEach(function (v) {
|
||||
if (v.items == null) {
|
||||
v.items = []
|
||||
}
|
||||
if (v.actions == null) {
|
||||
v.actions = []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let avgRequests = {
|
||||
duration: "",
|
||||
operator: "lte",
|
||||
value: ""
|
||||
}
|
||||
|
||||
let avgTrafficOut = {
|
||||
duration: "",
|
||||
operator: "lte",
|
||||
value: ""
|
||||
}
|
||||
|
||||
let avgTrafficIn = {
|
||||
duration: "",
|
||||
operator: "lte",
|
||||
value: ""
|
||||
}
|
||||
|
||||
thresholds.forEach(function (v) {
|
||||
switch (v.item) {
|
||||
case "avgRequests":
|
||||
avgRequests.duration = v.duration
|
||||
avgRequests.operator = v.operator
|
||||
avgRequests.value = v.value.toString()
|
||||
break
|
||||
case "avgTrafficOut":
|
||||
avgTrafficOut.duration = v.duration
|
||||
avgTrafficOut.operator = v.operator
|
||||
avgTrafficOut.value = v.value.toString()
|
||||
break
|
||||
case "avgTrafficIn":
|
||||
avgTrafficIn.duration = v.duration
|
||||
avgTrafficIn.operator = v.operator
|
||||
avgTrafficIn.value = v.value.toString()
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
editingIndex: -1,
|
||||
thresholds: thresholds,
|
||||
avgRequests: avgRequests,
|
||||
avgTrafficOut: avgTrafficOut,
|
||||
avgTrafficIn: avgTrafficIn
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"avgRequests.duration": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgRequests.operator": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgRequests.value": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficOut.duration": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficOut.operator": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficOut.value": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficIn.duration": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficIn.operator": function () {
|
||||
this.compose()
|
||||
},
|
||||
"avgTrafficIn.value": function () {
|
||||
this.compose()
|
||||
addingThreshold: {
|
||||
items: [],
|
||||
actions: []
|
||||
},
|
||||
isAdding: false,
|
||||
isAddingItem: false,
|
||||
isAddingAction: false,
|
||||
|
||||
itemCode: "nodeAvgRequests",
|
||||
itemReportGroups: [],
|
||||
itemOperator: "lte",
|
||||
itemValue: "",
|
||||
itemDuration: "5",
|
||||
allItems: window.IP_ADDR_THRESHOLD_ITEMS,
|
||||
allOperators: [
|
||||
{
|
||||
"name": "小于等于",
|
||||
"code": "lte"
|
||||
},
|
||||
{
|
||||
"name": "大于",
|
||||
"code": "gt"
|
||||
},
|
||||
{
|
||||
"name": "不等于",
|
||||
"code": "neq"
|
||||
},
|
||||
{
|
||||
"name": "小于",
|
||||
"code": "lt"
|
||||
},
|
||||
{
|
||||
"name": "大于等于",
|
||||
"code": "gte"
|
||||
}
|
||||
],
|
||||
allActions: window.IP_ADDR_THRESHOLD_ACTIONS,
|
||||
|
||||
actionCode: "up",
|
||||
actionBackupIPs: "",
|
||||
actionWebHookURL: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
compose: function () {
|
||||
let thresholds = []
|
||||
|
||||
// avg requests
|
||||
{
|
||||
let duration = parseInt(this.avgRequests.duration)
|
||||
let value = parseInt(this.avgRequests.value)
|
||||
if (!isNaN(duration) && duration > 0 && !isNaN(value) && value > 0) {
|
||||
thresholds.push({
|
||||
item: "avgRequests",
|
||||
operator: this.avgRequests.operator,
|
||||
duration: duration,
|
||||
durationUnit: "minute",
|
||||
value: value
|
||||
})
|
||||
}
|
||||
add: function () {
|
||||
this.isAdding = !this.isAdding
|
||||
},
|
||||
cancel: function () {
|
||||
this.isAdding = false
|
||||
this.editingIndex = -1
|
||||
this.addingThreshold = {
|
||||
items: [],
|
||||
actions: []
|
||||
}
|
||||
},
|
||||
confirm: function () {
|
||||
if (this.addingThreshold.items.length == 0) {
|
||||
teaweb.warn("需要至少添加一个阈值")
|
||||
return
|
||||
}
|
||||
if (this.addingThreshold.actions.length == 0) {
|
||||
teaweb.warn("需要至少添加一个动作")
|
||||
return
|
||||
}
|
||||
|
||||
// avg traffic out
|
||||
{
|
||||
let duration = parseInt(this.avgTrafficOut.duration)
|
||||
let value = parseInt(this.avgTrafficOut.value)
|
||||
if (!isNaN(duration) && duration > 0 && !isNaN(value) && value > 0) {
|
||||
thresholds.push({
|
||||
item: "avgTrafficOut",
|
||||
operator: this.avgTrafficOut.operator,
|
||||
duration: duration,
|
||||
durationUnit: "minute",
|
||||
value: value
|
||||
})
|
||||
}
|
||||
if (this.editingIndex >= 0) {
|
||||
this.thresholds[this.editingIndex].items = this.addingThreshold.items
|
||||
this.thresholds[this.editingIndex].actions = this.addingThreshold.actions
|
||||
} else {
|
||||
this.thresholds.push({
|
||||
items: this.addingThreshold.items,
|
||||
actions: this.addingThreshold.actions
|
||||
})
|
||||
}
|
||||
|
||||
// avg requests
|
||||
{
|
||||
let duration = parseInt(this.avgTrafficIn.duration)
|
||||
let value = parseInt(this.avgTrafficIn.value)
|
||||
if (!isNaN(duration) && duration > 0 && !isNaN(value) && value > 0) {
|
||||
thresholds.push({
|
||||
item: "avgTrafficIn",
|
||||
operator: this.avgTrafficIn.operator,
|
||||
duration: duration,
|
||||
durationUnit: "minute",
|
||||
value: value
|
||||
})
|
||||
}
|
||||
// 还原
|
||||
this.cancel()
|
||||
},
|
||||
remove: function (index) {
|
||||
this.cancel()
|
||||
this.thresholds.$remove(index)
|
||||
},
|
||||
update: function (index) {
|
||||
this.editingIndex = index
|
||||
this.addingThreshold = {
|
||||
items: this.thresholds[index].items.$copy(),
|
||||
actions: this.thresholds[index].actions.$copy()
|
||||
}
|
||||
this.isAdding = true
|
||||
},
|
||||
|
||||
addItem: function () {
|
||||
this.isAddingItem = !this.isAddingItem
|
||||
let that = this
|
||||
setTimeout(function () {
|
||||
that.$refs.itemValue.focus()
|
||||
}, 100)
|
||||
},
|
||||
cancelItem: function () {
|
||||
this.isAddingItem = false
|
||||
|
||||
this.itemCode = "nodeAvgRequests"
|
||||
this.itmeOperator = "lte"
|
||||
this.itemValue = ""
|
||||
this.itemDuration = "5"
|
||||
this.itemReportGroups = []
|
||||
},
|
||||
confirmItem: function () {
|
||||
if (this.itemDuration.length == 0) {
|
||||
let that = this
|
||||
teaweb.warn("请输入统计周期", function () {
|
||||
that.$refs.itemDuration.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
let itemDuration = parseInt(this.itemDuration)
|
||||
if (isNaN(itemDuration) || itemDuration <= 0) {
|
||||
teaweb.warn("请输入正确的统计周期", function () {
|
||||
that.$refs.itemDuration.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
this.thresholds = thresholds
|
||||
if (this.itemValue.length == 0) {
|
||||
let that = this
|
||||
teaweb.warn("请输入对比值", function () {
|
||||
that.$refs.itemValue.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
let itemValue = parseFloat(this.itemValue)
|
||||
if (isNaN(itemValue)) {
|
||||
teaweb.warn("请输入正确的对比值", function () {
|
||||
that.$refs.itemValue.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let options = {}
|
||||
|
||||
switch (this.itemCode) {
|
||||
case "connectivity": // 连通性校验
|
||||
if (itemValue > 100) {
|
||||
let that = this
|
||||
teaweb.warn("连通性对比值不能超过100", function () {
|
||||
that.$refs.itemValue.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
options["groups"] = this.itemReportGroups
|
||||
break
|
||||
}
|
||||
|
||||
// 添加
|
||||
this.addingThreshold.items.push({
|
||||
item: this.itemCode,
|
||||
operator: this.itemOperator,
|
||||
value: itemValue,
|
||||
duration: itemDuration,
|
||||
durationUnit: "minute",
|
||||
options: options
|
||||
})
|
||||
|
||||
// 还原
|
||||
this.cancelItem()
|
||||
},
|
||||
removeItem: function (index) {
|
||||
this.cancelItem()
|
||||
this.addingThreshold.items.$remove(index)
|
||||
},
|
||||
changeReportGroups: function (groups) {
|
||||
this.itemReportGroups = groups
|
||||
},
|
||||
itemName: function (item) {
|
||||
let result = ""
|
||||
this.allItems.forEach(function (v) {
|
||||
if (v.code == item) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
itemUnitName: function (itemCode) {
|
||||
let result = ""
|
||||
this.allItems.forEach(function (v) {
|
||||
if (v.code == itemCode) {
|
||||
result = v.unit
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
itemDurationUnitName: function (unit) {
|
||||
switch (unit) {
|
||||
case "minute":
|
||||
return "分钟"
|
||||
case "second":
|
||||
return "秒"
|
||||
case "hour":
|
||||
return "小时"
|
||||
case "day":
|
||||
return "天"
|
||||
}
|
||||
return unit
|
||||
},
|
||||
itemOperatorName: function (operator) {
|
||||
let result = ""
|
||||
this.allOperators.forEach(function (v) {
|
||||
if (v.code == operator) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
|
||||
addAction: function () {
|
||||
this.isAddingAction = !this.isAddingAction
|
||||
},
|
||||
cancelAction: function () {
|
||||
this.isAddingAction = false
|
||||
this.actionCode = "up"
|
||||
this.actionBackupIPs = ""
|
||||
this.actionWebHookURL = ""
|
||||
},
|
||||
confirmAction: function () {
|
||||
this.doConfirmAction(false)
|
||||
},
|
||||
doConfirmAction: function (validated, options) {
|
||||
// 是否已存在
|
||||
let exists = false
|
||||
let that = this
|
||||
this.addingThreshold.actions.forEach(function (v) {
|
||||
if (v.action == that.actionCode) {
|
||||
exists = true
|
||||
}
|
||||
})
|
||||
if (exists) {
|
||||
teaweb.warn("此动作已经添加过了,无需重复添加")
|
||||
return
|
||||
}
|
||||
|
||||
if (options == null) {
|
||||
options = {}
|
||||
}
|
||||
|
||||
switch (this.actionCode) {
|
||||
case "switch":
|
||||
if (!validated) {
|
||||
Tea.action("/ui/validateIPs")
|
||||
.params({
|
||||
"ips": this.actionBackupIPs
|
||||
})
|
||||
.success(function (resp) {
|
||||
if (resp.data.ips.length == 0) {
|
||||
teaweb.warn("请输入备用IP", function () {
|
||||
that.$refs.actionBackupIPs.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
options["ips"] = resp.data.ips
|
||||
that.doConfirmAction(true, options)
|
||||
})
|
||||
.fail(function (resp) {
|
||||
teaweb.warn("输入的IP '" + resp.data.failIP + "' 格式不正确,请改正后提交", function () {
|
||||
that.$refs.actionBackupIPs.focus()
|
||||
})
|
||||
})
|
||||
.post()
|
||||
return
|
||||
}
|
||||
break
|
||||
case "webHook":
|
||||
if (this.actionWebHookURL.length ==0) {
|
||||
teaweb.warn("请输入WebHook URL", function () {
|
||||
that.$refs.webHookURL.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
if (!this.actionWebHookURL.match(/^(http|https):\/\//i)) {
|
||||
teaweb.warn("URL开头必须是http://或者https://", function () {
|
||||
that.$refs.webHookURL.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
options["url"] = this.actionWebHookURL
|
||||
}
|
||||
|
||||
this.addingThreshold.actions.push({
|
||||
action: this.actionCode,
|
||||
options: options
|
||||
})
|
||||
|
||||
// 还原
|
||||
this.cancelAction()
|
||||
},
|
||||
removeAction: function (index) {
|
||||
this.cancelAction()
|
||||
this.addingThreshold.actions.$remove(index)
|
||||
},
|
||||
actionName: function (actionCode) {
|
||||
let result = ""
|
||||
this.allActions.forEach(function (v) {
|
||||
if (v.code == actionCode) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="thresholdsJSON" :value="JSON.stringify(thresholds)"/>
|
||||
<table class="ui table celled">
|
||||
<thead>
|
||||
|
||||
<!-- 已有条件 -->
|
||||
<div v-if="thresholds.length > 0">
|
||||
<div class="ui label basic small" v-for="(threshold, index) in thresholds">
|
||||
<span v-for="(item, itemIndex) in threshold.items">[{{item.duration}}{{itemDurationUnitName(item.durationUnit)}}] {{itemName(item.item)}}
|
||||
<!-- 连通性 -->
|
||||
<span v-if="item.item == 'connectivity' && item.options != null && item.options.groups != null && item.options.groups.length > 0">[<span v-for="(group, groupIndex) in item.options.groups">{{group.name}} <span v-if="groupIndex != item.options.groups.length - 1"> </span></span>]</span>
|
||||
|
||||
<span class="grey">[{{itemOperatorName(item.operator)}}]</span> {{item.value}}{{itemUnitName(item.item)}} <span v-if="itemIndex != threshold.items.length - 1" style="font-style: italic">AND </span></span>
|
||||
->
|
||||
<span v-for="(action, actionIndex) in threshold.actions">{{actionName(action.action)}}
|
||||
<span v-if="action.action == 'switch'">到{{action.options.ips.join(", ")}}</span>
|
||||
<span v-if="action.action == 'webHook'" class="small grey">({{action.options.url}})</span>
|
||||
<span v-if="actionIndex != threshold.actions.length - 1" style="font-style: italic">AND </span></span>
|
||||
|
||||
<a href="" title="修改" @click.prevent="update(index)"><i class="icon pencil small"></i></a>
|
||||
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon small remove"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新阈值 -->
|
||||
<div v-if="isAdding" style="margin-top: 0.5em">
|
||||
<table class="ui table celled">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 50%; background: #f9fafb; border-bottom: 1px solid rgba(34,36,38,.1)">阈值</td>
|
||||
<th>动作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>统计项目</td>
|
||||
<th>统计周期</th>
|
||||
<th>操作符</th>
|
||||
<th>对比值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>平均请求数/秒</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 5em" v-model="avgRequests.duration"/>
|
||||
<span class="ui label">分钟</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="avgRequests.operator">
|
||||
<option value="lte">小于等于</option>
|
||||
<option value="gt">大于</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 6em" v-model="avgRequests.value"/>
|
||||
<span class="ui label">个</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="title">平均下行流量/秒</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 5em" v-model="avgTrafficOut.duration"/>
|
||||
<span class="ui label">分钟</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="avgTrafficOut.operator">
|
||||
<option value="lte">小于等于</option>
|
||||
<option value="gt">大于</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 6em" v-model="avgTrafficOut.value"/>
|
||||
<span class="ui label">MB</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>平均上行流量/秒</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 5em" v-model="avgTrafficIn.duration"/>
|
||||
<span class="ui label">分钟</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="avgTrafficIn.operator">
|
||||
<option value="lte">小于等于</option>
|
||||
<option value="gt">大于</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" style="width: 6em" v-model="avgTrafficIn.value"/>
|
||||
<span class="ui label">MB</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="comment">满足所有阈值条件时IP才会上线,否则下线。统计周期和对比值设置为0表示没有限制。各个输入项只支持整数数字。</p>
|
||||
<td style="background: white">
|
||||
<!-- 已经添加的项目 -->
|
||||
<div>
|
||||
<div v-for="(item, index) in addingThreshold.items" class="ui label basic small" style="margin-bottom: 0.5em;">
|
||||
[{{item.duration}}{{itemDurationUnitName(item.durationUnit)}}] {{itemName(item.item)}}
|
||||
<!-- 连通性 -->
|
||||
<span v-if="item.item == 'connectivity' && item.options != null && item.options.groups != null && item.options.groups.length > 0">[<span v-for="(group, groupIndex) in item.options.groups">{{group.name}} <span v-if="groupIndex != item.options.groups.length - 1"> </span></span>]</span>
|
||||
<span class="grey">[{{itemOperatorName(item.operator)}}]</span> {{item.value}}{{itemUnitName(item.item)}}
|
||||
<a href="" title="删除" @click.prevent="removeItem(index)"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 正在添加的项目 -->
|
||||
<div v-if="isAddingItem" style="margin-top: 0.8em">
|
||||
<table class="ui table">
|
||||
<tr>
|
||||
<td style="width: 6em">统计项目</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="itemCode">
|
||||
<option v-for="item in allItems" :value="item.code">{{item.name}}</option>
|
||||
</select>
|
||||
<p class="comment" v-for="item in allItems" v-if="item.code == itemCode">{{item.description}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>统计周期</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" v-model="itemDuration" style="width: 4em" maxlength="4" ref="itemDuration" @keyup.enter="confirmItem()" @keypress.enter.prevent="1"/>
|
||||
<span class="ui label">分钟</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>操作符</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="itemOperator">
|
||||
<option v-for="operator in allOperators" :value="operator.code">{{operator.name}}</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>对比值</td>
|
||||
<td>
|
||||
<div class="ui input right labeled">
|
||||
<input type="text" maxlength="20" style="width: 5em" v-model="itemValue" ref="itemValue" @keyup.enter="confirmItem()" @keypress.enter.prevent="1"/>
|
||||
<span class="ui label" v-for="item in allItems" v-if="item.code == itemCode">{{item.unit}}</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 连通性 -->
|
||||
<tr v-if="itemCode == 'connectivity'">
|
||||
<td>终端分组</td>
|
||||
<td style="font-weight: normal">
|
||||
<div style="zoom: 0.8"><report-node-groups-selector @change="changeReportGroups"></report-node-groups-selector></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 0.8em">
|
||||
<button class="ui button tiny" type="button" @click.prevent="confirmItem">确定</button>
|
||||
<a href="" title="取消" @click.prevent="cancelItem"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 0.8em" v-if="!isAddingItem">
|
||||
<button class="ui button tiny" type="button" @click.prevent="addItem">+</button>
|
||||
</div>
|
||||
</td>
|
||||
<td style="background: white">
|
||||
<!-- 已经添加的动作 -->
|
||||
<div>
|
||||
<div v-for="(action, index) in addingThreshold.actions" class="ui label basic small" style="margin-bottom: 0.5em">
|
||||
{{actionName(action.action)}}
|
||||
<span v-if="action.action == 'switch'">到{{action.options.ips.join(", ")}}</span>
|
||||
<span v-if="action.action == 'webHook'" class="small grey">({{action.options.url}})</span>
|
||||
<a href="" title="删除" @click.prevent="removeAction(index)"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 正在添加的动作 -->
|
||||
<div v-if="isAddingAction" style="margin-top: 0.8em">
|
||||
<table class="ui table">
|
||||
<tr>
|
||||
<td style="width: 6em">动作类型</td>
|
||||
<td>
|
||||
<select class="ui dropdown auto-width" v-model="actionCode">
|
||||
<option v-for="action in allActions" :value="action.code">{{action.name}}</option>
|
||||
</select>
|
||||
<p class="comment" v-for="action in allActions" v-if="action.code == actionCode">{{action.description}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- 切换 -->
|
||||
<tr v-if="actionCode == 'switch'">
|
||||
<td>备用IP *</td>
|
||||
<td>
|
||||
<textarea rows="2" v-model="actionBackupIPs" ref="actionBackupIPs"></textarea>
|
||||
<p class="comment">每行一个备用IP。</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- WebHook -->
|
||||
<tr v-if="actionCode == 'webHook'">
|
||||
<td>URL *</td>
|
||||
<td>
|
||||
<input type="text" maxlength="1000" placeholder="https://..." v-model="actionWebHookURL" ref="webHookURL" @keyup.enter="confirmAction()" @keypress.enter.prevent="1"/>
|
||||
<p class="comment">完整的URL,比如<code-label>https://example.com/webhook/api</code-label>,系统会在触发阈值的时候通过GET调用此URL。</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 0.8em">
|
||||
<button class="ui button tiny" type="button" @click.prevent="confirmAction">确定</button>
|
||||
<a href="" title="取消" @click.prevent="cancelAction"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 0.8em" v-if="!isAddingAction">
|
||||
<button class="ui button tiny" type="button" @click.prevent="addAction">+</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 添加阈值 -->
|
||||
<div>
|
||||
<button class="ui button tiny" :class="{disabled: (isAddingItem || isAddingAction)}" type="button" @click.prevent="confirm">确定</button>
|
||||
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!isAdding" style="margin-top: 0.5em">
|
||||
<button class="ui button tiny" type="button" @click.prevent="add">+</button>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
115
web/public/js/components/node/node-ip-address-thresholds-view.js
Normal file
115
web/public/js/components/node/node-ip-address-thresholds-view.js
Normal file
@@ -0,0 +1,115 @@
|
||||
// 节点IP阈值
|
||||
Vue.component("node-ip-address-thresholds-view", {
|
||||
props: ["v-thresholds"],
|
||||
data: function () {
|
||||
let thresholds = this.vThresholds
|
||||
if (thresholds == null) {
|
||||
thresholds = []
|
||||
} else {
|
||||
thresholds.forEach(function (v) {
|
||||
if (v.items == null) {
|
||||
v.items = []
|
||||
}
|
||||
if (v.actions == null) {
|
||||
v.actions = []
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
thresholds: thresholds,
|
||||
allItems: window.IP_ADDR_THRESHOLD_ITEMS,
|
||||
allOperators: [
|
||||
{
|
||||
"name": "小于等于",
|
||||
"code": "lte"
|
||||
},
|
||||
{
|
||||
"name": "大于",
|
||||
"code": "gt"
|
||||
},
|
||||
{
|
||||
"name": "不等于",
|
||||
"code": "neq"
|
||||
},
|
||||
{
|
||||
"name": "小于",
|
||||
"code": "lt"
|
||||
},
|
||||
{
|
||||
"name": "大于等于",
|
||||
"code": "gte"
|
||||
}
|
||||
],
|
||||
allActions: window.IP_ADDR_THRESHOLD_ACTIONS
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
itemName: function (item) {
|
||||
let result = ""
|
||||
this.allItems.forEach(function (v) {
|
||||
if (v.code == item) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
itemUnitName: function (itemCode) {
|
||||
let result = ""
|
||||
this.allItems.forEach(function (v) {
|
||||
if (v.code == itemCode) {
|
||||
result = v.unit
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
itemDurationUnitName: function (unit) {
|
||||
switch (unit) {
|
||||
case "minute":
|
||||
return "分钟"
|
||||
case "second":
|
||||
return "秒"
|
||||
case "hour":
|
||||
return "小时"
|
||||
case "day":
|
||||
return "天"
|
||||
}
|
||||
return unit
|
||||
},
|
||||
itemOperatorName: function (operator) {
|
||||
let result = ""
|
||||
this.allOperators.forEach(function (v) {
|
||||
if (v.code == operator) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
actionName: function (actionCode) {
|
||||
let result = ""
|
||||
this.allActions.forEach(function (v) {
|
||||
if (v.code == actionCode) {
|
||||
result = v.name
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<!-- 已有条件 -->
|
||||
<div v-if="thresholds.length > 0">
|
||||
<div class="ui label basic small" v-for="(threshold, index) in thresholds" style="margin-bottom: 0.5em">
|
||||
<span v-for="(item, itemIndex) in threshold.items">[{{item.duration}}{{itemDurationUnitName(item.durationUnit)}}] {{itemName(item.item)}}
|
||||
<!-- 连通性 -->
|
||||
<span v-if="item.item == 'connectivity' && item.options != null && item.options.groups != null && item.options.groups.length > 0">[<span v-for="(group, groupIndex) in item.options.groups">{{group.name}} <span v-if="groupIndex != item.options.groups.length - 1"> </span></span>]</span>
|
||||
|
||||
<span class="grey">[{{itemOperatorName(item.operator)}}]</span> {{item.value}}{{itemUnitName(item.item)}} <span v-if="itemIndex != threshold.items.length - 1" style="font-style: italic">AND </span></span>
|
||||
->
|
||||
<span v-for="(action, actionIndex) in threshold.actions">{{actionName(action.action)}}
|
||||
<span v-if="action.action == 'switch'">到{{action.options.ips.join(", ")}}</span>
|
||||
<span v-if="action.action == 'webHook'" class="small grey">({{action.options.url}})</span>
|
||||
<span v-if="actionIndex != threshold.actions.length - 1" style="font-style: italic">AND </span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
@@ -56,7 +56,7 @@ Vue.component("node-ip-addresses-box", {
|
||||
<span class="small grey" v-if="address.name.length == 0 && !address.canAccess">(不可访问)</span>
|
||||
<span class="small red" v-if="!address.isOn" title="未启用">[off]</span>
|
||||
<span class="small red" v-if="!address.isUp" title="已下线">[down]</span>
|
||||
<span class="small" v-if="address.thresholds != null && address.thresholds.length > 0">[阈值]</span>
|
||||
<span class="small" v-if="address.thresholds != null && address.thresholds.length > 0">[{{address.thresholds.length}}个阈值]</span>
|
||||
|
||||
<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>
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
// 监控节点分组选择
|
||||
Vue.component("report-node-groups-selector", {
|
||||
props: ["v-group-ids"],
|
||||
mounted: function () {
|
||||
let that = this
|
||||
Tea.action("/clusters/monitors/groups/options")
|
||||
.post()
|
||||
.success(function (resp) {
|
||||
that.groups = resp.data.groups.map(function (group) {
|
||||
group.isChecked = that.groupIds.$contains(group.id)
|
||||
return group
|
||||
})
|
||||
that.isLoaded = true
|
||||
})
|
||||
},
|
||||
data: function () {
|
||||
var groupIds = this.vGroupIds
|
||||
if (groupIds == null) {
|
||||
groupIds = []
|
||||
}
|
||||
|
||||
return {
|
||||
groups: [],
|
||||
groupIds: groupIds,
|
||||
isLoaded: false,
|
||||
allGroups: groupIds.length == 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
check: function (group) {
|
||||
group.isChecked = !group.isChecked
|
||||
this.groupIds = []
|
||||
let that = this
|
||||
this.groups.forEach(function (v) {
|
||||
if (v.isChecked) {
|
||||
that.groupIds.push(v.id)
|
||||
}
|
||||
})
|
||||
this.change()
|
||||
},
|
||||
change: function () {
|
||||
let that = this
|
||||
let groups = []
|
||||
this.groupIds.forEach(function (groupId) {
|
||||
let group = that.groups.$find(function (k, v) {
|
||||
return v.id == groupId
|
||||
})
|
||||
if (group == null) {
|
||||
return
|
||||
}
|
||||
groups.push({
|
||||
id: group.id,
|
||||
name: group.name
|
||||
})
|
||||
})
|
||||
this.$emit("change", groups)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
allGroups: function (b) {
|
||||
if (b) {
|
||||
this.groupIds = []
|
||||
this.groups.forEach(function (v) {
|
||||
v.isChecked = false
|
||||
})
|
||||
}
|
||||
|
||||
this.change()
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="reportNodeGroupIdsJSON" :value="JSON.stringify(groupIds)"/>
|
||||
<span class="disabled" v-if="isLoaded && groups.length == 0">还没有分组。</span>
|
||||
<div v-if="groups.length > 0">
|
||||
<div>
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" v-model="allGroups" id="all-group"/>
|
||||
<label for="all-group">全部分组</label>
|
||||
</div>
|
||||
<div class="ui divider" v-if="!allGroups"></div>
|
||||
</div>
|
||||
<div v-show="!allGroups">
|
||||
<div v-for="group in groups" :key="group.id" style="float: left; width: 7.6em; margin-bottom: 0.5em">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" v-model="group.isChecked" value="1" :id="'report-node-group-' + group.id" @click.prevent="check(group)"/>
|
||||
<label :for="'report-node-group-' + group.id">{{group.name}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
90
web/public/js/components/server/domains-box.js
Normal file
90
web/public/js/components/server/domains-box.js
Normal file
@@ -0,0 +1,90 @@
|
||||
// 域名列表
|
||||
Vue.component("domains-box", {
|
||||
props: ["v-domains"],
|
||||
data: function () {
|
||||
let domains = this.vDomains
|
||||
if (domains == null) {
|
||||
domains = []
|
||||
}
|
||||
return {
|
||||
domains: domains,
|
||||
isAdding: false,
|
||||
addingDomain: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add: function () {
|
||||
this.isAdding = true
|
||||
let that = this
|
||||
setTimeout(function () {
|
||||
that.$refs.addingDomain.focus()
|
||||
}, 100)
|
||||
},
|
||||
confirm: function () {
|
||||
let that = this
|
||||
|
||||
// 删除其中的空格
|
||||
this.addingDomain = this.addingDomain.replace(/\s/g, "")
|
||||
|
||||
if (this.addingDomain.length == 0) {
|
||||
teaweb.warn("请输入要添加的域名", function () {
|
||||
that.$refs.addingDomain.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 基本校验
|
||||
if (this.addingDomain[0] == "~") {
|
||||
let expr = this.addingDomain.substring(1)
|
||||
try {
|
||||
new RegExp(expr)
|
||||
} catch (e) {
|
||||
teaweb.warn("正则表达式错误:" + e.message, function () {
|
||||
that.$refs.addingDomain.focus()
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.domains.push(this.addingDomain)
|
||||
this.cancel()
|
||||
},
|
||||
remove: function (index) {
|
||||
this.domains.$remove(index)
|
||||
},
|
||||
cancel: function () {
|
||||
this.isAdding = false
|
||||
this.addingDomain = ""
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="domainsJSON" :value="JSON.stringify(domains)"/>
|
||||
<div v-if="domains.length > 0">
|
||||
<span class="ui label small basic" v-for="(domain, index) in domains">
|
||||
<span v-if="domain.length > 0 && domain[0] == '~'" class="grey" style="font-style: normal">[正则]</span>
|
||||
<span v-if="domain.length > 0 && domain[0] == '.'" class="grey" style="font-style: normal">[后缀]</span>
|
||||
<span v-if="domain.length > 0 && domain[0] == '*'" class="grey" style="font-style: normal">[泛域名]</span>
|
||||
{{domain}}
|
||||
<a href="" title="删除" @click.prevent="remove(index)"><i class="icon remove small"></i></a>
|
||||
</span>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
<div v-if="isAdding">
|
||||
<div class="ui fields">
|
||||
<div class="ui field">
|
||||
<input type="text" v-model="addingDomain" @keyup.enter="confirm()" @keypress.enter.prevent="1" ref="addingDomain" placeholder="*.xxx.com" size="30"/>
|
||||
</div>
|
||||
<div class="ui field">
|
||||
<button class="ui button tiny" type="button" @click.prevent="confirm">确定</button>
|
||||
<a href="" title="取消" @click.prevent="cancel"><i class="icon remove small"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="comment">支持普通域名(<code-label>example.com</code-label>)、泛域名(<code-label>*.example.com</code-label>)、域名后缀(以点号开头,如<code-label>.example.com</code-label>)和正则表达式(以波浪号开头,如<code-label>~.*.example.com</code-label>)。</p>
|
||||
<div class="ui divider"></div>
|
||||
</div>
|
||||
<div style="margin-top: 0.5em" v-if="!isAdding">
|
||||
<button class="ui button tiny" type="button" @click.prevent="add">+</button>
|
||||
</div>
|
||||
</div>`
|
||||
})
|
||||
@@ -9,7 +9,7 @@ Vue.component("origin-list-box", {
|
||||
methods: {
|
||||
createPrimaryOrigin: function () {
|
||||
teaweb.popup("/servers/server/settings/origins/addPopup?originType=primary&" + this.vParams, {
|
||||
height: "24em",
|
||||
height: "27em",
|
||||
callback: function (resp) {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
@@ -19,7 +19,7 @@ Vue.component("origin-list-box", {
|
||||
},
|
||||
createBackupOrigin: function () {
|
||||
teaweb.popup("/servers/server/settings/origins/addPopup?originType=backup&" + this.vParams, {
|
||||
height: "24em",
|
||||
height: "27em",
|
||||
callback: function (resp) {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
@@ -29,7 +29,7 @@ Vue.component("origin-list-box", {
|
||||
},
|
||||
updateOrigin: function (originId, originType) {
|
||||
teaweb.popup("/servers/server/settings/origins/updatePopup?originType=" + originType + "&" + this.vParams + "&originId=" + originId, {
|
||||
height: "24em",
|
||||
height: "27em",
|
||||
callback: function (resp) {
|
||||
teaweb.success("保存成功", function () {
|
||||
window.location.reload()
|
||||
@@ -85,10 +85,13 @@ Vue.component("origin-list-table", {
|
||||
</tr>
|
||||
</thead>
|
||||
<tr v-for="origin in vOrigins">
|
||||
<td :class="{disabled:!origin.isOn}">{{origin.addr}}
|
||||
<td :class="{disabled:!origin.isOn}"><a href="" @click.prevent="updateOrigin(origin.id)">{{origin.addr}} <i class="icon clone outline small"></i></a>
|
||||
<div v-if="origin.name.length > 0" style="margin-top: 0.5em">
|
||||
<tiny-basic-label>{{origin.name}}</tiny-basic-label>
|
||||
</div>
|
||||
<div v-if="origin.domains != null && origin.domains.length > 0">
|
||||
<grey-label v-for="domain in origin.domains">{{domain}}</grey-label>
|
||||
</div>
|
||||
</td>
|
||||
<td :class="{disabled:!origin.isOn}">{{origin.weight}}</td>
|
||||
<td>
|
||||
|
||||
@@ -1,143 +1,146 @@
|
||||
Vue.component("reverse-proxy-box", {
|
||||
props: ["v-reverse-proxy-ref", "v-reverse-proxy-config", "v-is-location", "v-family"],
|
||||
data: function () {
|
||||
let reverseProxyRef = this.vReverseProxyRef
|
||||
if (reverseProxyRef == null) {
|
||||
reverseProxyRef = {
|
||||
isPrior: false,
|
||||
isOn: false,
|
||||
reverseProxyId: 0
|
||||
}
|
||||
}
|
||||
props: ["v-reverse-proxy-ref", "v-reverse-proxy-config", "v-is-location", "v-is-group", "v-family"],
|
||||
data: function () {
|
||||
let reverseProxyRef = this.vReverseProxyRef
|
||||
if (reverseProxyRef == null) {
|
||||
reverseProxyRef = {
|
||||
isPrior: false,
|
||||
isOn: false,
|
||||
reverseProxyId: 0
|
||||
}
|
||||
}
|
||||
|
||||
let reverseProxyConfig = this.vReverseProxyConfig
|
||||
if (reverseProxyConfig == null) {
|
||||
reverseProxyConfig = {
|
||||
requestPath: "",
|
||||
stripPrefix: "",
|
||||
requestURI: "",
|
||||
requestHost: "",
|
||||
requestHostType: 0,
|
||||
addHeaders: [],
|
||||
connTimeout: {count: 0, unit: "second"},
|
||||
readTimeout: {count: 0, unit: "second"},
|
||||
idleTimeout: {count: 0, unit: "second"},
|
||||
maxConns: 0,
|
||||
maxIdleConns: 0
|
||||
}
|
||||
}
|
||||
if (reverseProxyConfig.addHeaders == null) {
|
||||
reverseProxyConfig.addHeaders = []
|
||||
}
|
||||
if (reverseProxyConfig.connTimeout == null) {
|
||||
reverseProxyConfig.connTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
if (reverseProxyConfig.readTimeout == null) {
|
||||
reverseProxyConfig.readTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
if (reverseProxyConfig.idleTimeout == null) {
|
||||
reverseProxyConfig.idleTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
let reverseProxyConfig = this.vReverseProxyConfig
|
||||
if (reverseProxyConfig == null) {
|
||||
reverseProxyConfig = {
|
||||
requestPath: "",
|
||||
stripPrefix: "",
|
||||
requestURI: "",
|
||||
requestHost: "",
|
||||
requestHostType: 0,
|
||||
addHeaders: [],
|
||||
connTimeout: {count: 0, unit: "second"},
|
||||
readTimeout: {count: 0, unit: "second"},
|
||||
idleTimeout: {count: 0, unit: "second"},
|
||||
maxConns: 0,
|
||||
maxIdleConns: 0
|
||||
}
|
||||
}
|
||||
if (reverseProxyConfig.addHeaders == null) {
|
||||
reverseProxyConfig.addHeaders = []
|
||||
}
|
||||
if (reverseProxyConfig.connTimeout == null) {
|
||||
reverseProxyConfig.connTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
if (reverseProxyConfig.readTimeout == null) {
|
||||
reverseProxyConfig.readTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
if (reverseProxyConfig.idleTimeout == null) {
|
||||
reverseProxyConfig.idleTimeout = {count: 0, unit: "second"}
|
||||
}
|
||||
|
||||
let forwardHeaders = [
|
||||
{
|
||||
name: "X-Real-IP",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-For",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-By",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-Host",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-Proto",
|
||||
isChecked: false
|
||||
}
|
||||
]
|
||||
forwardHeaders.forEach(function (v) {
|
||||
v.isChecked = reverseProxyConfig.addHeaders.$contains(v.name)
|
||||
})
|
||||
let forwardHeaders = [
|
||||
{
|
||||
name: "X-Real-IP",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-For",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-By",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-Host",
|
||||
isChecked: false
|
||||
},
|
||||
{
|
||||
name: "X-Forwarded-Proto",
|
||||
isChecked: false
|
||||
}
|
||||
]
|
||||
forwardHeaders.forEach(function (v) {
|
||||
v.isChecked = reverseProxyConfig.addHeaders.$contains(v.name)
|
||||
})
|
||||
|
||||
return {
|
||||
reverseProxyRef: reverseProxyRef,
|
||||
reverseProxyConfig: reverseProxyConfig,
|
||||
advancedVisible: false,
|
||||
family: this.vFamily,
|
||||
forwardHeaders: forwardHeaders
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"reverseProxyConfig.requestHostType": function (v) {
|
||||
let requestHostType = parseInt(v)
|
||||
if (isNaN(requestHostType)) {
|
||||
requestHostType = 0
|
||||
}
|
||||
this.reverseProxyConfig.requestHostType = requestHostType
|
||||
},
|
||||
"reverseProxyConfig.connTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.connTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.readTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.readTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.idleTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.idleTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.maxConns": function (v) {
|
||||
let maxConns = parseInt(v)
|
||||
if (isNaN(maxConns) || maxConns < 0) {
|
||||
maxConns = 0
|
||||
}
|
||||
this.reverseProxyConfig.maxConns = maxConns
|
||||
},
|
||||
"reverseProxyConfig.maxIdleConns": function (v) {
|
||||
let maxIdleConns = parseInt(v)
|
||||
if (isNaN(maxIdleConns) || maxIdleConns < 0) {
|
||||
maxIdleConns = 0
|
||||
}
|
||||
this.reverseProxyConfig.maxIdleConns = maxIdleConns
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isOn: function () {
|
||||
return (!this.vIsLocation || this.reverseProxyRef.isPrior) && this.reverseProxyRef.isOn
|
||||
},
|
||||
changeAdvancedVisible: function (v) {
|
||||
this.advancedVisible = v
|
||||
},
|
||||
changeAddHeader: function () {
|
||||
this.reverseProxyConfig.addHeaders = this.forwardHeaders.filter(function (v) {
|
||||
return v.isChecked
|
||||
}).map(function (v) {
|
||||
return v.name
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
return {
|
||||
reverseProxyRef: reverseProxyRef,
|
||||
reverseProxyConfig: reverseProxyConfig,
|
||||
advancedVisible: false,
|
||||
family: this.vFamily,
|
||||
forwardHeaders: forwardHeaders
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
"reverseProxyConfig.requestHostType": function (v) {
|
||||
let requestHostType = parseInt(v)
|
||||
if (isNaN(requestHostType)) {
|
||||
requestHostType = 0
|
||||
}
|
||||
this.reverseProxyConfig.requestHostType = requestHostType
|
||||
},
|
||||
"reverseProxyConfig.connTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.connTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.readTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.readTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.idleTimeout.count": function (v) {
|
||||
let count = parseInt(v)
|
||||
if (isNaN(count) || count < 0) {
|
||||
count = 0
|
||||
}
|
||||
this.reverseProxyConfig.idleTimeout.count = count
|
||||
},
|
||||
"reverseProxyConfig.maxConns": function (v) {
|
||||
let maxConns = parseInt(v)
|
||||
if (isNaN(maxConns) || maxConns < 0) {
|
||||
maxConns = 0
|
||||
}
|
||||
this.reverseProxyConfig.maxConns = maxConns
|
||||
},
|
||||
"reverseProxyConfig.maxIdleConns": function (v) {
|
||||
let maxIdleConns = parseInt(v)
|
||||
if (isNaN(maxIdleConns) || maxIdleConns < 0) {
|
||||
maxIdleConns = 0
|
||||
}
|
||||
this.reverseProxyConfig.maxIdleConns = maxIdleConns
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isOn: function () {
|
||||
if (this.vIsLocation || this.vIsGroup) {
|
||||
return this.reverseProxyRef.isPrior && this.reverseProxyRef.isOn
|
||||
}
|
||||
return this.reverseProxyRef.isOn
|
||||
},
|
||||
changeAdvancedVisible: function (v) {
|
||||
this.advancedVisible = v
|
||||
},
|
||||
changeAddHeader: function () {
|
||||
this.reverseProxyConfig.addHeaders = this.forwardHeaders.filter(function (v) {
|
||||
return v.isChecked
|
||||
}).map(function (v) {
|
||||
return v.name
|
||||
})
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<input type="hidden" name="reverseProxyRefJSON" :value="JSON.stringify(reverseProxyRef)"/>
|
||||
<input type="hidden" name="reverseProxyJSON" :value="JSON.stringify(reverseProxyConfig)"/>
|
||||
<table class="ui table selectable definition">
|
||||
<prior-checkbox :v-config="reverseProxyRef" v-if="vIsLocation"></prior-checkbox>
|
||||
<tbody v-show="!vIsLocation || reverseProxyRef.isPrior">
|
||||
<prior-checkbox :v-config="reverseProxyRef" v-if="vIsLocation || vIsGroup"></prior-checkbox>
|
||||
<tbody v-show="(!vIsLocation && !vIsGroup) || reverseProxyRef.isPrior">
|
||||
<tr>
|
||||
<td class="title">是否启用反向代理</td>
|
||||
<td>
|
||||
|
||||
@@ -15,7 +15,7 @@ Vue.component("server-group-selector", {
|
||||
let groupIds = this.groups.map(function (v) {
|
||||
return v.id.toString()
|
||||
}).join(",")
|
||||
teaweb.popup("/servers/components/groups/selectPopup?selectedGroupIds=" + groupIds, {
|
||||
teaweb.popup("/servers/groups/selectPopup?selectedGroupIds=" + groupIds, {
|
||||
callback: function (resp) {
|
||||
that.groups.push(resp.data.group)
|
||||
}
|
||||
@@ -23,7 +23,7 @@ Vue.component("server-group-selector", {
|
||||
},
|
||||
addGroup: function () {
|
||||
let that = this
|
||||
teaweb.popup("/servers/components/groups/createPopup", {
|
||||
teaweb.popup("/servers/groups/createPopup", {
|
||||
callback: function (resp) {
|
||||
that.groups.push(resp.data.group)
|
||||
}
|
||||
|
||||
@@ -73,9 +73,10 @@ window.teaweb = {
|
||||
// 加载
|
||||
if (typeof Pikaday == "undefined") {
|
||||
let that = this
|
||||
this.loadJS("/js/moment.min.js")
|
||||
this.loadJS("/js/pikaday.js", function () {
|
||||
that.datepicker(element, callback)
|
||||
this.loadJS("/js/moment.min.js", function () {
|
||||
that.loadJS("/js/pikaday.js", function () {
|
||||
that.datepicker(element, callback)
|
||||
})
|
||||
})
|
||||
this.loadCSS("/js/pikaday.css")
|
||||
this.loadCSS("/js/pikaday.theme.css")
|
||||
|
||||
@@ -57,6 +57,12 @@
|
||||
.left-box.without-tabbar {
|
||||
top: 3em;
|
||||
}
|
||||
.left-box.with-menu {
|
||||
top: 10em;
|
||||
}
|
||||
.left-box.without-menu {
|
||||
top: 6em;
|
||||
}
|
||||
.right-box {
|
||||
position: fixed;
|
||||
top: 7.5em;
|
||||
@@ -80,6 +86,12 @@ body.expanded .right-box {
|
||||
.right-box.without-tabbar {
|
||||
top: 3em;
|
||||
}
|
||||
.right-box.with-menu {
|
||||
top: 10em;
|
||||
}
|
||||
.right-box.without-menu {
|
||||
top: 6em;
|
||||
}
|
||||
.main.without-footer .left-box {
|
||||
bottom: 0.2em;
|
||||
}
|
||||
@@ -174,6 +186,9 @@ div.margin,
|
||||
p.margin {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.opacity-mask {
|
||||
opacity: 0.6;
|
||||
}
|
||||
/** 操作按钮容器 **/
|
||||
.op.one {
|
||||
width: 4em;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -63,7 +63,7 @@
|
||||
<a href="" class="item" title="点击切换界面风格" @click.prevent="changeTheme()"><i class="icon adjust"></i></a>
|
||||
|
||||
<!-- 企业版 -->
|
||||
<!-- <a :href="'/settings/authority'" class="item" title="企业版" :v-if="teaIsPlus"><i class="icon gem outline yellow"></i></a>-->
|
||||
<!-- <a :href="'/settings/authority'" class="item" title="商业版" :v-if="teaIsPlus"><i class="icon gem outline yellow"></i></a>-->
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<a :href="Tea.url('logout')" class="item" title="安全退出登录"><i class="icon sign out"></i>
|
||||
|
||||
@@ -103,6 +103,10 @@ div.margin, p.margin {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.opacity-mask {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
/** 操作按钮容器 **/
|
||||
.op.one {
|
||||
width: 4em;
|
||||
@@ -799,4 +803,4 @@ td {
|
||||
// input
|
||||
input.error {
|
||||
border: 1px #e0b4b4 solid !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,14 @@
|
||||
top: 3em;
|
||||
}
|
||||
|
||||
.left-box.with-menu {
|
||||
top: 10em;
|
||||
}
|
||||
|
||||
.left-box.without-menu {
|
||||
top: 6em;
|
||||
}
|
||||
|
||||
.right-box {
|
||||
position: fixed;
|
||||
top: 7.5em;
|
||||
@@ -107,6 +115,13 @@ body.expanded .right-box {
|
||||
top: 3em;
|
||||
}
|
||||
|
||||
.right-box.with-menu {
|
||||
top: 10em;
|
||||
}
|
||||
|
||||
.right-box.without-menu {
|
||||
top: 6em;
|
||||
}
|
||||
|
||||
// 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>
|
||||
9
web/views/@default/@left_menu_without_menu.html
Normal file
9
web/views/@default/@left_menu_without_menu.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="margin"></div>
|
||||
|
||||
<div class="left-box without-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>
|
||||
@@ -22,7 +22,7 @@
|
||||
<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
|
||||
<td>{{group.name}}</td>
|
||||
<td class="center">
|
||||
<span v-if="group.countNodes > 0">{{group.countNodes}}</span>
|
||||
<a :href="'/clusters/cluster/nodes?clusterId=' + clusterId + '&groupId=' + group.id" v-if="group.countNodes > 0">{{group.countNodes}}</a>
|
||||
<span v-else class="disabled">0</span>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<source-code-box id="cluster-config-box" type="text/yaml">rpc:
|
||||
endpoints: [ {{cluster.endpoints}} ]
|
||||
endpoints: [ {{cluster.endpoints}} ]
|
||||
clusterId: "{{cluster.uniqueId}}"
|
||||
secret: "{{cluster.secret}}"</source-code-box>
|
||||
</td>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
<second-menu>
|
||||
<menu-item :href="'/clusters/cluster/nodes?clusterId=' + clusterId">节点列表</menu-item>
|
||||
<span class="item disabled">|</span>
|
||||
<a :href="'/clusters/cluster/nodes?clusterId=' + clusterId" class="item" style="padding-right: 0">{{currentClusterName}} »</a>
|
||||
<a :href="'/clusters/cluster/nodes?clusterId=' + clusterId + '&groupId=' + node.group.id" v-if="node.group != null" class="item" style="padding-left: 0"> {{node.group.name}} »</a>
|
||||
<menu-item :href="'/clusters/cluster/node?clusterId=' + clusterId + '&nodeId=' + node.id" code="node"
|
||||
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>
|
||||
v-if="!teaIsPlus" style="padding-left: 0">"{{node.name}}"节点详情</menu-item>
|
||||
<menu-item :href="'/clusters/cluster/node/boards?clusterId=' + clusterId + '&nodeId=' + node.id" code="board" v-if="teaIsPlus" style="padding-left: 0">"{{node.name}}" 节点看板</menu-item>
|
||||
<menu-item :href="'/clusters/cluster/node/detail?clusterId=' + clusterId + '&nodeId=' + node.id" code="node" v-if="teaIsPlus" style="padding-left: 0">节点详情</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>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user