Files
EdgeCommon/pkg/nodeconfigs/node_actions.go

433 lines
12 KiB
Go
Raw Normal View History

2023-05-17 18:42:35 +08:00
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
//go:build plus
package nodeconfigs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
)
type NodeActionParam = string
const (
NodeActionParamDailyTrafficOut NodeActionParam = "dailyTrafficOut" // 节点日出口流量
NodeActionParamMonthlyTrafficOut NodeActionParam = "monthlyTrafficOut" // 节点月出口流量
// NodeActionParamTotalTraffic NodeActionParam = "totalTraffic" // 节点总流量 TODO 需要实现
NodeActionParamBandwidthIn NodeActionParam = "bandwidthIn" // 节点入口带宽
NodeActionParamBandwidthOut NodeActionParam = "bandwidthOut" // 节点出口带宽
NodeActionParamCPUUsage NodeActionParam = "cpuUsage" // 节点CPU用量百分比制0-100
NodeActionParamMemoryUsage NodeActionParam = "memoryUsage" // 节点内存用量百分比制0-100
NodeActionParamLoad NodeActionParam = "load" // 当前节点负载
// NodeActionParamConnectivity NodeActionParam = "connectivity" // 节点连通性 TODO 需要实现
NodeActionParamHealthCheckFailure NodeActionParam = "heathCheckFailure" // 节点健康检查失败
)
type NodeActionParamDefinition struct {
Name string `json:"name"`
Code string `json:"code"`
Description string `json:"description"`
Operators []NodeActionOperator `json:"operators"`
ValueName string `json:"valueName"`
ValueType string `json:"valueType"`
HasDuration bool `json:"hasDuration"`
2023-05-17 18:42:35 +08:00
}
func FindAllNodeActionParamDefinitions() []*NodeActionParamDefinition {
return []*NodeActionParamDefinition{
{
Code: NodeActionParamBandwidthOut,
Name: "节点出口带宽",
Description: "当前节点当前时间点的出口平均带宽(从节点发送到客户端)。",
Operators: allNodeActionNumberOperators,
ValueName: "对比带宽",
ValueType: "bandwidth",
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamBandwidthIn,
Name: "节点入口带宽",
Description: "当前节点当前时间点的入口平均带宽(从客户端发送到节点)。",
Operators: allNodeActionNumberOperators,
ValueName: "对比带宽",
ValueType: "bandwidth",
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamMonthlyTrafficOut,
Name: "节点当月流量",
Description: "当前节点在当月的出口流量。",
Operators: allNodeActionNumberOperators,
ValueName: "对比流量",
ValueType: "traffic",
HasDuration: false,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamDailyTrafficOut,
Name: "节点当日流量",
Description: "当前节点在当天的出口流量。",
Operators: allNodeActionNumberOperators,
ValueName: "对比流量",
ValueType: "traffic",
HasDuration: false,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamCPUUsage,
Name: "节点CPU利用率",
Description: "节点当前CPU利用率取值范围为0-100。",
Operators: allNodeActionNumberOperators,
ValueName: "CPU利用率",
ValueType: "cpu",
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamMemoryUsage,
Name: "节点内存利用率",
Description: "节点当前内存利用率取值范围为0-100。",
Operators: allNodeActionNumberOperators,
ValueName: "内存利用率",
ValueType: "memory",
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamLoad,
Name: "节点负载",
Description: "节点当前负载取值范围为0-∞通常超过10表示系统负载较重。",
Operators: allNodeActionNumberOperators,
ValueName: "系统负载",
ValueType: "load",
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionParamHealthCheckFailure,
Name: "健康检查失败",
Description: "当前节点任一IP健康检查失败。",
Operators: nil,
HasDuration: true,
2023-05-17 18:42:35 +08:00
},
}
}
type NodeActionOperator = string
const (
NodeActionOperatorGt NodeActionOperator = "gt"
NodeActionOperatorGte NodeActionOperator = "gte"
NodeActionOperatorLt NodeActionOperator = "lt"
NodeActionOperatorLte NodeActionOperator = "lte"
NodeActionOperatorEq NodeActionOperator = "eq"
)
var allNodeActionNumberOperators = []NodeActionOperator{NodeActionOperatorGt, NodeActionOperatorGte, NodeActionOperatorLt, NodeActionOperatorLte, NodeActionOperatorEq}
func FindAllNodeActionOperatorDefinitions() []*shared.Definition {
return []*shared.Definition{
{
Code: NodeActionOperatorGt,
Name: "大于()",
},
{
Code: NodeActionOperatorGte,
Name: "大于等于(≥)",
},
{
Code: NodeActionOperatorLt,
Name: "小于()",
},
{
Code: NodeActionOperatorLte,
Name: "小于等于(≤)",
},
{
Code: NodeActionOperatorEq,
Name: "等于(=)",
},
}
}
// NodeActionCondConnector 条件之间关系
type NodeActionCondConnector = string
const (
NodeActionCondConnectorAnd NodeActionCondConnector = "and"
NodeActionCondConnectorOr NodeActionCondConnector = "or"
)
type NodeActionCond struct {
Param NodeActionParam `json:"param"` // 参数名
Operator NodeActionOperator `json:"operator"` // 操作符
Value any `json:"value"` // 对比值
}
func (this *NodeActionCond) Match(value any) bool {
var paramDef *NodeActionParamDefinition
for _, paramDef2 := range FindAllNodeActionParamDefinitions() {
if paramDef2.Code == this.Param {
paramDef = paramDef2
break
}
}
if paramDef == nil {
return false
}
switch paramDef.ValueType {
case "bandwidth":
if value != nil && !this.isScalar(value) {
var value1Map = maps.NewMap(value)
value = this.toBandwidthBits(value1Map)
}
var value2Map = maps.NewMap(this.Value)
return this.compare(value, this.toBandwidthBits(value2Map))
case "traffic":
if value != nil && !this.isScalar(value) {
var value1Map = maps.NewMap(value)
value = this.toTrafficBytes(value1Map)
}
var value2Map = maps.NewMap(this.Value)
return this.compare(value, this.toTrafficBytes(value2Map))
case "cpu":
return this.compare(value, this.Value)
case "memory":
return this.compare(value, this.Value)
case "load":
return this.compare(value, this.Value)
case "":
return true
}
return false
}
func (this *NodeActionCond) compare(value1, value2 any) bool {
switch this.Operator {
case NodeActionOperatorGt:
return types.Int64(value1) > types.Int64(value2)
case NodeActionOperatorGte:
return types.Int64(value1) >= types.Int64(value2)
case NodeActionOperatorLt:
return types.Int64(value1) < types.Int64(value2)
case NodeActionOperatorLte:
return types.Int64(value1) <= types.Int64(value2)
case NodeActionOperatorEq:
return types.Int64(value1) == types.Int64(value2)
}
return false
}
func (this *NodeActionCond) toBandwidthBits(m maps.Map) int64 {
var count = m.GetInt64("count")
var unit = m.GetString("unit")
if count <= 0 {
return 0
}
switch unit {
case "b":
return count
case "kb":
return count << 10
case "mb":
return count << 20
case "gb":
return count << 30
case "tb":
return count << 40
}
return 0
}
func (this *NodeActionCond) toTrafficBytes(m maps.Map) int64 {
var count = m.GetInt64("count")
var unit = m.GetString("unit")
if count <= 0 {
return 0
}
switch unit {
case "b":
return count
case "kb":
return count << 10
case "mb":
return count << 20
case "gb":
return count << 30
case "tb":
return count << 40
case "pb":
return count << 50
case "eb":
return count << 60
}
return 0
}
func (this *NodeActionCond) isScalar(value any) bool {
if value == nil {
return false
}
switch value.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint64, float32, float64, string, bool:
return true
}
return false
}
type NodeActionCondsConfig struct {
Conds []*NodeActionCond `json:"conds"`
Connector NodeActionCondConnector `json:"connector"`
}
func NewNodeActionCondsConfig() *NodeActionCondsConfig {
return &NodeActionCondsConfig{
Connector: NodeActionCondConnectorAnd,
}
}
func (this *NodeActionCondsConfig) Match(valueGetter func(param NodeActionParam) (value any, err error)) (bool, error) {
if len(this.Conds) == 0 {
return false, nil
}
for index, cond := range this.Conds {
value, err := valueGetter(cond.Param)
if err != nil {
return false, err
}
var b = cond.Match(value)
if !b {
if this.Connector == NodeActionCondConnectorAnd {
return false, nil
}
// 如果是最后一个OR条件则直接返回false
if index == len(this.Conds)-1 {
return false, nil
}
} else {
if this.Connector == NodeActionCondConnectorOr {
return true, nil
}
// 如果是最后一个AND条件则直接返回true
if index == len(this.Conds)-1 {
return true, nil
}
}
}
return true, nil
}
// NodeActionCode 动作代号
type NodeActionCode = string
const (
NodeActionCodeUp NodeActionCode = "up" // 上线
NodeActionCodeDown NodeActionCode = "down" // 下线
NodeActionCodeSwitchToBackupNodesInCluster NodeActionCode = "switchToBackupNodesInCluster" // 切换到集群备用节点
NodeActionCodeSwitchToBackupNodesInGroup NodeActionCode = "switchToBackupNodesInGroup" // 切换到分组备用节点
NodeActionCodeSwitchToBackupIP NodeActionCode = "switchToBackupIP" // 切换到备用IP
NodeActionCodeEnableBackupNodesInCluster NodeActionCode = "enableBackupNodesInCluster" // 启用集群备用节点
NodeActionCodeEnableBackupNodesInGroup NodeActionCode = "enableBackupNodesInGroup" // 启用分组备用节点
NodeActionCodeEnableBackupIP NodeActionCode = "enableBackupIP" // 启用备用IP
NodeActionCodeWebHook NodeActionCode = "webHook" // WebHook
)
func FindAllNodeActionDefinitions() []*shared.Definition {
return []*shared.Definition{
{
Code: NodeActionCodeUp,
Name: "上线当前节点",
Description: "将当前节点状态设置为在线。",
},
{
Code: NodeActionCodeDown,
Name: "下线当前节点",
Description: "将当前节点状态设置为离线。",
},
{
Code: NodeActionCodeSwitchToBackupNodesInCluster,
Name: "切换到集群备用节点",
Description: "下线当前节点并启用节点所在集群备用节点。",
},
{
Code: NodeActionCodeSwitchToBackupNodesInGroup,
Name: "切换到分组备用节点",
Description: "下线当前节点并启用节点所在分组备用节点。",
},
{
Code: NodeActionCodeSwitchToBackupIP,
Name: "切换到备用IP",
Description: "将当前节点的IP切换到当前节点配置的备用IP。",
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionCodeEnableBackupNodesInCluster,
Name: "启用集群备用节点",
Description: "保持当前节点并启用节点所在集群备用节点。",
},
{
Code: NodeActionCodeEnableBackupNodesInGroup,
Name: "启用分组备用节点",
Description: "保持当前节点并启用节点所在分组备用节点。",
},
{
Code: NodeActionCodeEnableBackupIP,
Name: "启用备用IP",
Description: "保持当前节点的IP并启用当前节点配置的备用IP。",
2023-05-17 18:42:35 +08:00
},
{
Code: NodeActionCodeWebHook,
Name: "WebHook",
Description: "通过WebHook发送通知到URL。",
2023-05-17 18:42:35 +08:00
},
}
}
func FindNodeActionDefinition(code NodeActionCode) *shared.Definition {
for _, def := range FindAllNodeActionDefinitions() {
if def.Code == code {
return def
}
}
return nil
}
func FindNodeActionName(code NodeActionCode) string {
var def = FindNodeActionDefinition(code)
if def != nil {
return def.Name
}
return ""
}
// NodeActionConfig 动作配置
type NodeActionConfig struct {
Code NodeActionCode `json:"code"` // 动作代号
Params any `json:"params"` // 动作参数
}
func NewNodeActionConfig() *NodeActionConfig {
return &NodeActionConfig{}
}
type NodeActionCodeWebHookParams struct {
URL string `json:"url"` // URL路径
}
// NodeActionStatus 动作状态
type NodeActionStatus struct {
ActionId int64 `json:"actionId"` // 动作ID
CreatedAt int64 `json:"createdAt"` // 状态创建时间
Conds *NodeActionCondsConfig `json:"conds"` // 动作条件
Action *NodeActionConfig `json:"action"` // 动作配置
ExpiresAt int64 `json:"expiresAt"` // 过期时间
}