This commit is contained in:
unknown
2026-02-04 20:27:13 +08:00
commit 3b042d1dad
9410 changed files with 1488147 additions and 0 deletions

View File

@@ -0,0 +1,879 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build plus
package models
import (
"encoding/json"
"errors"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/dns"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
"github.com/TeaOSLab/EdgeAPI/internal/zero"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
timeutil "github.com/iwind/TeaGo/utils/time"
"net/http"
"strings"
"sync"
"time"
)
// 从集群加载其他服务
func (this *NodeDAO) loadServersFromCluster(tx *dbs.Tx, clusterId int64, serverIdMap map[int64]zero.Zero) ([]*Server, error) {
// 高防实例
// TODO 将来支持部署到具体节点
objectCodes, err := SharedADPackageInstanceDAO.FindAvailableObjectCodesInCluster(tx, clusterId)
if err != nil {
return nil, err
}
var resultServers = []*Server{}
for _, objectCode := range objectCodes {
objectType, objectValue := SharedUserADInstanceDAO.SplitObjectCode(objectCode)
if objectType == ADObjectTypeServer && len(objectValue) > 0 {
var serverId = types.Int64(objectValue)
if serverId > 0 {
_, ok := serverIdMap[serverId]
if !ok {
serverIdMap[serverId] = zero.Zero{}
// TODO 将来支持一次性读取一批server
server, err := SharedServerDAO.FindEnabledServer(tx, serverId)
if err != nil {
return nil, err
}
if server != nil && server.IsOn {
resultServers = append(resultServers, server)
}
}
}
}
}
return resultServers, nil
}
// 组合扩展配置
func (this *NodeDAO) composeExtConfig(tx *dbs.Tx, config *nodeconfigs.NodeConfig, clusterIds []int64, cacheMap *utils.CacheMap) error {
// 脚本
// scripts
scriptConfigs, err := SharedScriptHistoryDAO.ComposeScriptConfigs(tx, 0, cacheMap)
if err != nil {
return err
}
config.CommonScripts = scriptConfigs
// 套餐
// plan
plans, err := SharedPlanDAO.FindAllAvailableBasicPlans(tx)
if err != nil {
return err
}
var planMap = map[int64]*serverconfigs.PlanConfig{}
for _, plan := range plans {
planMap[int64(plan.Id)] = &serverconfigs.PlanConfig{
Id: int64(plan.Id),
Name: plan.Name,
BandwidthLimitPerNode: plan.DecodeBandwidthLimitPerNode(),
TrafficLimit: plan.DecodeTrafficLimit(),
MaxUploadSize: plan.DecodeMaxUploadSize(),
}
}
config.Plans = planMap
// 父节点
// 这里不需要进行 teaconst.IsPlus 判断是为了防止在API节点升级过程中或者用户授权过期又激活时节点无法正常更新
if config.Level == 1 {
parentNodes, err := SharedNodeDAO.FindParentNodeConfigs(tx, config.Id, config.GroupId, clusterIds, types.Int(config.Level))
if err != nil {
return err
}
config.ParentNodes = parentNodes
}
return nil
}
// UpdateNodeSchedule 修改智能调度信息
// offlineDay YYYYMMDD
func (this *NodeDAO) UpdateNodeSchedule(tx *dbs.Tx, nodeId int64, offlineDay string, isBackupForCluster bool, isBackupForGroup bool, backupIPs []string) error {
if nodeId <= 0 {
return errors.New("invalid nodeId")
}
var op = NewNodeOperator()
op.Id = nodeId
if len(offlineDay) > 0 && !regexputils.YYYYMMDD.MatchString(offlineDay) {
return errors.New("invalid 'offlineDay' value: " + offlineDay)
}
op.OfflineDay = offlineDay
if offlineDay >= timeutil.Format("Ymd") {
op.OfflineIsNotified = false
}
op.IsBackupForCluster = isBackupForCluster
op.IsBackupForGroup = isBackupForGroup
if backupIPs == nil {
backupIPs = []string{}
}
backupIPsJSON, err := json.Marshal(backupIPs)
if err != nil {
return err
}
op.BackupIPs = backupIPsJSON
err = this.Save(tx, op)
if err != nil {
return err
}
return this.NotifyDNSUpdate(tx, nodeId)
}
// FindAllNodeScheduleWithClusterId 查找集群下的节点
func (this *NodeDAO) FindAllNodeScheduleWithClusterId(tx *dbs.Tx, clusterId int64) (result []*Node, err error) {
if clusterId <= 0 {
return
}
_, err = this.Query(tx).
Result("id", "name", "groupId", "offlineDay", "backupIPs", "isBackupForCluster", "isBackupForGroup", "actionStatus").
Attr("clusterId", clusterId).
State(NodeStateEnabled).
Slice(&result).
FindAll()
return
}
// FindNodeSchedule 查找智能调度信息
func (this *NodeDAO) FindNodeSchedule(tx *dbs.Tx, nodeId int64) (node *Node, err error) {
if nodeId <= 0 {
err = errors.New("invalid nodeId")
return
}
one, err := this.Query(tx).
Result("id", "offlineDay", "isBackupForCluster", "isBackupForGroup", "backupIPs", "actionStatus").
Pk(nodeId).
Find()
if err != nil || one == nil {
return nil, err
}
return one.(*Node), nil
}
// NotifyNodesWithOfflineDay 通知租期到期的节点
var notifiedOfflineDayMap = map[string]bool{} // DAY_{END|00}
var notifiedOfflineDayLocker = &sync.Mutex{}
func (this *NodeDAO) NotifyNodesWithOfflineDay(tx *dbs.Tx) error {
// 每天最多两次
var cacheKey = timeutil.Format("Ymd")
var endHour = 23
if time.Now().Hour() == endHour {
cacheKey += "_END"
} else {
cacheKey += "_00"
}
notifiedOfflineDayLocker.Lock()
if notifiedOfflineDayMap[cacheKey] {
notifiedOfflineDayLocker.Unlock()
return nil
}
notifiedOfflineDayLocker.Unlock()
var query = this.Query(tx).
State(NodeStateEnabled).
Result("id", "clusterId", "offlineDay").
Attr("offlineIsNotified", false)
if time.Now().Hour() == endHour {
// 提前将今天到期的也下线
query.
Where("(LENGTH(offlineDay) > 0 AND offlineDay<=:offlineDay)").
Param("offlineDay", timeutil.Format("Ymd"))
} else {
// 将以往的下线
query.
Where("(LENGTH(offlineDay) > 0 AND offlineDay<:offlineDay)").
Param("offlineDay", timeutil.Format("Ymd"))
}
nodeOnes, err := query.
FindAll()
if err != nil {
return err
}
var clusterIdMap = map[int64]bool{} // clusterId => bool
for _, nodeOne := range nodeOnes {
var node = nodeOne.(*Node)
var offlineDay = node.OfflineDay
if len(offlineDay) != 8 {
continue
}
var realOfflineDay = offlineDay[:4] + "-" + offlineDay[4:6] + "-" + offlineDay[6:]
var nodeId = int64(node.Id)
var clusterId = int64(node.ClusterId)
if clusterId > 0 && !clusterIdMap[clusterId] {
err = dns.SharedDNSTaskDAO.CreateClusterTask(tx, clusterId, dns.DNSTaskTypeClusterNodesChange)
if err != nil {
return err
}
clusterIdMap[clusterId] = true
}
// 设置为已通知
err = this.Query(tx).
Pk(nodeId).
Set("offlineIsNotified", true).
UpdateQuickly()
if err != nil {
return err
}
// 发送消息
err = SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, MessageTypeNodeOfflineDay, MessageLevelError, "节点租期已结束("+realOfflineDay+"", "节点租期已结束("+realOfflineDay+")", nil, true)
if err != nil {
return err
}
}
notifiedOfflineDayLocker.Lock()
notifiedOfflineDayMap[cacheKey] = true
notifiedOfflineDayLocker.Unlock()
return nil
}
// ResetNodeActionStatus 重置节点动作状态
// checkConds 是否检查条件
func (this *NodeDAO) ResetNodeActionStatus(tx *dbs.Tx, nodeId int64, checkConds bool) error {
if nodeId <= 0 {
return errors.New("invalid 'nodeId'")
}
nodeOne, err := this.Query(tx).
Pk(nodeId).
Result("clusterId", "actionStatus").
Find()
if err != nil {
return err
}
if nodeOne == nil {
return nil
}
var node = nodeOne.(*Node)
var clusterId = int64(node.ClusterId)
if clusterId <= 0 {
return nil
}
if len(node.ActionStatus) == 0 {
return nil
}
if checkConds {
var actionStatus = &nodeconfigs.NodeActionStatus{}
err = json.Unmarshal(node.ActionStatus, actionStatus)
if err != nil {
return err
}
// 处理健康检查的特殊情况
if actionStatus.ActionId > 0 {
upAddressId, err := SharedNodeIPAddressDAO.FindFirstNodeAccessIPAddressId(tx, nodeId, true, nodeconfigs.NodeRoleNode)
if err != nil {
return err
}
if upAddressId <= 0 {
if actionStatus.DurationSeconds <= 0 || actionStatus.DurationSeconds > 3600 {
actionStatus.DurationSeconds = 3600
}
actionStatus.ExpiresAt += actionStatus.DurationSeconds
actionStatusJSON, err := json.Marshal(actionStatus)
if err != nil {
return err
}
err = this.Query(tx).
Pk(nodeId).
Set("actionStatus", actionStatusJSON).
UpdateQuickly()
if err != nil {
return err
}
// 发送通知
return SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, MessageTypeNodeSchedule, MessageLevelError, "节点未能从智能调度状态中恢复", "节点由于没有可以正常访问的IP所以未能从智能调度状态中恢复将在下次循环中再次尝试。", nil, true)
}
}
}
err = this.Query(tx).
Pk(nodeId).
Set("actionStatus", dbs.SQL("NULL")).
UpdateQuickly()
if err != nil {
return err
}
err = dns.SharedDNSTaskDAO.CreateClusterTask(tx, clusterId, dns.DNSTaskTypeClusterNodesChange)
if err != nil {
return err
}
// 发送通知
return SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, MessageTypeNodeSchedule, MessageLevelSuccess, "节点已从智能调度状态中恢复", "节点已从智能调度状态中恢复。", nil, true)
}
// FindNodeIdsWithExpiredActions 查找动作状态已过期的节点ID
func (this *NodeDAO) FindNodeIdsWithExpiredActions(tx *dbs.Tx) (nodeIds []int64, err error) {
ones, err := this.Query(tx).
Result("id").
State(NodeStateEnabled).
Where("(actionStatus IS NOT NULL AND JSON_EXTRACT(actionStatus, '$.expiresAt')<:currentTime)").
Param("currentTime", time.Now().Unix()).
FindAll()
if err != nil {
return nil, err
}
for _, one := range ones {
nodeIds = append(nodeIds, int64(one.(*Node).Id))
}
return
}
// CopyNodeActionsToGroup 复制动作设置到分组
func (this *NodeDAO) CopyNodeActionsToGroup(tx *dbs.Tx, nodeId int64) error {
groupId, err := this.Query(tx).
Pk(nodeId).
Result("groupId").
FindInt64Col(0)
if err != nil {
return err
}
if groupId <= 0 {
return nil
}
const nodeRole = nodeconfigs.NodeRoleNode
actions, err := SharedNodeActionDAO.FindAllNodeActions(tx, nodeRole, nodeId)
if err != nil {
return err
}
nodeOnes, err := this.Query(tx).
ResultPk().
Attr("groupId", groupId).
Neq("id", nodeId).
State(NodeStateEnabled).
FindAll()
if err != nil {
return err
}
for _, nodeOne := range nodeOnes {
var targetNodeId = int64(nodeOne.(*Node).Id)
err = SharedNodeActionDAO.DisableAllNodeActions(tx, nodeRole, targetNodeId)
if err != nil {
return err
}
for _, action := range actions {
err = SharedNodeActionDAO.DuplicateNodeAction(tx, action, nodeRole, targetNodeId)
if err != nil {
return err
}
}
}
return nil
}
// CopyNodeActionsToCluster 复制动作设置到集群
func (this *NodeDAO) CopyNodeActionsToCluster(tx *dbs.Tx, nodeId int64) error {
clusterId, err := this.Query(tx).
Pk(nodeId).
Result("clusterId").
FindInt64Col(0)
if err != nil {
return err
}
if clusterId <= 0 {
return nil
}
const nodeRole = nodeconfigs.NodeRoleNode
actions, err := SharedNodeActionDAO.FindAllNodeActions(tx, nodeRole, nodeId)
if err != nil {
return err
}
nodeOnes, err := this.Query(tx).
ResultPk().
Attr("clusterId", clusterId).
Neq("id", nodeId).
State(NodeStateEnabled).
FindAll()
if err != nil {
return err
}
for _, nodeOne := range nodeOnes {
var targetNodeId = int64(nodeOne.(*Node).Id)
err = SharedNodeActionDAO.DisableAllNodeActions(tx, nodeRole, targetNodeId)
if err != nil {
return err
}
for _, action := range actions {
err = SharedNodeActionDAO.DuplicateNodeAction(tx, action, nodeRole, targetNodeId)
if err != nil {
return err
}
}
}
return nil
}
// FireNodeActions 触发动作
func (this *NodeDAO) FireNodeActions(tx *dbs.Tx, nodeId int64, paramCode nodeconfigs.NodeActionParam, paramValue any) error {
// 只有Plus会员才会触发
if !teaconst.IsPlus {
return nil
}
nodeOne, err := this.Query(tx).
Pk(nodeId).
Result("isBackupForCluster", "isBackupForGroup", "actionStatus", "offlineDay").
State(NodeStateEnabled).
Find()
if err != nil {
return err
}
if nodeOne == nil {
return nil
}
var node = nodeOne.(*Node)
// 备用节点不处理
if node.IsBackupForCluster || node.IsBackupForGroup {
return nil
}
// 是否已下线
if node.CheckIsOffline() {
return nil
}
// 当前节点是否已经在动作状态中
var statusJSON = node.ActionStatus
if len(statusJSON) == 0 {
return this.fireNodeActions(tx, nodeId, paramCode, paramValue)
}
var status = &nodeconfigs.NodeActionStatus{}
err = json.Unmarshal(statusJSON, status)
if err != nil {
return err
}
if status.ActionId <= 0 {
return this.fireNodeActions(tx, nodeId, paramCode, paramValue)
}
// 如果现在已经处于切换状态,则不做任何处理(使用任务来处理)
return nil
}
// 触发某个参数相关的动作
func (this *NodeDAO) fireNodeActions(tx *dbs.Tx, nodeId int64, paramCode nodeconfigs.NodeActionParam, paramValue any) error {
actions, err := SharedNodeActionDAO.FindAllAvailableNodeActionsWithParam(tx, nodeconfigs.NodeRoleNode, nodeId, paramCode)
if err != nil {
return err
}
if len(actions) == 0 {
return nil
}
for _, action := range actions {
var condsConfig = action.DecodeCondsConfig()
b, err := condsConfig.Match(func(param nodeconfigs.NodeActionParam) (value any, err error) {
if paramCode == param && paramValue != nil {
return paramValue, nil
}
switch param {
case nodeconfigs.NodeActionParamDailyTrafficOut:
var today = timeutil.Format("Ymd")
stat, err := SharedNodeTrafficDailyStatDAO.SumDailyStat(tx, nodeconfigs.NodeRoleNode, nodeId, today, today)
if err != nil {
return nil, err
}
if stat != nil {
value = stat.Bytes
} else {
value = 0
}
case nodeconfigs.NodeActionParamMonthlyTrafficOut:
var monthBegin = timeutil.Format("Ym01")
var today = timeutil.Format("Ymd")
stat, err := SharedNodeTrafficDailyStatDAO.SumDailyStat(tx, nodeconfigs.NodeRoleNode, nodeId, monthBegin, today)
if err != nil {
return nil, err
}
if stat != nil {
value = stat.Bytes
} else {
value = 0
}
case nodeconfigs.NodeActionParamBandwidthIn:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemAllTraffic)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetInt64("avgInBytes") * 8
} else {
value = 0
}
case nodeconfigs.NodeActionParamBandwidthOut:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemAllTraffic)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetInt64("avgOutBytes") * 8
} else {
value = 0
}
case nodeconfigs.NodeActionParamUDPDPSIn:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemAllTraffic)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetInt64("avgUDPInDatagrams")
} else {
value = 0
}
case nodeconfigs.NodeActionParamUDPDPSOut:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemAllTraffic)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetInt64("avgUDPOutDatagrams")
} else {
value = 0
}
case nodeconfigs.NodeActionParamCPUUsage:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemCPU)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetFloat64("usage") * 100
} else {
value = 0
}
case nodeconfigs.NodeActionParamMemoryUsage:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemMemory)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetFloat64("usage") * 100
} else {
value = 0
}
case nodeconfigs.NodeActionParamLoad:
itemValue, err := SharedNodeValueDAO.FindLatestNodeValue(tx, nodeconfigs.NodeRoleNode, nodeId, nodeconfigs.NodeValueItemLoad)
if err != nil {
return nil, err
}
if itemValue == nil {
return 0, nil
}
var mapValue = itemValue.DecodeMapValue()
if mapValue != nil {
value = mapValue.GetInt64("load5m")
} else {
value = 0
}
case nodeconfigs.NodeActionParamHealthCheckFailure:
// 不需要返回值
}
return
})
if err != nil {
return err
}
if b {
return this.runAction(tx, nodeId, int64(action.Id), condsConfig, action.DecodeAction(), action.DecodeDuration())
}
}
return nil
}
// 执行动作
func (this *NodeDAO) runAction(tx *dbs.Tx, nodeId int64, actionId int64, condsConfig *nodeconfigs.NodeActionCondsConfig, actionConfig *nodeconfigs.NodeActionConfig, duration *shared.TimeDuration) error {
if actionConfig == nil {
return errors.New("'actionConfig' should not be nil")
}
// 暂时不处理secondary clusters
clusterId, err := this.Query(tx).
Result("clusterId").
Pk(nodeId).
FindInt64Col(0)
if err != nil {
return err
}
if clusterId == 0 {
return nil
}
var status = &nodeconfigs.NodeActionStatus{
ActionId: actionId,
Conds: condsConfig,
Action: actionConfig,
CreatedAt: time.Now().Unix(),
}
if duration != nil {
var seconds = duration.Seconds()
if seconds > 0 {
status.ExpiresAt = time.Now().Unix() + seconds
status.DurationSeconds = seconds
}
}
if status.ExpiresAt <= 0 {
status.ExpiresAt = time.Now().Unix() + 3600 // 默认1个小时
}
if status.DurationSeconds <= 0 {
status.DurationSeconds = 3600
}
// 特殊情况下的过期时间
if condsConfig != nil {
var now = time.Now()
for _, cond := range condsConfig.Conds {
if cond.Param == nodeconfigs.NodeActionParamDailyTrafficOut {
// 当天结束
var expiresAt = now.Unix() - int64(now.Hour()*3600) - int64(now.Minute()*60) - int64(now.Second()) + 86400
if expiresAt > status.ExpiresAt {
status.ExpiresAt = expiresAt
}
} else if cond.Param == nodeconfigs.NodeActionParamMonthlyTrafficOut {
// 当月结束
var endDay = 32 - time.Date(now.Year(), now.Month(), 32, 0, 0, 0, 0, time.Local).Day()
var expiresAt = now.Unix() - int64(now.Hour()*3600) - int64(now.Minute()*60) - int64(now.Second()) + int64((endDay-now.Day()+1)*86400)
if expiresAt > status.ExpiresAt {
status.ExpiresAt = expiresAt
}
}
}
}
statusJSON, err := json.Marshal(status)
if err != nil {
return err
}
err = this.Query(tx).
Pk(nodeId).
Set("actionStatus", statusJSON).
UpdateQuickly()
if err != nil {
return err
}
switch actionConfig.Code {
case nodeconfigs.NodeActionCodeWebHook:
var url = maps.NewMap(actionConfig.Params).GetString("url")
if len(url) > 0 {
if strings.Contains(url, "?") {
url += "&"
} else {
url += "?"
}
url += "role=node&clusterId=" + types.String(clusterId) + "&nodeId=" + types.String(nodeId)
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}
var httpClient = utils.SharedHttpClient(5 * time.Second)
httpResp, httpErr := httpClient.Do(req)
if httpErr == nil {
_ = httpResp.Body.Close()
}
}
default:
// 通知更新
err = dns.SharedDNSTaskDAO.CreateClusterTask(tx, clusterId, dns.DNSTaskTypeClusterNodesChange)
if err != nil {
return err
}
}
// 发送消息
return SharedMessageDAO.CreateNodeMessage(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, MessageTypeNodeSchedule, MessageLevelError, "节点已满足调度条件", "节点已满足调度条件,并执行动作:"+nodeconfigs.FindNodeActionName(actionConfig.Code), nil, true)
}
// CheckNodeIPAddresses 检查节点IP地址
func (this *NodeDAO) CheckNodeIPAddresses(tx *dbs.Tx, node *Node) (shouldSkip bool, shouldOverwrite bool, ipAddressStrings []string, err error) {
// 是否到期
if len(node.OfflineDay) > 0 && node.OfflineDay < timeutil.Format("Ymd") {
// 到期后直接跳过
shouldSkip = true
return
}
// 是否为备用
if node.IsBackupForCluster || node.IsBackupForGroup {
shouldSkip = true
return
}
// 当前状态
if len(node.ActionStatus) > 0 {
var actionStatus = node.DecodeActionStatus()
if actionStatus.ActionId > 0 && actionStatus.Action != nil {
switch actionStatus.Action.Code {
case nodeconfigs.NodeActionCodeUp:
// do nothing
return
case nodeconfigs.NodeActionCodeDown:
shouldSkip = true
return
case nodeconfigs.NodeActionCodeSwitchToBackupNodesInCluster:
if node.ClusterId <= 0 {
shouldSkip = true
return
}
addresses, addressesErr := SharedNodeIPAddressDAO.FindAllBackupNodeAccessAndUpIPAddresses(tx, int64(node.ClusterId), 0, nodeconfigs.NodeRoleNode)
if addressesErr != nil {
return false, false, nil, addressesErr
}
for _, address := range addresses {
var ip = address.DNSIP()
if !lists.ContainsString(ipAddressStrings, ip) {
ipAddressStrings = append(ipAddressStrings, ip)
}
}
if len(ipAddressStrings) > 0 {
shouldOverwrite = true
}
return
case nodeconfigs.NodeActionCodeSwitchToBackupNodesInGroup:
if node.GroupId <= 0 {
shouldSkip = true
return
}
addresses, addressesErr := SharedNodeIPAddressDAO.FindAllBackupNodeAccessAndUpIPAddresses(tx, 0, int64(node.GroupId), nodeconfigs.NodeRoleNode)
if addressesErr != nil {
return false, false, nil, addressesErr
}
for _, address := range addresses {
var ip = address.DNSIP()
if !lists.ContainsString(ipAddressStrings, ip) {
ipAddressStrings = append(ipAddressStrings, ip)
}
}
if len(ipAddressStrings) > 0 {
shouldOverwrite = true
}
return
case nodeconfigs.NodeActionCodeSwitchToBackupIP:
ipAddressStrings = node.DecodeBackupIPs()
shouldOverwrite = true
return
case nodeconfigs.NodeActionCodeEnableBackupNodesInCluster:
if node.ClusterId <= 0 {
shouldSkip = true
return
}
addresses, addressesErr := SharedNodeIPAddressDAO.FindAllBackupNodeAccessAndUpIPAddresses(tx, int64(node.ClusterId), 0, nodeconfigs.NodeRoleNode)
if addressesErr != nil {
return false, false, nil, addressesErr
}
for _, address := range addresses {
var ip = address.DNSIP()
if !lists.ContainsString(ipAddressStrings, ip) {
ipAddressStrings = append(ipAddressStrings, ip)
}
}
return
case nodeconfigs.NodeActionCodeEnableBackupNodesInGroup:
if node.GroupId <= 0 {
// 不能跳过
return
}
addresses, addressesErr := SharedNodeIPAddressDAO.FindAllBackupNodeAccessAndUpIPAddresses(tx, 0, int64(node.GroupId), nodeconfigs.NodeRoleNode)
if addressesErr != nil {
return false, false, nil, addressesErr
}
for _, address := range addresses {
var ip = address.DNSIP()
if !lists.ContainsString(ipAddressStrings, ip) {
ipAddressStrings = append(ipAddressStrings, ip)
}
}
return
case nodeconfigs.NodeActionCodeEnableBackupIP:
ipAddressStrings = node.DecodeBackupIPs()
return
case nodeconfigs.NodeActionCodeWebHook:
// do nothing
return
}
}
}
return
}