Files
waf-platform/EdgeAPI/internal/db/models/node_task_dao.go
2026-02-27 10:35:22 +08:00

448 lines
14 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package models
import (
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"strings"
"time"
)
type NodeTaskType = string
const (
// CDN鐩稿叧
NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 鑺傜偣鏁翠綋閰嶇疆鍙樺寲
NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 鑺傜偣DDoS閰嶇疆鍙樻洿
NodeTaskTypeGlobalServerConfigChanged NodeTaskType = "globalServerConfigChanged" // 鍏ㄥ眬鏈嶅姟璁剧疆鍙樺寲
NodeTaskTypeIPListDeleted NodeTaskType = "ipListDeleted" // IPList琚垹闄?
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged" // IP鏉洰鍙樻洿
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged" // 鑺傜偣鐗堟湰鍙樺寲
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 鑴氭湰閰嶇疆鍙樺寲
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 鑺傜偣绾у埆鍙樺寲
NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 鐢ㄦ埛鏈嶅姟鐘舵€佸彉鍖?
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM绛栫暐鍙樺寲
NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 鑷畾涔夐〉闈㈠彉鍖?
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC绛栫暐鍙樺寲
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3绛栫暐鍙樺寲
NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 缃戠粶瀹夊叏绛栫暐鍙樺寲
NodeTaskTypeWebPPolicyChanged NodeTaskType = "webPPolicyChanged" // WebP绛栫暐鍙樺寲
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 鏇存柊涓€缁勬湇鍔?
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA閰嶇疆鍙樺寲
NodeTaskTypePlanChanged NodeTaskType = "planChanged" // 濂楅鍙樺寲
// NS鐩稿叧
NSNodeTaskTypeConfigChanged NodeTaskType = "nsConfigChanged"
NSNodeTaskTypeDomainChanged NodeTaskType = "nsDomainChanged"
NSNodeTaskTypeRecordChanged NodeTaskType = "nsRecordChanged"
NSNodeTaskTypeRouteChanged NodeTaskType = "nsRouteChanged"
NSNodeTaskTypeKeyChanged NodeTaskType = "nsKeyChanged"
NSNodeTaskTypeDDosProtectionChanged NodeTaskType = "nsDDoSProtectionChanged" // 鑺傜偣DDoS閰嶇疆鍙樻洿
// HTTPDNS相关
HTTPDNSNodeTaskTypeConfigChanged NodeTaskType = "httpdnsConfigChanged"
HTTPDNSNodeTaskTypeAppChanged NodeTaskType = "httpdnsAppChanged"
HTTPDNSNodeTaskTypeDomainChanged NodeTaskType = "httpdnsDomainChanged"
HTTPDNSNodeTaskTypeRuleChanged NodeTaskType = "httpdnsRuleChanged"
HTTPDNSNodeTaskTypeTLSChanged NodeTaskType = "httpdnsTLSChanged"
)
type NodeTaskDAO dbs.DAO
func NewNodeTaskDAO() *NodeTaskDAO {
return dbs.NewDAO(&NodeTaskDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNodeTasks",
Model: new(NodeTask),
PkName: "id",
},
}).(*NodeTaskDAO)
}
var SharedNodeTaskDAO *NodeTaskDAO
func init() {
dbs.OnReady(func() {
SharedNodeTaskDAO = NewNodeTaskDAO()
})
}
// CreateNodeTask 鍒涘缓鍗曚釜鑺傜偣浠诲姟
func (this *NodeTaskDAO) CreateNodeTask(tx *dbs.Tx, role string, clusterId int64, nodeId int64, userId int64, serverId int64, taskType NodeTaskType) error {
if clusterId <= 0 || nodeId <= 0 {
return nil
}
var uniqueId = role + "@" + types.String(nodeId) + "@node@" + types.String(serverId) + "@" + taskType
// 鐢ㄦ埛淇℃伅
// 娌℃湁鐩存帴鍔犲叆鍒?uniqueId 涓紝鏄负浜嗗吋瀹逛互鍓嶇殑瀛楁鍊?
if userId > 0 {
uniqueId += "@" + types.String(userId)
}
version, err := this.increaseVersion(tx)
if err != nil {
return err
}
var updatedAt = time.Now().Unix()
_, _, err = this.Query(tx).
InsertOrUpdate(maps.Map{
"role": role,
"clusterId": clusterId,
"nodeId": nodeId,
"userId": userId,
"serverId": serverId,
"type": taskType,
"uniqueId": uniqueId,
"updatedAt": updatedAt,
"isDone": 0,
"isOk": 0,
"error": "",
"version": version,
}, maps.Map{
"clusterId": clusterId,
"updatedAt": updatedAt,
"isDone": 0,
"isOk": 0,
"error": "",
"isNotified": 0,
"version": version,
"serverId": serverId,
})
return err
}
// CreateClusterTask 鍒涘缓闆嗙兢浠诲姟
func (this *NodeTaskDAO) CreateClusterTask(tx *dbs.Tx, role string, clusterId int64, userId int64, serverId int64, taskType NodeTaskType) error {
if clusterId <= 0 {
return nil
}
var uniqueId = role + "@" + types.String(clusterId) + "@" + types.String(serverId) + "@cluster@" + taskType
// 鐢ㄦ埛淇℃伅
// 娌℃湁鐩存帴鍔犲叆鍒?uniqueId 涓紝鏄负浜嗗吋瀹逛互鍓嶇殑瀛楁鍊?
if userId > 0 {
uniqueId += "@" + types.String(userId)
}
var updatedAt = time.Now().Unix()
_, _, err := this.Query(tx).
InsertOrUpdate(maps.Map{
"role": role,
"clusterId": clusterId,
"userId": userId,
"serverId": serverId,
"nodeId": 0,
"type": taskType,
"uniqueId": uniqueId,
"updatedAt": updatedAt,
"isDone": 0,
"isOk": 0,
"isNotified": 0,
"error": "",
"version": time.Now().UnixNano(),
}, maps.Map{
"updatedAt": updatedAt,
"isDone": 0,
"isOk": 0,
"isNotified": 0,
"error": "",
"version": time.Now().UnixNano(),
"serverId": serverId,
})
return err
}
// ExtractNodeClusterTask 鍒嗚В杈圭紭鑺傜偣闆嗙兢浠诲姟
func (this *NodeTaskDAO) ExtractNodeClusterTask(tx *dbs.Tx, clusterId int64, userId int64, serverId int64, taskType NodeTaskType) error {
nodeIds, err := SharedNodeDAO.FindAllNodeIdsMatch(tx, clusterId, true, configutils.BoolStateYes)
if err != nil {
return err
}
_, err = this.Query(tx).
Attr("role", nodeconfigs.NodeRoleNode).
Attr("clusterId", clusterId).
Attr("serverId", serverId).
Gt("nodeId", 0).
Attr("type", taskType).
Delete()
if err != nil {
return err
}
for _, nodeId := range nodeIds {
err = this.CreateNodeTask(tx, nodeconfigs.NodeRoleNode, clusterId, nodeId, userId, serverId, taskType)
if err != nil {
return err
}
}
_, err = this.Query(tx).
Attr("role", nodeconfigs.NodeRoleNode).
Attr("clusterId", clusterId).
Attr("nodeId", 0).
Attr("type", taskType).
Delete()
if err != nil {
return err
}
return nil
}
// ExtractAllClusterTasks 鍒嗚В鎵€鏈夐泦缇や换鍔?
func (this *NodeTaskDAO) ExtractAllClusterTasks(tx *dbs.Tx, role string) error {
ones, err := this.Query(tx).
Attr("role", role).
Attr("nodeId", 0).
FindAll()
if err != nil {
return err
}
for _, one := range ones {
var clusterId = int64(one.(*NodeTask).ClusterId)
switch role {
case nodeconfigs.NodeRoleNode:
var nodeTask = one.(*NodeTask)
err = this.ExtractNodeClusterTask(tx, clusterId, int64(nodeTask.UserId), int64(nodeTask.ServerId), nodeTask.Type)
if err != nil {
return err
}
case nodeconfigs.NodeRoleDNS:
err = this.ExtractNSClusterTask(tx, clusterId, one.(*NodeTask).Type)
if err != nil {
return err
}
case nodeconfigs.NodeRoleHTTPDNS:
err = this.ExtractHTTPDNSClusterTask(tx, clusterId, one.(*NodeTask).Type)
if err != nil {
return err
}
}
}
return nil
}
// DeleteAllClusterTasks 鍒犻櫎闆嗙兢鎵€鏈夌浉鍏充换鍔?
func (this *NodeTaskDAO) DeleteAllClusterTasks(tx *dbs.Tx, role string, clusterId int64) error {
_, err := this.Query(tx).
Attr("role", role).
Attr("clusterId", clusterId).
Delete()
return err
}
// DeleteNodeTasks 鍒犻櫎鑺傜偣鐩稿叧浠诲姟
func (this *NodeTaskDAO) DeleteNodeTasks(tx *dbs.Tx, role string, nodeId int64) error {
_, err := this.Query(tx).
Attr("role", role).
Attr("nodeId", nodeId).
Delete()
return err
}
// DeleteAllNodeTasks 鍒犻櫎鎵€鏈夎妭鐐圭浉鍏充换鍔?
func (this *NodeTaskDAO) DeleteAllNodeTasks(tx *dbs.Tx) error {
return this.Query(tx).
DeleteQuickly()
}
// FindDoingNodeTasks 鏌ヨ涓€涓妭鐐圭殑鎵€鏈変换鍔?
func (this *NodeTaskDAO) FindDoingNodeTasks(tx *dbs.Tx, role string, nodeId int64, version int64) (result []*NodeTask, err error) {
if nodeId <= 0 {
return
}
var query = this.Query(tx).
Attr("role", role).
Attr("nodeId", nodeId).
UseIndex("nodeId").
Asc("version")
if version > 0 {
query.Lt("LENGTH(version)", 19) // 鍏煎浠ュ線鐗堟湰
query.Gt("version", version)
} else {
// 绗竴娆¤闂椂鍙彇褰撳墠姝e湪鎵ц鐨勬垨鑰呮墽琛屽け璐ョ殑
query.Where("(isDone=0 OR (isDone=1 AND isOk=0))")
}
_, err = query.
Slice(&result).
FindAll()
return
}
// UpdateNodeTaskDone 淇敼鑺傜偣浠诲姟鐨勫畬鎴愮姸鎬?
func (this *NodeTaskDAO) UpdateNodeTaskDone(tx *dbs.Tx, taskId int64, isOk bool, errorMessage string) error {
if isOk {
// 鐗规畩浠诲姟鍒犻櫎
taskType, err := this.Query(tx).
Pk(taskId).
Result("type").
FindStringCol("")
if err != nil {
return err
}
if strings.HasPrefix(taskType, NodeTaskTypeIPListDeleted+"@") {
return this.Query(tx).
Pk(taskId).
DeleteQuickly()
}
}
// 鍏朵粬浠诲姟鏍囪涓哄畬鎴?
var query = this.Query(tx).
Pk(taskId)
if !isOk {
version, err := this.increaseVersion(tx)
if err != nil {
return err
}
query.Set("version", version)
}
_, err := query.
Set("isDone", true).
Set("isOk", isOk).
Set("error", errorMessage).
Update()
return err
}
// FindAllDoingTaskClusterIds 鏌ユ壘姝湪鏇存柊鐨勯泦缇Ds
func (this *NodeTaskDAO) FindAllDoingTaskClusterIds(tx *dbs.Tx, role string) ([]int64, error) {
ones, _, err := this.Query(tx).
Result("DISTINCT(clusterId) AS clusterId").
Attr("role", role).
Where("(nodeId=0 OR (isDone=0 OR (isDone=1 AND isOk=0)))").
FindOnes()
if err != nil {
return nil, err
}
result := []int64{}
for _, one := range ones {
result = append(result, one.GetInt64("clusterId"))
}
return result, nil
}
// FindAllDoingNodeTasksWithClusterId 鏌ヨ鏌愪釜闆嗙兢涓嬫墍鏈夌殑浠诲姟
func (this *NodeTaskDAO) FindAllDoingNodeTasksWithClusterId(tx *dbs.Tx, role string, clusterId int64) (result []*NodeTask, err error) {
_, err = this.Query(tx).
Attr("role", role).
Attr("clusterId", clusterId).
Gt("nodeId", 0).
Where("(isDone=0 OR (isDone=1 AND isOk=0))").
Desc("isDone").
Asc("nodeId").
AscPk().
Slice(&result).
FindAll()
return
}
// FindAllDoingNodeIds 鏌ヨ鏈変换鍔殑鑺傜偣IDs
func (this *NodeTaskDAO) FindAllDoingNodeIds(tx *dbs.Tx, role string) ([]int64, error) {
ones, err := this.Query(tx).
Result("DISTINCT(nodeId) AS nodeId").
Attr("role", role).
Gt("nodeId", 0).
Attr("isDone", false).
Attr("isNotified", 0).
FindAll()
if err != nil {
return nil, err
}
var result []int64
for _, one := range ones {
result = append(result, int64(one.(*NodeTask).NodeId))
}
return result, nil
}
// ExistsDoingNodeTasks 妫€鏌ユ槸鍚︽湁姝e湪鎵ц鐨勪换鍔?
func (this *NodeTaskDAO) ExistsDoingNodeTasks(tx *dbs.Tx, role string, excludeTypes []NodeTaskType) (bool, error) {
var query = this.Query(tx).
Attr("role", role).
Where("(isDone=0 OR (isDone=1 AND isOk=0))").
Gt("nodeId", 0)
if len(excludeTypes) > 0 {
for _, excludeType := range excludeTypes {
query.Neq("type", excludeType)
}
}
return query.Exist()
}
// ExistsErrorNodeTasks 鏄惁鏈夐敊璇殑浠诲姟
func (this *NodeTaskDAO) ExistsErrorNodeTasks(tx *dbs.Tx, role string, excludeTypes []NodeTaskType) (bool, error) {
var query = this.Query(tx).
Attr("role", role).
Where("(isDone=1 AND isOk=0)")
if len(excludeTypes) > 0 {
for _, excludeType := range excludeTypes {
query.Neq("type", excludeType)
}
}
return query.Exist()
}
// DeleteNodeTask 鍒犻櫎浠诲姟
func (this *NodeTaskDAO) DeleteNodeTask(tx *dbs.Tx, taskId int64) error {
_, err := this.Query(tx).
Pk(taskId).
Delete()
return err
}
// CountDoingNodeTasks 璁$畻姝e湪鎵ц鐨勪换鍔?
func (this *NodeTaskDAO) CountDoingNodeTasks(tx *dbs.Tx, role string) (int64, error) {
return this.Query(tx).
Attr("isDone", 0).
Attr("role", role).
Gt("nodeId", 0).
Count()
}
// FindNotifyingNodeTasks 鏌ユ壘闇€瑕侀€氱煡鐨勪换鍔?
func (this *NodeTaskDAO) FindNotifyingNodeTasks(tx *dbs.Tx, role string, size int64) (result []*NodeTask, err error) {
_, err = this.Query(tx).
Attr("role", role).
Gt("nodeId", 0).
Attr("isNotified", 0).
Attr("isDone", 0).
Limit(size).
Slice(&result).
FindAll()
return
}
// UpdateTasksNotified 璁剧疆浠诲姟宸查€氱煡
func (this *NodeTaskDAO) UpdateTasksNotified(tx *dbs.Tx, taskIds []int64) error {
if len(taskIds) == 0 {
return nil
}
for _, taskId := range taskIds {
_, err := this.Query(tx).
Pk(taskId).
Set("isNotified", 1).
Update()
if err != nil {
return err
}
}
return nil
}
// 鐢熸垚涓€涓増鏈彿
func (this *NodeTaskDAO) increaseVersion(tx *dbs.Tx) (version int64, err error) {
return SharedSysLockerDAO.Increase(tx, "NODE_TASK_VERSION", 0)
}