Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b60bb5f6da | ||
|
|
ff4ea41963 | ||
|
|
b7dccad449 | ||
|
|
7fead214d4 | ||
|
|
d9590ec605 | ||
|
|
20b936580f | ||
|
|
b7b43bc31f | ||
|
|
6fd4f26755 | ||
|
|
f15d114708 | ||
|
|
fc24195b55 | ||
|
|
ed5de57244 | ||
|
|
4ce347738f | ||
|
|
f6e725781c | ||
|
|
55d70418cc | ||
|
|
7f5b070e36 | ||
|
|
993c7ee822 | ||
|
|
b5bb4e0df9 | ||
|
|
9f120fd0e0 | ||
|
|
77d614c9ea | ||
|
|
531ec3c55d | ||
|
|
0d6c064194 | ||
|
|
180e86c643 | ||
|
|
86b04b2b6b | ||
|
|
7a5ec79ace | ||
|
|
7290ffd2cd | ||
|
|
2f361c5bcc | ||
|
|
500d72aaf3 | ||
|
|
9fc391d1e8 | ||
|
|
c86e3e2047 | ||
|
|
7e72a90f53 | ||
|
|
7692fed38d | ||
|
|
bdd7d2a181 | ||
|
|
118c3f79e4 | ||
|
|
804a33a002 | ||
|
|
fe00588039 | ||
|
|
67aac200a7 | ||
|
|
3e01ad4b68 | ||
|
|
b39690484e | ||
|
|
31a69ecb12 | ||
|
|
94b95beadf |
@@ -12,5 +12,5 @@ dbs:
|
|||||||
|
|
||||||
|
|
||||||
fields:
|
fields:
|
||||||
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified", "http2Enabled", "http3Enabled", "enableHTTP2", "retry50X" ]
|
bool: [ "uamIsOn", "followPort", "requestHostExcludingPort", "autoRemoteStart", "autoInstallNftables", "enableIPLists", "detectAgents", "checkingPorts", "enableRecordHealthCheck", "offlineIsNotified", "http2Enabled", "http3Enabled", "enableHTTP2", "retry50X", "retry40X", "autoSystemTuning", "disableDefaultDB" ]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
go run `dirname $0`/../cmd/sql-dump/main.go -dir=`dirname $0`
|
# generate 'internal/setup/sql.json' file
|
||||||
|
|
||||||
|
CWD="$(dirname "$0")"
|
||||||
|
|
||||||
|
go run "${CWD}"/../cmd/sql-dump/main.go -dir="${CWD}"
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
package teaconst
|
package teaconst
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version = "1.2.9"
|
Version = "1.3.0"
|
||||||
|
|
||||||
ProductName = "Edge API"
|
ProductName = "Edge API"
|
||||||
ProcessName = "edge-api"
|
ProcessName = "edge-api"
|
||||||
ProductNameZH = "Edge"
|
ProductNameZH = "Edge"
|
||||||
|
|
||||||
|
GlobalProductName = "GoEdge"
|
||||||
|
|
||||||
Role = "api"
|
Role = "api"
|
||||||
|
|
||||||
EncryptKey = "8f983f4d69b83aaa0d74b21a212f6967"
|
EncryptKey = "8f983f4d69b83aaa0d74b21a212f6967"
|
||||||
@@ -18,7 +20,7 @@ const (
|
|||||||
|
|
||||||
// 其他节点版本号,用来检测是否有需要升级的节点
|
// 其他节点版本号,用来检测是否有需要升级的节点
|
||||||
|
|
||||||
NodeVersion = "1.2.9"
|
NodeVersion = "1.3.0"
|
||||||
|
|
||||||
// SQLVersion SQL版本号
|
// SQLVersion SQL版本号
|
||||||
SQLVersion = "11"
|
SQLVersion = "11"
|
||||||
|
|||||||
@@ -107,9 +107,17 @@ func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CountAllEnabledACMETasks 计算所有任务数量
|
// CountAllEnabledACMETasks 计算所有任务数量
|
||||||
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) {
|
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userOnly bool) (int64, error) {
|
||||||
var query = this.Query(tx)
|
var query = this.Query(tx)
|
||||||
query.Attr("userId", userId) // 这个条件必须加上
|
if userId > 0 {
|
||||||
|
query.Attr("userId", userId)
|
||||||
|
} else {
|
||||||
|
if userOnly {
|
||||||
|
query.Gt("userId", 0)
|
||||||
|
} else {
|
||||||
|
query.Attr("userId", 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
if isAvailable || isExpired || expiringDays > 0 {
|
if isAvailable || isExpired || expiringDays > 0 {
|
||||||
query.Gt("certId", 0)
|
query.Gt("certId", 0)
|
||||||
|
|
||||||
@@ -139,9 +147,17 @@ func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, userId int64, isAv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListEnabledACMETasks 列出单页任务
|
// ListEnabledACMETasks 列出单页任务
|
||||||
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) {
|
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userOnly bool, offset int64, size int64) (result []*ACMETask, err error) {
|
||||||
var query = this.Query(tx)
|
var query = this.Query(tx)
|
||||||
query.Attr("userId", userId) // 这个条件必须加上
|
if userId > 0 {
|
||||||
|
query.Attr("userId", userId)
|
||||||
|
} else {
|
||||||
|
if userOnly {
|
||||||
|
query.Gt("userId", 0)
|
||||||
|
} else {
|
||||||
|
query.Attr("userId", 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
if isAvailable || isExpired || expiringDays > 0 {
|
if isAvailable || isExpired || expiringDays > 0 {
|
||||||
query.Gt("certId", 0)
|
query.Gt("certId", 0)
|
||||||
|
|
||||||
@@ -229,8 +245,8 @@ func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckACMETask 检查权限
|
// CheckUserACMETask 检查用户权限
|
||||||
func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, userId int64, acmeTaskId int64) (bool, error) {
|
func (this *ACMETaskDAO) CheckUserACMETask(tx *dbs.Tx, userId int64, acmeTaskId int64) (bool, error) {
|
||||||
var query = this.Query(tx)
|
var query = this.Query(tx)
|
||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
query.Attr("userId", userId)
|
query.Attr("userId", userId)
|
||||||
@@ -242,6 +258,15 @@ func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, userId int64, acmeTaskId int6
|
|||||||
Exist()
|
Exist()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindACMETaskUserId 查找任务所属用户ID
|
||||||
|
func (this *ACMETaskDAO) FindACMETaskUserId(tx *dbs.Tx, taskId int64) (userId int64, err error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(taskId).
|
||||||
|
Result("userId").
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// UpdateACMETaskCert 设置任务关联的证书
|
// UpdateACMETaskCert 设置任务关联的证书
|
||||||
func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int64) error {
|
func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int64) error {
|
||||||
if taskId <= 0 {
|
if taskId <= 0 {
|
||||||
|
|||||||
6
internal/db/models/authority/authority_key_dao_test.go
Normal file
6
internal/db/models/authority/authority_key_dao_test.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package authority_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
_ "github.com/iwind/TeaGo/bootstrap"
|
||||||
|
)
|
||||||
@@ -2,6 +2,18 @@ package authority
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
AuthorityKeyField_Id dbs.FieldName = "id" // ID
|
||||||
|
AuthorityKeyField_Value dbs.FieldName = "value" // Key值
|
||||||
|
AuthorityKeyField_DayFrom dbs.FieldName = "dayFrom" // 开始日期
|
||||||
|
AuthorityKeyField_DayTo dbs.FieldName = "dayTo" // 结束日期
|
||||||
|
AuthorityKeyField_Hostname dbs.FieldName = "hostname" // Hostname
|
||||||
|
AuthorityKeyField_MacAddresses dbs.FieldName = "macAddresses" // MAC地址
|
||||||
|
AuthorityKeyField_UpdatedAt dbs.FieldName = "updatedAt" // 创建/修改时间
|
||||||
|
AuthorityKeyField_Company dbs.FieldName = "company" // 公司组织
|
||||||
|
AuthorityKeyField_RequestCode dbs.FieldName = "requestCode" // 申请码
|
||||||
|
)
|
||||||
|
|
||||||
// AuthorityKey 企业版认证信息
|
// AuthorityKey 企业版认证信息
|
||||||
type AuthorityKey struct {
|
type AuthorityKey struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
@@ -12,17 +24,19 @@ type AuthorityKey struct {
|
|||||||
MacAddresses dbs.JSON `field:"macAddresses"` // MAC地址
|
MacAddresses dbs.JSON `field:"macAddresses"` // MAC地址
|
||||||
UpdatedAt uint64 `field:"updatedAt"` // 创建/修改时间
|
UpdatedAt uint64 `field:"updatedAt"` // 创建/修改时间
|
||||||
Company string `field:"company"` // 公司组织
|
Company string `field:"company"` // 公司组织
|
||||||
|
RequestCode string `field:"requestCode"` // 申请码
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorityKeyOperator struct {
|
type AuthorityKeyOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
Value interface{} // Key值
|
Value any // Key值
|
||||||
DayFrom interface{} // 开始日期
|
DayFrom any // 开始日期
|
||||||
DayTo interface{} // 结束日期
|
DayTo any // 结束日期
|
||||||
Hostname interface{} // Hostname
|
Hostname any // Hostname
|
||||||
MacAddresses interface{} // MAC地址
|
MacAddresses any // MAC地址
|
||||||
UpdatedAt interface{} // 创建/修改时间
|
UpdatedAt any // 创建/修改时间
|
||||||
Company interface{} // 公司组织
|
Company any // 公司组织
|
||||||
|
RequestCode any // 申请码
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthorityKeyOperator() *AuthorityKeyOperator {
|
func NewAuthorityKeyOperator() *AuthorityKeyOperator {
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLog(tx *dbs.Tx, dao *HTTPAccessLog
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fields := map[string]interface{}{}
|
var fields = map[string]any{}
|
||||||
fields["serverId"] = accessLog.ServerId
|
fields["serverId"] = accessLog.ServerId
|
||||||
fields["nodeId"] = accessLog.NodeId
|
fields["nodeId"] = accessLog.NodeId
|
||||||
fields["status"] = accessLog.Status
|
fields["status"] = accessLog.Status
|
||||||
@@ -265,7 +265,11 @@ func (this *HTTPAccessLogDAO) CreateHTTPAccessLog(tx *dbs.Tx, dao *HTTPAccessLog
|
|||||||
fields["remoteAddr"] = accessLog.RemoteAddr
|
fields["remoteAddr"] = accessLog.RemoteAddr
|
||||||
}
|
}
|
||||||
if tableDef.HasDomain {
|
if tableDef.HasDomain {
|
||||||
fields["domain"] = accessLog.Host
|
if len(accessLog.Host) > 128 {
|
||||||
|
fields["domain"] = accessLog.Host[:128]
|
||||||
|
} else {
|
||||||
|
fields["domain"] = accessLog.Host
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := json.Marshal(accessLog)
|
content, err := json.Marshal(accessLog)
|
||||||
@@ -461,6 +465,7 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx,
|
|||||||
var protoReg = regexp.MustCompile(`proto:(\S+)`)
|
var protoReg = regexp.MustCompile(`proto:(\S+)`)
|
||||||
var schemeReg = regexp.MustCompile(`scheme:(\S+)`)
|
var schemeReg = regexp.MustCompile(`scheme:(\S+)`)
|
||||||
var methodReg = regexp.MustCompile(`(?:method|requestMethod):(\S+)`)
|
var methodReg = regexp.MustCompile(`(?:method|requestMethod):(\S+)`)
|
||||||
|
var refererReg = regexp.MustCompile(`referer:(\S+)`)
|
||||||
|
|
||||||
var count = len(tableQueries)
|
var count = len(tableQueries)
|
||||||
var wg = &sync.WaitGroup{}
|
var wg = &sync.WaitGroup{}
|
||||||
@@ -613,6 +618,11 @@ func (this *HTTPAccessLogDAO) listAccessLogs(tx *dbs.Tx,
|
|||||||
var matches = methodReg.FindStringSubmatch(keyword)
|
var matches = methodReg.FindStringSubmatch(keyword)
|
||||||
query.Where("JSON_EXTRACT(content, '$.requestMethod')=:keyword").
|
query.Where("JSON_EXTRACT(content, '$.requestMethod')=:keyword").
|
||||||
Param("keyword", strings.ToUpper(matches[1]))
|
Param("keyword", strings.ToUpper(matches[1]))
|
||||||
|
} else if refererReg.MatchString(keyword) {
|
||||||
|
isSpecialKeyword = true
|
||||||
|
var matches = refererReg.FindStringSubmatch(keyword)
|
||||||
|
query.Where("JSON_EXTRACT(content, '$.referer') LIKE :keyword").
|
||||||
|
Param("keyword", dbutils.QuoteLike(matches[1]))
|
||||||
}
|
}
|
||||||
if !isSpecialKeyword {
|
if !isSpecialKeyword {
|
||||||
if regexp.MustCompile(`^ip:.+`).MatchString(keyword) {
|
if regexp.MustCompile(`^ip:.+`).MatchString(keyword) {
|
||||||
@@ -857,8 +867,4 @@ func (this *HTTPAccessLogDAO) SetupQueue() {
|
|||||||
oldAccessLogQueue = accessLogQueue
|
oldAccessLogQueue = accessLogQueue
|
||||||
accessLogQueue = make(chan *pb.HTTPAccessLog, config.MaxLength)
|
accessLogQueue = make(chan *pb.HTTPAccessLog, config.MaxLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Tea.IsTesting() {
|
|
||||||
remotelogs.Println("HTTP_ACCESS_LOG_QUEUE", "change queue "+string(configJSON))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ func (this *HTTPAccessLogManager) FindLastTable(db *dbs.DB, day string, force bo
|
|||||||
|
|
||||||
// CreateTable 创建访问日志表格
|
// CreateTable 创建访问日志表格
|
||||||
func (this *HTTPAccessLogManager) CreateTable(db *dbs.DB, tableName string) error {
|
func (this *HTTPAccessLogManager) CreateTable(db *dbs.DB, tableName string) error {
|
||||||
_, err := db.Exec("CREATE TABLE `" + tableName + "` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(128) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志';")
|
_, err := db.Exec("CREATE TABLE `" + tableName + "` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',\n `serverId` int(11) unsigned DEFAULT '0' COMMENT '服务ID',\n `nodeId` int(11) unsigned DEFAULT '0' COMMENT '节点ID',\n `status` int(3) unsigned DEFAULT '0' COMMENT '状态码',\n `createdAt` bigint(11) unsigned DEFAULT '0' COMMENT '创建时间',\n `content` json DEFAULT NULL COMMENT '日志内容',\n `requestId` varchar(128) DEFAULT NULL COMMENT '请求ID',\n `firewallPolicyId` int(11) unsigned DEFAULT '0' COMMENT 'WAF策略ID',\n `firewallRuleGroupId` int(11) unsigned DEFAULT '0' COMMENT 'WAF分组ID',\n `firewallRuleSetId` int(11) unsigned DEFAULT '0' COMMENT 'WAF集ID',\n `firewallRuleId` int(11) unsigned DEFAULT '0' COMMENT 'WAF规则ID',\n `remoteAddr` varchar(64) DEFAULT NULL COMMENT 'IP地址',\n `domain` varchar(255) DEFAULT NULL COMMENT '域名',\n `requestBody` mediumblob COMMENT '请求内容',\n `responseBody` mediumblob COMMENT '响应内容',\n PRIMARY KEY (`id`),\n KEY `serverId` (`serverId`),\n KEY `nodeId` (`nodeId`),\n KEY `serverId_status` (`serverId`,`status`),\n KEY `requestId` (`requestId`),\n KEY `firewallPolicyId` (`firewallPolicyId`),\n KEY `firewallRuleGroupId` (`firewallRuleGroupId`),\n KEY `firewallRuleSetId` (`firewallRuleSetId`),\n KEY `firewallRuleId` (`firewallRuleId`),\n KEY `remoteAddr` (`remoteAddr`),\n KEY `domain` (`domain`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='访问日志';")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if CheckSQLErrCode(err, 1050) { // Error 1050: Table 'xxx' already exists
|
if CheckSQLErrCode(err, 1050) { // Error 1050: Table 'xxx' already exists
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func (this *HTTPAccessLogPolicyDAO) FindAllEnabledAndOnPolicies(tx *dbs.Tx) (res
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreatePolicy 创建策略
|
// CreatePolicy 创建策略
|
||||||
func (this *HTTPAccessLogPolicyDAO) CreatePolicy(tx *dbs.Tx, name string, policyType string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool) (policyId int64, err error) {
|
func (this *HTTPAccessLogPolicyDAO) CreatePolicy(tx *dbs.Tx, name string, policyType string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool, disableDefaultDB bool) (policyId int64, err error) {
|
||||||
var op = NewHTTPAccessLogPolicyOperator()
|
var op = NewHTTPAccessLogPolicyOperator()
|
||||||
op.Name = name
|
op.Name = name
|
||||||
op.Type = policyType
|
op.Type = policyType
|
||||||
@@ -120,12 +120,13 @@ func (this *HTTPAccessLogPolicyDAO) CreatePolicy(tx *dbs.Tx, name string, policy
|
|||||||
op.IsPublic = isPublic
|
op.IsPublic = isPublic
|
||||||
op.IsOn = true
|
op.IsOn = true
|
||||||
op.FirewallOnly = firewallOnly
|
op.FirewallOnly = firewallOnly
|
||||||
|
op.DisableDefaultDB = disableDefaultDB
|
||||||
op.State = HTTPAccessLogPolicyStateEnabled
|
op.State = HTTPAccessLogPolicyStateEnabled
|
||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePolicy 修改策略
|
// UpdatePolicy 修改策略
|
||||||
func (this *HTTPAccessLogPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, name string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool, isOn bool) error {
|
func (this *HTTPAccessLogPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, name string, optionsJSON []byte, condsJSON []byte, isPublic bool, firewallOnly bool, disableDefaultDB bool, isOn bool) error {
|
||||||
if policyId <= 0 {
|
if policyId <= 0 {
|
||||||
return errors.New("invalid policyId")
|
return errors.New("invalid policyId")
|
||||||
}
|
}
|
||||||
@@ -159,6 +160,7 @@ func (this *HTTPAccessLogPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, nam
|
|||||||
|
|
||||||
op.IsPublic = isPublic
|
op.IsPublic = isPublic
|
||||||
op.FirewallOnly = firewallOnly
|
op.FirewallOnly = firewallOnly
|
||||||
|
op.DisableDefaultDB = disableDefaultDB
|
||||||
op.IsOn = isOn
|
op.IsOn = isOn
|
||||||
return this.Save(tx, op)
|
return this.Save(tx, op)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,39 +2,59 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTPAccessLogPolicyField_Id dbs.FieldName = "id" // ID
|
||||||
|
HTTPAccessLogPolicyField_TemplateId dbs.FieldName = "templateId" // 模版ID
|
||||||
|
HTTPAccessLogPolicyField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
HTTPAccessLogPolicyField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
HTTPAccessLogPolicyField_State dbs.FieldName = "state" // 状态
|
||||||
|
HTTPAccessLogPolicyField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
HTTPAccessLogPolicyField_Name dbs.FieldName = "name" // 名称
|
||||||
|
HTTPAccessLogPolicyField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
HTTPAccessLogPolicyField_Type dbs.FieldName = "type" // 存储类型
|
||||||
|
HTTPAccessLogPolicyField_Options dbs.FieldName = "options" // 存储选项
|
||||||
|
HTTPAccessLogPolicyField_Conds dbs.FieldName = "conds" // 请求条件
|
||||||
|
HTTPAccessLogPolicyField_IsPublic dbs.FieldName = "isPublic" // 是否为公用
|
||||||
|
HTTPAccessLogPolicyField_FirewallOnly dbs.FieldName = "firewallOnly" // 是否只记录防火墙相关
|
||||||
|
HTTPAccessLogPolicyField_Version dbs.FieldName = "version" // 版本号
|
||||||
|
HTTPAccessLogPolicyField_DisableDefaultDB dbs.FieldName = "disableDefaultDB" // 是否停止默认数据库存储
|
||||||
|
)
|
||||||
|
|
||||||
// HTTPAccessLogPolicy 访问日志策略
|
// HTTPAccessLogPolicy 访问日志策略
|
||||||
type HTTPAccessLogPolicy struct {
|
type HTTPAccessLogPolicy struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
TemplateId uint32 `field:"templateId"` // 模版ID
|
TemplateId uint32 `field:"templateId"` // 模版ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
Name string `field:"name"` // 名称
|
Name string `field:"name"` // 名称
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
Type string `field:"type"` // 存储类型
|
Type string `field:"type"` // 存储类型
|
||||||
Options dbs.JSON `field:"options"` // 存储选项
|
Options dbs.JSON `field:"options"` // 存储选项
|
||||||
Conds dbs.JSON `field:"conds"` // 请求条件
|
Conds dbs.JSON `field:"conds"` // 请求条件
|
||||||
IsPublic bool `field:"isPublic"` // 是否为公用
|
IsPublic bool `field:"isPublic"` // 是否为公用
|
||||||
FirewallOnly uint8 `field:"firewallOnly"` // 是否只记录防火墙相关
|
FirewallOnly uint8 `field:"firewallOnly"` // 是否只记录防火墙相关
|
||||||
Version uint32 `field:"version"` // 版本号
|
Version uint32 `field:"version"` // 版本号
|
||||||
|
DisableDefaultDB bool `field:"disableDefaultDB"` // 是否停止默认数据库存储
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPAccessLogPolicyOperator struct {
|
type HTTPAccessLogPolicyOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
TemplateId interface{} // 模版ID
|
TemplateId any // 模版ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
Name interface{} // 名称
|
Name any // 名称
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
Type interface{} // 存储类型
|
Type any // 存储类型
|
||||||
Options interface{} // 存储选项
|
Options any // 存储选项
|
||||||
Conds interface{} // 请求条件
|
Conds any // 请求条件
|
||||||
IsPublic interface{} // 是否为公用
|
IsPublic any // 是否为公用
|
||||||
FirewallOnly interface{} // 是否只记录防火墙相关
|
FirewallOnly any // 是否只记录防火墙相关
|
||||||
Version interface{} // 版本号
|
Version any // 版本号
|
||||||
|
DisableDefaultDB any // 是否停止默认数据库存储
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPAccessLogPolicyOperator() *HTTPAccessLogPolicyOperator {
|
func NewHTTPAccessLogPolicyOperator() *HTTPAccessLogPolicyOperator {
|
||||||
|
|||||||
@@ -279,6 +279,31 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInbound(tx *dbs.Tx, polic
|
|||||||
return this.NotifyUpdate(tx, policyId)
|
return this.NotifyUpdate(tx, policyId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateFirewallPolicyInboundRegion 修改入站封禁区域设置
|
||||||
|
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInboundRegion(tx *dbs.Tx, policyId int64, regionConfig *firewallconfigs.HTTPFirewallRegionConfig) error {
|
||||||
|
var inboundConfig = &firewallconfigs.HTTPFirewallInboundConfig{IsOn: true}
|
||||||
|
inboundJSON, err := this.Query(tx).
|
||||||
|
Pk(policyId).
|
||||||
|
Result("inbound").
|
||||||
|
FindJSONCol()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if IsNotNull(inboundJSON) {
|
||||||
|
err = json.Unmarshal(inboundJSON, inboundConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inboundConfig.Region = regionConfig
|
||||||
|
newInboundJSON, err := json.Marshal(inboundConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return this.UpdateFirewallPolicyInbound(tx, policyId, newInboundJSON)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateFirewallPolicy 修改策略
|
// UpdateFirewallPolicy 修改策略
|
||||||
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicy(tx *dbs.Tx,
|
||||||
policyId int64,
|
policyId int64,
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ func (this *HTTPFirewallRuleGroupDAO) ComposeFirewallRuleGroup(tx *dbs.Tx, group
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, setRef := range setRefs {
|
for _, setRef := range setRefs {
|
||||||
setConfig, err := SharedHTTPFirewallRuleSetDAO.ComposeFirewallRuleSet(tx, setRef.SetId)
|
setConfig, err := SharedHTTPFirewallRuleSetDAO.ComposeFirewallRuleSet(tx, setRef.SetId, forNode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ func (this *HTTPFirewallRuleSetDAO) FindHTTPFirewallRuleSetName(tx *dbs.Tx, id i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ComposeFirewallRuleSet 组合配置
|
// ComposeFirewallRuleSet 组合配置
|
||||||
func (this *HTTPFirewallRuleSetDAO) ComposeFirewallRuleSet(tx *dbs.Tx, setId int64) (*firewallconfigs.HTTPFirewallRuleSet, error) {
|
func (this *HTTPFirewallRuleSetDAO) ComposeFirewallRuleSet(tx *dbs.Tx, setId int64, forNode bool) (*firewallconfigs.HTTPFirewallRuleSet, error) {
|
||||||
set, err := this.FindEnabledHTTPFirewallRuleSet(tx, setId)
|
set, err := this.FindEnabledHTTPFirewallRuleSet(tx, setId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -133,12 +133,19 @@ func (this *HTTPFirewallRuleSetDAO) ComposeFirewallRuleSet(tx *dbs.Tx, setId int
|
|||||||
if actionConfig.Code == firewallconfigs.HTTPFirewallActionRecordIP { // 记录IP动作
|
if actionConfig.Code == firewallconfigs.HTTPFirewallActionRecordIP { // 记录IP动作
|
||||||
if actionConfig.Options != nil {
|
if actionConfig.Options != nil {
|
||||||
var ipListId = actionConfig.Options.GetInt64("ipListId")
|
var ipListId = actionConfig.Options.GetInt64("ipListId")
|
||||||
exists, err := SharedIPListDAO.ExistsEnabledIPList(tx, ipListId)
|
if ipListId <= 0 { // default list id
|
||||||
if err != nil {
|
if forNode {
|
||||||
return nil, err
|
actionConfig.Options["ipListId"] = firewallconfigs.GlobalListId
|
||||||
}
|
}
|
||||||
if !exists {
|
actionConfig.Options["ipListIsDeleted"] = false
|
||||||
actionConfig.Options["ipListIsDeleted"] = true
|
} else {
|
||||||
|
exists, err := SharedIPListDAO.ExistsEnabledIPList(tx, ipListId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
actionConfig.Options["ipListIsDeleted"] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ func (this *HTTPPageDAO) FindEnabledHTTPPage(tx *dbs.Tx, id int64) (*HTTPPage, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreatePage 创建Page
|
// CreatePage 创建Page
|
||||||
func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []string, bodyType shared.BodyType, url string, body string, newStatus int) (pageId int64, err error) {
|
func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int, exceptURLPatterns []*shared.URLPattern, onlyURLPatterns []*shared.URLPattern) (pageId int64, err error) {
|
||||||
var op = NewHTTPPageOperator()
|
var op = NewHTTPPageOperator()
|
||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
op.IsOn = true
|
op.IsOn = true
|
||||||
@@ -94,6 +94,29 @@ func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []strin
|
|||||||
op.Url = url
|
op.Url = url
|
||||||
op.Body = body
|
op.Body = body
|
||||||
op.NewStatus = newStatus
|
op.NewStatus = newStatus
|
||||||
|
|
||||||
|
{
|
||||||
|
if exceptURLPatterns == nil {
|
||||||
|
exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
}
|
||||||
|
exceptURLPatternsJSON, err := json.Marshal(exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.ExceptURLPatterns = exceptURLPatternsJSON
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if onlyURLPatterns == nil {
|
||||||
|
onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
}
|
||||||
|
onlyURLPatternsJSON, err := json.Marshal(onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.OnlyURLPatterns = onlyURLPatternsJSON
|
||||||
|
}
|
||||||
|
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -103,7 +126,7 @@ func (this *HTTPPageDAO) CreatePage(tx *dbs.Tx, userId int64, statusList []strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePage 修改Page
|
// UpdatePage 修改Page
|
||||||
func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []string, bodyType shared.BodyType, url string, body string, newStatus int) error {
|
func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []string, bodyType serverconfigs.HTTPPageBodyType, url string, body string, newStatus int, exceptURLPatterns []*shared.URLPattern, onlyURLPatterns []*shared.URLPattern) error {
|
||||||
if pageId <= 0 {
|
if pageId <= 0 {
|
||||||
return errors.New("invalid pageId")
|
return errors.New("invalid pageId")
|
||||||
}
|
}
|
||||||
@@ -126,6 +149,29 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin
|
|||||||
op.Url = url
|
op.Url = url
|
||||||
op.Body = body
|
op.Body = body
|
||||||
op.NewStatus = newStatus
|
op.NewStatus = newStatus
|
||||||
|
|
||||||
|
{
|
||||||
|
if exceptURLPatterns == nil {
|
||||||
|
exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
}
|
||||||
|
exceptURLPatternsJSON, err := json.Marshal(exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.ExceptURLPatterns = exceptURLPatternsJSON
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if onlyURLPatterns == nil {
|
||||||
|
onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
}
|
||||||
|
onlyURLPatternsJSON, err := json.Marshal(onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op.OnlyURLPatterns = onlyURLPatternsJSON
|
||||||
|
}
|
||||||
|
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -156,6 +202,14 @@ func (this *HTTPPageDAO) ClonePage(tx *dbs.Tx, fromPageId int64) (newPageId int6
|
|||||||
op.Body = page.Body
|
op.Body = page.Body
|
||||||
op.BodyType = page.BodyType
|
op.BodyType = page.BodyType
|
||||||
op.State = page.State
|
op.State = page.State
|
||||||
|
|
||||||
|
if len(page.ExceptURLPatterns) > 0 {
|
||||||
|
op.ExceptURLPatterns = page.ExceptURLPatterns
|
||||||
|
}
|
||||||
|
if len(page.OnlyURLPatterns) > 0 {
|
||||||
|
op.OnlyURLPatterns = page.OnlyURLPatterns
|
||||||
|
}
|
||||||
|
|
||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +233,7 @@ func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *u
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &serverconfigs.HTTPPageConfig{}
|
var config = &serverconfigs.HTTPPageConfig{}
|
||||||
config.Id = int64(page.Id)
|
config.Id = int64(page.Id)
|
||||||
config.IsOn = page.IsOn
|
config.IsOn = page.IsOn
|
||||||
config.NewStatus = int(page.NewStatus)
|
config.NewStatus = int(page.NewStatus)
|
||||||
@@ -188,7 +242,7 @@ func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *u
|
|||||||
config.BodyType = page.BodyType
|
config.BodyType = page.BodyType
|
||||||
|
|
||||||
if len(page.BodyType) == 0 {
|
if len(page.BodyType) == 0 {
|
||||||
page.BodyType = shared.BodyTypeURL
|
page.BodyType = serverconfigs.HTTPPageBodyTypeURL
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(page.StatusList) > 0 {
|
if len(page.StatusList) > 0 {
|
||||||
@@ -202,6 +256,28 @@ func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *u
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(page.ExceptURLPatterns) > 0 {
|
||||||
|
var exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
err = json.Unmarshal(page.ExceptURLPatterns, &exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(exceptURLPatterns) > 0 {
|
||||||
|
config.ExceptURLPatterns = exceptURLPatterns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(page.OnlyURLPatterns) > 0 {
|
||||||
|
var onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
err = json.Unmarshal(page.OnlyURLPatterns, &onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(onlyURLPatterns) > 0 {
|
||||||
|
config.OnlyURLPatterns = onlyURLPatterns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cacheMap != nil {
|
if cacheMap != nil {
|
||||||
cacheMap.Put(cacheKey, config)
|
cacheMap.Put(cacheKey, config)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,33 +2,53 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTPPageField_Id dbs.FieldName = "id" // ID
|
||||||
|
HTTPPageField_AdminId dbs.FieldName = "adminId" // 管理员ID
|
||||||
|
HTTPPageField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
HTTPPageField_IsOn dbs.FieldName = "isOn" // 是否启用
|
||||||
|
HTTPPageField_StatusList dbs.FieldName = "statusList" // 状态列表
|
||||||
|
HTTPPageField_Url dbs.FieldName = "url" // 页面URL
|
||||||
|
HTTPPageField_NewStatus dbs.FieldName = "newStatus" // 新状态码
|
||||||
|
HTTPPageField_State dbs.FieldName = "state" // 状态
|
||||||
|
HTTPPageField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
HTTPPageField_Body dbs.FieldName = "body" // 页面内容
|
||||||
|
HTTPPageField_BodyType dbs.FieldName = "bodyType" // 内容类型
|
||||||
|
HTTPPageField_ExceptURLPatterns dbs.FieldName = "exceptURLPatterns" // 例外URL
|
||||||
|
HTTPPageField_OnlyURLPatterns dbs.FieldName = "onlyURLPatterns" // 限制URL
|
||||||
|
)
|
||||||
|
|
||||||
// HTTPPage 特殊页面
|
// HTTPPage 特殊页面
|
||||||
type HTTPPage struct {
|
type HTTPPage struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
UserId uint32 `field:"userId"` // 用户ID
|
UserId uint32 `field:"userId"` // 用户ID
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
IsOn bool `field:"isOn"` // 是否启用
|
||||||
StatusList dbs.JSON `field:"statusList"` // 状态列表
|
StatusList dbs.JSON `field:"statusList"` // 状态列表
|
||||||
Url string `field:"url"` // 页面URL
|
Url string `field:"url"` // 页面URL
|
||||||
NewStatus int32 `field:"newStatus"` // 新状态码
|
NewStatus int32 `field:"newStatus"` // 新状态码
|
||||||
State uint8 `field:"state"` // 状态
|
State uint8 `field:"state"` // 状态
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
Body string `field:"body"` // 页面内容
|
Body string `field:"body"` // 页面内容
|
||||||
BodyType string `field:"bodyType"` // 内容类型
|
BodyType string `field:"bodyType"` // 内容类型
|
||||||
|
ExceptURLPatterns dbs.JSON `field:"exceptURLPatterns"` // 例外URL
|
||||||
|
OnlyURLPatterns dbs.JSON `field:"onlyURLPatterns"` // 限制URL
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPPageOperator struct {
|
type HTTPPageOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
StatusList interface{} // 状态列表
|
StatusList any // 状态列表
|
||||||
Url interface{} // 页面URL
|
Url any // 页面URL
|
||||||
NewStatus interface{} // 新状态码
|
NewStatus any // 新状态码
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
Body interface{} // 页面内容
|
Body any // 页面内容
|
||||||
BodyType interface{} // 内容类型
|
BodyType any // 内容类型
|
||||||
|
ExceptURLPatterns any // 例外URL
|
||||||
|
OnlyURLPatterns any // 限制URL
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPPageOperator() *HTTPPageOperator {
|
func NewHTTPPageOperator() *HTTPPageOperator {
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ const (
|
|||||||
type MessageType = string
|
type MessageType = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
MessageTypeAll MessageType = "*"
|
||||||
|
|
||||||
// 这里的命名问题(首字母大写)为历史遗留问题,暂不修改
|
// 这里的命名问题(首字母大写)为历史遗留问题,暂不修改
|
||||||
|
|
||||||
MessageTypeHealthCheckFailed MessageType = "HealthCheckFailed" // 节点健康检查失败
|
MessageTypeHealthCheckFailed MessageType = "HealthCheckFailed" // 节点健康检查失败
|
||||||
@@ -109,14 +111,17 @@ func (this *MessageDAO) FindEnabledMessage(tx *dbs.Tx, id int64) (*Message, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateClusterMessage 创建集群消息
|
// CreateClusterMessage 创建集群消息
|
||||||
func (this *MessageDAO) CreateClusterMessage(tx *dbs.Tx, role string, clusterId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte) error {
|
func (this *MessageDAO) CreateClusterMessage(tx *dbs.Tx, role string, clusterId int64, messageType MessageType, level string, subject string, shortBody string, body string, paramsJSON []byte) error {
|
||||||
_, err := this.createMessage(tx, role, clusterId, 0, messageType, level, subject, body, paramsJSON)
|
if len(shortBody) == 0 {
|
||||||
|
shortBody = body
|
||||||
|
}
|
||||||
|
_, err := this.createMessage(tx, role, clusterId, 0, messageType, level, subject, shortBody, paramsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送给媒介接收人
|
// 发送给媒介接收人
|
||||||
err = SharedMessageTaskDAO.CreateMessageTasks(tx, role, 0, 0, 0, messageType, subject, body)
|
err = SharedMessageTaskDAO.CreateMessageTasks(tx, role, clusterId, 0, 0, messageType, subject, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func TestMessageDAO_CreateClusterMessage(t *testing.T) {
|
|||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
|
|
||||||
dao := NewMessageDAO()
|
dao := NewMessageDAO()
|
||||||
err := dao.CreateClusterMessage(tx, nodeconfigs.NodeRoleNode, 1, "test", "error", "123", "123", []byte("456"))
|
err := dao.CreateClusterMessage(tx, nodeconfigs.NodeRoleNode, 1, "test", "error", "123", "123", "123", []byte("456"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import (
|
|||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/lists"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -34,7 +32,7 @@ func init() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启用条目
|
// EnableMessageMedia 启用条目
|
||||||
func (this *MessageMediaDAO) EnableMessageMedia(tx *dbs.Tx, id int64) error {
|
func (this *MessageMediaDAO) EnableMessageMedia(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -43,7 +41,7 @@ func (this *MessageMediaDAO) EnableMessageMedia(tx *dbs.Tx, id int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用条目
|
// DisableMessageMedia 禁用条目
|
||||||
func (this *MessageMediaDAO) DisableMessageMedia(tx *dbs.Tx, id int64) error {
|
func (this *MessageMediaDAO) DisableMessageMedia(tx *dbs.Tx, id int64) error {
|
||||||
_, err := this.Query(tx).
|
_, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -52,7 +50,7 @@ func (this *MessageMediaDAO) DisableMessageMedia(tx *dbs.Tx, id int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查找启用中的条目
|
// FindEnabledMessageMedia 查找启用中的条目
|
||||||
func (this *MessageMediaDAO) FindEnabledMessageMedia(tx *dbs.Tx, id int64) (*MessageMedia, error) {
|
func (this *MessageMediaDAO) FindEnabledMessageMedia(tx *dbs.Tx, id int64) (*MessageMedia, error) {
|
||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -64,7 +62,7 @@ func (this *MessageMediaDAO) FindEnabledMessageMedia(tx *dbs.Tx, id int64) (*Mes
|
|||||||
return result.(*MessageMedia), err
|
return result.(*MessageMedia), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据主键查找名称
|
// FindMessageMediaName 根据主键查找名称
|
||||||
func (this *MessageMediaDAO) FindMessageMediaName(tx *dbs.Tx, id int64) (string, error) {
|
func (this *MessageMediaDAO) FindMessageMediaName(tx *dbs.Tx, id int64) (string, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
Pk(id).
|
Pk(id).
|
||||||
@@ -72,7 +70,7 @@ func (this *MessageMediaDAO) FindMessageMediaName(tx *dbs.Tx, id int64) (string,
|
|||||||
FindStringCol("")
|
FindStringCol("")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询所有可用媒介
|
// FindAllEnabledMessageMedias 查询所有可用媒介
|
||||||
func (this *MessageMediaDAO) FindAllEnabledMessageMedias(tx *dbs.Tx) (result []*MessageMedia, err error) {
|
func (this *MessageMediaDAO) FindAllEnabledMessageMedias(tx *dbs.Tx) (result []*MessageMedia, err error) {
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
State(MessageMediaStateEnabled).
|
State(MessageMediaStateEnabled).
|
||||||
@@ -82,74 +80,3 @@ func (this *MessageMediaDAO) FindAllEnabledMessageMedias(tx *dbs.Tx) (result []*
|
|||||||
FindAll()
|
FindAll()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置当前所有可用的媒介
|
|
||||||
func (this *MessageMediaDAO) UpdateMessageMedias(tx *dbs.Tx, mediaMaps []maps.Map) error {
|
|
||||||
// 新的媒介信息
|
|
||||||
mediaTypes := []string{}
|
|
||||||
for index, m := range mediaMaps {
|
|
||||||
order := len(mediaMaps) - index
|
|
||||||
mediaType := m.GetString("type")
|
|
||||||
mediaTypes = append(mediaTypes, mediaType)
|
|
||||||
|
|
||||||
name := m.GetString("name")
|
|
||||||
description := m.GetString("description")
|
|
||||||
userDescription := m.GetString("userDescription")
|
|
||||||
isOn := m.GetBool("isOn")
|
|
||||||
|
|
||||||
mediaId, err := this.Query(tx).
|
|
||||||
ResultPk().
|
|
||||||
Attr("type", mediaType).
|
|
||||||
FindInt64Col(0)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var op = NewMessageMediaOperator()
|
|
||||||
if mediaId > 0 {
|
|
||||||
op.Id = mediaId
|
|
||||||
}
|
|
||||||
op.Name = name
|
|
||||||
op.Type = mediaType
|
|
||||||
op.Description = description
|
|
||||||
op.UserDescription = userDescription
|
|
||||||
op.IsOn = isOn
|
|
||||||
op.Order = order
|
|
||||||
op.State = MessageMediaStateEnabled
|
|
||||||
err = this.Save(tx, op)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 老的媒介信息
|
|
||||||
ones, err := this.Query(tx).
|
|
||||||
FindAll()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, one := range ones {
|
|
||||||
mediaType := one.(*MessageMedia).Type
|
|
||||||
if !lists.ContainsString(mediaTypes, mediaType) {
|
|
||||||
err := this.Query(tx).
|
|
||||||
Pk(one.(*MessageMedia).Id).
|
|
||||||
Set("state", MessageMediaStateDisabled).
|
|
||||||
UpdateQuickly()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据类型查找媒介
|
|
||||||
func (this *MessageMediaDAO) FindEnabledMediaWithType(tx *dbs.Tx, mediaType string) (*MessageMedia, error) {
|
|
||||||
one, err := this.Query(tx).
|
|
||||||
Attr("type", mediaType).
|
|
||||||
State(MessageMediaStateEnabled).
|
|
||||||
Find()
|
|
||||||
if one == nil || err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return one.(*MessageMedia), nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -98,24 +98,6 @@ func (this *MessageReceiverDAO) CreateReceiver(tx *dbs.Tx, role string, clusterI
|
|||||||
return this.SaveInt64(tx, op)
|
return this.SaveInt64(tx, op)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledReceivers 查询接收人
|
|
||||||
func (this *MessageReceiverDAO) FindAllEnabledReceivers(tx *dbs.Tx, role string, clusterId int64, nodeId int64, serverId int64, messageType string) (result []*MessageReceiver, err error) {
|
|
||||||
query := this.Query(tx)
|
|
||||||
if len(messageType) > 0 {
|
|
||||||
query.Attr("type", []string{"*", messageType}) // *表示所有的
|
|
||||||
}
|
|
||||||
_, err = query.
|
|
||||||
Attr("role", role).
|
|
||||||
Attr("clusterId", clusterId).
|
|
||||||
Attr("nodeId", nodeId).
|
|
||||||
Attr("serverId", serverId).
|
|
||||||
State(MessageReceiverStateEnabled).
|
|
||||||
AscPk().
|
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledReceivers 计算接收人数量
|
// CountAllEnabledReceivers 计算接收人数量
|
||||||
func (this *MessageReceiverDAO) CountAllEnabledReceivers(tx *dbs.Tx, role string, clusterId int64, nodeId int64, serverId int64, messageType string) (int64, error) {
|
func (this *MessageReceiverDAO) CountAllEnabledReceivers(tx *dbs.Tx, role string, clusterId int64, nodeId int64, serverId int64, messageType string) (int64, error) {
|
||||||
query := this.Query(tx)
|
query := this.Query(tx)
|
||||||
@@ -146,6 +128,8 @@ func (this *MessageReceiverDAO) FindEnabledBestFitReceivers(tx *dbs.Tx, role str
|
|||||||
} else if nodeId > 0 {
|
} else if nodeId > 0 {
|
||||||
query.Attr("nodeId", nodeId)
|
query.Attr("nodeId", nodeId)
|
||||||
} else if clusterId > 0 {
|
} else if clusterId > 0 {
|
||||||
|
query.Attr("serverId", 0)
|
||||||
|
query.Attr("nodeId", 0)
|
||||||
query.Attr("clusterId", clusterId)
|
query.Attr("clusterId", clusterId)
|
||||||
}
|
}
|
||||||
_, err = query.
|
_, err = query.
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
|
||||||
_ "github.com/iwind/TeaGo/bootstrap"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/logs"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMessageReceiverDAO_FindEnabledBestFitReceivers(t *testing.T) {
|
|
||||||
var tx *dbs.Tx
|
|
||||||
|
|
||||||
{
|
|
||||||
receivers, err := NewMessageReceiverDAO().FindEnabledBestFitReceivers(tx, nodeconfigs.NodeRoleNode, 18, 1, 2, "*")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
logs.PrintAsJSON(receivers, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
receivers, err := NewMessageReceiverDAO().FindEnabledBestFitReceivers(tx, nodeconfigs.NodeRoleNode, 30, 1, 2, "*")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
logs.PrintAsJSON(receivers, t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,31 +1,19 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
"github.com/TeaOSLab/EdgeAPI/internal/goman"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
stringutil "github.com/iwind/TeaGo/utils/string"
|
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageTaskStatus = int
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MessageTaskStateEnabled = 1 // 已启用
|
MessageTaskStateEnabled = 1 // 已启用
|
||||||
MessageTaskStateDisabled = 0 // 已禁用
|
MessageTaskStateDisabled = 0 // 已禁用
|
||||||
|
|
||||||
MessageTaskStatusNone MessageTaskStatus = 0 // 普通状态
|
|
||||||
MessageTaskStatusSending MessageTaskStatus = 1 // 发送中
|
|
||||||
MessageTaskStatusSuccess MessageTaskStatus = 2 // 发送成功
|
|
||||||
MessageTaskStatusFailed MessageTaskStatus = 3 // 发送失败
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MessageTaskDAO dbs.DAO
|
type MessageTaskDAO dbs.DAO
|
||||||
@@ -94,151 +82,6 @@ func (this *MessageTaskDAO) FindEnabledMessageTask(tx *dbs.Tx, id int64) (*Messa
|
|||||||
return result.(*MessageTask), err
|
return result.(*MessageTask), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateMessageTask 创建任务
|
|
||||||
func (this *MessageTaskDAO) CreateMessageTask(tx *dbs.Tx, recipientId int64, instanceId int64, user string, subject string, body string, isPrimary bool) (int64, error) {
|
|
||||||
if !teaconst.IsPlus {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var hash = stringutil.Md5(types.String(recipientId) + "@" + types.String(instanceId) + "@" + user + "@" + subject + "@" + types.String(isPrimary))
|
|
||||||
recipientInstanceId, err := SharedMessageRecipientDAO.FindRecipientInstanceId(tx, recipientId)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if recipientInstanceId > 0 {
|
|
||||||
hashLifeSeconds, err := SharedMessageMediaInstanceDAO.FindInstanceHashLifeSeconds(tx, recipientInstanceId)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if hashLifeSeconds >= 0 { // 意味着此值如果小于0,则不做判断
|
|
||||||
lastMessageAt, err := this.Query(tx).
|
|
||||||
Attr("hash", hash).
|
|
||||||
Result("createdAt").
|
|
||||||
DescPk().
|
|
||||||
FindInt64Col(0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对于同一个人N分钟内消息不重复发送
|
|
||||||
if hashLifeSeconds <= 0 {
|
|
||||||
hashLifeSeconds = 60
|
|
||||||
}
|
|
||||||
if lastMessageAt > 0 && time.Now().Unix()-lastMessageAt < int64(hashLifeSeconds) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = NewMessageTaskOperator()
|
|
||||||
op.RecipientId = recipientId
|
|
||||||
op.InstanceId = instanceId
|
|
||||||
op.Hash = hash
|
|
||||||
op.User = user
|
|
||||||
op.Subject = subject
|
|
||||||
op.Body = body
|
|
||||||
op.IsPrimary = isPrimary
|
|
||||||
op.Day = timeutil.Format("Ymd")
|
|
||||||
op.Status = MessageTaskStatusNone
|
|
||||||
op.State = MessageTaskStateEnabled
|
|
||||||
return this.SaveInt64(tx, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindSendingMessageTasks 查找需要发送的任务
|
|
||||||
func (this *MessageTaskDAO) FindSendingMessageTasks(tx *dbs.Tx, size int64) (result []*MessageTask, err error) {
|
|
||||||
if size <= 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
_, err = this.Query(tx).
|
|
||||||
State(MessageTaskStateEnabled).
|
|
||||||
Attr("status", MessageTaskStatusNone).
|
|
||||||
Where("(recipientId=0 OR recipientId IN (SELECT id FROM "+SharedMessageRecipientDAO.Table+" WHERE state=1 AND isOn=1 AND (timeFrom IS NULL OR timeTo IS NULL OR :time BETWEEN timeFrom AND timeTo)))").
|
|
||||||
Param("time", timeutil.Format("H:i:s")).
|
|
||||||
Desc("isPrimary").
|
|
||||||
AscPk().
|
|
||||||
Limit(size).
|
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountMessageTasksWithStatus 根据状态计算任务数量
|
|
||||||
func (this *MessageTaskDAO) CountMessageTasksWithStatus(tx *dbs.Tx, status MessageTaskStatus) (int64, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
State(MessageTaskStateEnabled).
|
|
||||||
Attr("status", status).
|
|
||||||
Count()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMessageTasksWithStatus 根据状态列出单页任务
|
|
||||||
func (this *MessageTaskDAO) ListMessageTasksWithStatus(tx *dbs.Tx, status MessageTaskStatus, offset int64, size int64) (result []*MessageTask, err error) {
|
|
||||||
_, err = this.Query(tx).
|
|
||||||
State(MessageTaskStateEnabled).
|
|
||||||
Attr("status", status).
|
|
||||||
Desc("isPrimary").
|
|
||||||
AscPk().
|
|
||||||
Offset(offset).
|
|
||||||
Limit(size).
|
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageTaskStatus 设置发送的状态
|
|
||||||
func (this *MessageTaskDAO) UpdateMessageTaskStatus(tx *dbs.Tx, taskId int64, status MessageTaskStatus, result []byte) error {
|
|
||||||
if taskId <= 0 {
|
|
||||||
return errors.New("invalid taskId")
|
|
||||||
}
|
|
||||||
var op = NewMessageTaskOperator()
|
|
||||||
op.Id = taskId
|
|
||||||
op.Status = status
|
|
||||||
op.SentAt = time.Now().Unix()
|
|
||||||
if len(result) > 0 {
|
|
||||||
op.Result = result
|
|
||||||
}
|
|
||||||
return this.Save(tx, op)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMessageTasks 从集群、节点或者服务中创建任务
|
|
||||||
func (this *MessageTaskDAO) CreateMessageTasks(tx *dbs.Tx, role nodeconfigs.NodeRole, clusterId int64, nodeId int64, serverId int64, messageType MessageType, subject string, body string) error {
|
|
||||||
if !teaconst.IsPlus {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
receivers, err := SharedMessageReceiverDAO.FindEnabledBestFitReceivers(tx, role, clusterId, nodeId, serverId, messageType)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
allRecipientIds := []int64{}
|
|
||||||
for _, receiver := range receivers {
|
|
||||||
if receiver.RecipientId > 0 {
|
|
||||||
allRecipientIds = append(allRecipientIds, int64(receiver.RecipientId))
|
|
||||||
} else if receiver.RecipientGroupId > 0 {
|
|
||||||
recipientIds, err := SharedMessageRecipientDAO.FindAllEnabledAndOnRecipientIdsWithGroup(tx, int64(receiver.RecipientGroupId))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
allRecipientIds = append(allRecipientIds, recipientIds...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sentMap := map[int64]bool{} // recipientId => bool 用来检查是否已经发送,防止重复发送给某个接收人
|
|
||||||
for _, recipientId := range allRecipientIds {
|
|
||||||
_, ok := sentMap[recipientId]
|
|
||||||
if ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
sentMap[recipientId] = true
|
|
||||||
_, err := this.CreateMessageTask(tx, recipientId, 0, "", subject, body, false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CleanExpiredMessageTasks 清理
|
// CleanExpiredMessageTasks 清理
|
||||||
func (this *MessageTaskDAO) CleanExpiredMessageTasks(tx *dbs.Tx, days int) error {
|
func (this *MessageTaskDAO) CleanExpiredMessageTasks(tx *dbs.Tx, days int) error {
|
||||||
if days <= 0 {
|
if days <= 0 {
|
||||||
|
|||||||
14
internal/db/models/message_task_dao_ext.go
Normal file
14
internal/db/models/message_task_dao_ext.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateMessageTasks 从集群、节点或者服务中创建任务
|
||||||
|
func (this *MessageTaskDAO) CreateMessageTasks(tx *dbs.Tx, role nodeconfigs.NodeRole, clusterId int64, nodeId int64, serverId int64, messageType MessageType, subject string, body string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -8,20 +8,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMessageTaskDAO_FindSendingMessageTasks(t *testing.T) {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
var tx *dbs.Tx
|
|
||||||
tasks, err := models.NewMessageTaskDAO().FindSendingMessageTasks(tx, 100)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
t.Log(len(tasks), "tasks")
|
|
||||||
for _, task := range tasks {
|
|
||||||
t.Log("task:", task.Id, "recipient:", task.RecipientId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMessageTaskDAO_CleanExpiredMessageTasks(t *testing.T) {
|
func TestMessageTaskDAO_CleanExpiredMessageTasks(t *testing.T) {
|
||||||
var dao = models.NewMessageTaskDAO()
|
var dao = models.NewMessageTaskDAO()
|
||||||
var tx *dbs.Tx
|
var tx *dbs.Tx
|
||||||
|
|||||||
@@ -1,215 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"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/rands"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
MonitorNodeStateEnabled = 1 // 已启用
|
|
||||||
MonitorNodeStateDisabled = 0 // 已禁用
|
|
||||||
)
|
|
||||||
|
|
||||||
type MonitorNodeDAO dbs.DAO
|
|
||||||
|
|
||||||
func NewMonitorNodeDAO() *MonitorNodeDAO {
|
|
||||||
return dbs.NewDAO(&MonitorNodeDAO{
|
|
||||||
DAOObject: dbs.DAOObject{
|
|
||||||
DB: Tea.Env,
|
|
||||||
Table: "edgeMonitorNodes",
|
|
||||||
Model: new(MonitorNode),
|
|
||||||
PkName: "id",
|
|
||||||
},
|
|
||||||
}).(*MonitorNodeDAO)
|
|
||||||
}
|
|
||||||
|
|
||||||
var SharedMonitorNodeDAO *MonitorNodeDAO
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
dbs.OnReady(func() {
|
|
||||||
SharedMonitorNodeDAO = NewMonitorNodeDAO()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnableMonitorNode 启用条目
|
|
||||||
func (this *MonitorNodeDAO) EnableMonitorNode(tx *dbs.Tx, id int64) error {
|
|
||||||
_, err := this.Query(tx).
|
|
||||||
Pk(id).
|
|
||||||
Set("state", MonitorNodeStateEnabled).
|
|
||||||
Update()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableMonitorNode 禁用条目
|
|
||||||
func (this *MonitorNodeDAO) DisableMonitorNode(tx *dbs.Tx, nodeId int64) error {
|
|
||||||
_, err := this.Query(tx).
|
|
||||||
Pk(nodeId).
|
|
||||||
Set("state", MonitorNodeStateDisabled).
|
|
||||||
Update()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除运行日志
|
|
||||||
return SharedNodeLogDAO.DeleteNodeLogs(tx, nodeconfigs.NodeRoleMonitor, nodeId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMonitorNode 查找启用中的条目
|
|
||||||
func (this *MonitorNodeDAO) FindEnabledMonitorNode(tx *dbs.Tx, id int64) (*MonitorNode, error) {
|
|
||||||
result, err := this.Query(tx).
|
|
||||||
Pk(id).
|
|
||||||
Attr("state", MonitorNodeStateEnabled).
|
|
||||||
Find()
|
|
||||||
if result == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result.(*MonitorNode), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindMonitorNodeName 根据主键查找名称
|
|
||||||
func (this *MonitorNodeDAO) FindMonitorNodeName(tx *dbs.Tx, id int64) (string, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(id).
|
|
||||||
Result("name").
|
|
||||||
FindStringCol("")
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindAllEnabledMonitorNodes 列出所有可用监控节点
|
|
||||||
func (this *MonitorNodeDAO) FindAllEnabledMonitorNodes(tx *dbs.Tx) (result []*MonitorNode, err error) {
|
|
||||||
_, err = this.Query(tx).
|
|
||||||
State(MonitorNodeStateEnabled).
|
|
||||||
Desc("order").
|
|
||||||
AscPk().
|
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledMonitorNodes 计算监控节点数量
|
|
||||||
func (this *MonitorNodeDAO) CountAllEnabledMonitorNodes(tx *dbs.Tx) (int64, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
State(MonitorNodeStateEnabled).
|
|
||||||
Count()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListEnabledMonitorNodes 列出单页的监控节点
|
|
||||||
func (this *MonitorNodeDAO) ListEnabledMonitorNodes(tx *dbs.Tx, offset int64, size int64) (result []*MonitorNode, err error) {
|
|
||||||
_, err = this.Query(tx).
|
|
||||||
State(MonitorNodeStateEnabled).
|
|
||||||
Offset(offset).
|
|
||||||
Limit(size).
|
|
||||||
Desc("order").
|
|
||||||
DescPk().
|
|
||||||
Slice(&result).
|
|
||||||
FindAll()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMonitorNode 创建监控节点
|
|
||||||
func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, description string, isOn bool) (nodeId int64, err error) {
|
|
||||||
uniqueId, err := this.GenUniqueId(tx)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
secret := rands.String(32)
|
|
||||||
err = NewApiTokenDAO().CreateAPIToken(tx, uniqueId, secret, nodeconfigs.NodeRoleMonitor)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = NewMonitorNodeOperator()
|
|
||||||
op.IsOn = isOn
|
|
||||||
op.UniqueId = uniqueId
|
|
||||||
op.Secret = secret
|
|
||||||
op.Name = name
|
|
||||||
op.Description = description
|
|
||||||
op.State = NodeStateEnabled
|
|
||||||
err = this.Save(tx, op)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return types.Int64(op.Id), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMonitorNode 修改监控节点
|
|
||||||
func (this *MonitorNodeDAO) UpdateMonitorNode(tx *dbs.Tx, nodeId int64, name string, description string, isOn bool) error {
|
|
||||||
if nodeId <= 0 {
|
|
||||||
return errors.New("invalid nodeId")
|
|
||||||
}
|
|
||||||
|
|
||||||
var op = NewMonitorNodeOperator()
|
|
||||||
op.Id = nodeId
|
|
||||||
op.Name = name
|
|
||||||
op.Description = description
|
|
||||||
op.IsOn = isOn
|
|
||||||
err := this.Save(tx, op)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMonitorNodeWithUniqueId 根据唯一ID获取节点信息
|
|
||||||
func (this *MonitorNodeDAO) FindEnabledMonitorNodeWithUniqueId(tx *dbs.Tx, uniqueId string) (*MonitorNode, error) {
|
|
||||||
result, err := this.Query(tx).
|
|
||||||
Attr("uniqueId", uniqueId).
|
|
||||||
Attr("state", MonitorNodeStateEnabled).
|
|
||||||
Find()
|
|
||||||
if result == nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return result.(*MonitorNode), err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMonitorNodeIdWithUniqueId 根据唯一ID获取节点ID
|
|
||||||
func (this *MonitorNodeDAO) FindEnabledMonitorNodeIdWithUniqueId(tx *dbs.Tx, uniqueId string) (int64, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
Attr("uniqueId", uniqueId).
|
|
||||||
Attr("state", MonitorNodeStateEnabled).
|
|
||||||
ResultPk().
|
|
||||||
FindInt64Col(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GenUniqueId 生成唯一ID
|
|
||||||
func (this *MonitorNodeDAO) GenUniqueId(tx *dbs.Tx) (string, error) {
|
|
||||||
for {
|
|
||||||
uniqueId := rands.HexString(32)
|
|
||||||
ok, err := this.Query(tx).
|
|
||||||
Attr("uniqueId", uniqueId).
|
|
||||||
Exist()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return uniqueId, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateNodeStatus 更改节点状态
|
|
||||||
func (this *MonitorNodeDAO) UpdateNodeStatus(tx *dbs.Tx, nodeId int64, statusJSON []byte) error {
|
|
||||||
if statusJSON == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
_, err := this.Query(tx).
|
|
||||||
Pk(nodeId).
|
|
||||||
Set("status", string(statusJSON)).
|
|
||||||
Update()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllLowerVersionNodes 计算所有节点中低于某个版本的节点数量
|
|
||||||
func (this *MonitorNodeDAO) CountAllLowerVersionNodes(tx *dbs.Tx, version string) (int64, error) {
|
|
||||||
return this.Query(tx).
|
|
||||||
State(MonitorNodeStateEnabled).
|
|
||||||
Attr("isOn", true).
|
|
||||||
Where("status IS NOT NULL").
|
|
||||||
Where("(JSON_EXTRACT(status, '$.buildVersionCode') IS NULL OR JSON_EXTRACT(status, '$.buildVersionCode')<:version)").
|
|
||||||
Param("version", utils.VersionToLong(version)).
|
|
||||||
Count()
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package models
|
|
||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
|
||||||
|
|
||||||
// MonitorNode 监控节点
|
|
||||||
type MonitorNode struct {
|
|
||||||
Id uint32 `field:"id"` // ID
|
|
||||||
IsOn bool `field:"isOn"` // 是否启用
|
|
||||||
UniqueId string `field:"uniqueId"` // 唯一ID
|
|
||||||
Secret string `field:"secret"` // 密钥
|
|
||||||
Name string `field:"name"` // 名称
|
|
||||||
Description string `field:"description"` // 描述
|
|
||||||
Order uint32 `field:"order"` // 排序
|
|
||||||
State uint8 `field:"state"` // 状态
|
|
||||||
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
|
||||||
Weight uint32 `field:"weight"` // 权重
|
|
||||||
Status dbs.JSON `field:"status"` // 运行状态
|
|
||||||
}
|
|
||||||
|
|
||||||
type MonitorNodeOperator struct {
|
|
||||||
Id interface{} // ID
|
|
||||||
IsOn interface{} // 是否启用
|
|
||||||
UniqueId interface{} // 唯一ID
|
|
||||||
Secret interface{} // 密钥
|
|
||||||
Name interface{} // 名称
|
|
||||||
Description interface{} // 描述
|
|
||||||
Order interface{} // 排序
|
|
||||||
State interface{} // 状态
|
|
||||||
CreatedAt interface{} // 创建时间
|
|
||||||
AdminId interface{} // 管理员ID
|
|
||||||
Weight interface{} // 权重
|
|
||||||
Status interface{} // 运行状态
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewMonitorNodeOperator() *MonitorNodeOperator {
|
|
||||||
return &MonitorNodeOperator{}
|
|
||||||
}
|
|
||||||
@@ -126,7 +126,7 @@ func (this *NodeClusterDAO) FindAllEnableClusterIds(tx *dbs.Tx) (result []int64,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateCluster 创建集群
|
// CreateCluster 创建集群
|
||||||
func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string, grantId int64, installDir string, dnsDomainId int64, dnsName string, dnsTTL int32, cachePolicyId int64, httpFirewallPolicyId int64, systemServices map[string]maps.Map, globalServerConfig *serverconfigs.GlobalServerConfig, autoInstallNftables bool) (clusterId int64, err error) {
|
func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string, grantId int64, installDir string, dnsDomainId int64, dnsName string, dnsTTL int32, cachePolicyId int64, httpFirewallPolicyId int64, systemServices map[string]maps.Map, globalServerConfig *serverconfigs.GlobalServerConfig, autoInstallNftables bool, autoSystemTuning bool) (clusterId int64, err error) {
|
||||||
uniqueId, err := this.GenUniqueId(tx)
|
uniqueId, err := this.GenUniqueId(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -189,6 +189,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
op.UniqueId = uniqueId
|
op.UniqueId = uniqueId
|
||||||
op.Secret = secret
|
op.Secret = secret
|
||||||
op.AutoInstallNftables = autoInstallNftables
|
op.AutoInstallNftables = autoInstallNftables
|
||||||
|
op.AutoSystemTuning = autoSystemTuning
|
||||||
op.State = NodeClusterStateEnabled
|
op.State = NodeClusterStateEnabled
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -199,7 +200,7 @@ func (this *NodeClusterDAO) CreateCluster(tx *dbs.Tx, adminId int64, name string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdateCluster 修改集群
|
// UpdateCluster 修改集群
|
||||||
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig, autoRemoteStart bool, autoInstallTables bool, sshParams *nodeconfigs.SSHParams) error {
|
func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name string, grantId int64, installDir string, timezone string, nodeMaxThreads int32, autoOpenPorts bool, clockConfig *nodeconfigs.ClockConfig, autoRemoteStart bool, autoInstallTables bool, sshParams *nodeconfigs.SSHParams, autoSystemTuning bool) error {
|
||||||
if clusterId <= 0 {
|
if clusterId <= 0 {
|
||||||
return errors.New("invalid clusterId")
|
return errors.New("invalid clusterId")
|
||||||
}
|
}
|
||||||
@@ -226,6 +227,7 @@ func (this *NodeClusterDAO) UpdateCluster(tx *dbs.Tx, clusterId int64, name stri
|
|||||||
|
|
||||||
op.AutoRemoteStart = autoRemoteStart
|
op.AutoRemoteStart = autoRemoteStart
|
||||||
op.AutoInstallNftables = autoInstallTables
|
op.AutoInstallNftables = autoInstallTables
|
||||||
|
op.AutoSystemTuning = autoSystemTuning
|
||||||
|
|
||||||
if sshParams != nil {
|
if sshParams != nil {
|
||||||
sshParamsJSON, err := json.Marshal(sshParams)
|
sshParamsJSON, err := json.Marshal(sshParams)
|
||||||
@@ -950,11 +952,12 @@ func (this *NodeClusterDAO) GenUniqueId(tx *dbs.Tx) (string, error) {
|
|||||||
|
|
||||||
// FindLatestNodeClusters 查询最近访问的集群
|
// FindLatestNodeClusters 查询最近访问的集群
|
||||||
func (this *NodeClusterDAO) FindLatestNodeClusters(tx *dbs.Tx, size int64) (result []*NodeCluster, err error) {
|
func (this *NodeClusterDAO) FindLatestNodeClusters(tx *dbs.Tx, size int64) (result []*NodeCluster, err error) {
|
||||||
itemTable := SharedLatestItemDAO.Table
|
var itemTable = SharedLatestItemDAO.Table
|
||||||
itemType := LatestItemTypeCluster
|
var itemType = LatestItemTypeCluster
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
Result(this.Table+".id", this.Table+".name").
|
Result(this.Table+".id", this.Table+".name").
|
||||||
Join(SharedLatestItemDAO, dbs.QueryJoinRight, this.Table+".id="+itemTable+".itemId AND "+itemTable+".itemType='"+itemType+"'").
|
Join(SharedLatestItemDAO, dbs.QueryJoinRight, this.Table+".id="+itemTable+".itemId AND "+itemTable+".itemType='"+itemType+"'").
|
||||||
|
Where(itemTable + ".updatedAt<=UNIX_TIMESTAMP()"). // VERY IMPORTANT
|
||||||
Asc("CEIL((UNIX_TIMESTAMP() - " + itemTable + ".updatedAt) / (7 * 86400))"). // 优先一个星期以内的
|
Asc("CEIL((UNIX_TIMESTAMP() - " + itemTable + ".updatedAt) / (7 * 86400))"). // 优先一个星期以内的
|
||||||
Desc(itemTable + ".count").
|
Desc(itemTable + ".count").
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
@@ -1018,7 +1021,7 @@ func (this *NodeClusterDAO) FindClusterBasicInfo(tx *dbs.Tx, clusterId int64, ca
|
|||||||
cluster, err := this.Query(tx).
|
cluster, err := this.Query(tx).
|
||||||
Pk(clusterId).
|
Pk(clusterId).
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "http3", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables").
|
Result("id", "name", "timeZone", "nodeMaxThreads", "cachePolicyId", "httpFirewallPolicyId", "autoOpenPorts", "webp", "uam", "cc", "httpPages", "http3", "isOn", "ddosProtection", "clock", "globalServerConfig", "autoInstallNftables", "autoSystemTuning", "networkSecurity").
|
||||||
Find()
|
Find()
|
||||||
if err != nil || cluster == nil {
|
if err != nil || cluster == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1266,6 +1269,57 @@ func (this *NodeClusterDAO) FindClusterHTTP3Policy(tx *dbs.Tx, clusterId int64,
|
|||||||
return policy, nil
|
return policy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateClusterNetworkSecurityPolicy 修改网络安全策略设置
|
||||||
|
func (this *NodeClusterDAO) UpdateClusterNetworkSecurityPolicy(tx *dbs.Tx, clusterId int64, networkSecurityPolicy *nodeconfigs.NetworkSecurityPolicy) error {
|
||||||
|
if networkSecurityPolicy == nil {
|
||||||
|
networkSecurityPolicy = nodeconfigs.NewNetworkSecurityPolicy()
|
||||||
|
}
|
||||||
|
|
||||||
|
networkSecurityPolicyJSON, err := json.Marshal(networkSecurityPolicy)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
Set("networkSecurity", networkSecurityPolicyJSON).
|
||||||
|
UpdateQuickly()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.NotifyNetworkSecurityUpdate(tx, clusterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindClusterNetworkSecurityPolicy 查询网络安全策略设置
|
||||||
|
func (this *NodeClusterDAO) FindClusterNetworkSecurityPolicy(tx *dbs.Tx, clusterId int64, cacheMap *utils.CacheMap) (*nodeconfigs.NetworkSecurityPolicy, error) {
|
||||||
|
var cacheKey = this.Table + ":FindClusterNetworkSecurityPolicy:" + types.String(clusterId)
|
||||||
|
if cacheMap != nil {
|
||||||
|
cache, ok := cacheMap.Get(cacheKey)
|
||||||
|
if ok {
|
||||||
|
return cache.(*nodeconfigs.NetworkSecurityPolicy), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
networkSecurityPolicyJSON, err := this.Query(tx).
|
||||||
|
Pk(clusterId).
|
||||||
|
Result("networkSecurity").
|
||||||
|
FindJSONCol()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if IsNull(networkSecurityPolicyJSON) {
|
||||||
|
return nodeconfigs.NewNetworkSecurityPolicy(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var policy = nodeconfigs.NewNetworkSecurityPolicy()
|
||||||
|
err = json.Unmarshal(networkSecurityPolicyJSON, policy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return policy, nil
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateClusterHTTPPagesPolicy 修改自定义页面设置
|
// UpdateClusterHTTPPagesPolicy 修改自定义页面设置
|
||||||
func (this *NodeClusterDAO) UpdateClusterHTTPPagesPolicy(tx *dbs.Tx, clusterId int64, httpPagesPolicy *nodeconfigs.HTTPPagesPolicy) error {
|
func (this *NodeClusterDAO) UpdateClusterHTTPPagesPolicy(tx *dbs.Tx, clusterId int64, httpPagesPolicy *nodeconfigs.HTTPPagesPolicy) error {
|
||||||
if httpPagesPolicy == nil {
|
if httpPagesPolicy == nil {
|
||||||
@@ -1449,6 +1503,11 @@ func (this *NodeClusterDAO) NotifyHTTP3Update(tx *dbs.Tx, clusterId int64) error
|
|||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTP3PolicyChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTP3PolicyChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotifyNetworkSecurityUpdate 通知网络安全策略更新
|
||||||
|
func (this *NodeClusterDAO) NotifyNetworkSecurityUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeNetworkSecurityPolicyChanged)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyHTTPPagesPolicyUpdate 通知HTTP Pages更新
|
// NotifyHTTPPagesPolicyUpdate 通知HTTP Pages更新
|
||||||
func (this *NodeClusterDAO) NotifyHTTPPagesPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
func (this *NodeClusterDAO) NotifyHTTPPagesPolicyUpdate(tx *dbs.Tx, clusterId int64) error {
|
||||||
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPPagesPolicyChanged)
|
return SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, clusterId, 0, 0, NodeTaskTypeHTTPPagesPolicyChanged)
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ const (
|
|||||||
NodeClusterField_HttpPages dbs.FieldName = "httpPages" // 自定义页面设置
|
NodeClusterField_HttpPages dbs.FieldName = "httpPages" // 自定义页面设置
|
||||||
NodeClusterField_Cc dbs.FieldName = "cc" // CC设置
|
NodeClusterField_Cc dbs.FieldName = "cc" // CC设置
|
||||||
NodeClusterField_Http3 dbs.FieldName = "http3" // HTTP3设置
|
NodeClusterField_Http3 dbs.FieldName = "http3" // HTTP3设置
|
||||||
|
NodeClusterField_AutoSystemTuning dbs.FieldName = "autoSystemTuning" // 是否自动调整系统参数
|
||||||
|
NodeClusterField_NetworkSecurity dbs.FieldName = "networkSecurity" // 网络安全策略
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeCluster 节点集群
|
// NodeCluster 节点集群
|
||||||
@@ -87,6 +89,8 @@ type NodeCluster struct {
|
|||||||
HttpPages dbs.JSON `field:"httpPages"` // 自定义页面设置
|
HttpPages dbs.JSON `field:"httpPages"` // 自定义页面设置
|
||||||
Cc dbs.JSON `field:"cc"` // CC设置
|
Cc dbs.JSON `field:"cc"` // CC设置
|
||||||
Http3 dbs.JSON `field:"http3"` // HTTP3设置
|
Http3 dbs.JSON `field:"http3"` // HTTP3设置
|
||||||
|
AutoSystemTuning bool `field:"autoSystemTuning"` // 是否自动调整系统参数
|
||||||
|
NetworkSecurity dbs.JSON `field:"networkSecurity"` // 网络安全策略
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeClusterOperator struct {
|
type NodeClusterOperator struct {
|
||||||
@@ -130,6 +134,8 @@ type NodeClusterOperator struct {
|
|||||||
HttpPages any // 自定义页面设置
|
HttpPages any // 自定义页面设置
|
||||||
Cc any // CC设置
|
Cc any // CC设置
|
||||||
Http3 any // HTTP3设置
|
Http3 any // HTTP3设置
|
||||||
|
AutoSystemTuning any // 是否自动调整系统参数
|
||||||
|
NetworkSecurity any // 网络安全策略
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeClusterOperator() *NodeClusterOperator {
|
func NewNodeClusterOperator() *NodeClusterOperator {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ func (this *NodeCluster) DecodeDDoSProtection() *ddosconfigs.ProtectionConfig {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasDDoSProtection 检查是否有DDOS设置
|
// HasDDoSProtection 检查是否有DDoS设置
|
||||||
func (this *NodeCluster) HasDDoSProtection() bool {
|
func (this *NodeCluster) HasDDoSProtection() bool {
|
||||||
var config = this.DecodeDDoSProtection()
|
var config = this.DecodeDDoSProtection()
|
||||||
if config != nil {
|
if config != nil {
|
||||||
@@ -46,6 +46,27 @@ func (this *NodeCluster) HasDDoSProtection() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasNetworkSecurityPolicy 检查是否有安全策略设置
|
||||||
|
func (this *NodeCluster) HasNetworkSecurityPolicy() bool {
|
||||||
|
var policy = this.DecodeNetworkSecurityPolicy()
|
||||||
|
if policy != nil {
|
||||||
|
return policy.IsOn()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeNetworkSecurityPolicy 解析安全策略设置
|
||||||
|
func (this *NodeCluster) DecodeNetworkSecurityPolicy() *nodeconfigs.NetworkSecurityPolicy {
|
||||||
|
var policy = nodeconfigs.NewNetworkSecurityPolicy()
|
||||||
|
if IsNotNull(this.NetworkSecurity) {
|
||||||
|
err := json.Unmarshal(this.NetworkSecurity, policy)
|
||||||
|
if err != nil {
|
||||||
|
remotelogs.Error("NodeCluster.DecodeNetworkSecurityPolicy()", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return policy
|
||||||
|
}
|
||||||
|
|
||||||
// DecodeClock 解析时钟配置
|
// DecodeClock 解析时钟配置
|
||||||
func (this *NodeCluster) DecodeClock() *nodeconfigs.ClockConfig {
|
func (this *NodeCluster) DecodeClock() *nodeconfigs.ClockConfig {
|
||||||
var clock = nodeconfigs.DefaultClockConfig()
|
var clock = nodeconfigs.DefaultClockConfig()
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/ddosconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
@@ -27,6 +26,7 @@ import (
|
|||||||
"github.com/iwind/TeaGo/rands"
|
"github.com/iwind/TeaGo/rands"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
timeutil "github.com/iwind/TeaGo/utils/time"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -1018,6 +1018,13 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
}
|
}
|
||||||
config.AllowedIPs = append(config.AllowedIPs, apiNodeIPs...)
|
config.AllowedIPs = append(config.AllowedIPs, apiNodeIPs...)
|
||||||
|
|
||||||
|
// 当前的节点IP地址
|
||||||
|
nodeNodeIPs, err := SharedNodeIPAddressDAO.FindAllEnabledAddressStringsWithNode(tx, nodeId, nodeconfigs.NodeRoleNode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
config.IPAddresses = nodeNodeIPs
|
||||||
|
|
||||||
// 所属集群
|
// 所属集群
|
||||||
var primaryClusterId = int64(node.ClusterId)
|
var primaryClusterId = int64(node.ClusterId)
|
||||||
var clusterIds = []int64{primaryClusterId}
|
var clusterIds = []int64{primaryClusterId}
|
||||||
@@ -1057,30 +1064,6 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 全局设置
|
|
||||||
// TODO 根据用户的不同读取不同的全局设置
|
|
||||||
var settingCacheKey = "SharedSysSettingDAO:" + systemconfigs.SettingCodeServerGlobalConfig
|
|
||||||
settingJSONCache, ok := cacheMap.Get(settingCacheKey)
|
|
||||||
var settingJSON []byte
|
|
||||||
if ok {
|
|
||||||
settingJSON = settingJSONCache.([]byte)
|
|
||||||
} else {
|
|
||||||
settingJSON, err = SharedSysSettingDAO.ReadSetting(tx, systemconfigs.SettingCodeServerGlobalConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cacheMap.Put(settingCacheKey, settingJSON)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(settingJSON) > 0 {
|
|
||||||
globalConfig := &serverconfigs.GlobalConfig{}
|
|
||||||
err = json.Unmarshal(settingJSON, globalConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
config.GlobalConfig = globalConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
var clusterIndex = 0
|
var clusterIndex = 0
|
||||||
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
|
config.WebPImagePolicies = map[int64]*nodeconfigs.WebPImagePolicy{}
|
||||||
config.UAMPolicies = map[int64]*nodeconfigs.UAMPolicy{}
|
config.UAMPolicies = map[int64]*nodeconfigs.UAMPolicy{}
|
||||||
@@ -1100,7 +1083,7 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 节点IP地址
|
// 所有节点IP地址
|
||||||
nodeIPAddresses, err := SharedNodeIPAddressDAO.FindAllAccessibleIPAddressesWithClusterId(tx, nodeconfigs.NodeRoleNode, clusterId, cacheMap)
|
nodeIPAddresses, err := SharedNodeIPAddressDAO.FindAllAccessibleIPAddressesWithClusterId(tx, nodeconfigs.NodeRoleNode, clusterId, cacheMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1242,6 +1225,12 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64, dataMap *shared
|
|||||||
// 自动安装nftables
|
// 自动安装nftables
|
||||||
if clusterIndex == 0 {
|
if clusterIndex == 0 {
|
||||||
config.AutoInstallNftables = nodeCluster.AutoInstallNftables
|
config.AutoInstallNftables = nodeCluster.AutoInstallNftables
|
||||||
|
config.AutoSystemTuning = nodeCluster.AutoSystemTuning
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全设置
|
||||||
|
if clusterIndex == 0 {
|
||||||
|
config.NetworkSecurityPolicy = nodeCluster.DecodeNetworkSecurityPolicy()
|
||||||
}
|
}
|
||||||
|
|
||||||
clusterIndex++
|
clusterIndex++
|
||||||
@@ -2128,6 +2117,12 @@ func (this *NodeDAO) FindParentNodeConfigs(tx *dbs.Tx, nodeId int64, groupId int
|
|||||||
Addrs: addrStrings,
|
Addrs: addrStrings,
|
||||||
SecretHash: secretHash,
|
SecretHash: secretHash,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 排序
|
||||||
|
sort.Slice(parentNodeConfigs, func(i, j int) bool {
|
||||||
|
return parentNodeConfigs[i].Id < parentNodeConfigs[j].Id
|
||||||
|
})
|
||||||
|
|
||||||
result[clusterId] = parentNodeConfigs
|
result[clusterId] = parentNodeConfigs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,32 @@ func (this *NodeIPAddressDAO) FindAllEnabledAddressesWithNode(tx *dbs.Tx, nodeId
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindAllEnabledAddressStringsWithNode 查找节点的所有的IP地址地府传
|
||||||
|
func (this *NodeIPAddressDAO) FindAllEnabledAddressStringsWithNode(tx *dbs.Tx, nodeId int64, role nodeconfigs.NodeRole) (result []string, err error) {
|
||||||
|
if len(role) == 0 {
|
||||||
|
role = nodeconfigs.NodeRoleNode
|
||||||
|
}
|
||||||
|
ones, err := this.Query(tx).
|
||||||
|
Attr("nodeId", nodeId).
|
||||||
|
Attr("role", role).
|
||||||
|
State(NodeIPAddressStateEnabled).
|
||||||
|
Result("ip", "backupIP").
|
||||||
|
FindAll()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, one := range ones {
|
||||||
|
var addr = one.(*NodeIPAddress)
|
||||||
|
result = append(result, addr.Ip)
|
||||||
|
if len(addr.BackupIP) > 0 {
|
||||||
|
result = append(result, addr.BackupIP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// FindFirstNodeAccessIPAddress 查找节点的第一个可访问的IP地址
|
// FindFirstNodeAccessIPAddress 查找节点的第一个可访问的IP地址
|
||||||
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64, mustUp bool, role nodeconfigs.NodeRole) (ip string, addrId int64, err error) {
|
func (this *NodeIPAddressDAO) FindFirstNodeAccessIPAddress(tx *dbs.Tx, nodeId int64, mustUp bool, role nodeconfigs.NodeRole) (ip string, addrId int64, err error) {
|
||||||
if len(role) == 0 {
|
if len(role) == 0 {
|
||||||
|
|||||||
@@ -17,21 +17,22 @@ type NodeTaskType = string
|
|||||||
const (
|
const (
|
||||||
// CDN相关
|
// CDN相关
|
||||||
|
|
||||||
NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 节点整体配置变化
|
NodeTaskTypeConfigChanged NodeTaskType = "configChanged" // 节点整体配置变化
|
||||||
NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 节点DDoS配置变更
|
NodeTaskTypeDDosProtectionChanged NodeTaskType = "ddosProtectionChanged" // 节点DDoS配置变更
|
||||||
NodeTaskTypeGlobalServerConfigChanged NodeTaskType = "globalServerConfigChanged" // 全局服务设置变化
|
NodeTaskTypeGlobalServerConfigChanged NodeTaskType = "globalServerConfigChanged" // 全局服务设置变化
|
||||||
NodeTaskTypeIPListDeleted NodeTaskType = "ipListDeleted" // IPList被删除
|
NodeTaskTypeIPListDeleted NodeTaskType = "ipListDeleted" // IPList被删除
|
||||||
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged" // IP条目变更
|
NodeTaskTypeIPItemChanged NodeTaskType = "ipItemChanged" // IP条目变更
|
||||||
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged" // 节点版本变化
|
NodeTaskTypeNodeVersionChanged NodeTaskType = "nodeVersionChanged" // 节点版本变化
|
||||||
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化
|
NodeTaskTypeScriptsChanged NodeTaskType = "scriptsChanged" // 脚本配置变化
|
||||||
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化
|
NodeTaskTypeNodeLevelChanged NodeTaskType = "nodeLevelChanged" // 节点级别变化
|
||||||
NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化
|
NodeTaskTypeUserServersStateChanged NodeTaskType = "userServersStateChanged" // 用户服务状态变化
|
||||||
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
|
NodeTaskTypeUAMPolicyChanged NodeTaskType = "uamPolicyChanged" // UAM策略变化
|
||||||
NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 自定义页面变化
|
NodeTaskTypeHTTPPagesPolicyChanged NodeTaskType = "httpPagesPolicyChanged" // 自定义页面变化
|
||||||
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
NodeTaskTypeHTTPCCPolicyChanged NodeTaskType = "httpCCPolicyChanged" // CC策略变化
|
||||||
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化
|
NodeTaskTypeHTTP3PolicyChanged NodeTaskType = "http3PolicyChanged" // HTTP3策略变化
|
||||||
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
NodeTaskTypeNetworkSecurityPolicyChanged NodeTaskType = "networkSecurityPolicyChanged" // 网络安全策略变化
|
||||||
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
NodeTaskTypeUpdatingServers NodeTaskType = "updatingServers" // 更新一组服务
|
||||||
|
NodeTaskTypeTOAChanged NodeTaskType = "toaChanged" // TOA配置变化
|
||||||
|
|
||||||
// NS相关
|
// NS相关
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/iwind/TeaGo/Tea"
|
"github.com/iwind/TeaGo/Tea"
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
timeutil "github.com/iwind/TeaGo/utils/time"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -153,12 +147,13 @@ func (this *NodeThresholdDAO) FindAllEnabledAndOnClusterThresholds(tx *dbs.Tx, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FindAllEnabledAndOnNodeThresholds 查询节点专属的阈值设置
|
// FindAllEnabledAndOnNodeThresholds 查询节点专属的阈值设置
|
||||||
func (this *NodeThresholdDAO) FindAllEnabledAndOnNodeThresholds(tx *dbs.Tx, role string, nodeId int64, item string) (result []*NodeThreshold, err error) {
|
func (this *NodeThresholdDAO) FindAllEnabledAndOnNodeThresholds(tx *dbs.Tx, role string, clusterId int64, nodeId int64, item string) (result []*NodeThreshold, err error) {
|
||||||
if nodeId <= 0 {
|
if clusterId <= 0 || nodeId <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
Attr("role", role).
|
Attr("role", role).
|
||||||
|
Attr("clusterId", clusterId).
|
||||||
Attr("nodeId", nodeId).
|
Attr("nodeId", nodeId).
|
||||||
Attr("item", item).
|
Attr("item", item).
|
||||||
Attr("isOn", true).
|
Attr("isOn", true).
|
||||||
@@ -186,87 +181,3 @@ func (this *NodeThresholdDAO) CountAllEnabledThresholds(tx *dbs.Tx, role string,
|
|||||||
query.State(NodeThresholdStateEnabled)
|
query.State(NodeThresholdStateEnabled)
|
||||||
return query.Count()
|
return query.Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FireNodeThreshold 触发相关阈值设置
|
|
||||||
func (this *NodeThresholdDAO) FireNodeThreshold(tx *dbs.Tx, role string, nodeId int64, item string) error {
|
|
||||||
clusterId, err := SharedNodeDAO.FindNodeClusterId(tx, nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if clusterId == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 集群相关阈值
|
|
||||||
var thresholds []*NodeThreshold
|
|
||||||
{
|
|
||||||
clusterThresholds, err := this.FindAllEnabledAndOnClusterThresholds(tx, role, clusterId, item)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
thresholds = append(thresholds, clusterThresholds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 节点相关阈值
|
|
||||||
{
|
|
||||||
nodeThresholds, err := this.FindAllEnabledAndOnNodeThresholds(tx, role, nodeId, item)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
thresholds = append(thresholds, nodeThresholds...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(thresholds) > 0 {
|
|
||||||
for _, threshold := range thresholds {
|
|
||||||
if len(threshold.Param) == 0 || threshold.Duration <= 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
paramValue, err := SharedNodeValueDAO.SumNodeValues(tx, role, nodeId, item, threshold.Param, threshold.SumMethod, types.Int32(threshold.Duration), threshold.DurationUnit)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
originValue := nodeconfigs.UnmarshalNodeValue(threshold.Value)
|
|
||||||
thresholdValue := types.Float64(originValue)
|
|
||||||
isMatched := nodeconfigs.CompareNodeValue(threshold.Operator, paramValue, thresholdValue)
|
|
||||||
if isMatched {
|
|
||||||
// TODO 执行其他动作
|
|
||||||
|
|
||||||
// 是否已经通知过
|
|
||||||
if threshold.NotifyDuration > 0 && threshold.NotifiedAt > 0 && time.Now().Unix()-int64(threshold.NotifiedAt) < int64(threshold.NotifyDuration*60) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建消息
|
|
||||||
nodeName, err := SharedNodeDAO.FindNodeName(tx, nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
itemName := nodeconfigs.FindNodeValueItemName(threshold.Item)
|
|
||||||
paramName := nodeconfigs.FindNodeValueItemParamName(threshold.Item, threshold.Param)
|
|
||||||
operatorName := nodeconfigs.FindNodeValueOperatorName(threshold.Operator)
|
|
||||||
|
|
||||||
subject := "节点 \"" + nodeName + "\" " + itemName + " 达到阈值"
|
|
||||||
body := "节点 \"" + nodeName + "\" " + itemName + " 达到阈值\n阈值设置:" + paramName + " " + operatorName + " " + originValue + "\n当前值:" + fmt.Sprintf("%.2f", paramValue) + "\n触发时间:" + timeutil.Format("Y-m-d H:i:s")
|
|
||||||
if len(threshold.Message) > 0 {
|
|
||||||
body = threshold.Message
|
|
||||||
body = strings.Replace(body, "${item.name}", itemName, -1)
|
|
||||||
body = strings.Replace(body, "${value}", fmt.Sprintf("%.2f", paramValue), -1)
|
|
||||||
}
|
|
||||||
err = SharedMessageDAO.CreateNodeMessage(tx, role, clusterId, nodeId, MessageTypeThresholdSatisfied, MessageLevelWarning, subject, body, maps.Map{}.AsJSON(), true)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置通知时间
|
|
||||||
_, err = this.Query(tx).
|
|
||||||
Pk(threshold.Id).
|
|
||||||
Set("notifiedAt", time.Now().Unix()).
|
|
||||||
Update()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
12
internal/db/models/node_threshold_dao_ext.go
Normal file
12
internal/db/models/node_threshold_dao_ext.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
// FireNodeThreshold 触发相关阈值设置
|
||||||
|
func (this *NodeThresholdDAO) FireNodeThreshold(tx *dbs.Tx, role string, nodeId int64, item string) error {
|
||||||
|
// stub
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -227,6 +227,8 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
op.Oss = ossConfigJSON
|
op.Oss = ossConfigJSON
|
||||||
|
} else {
|
||||||
|
op.Oss = dbs.SQL("NULL")
|
||||||
}
|
}
|
||||||
|
|
||||||
op.Description = description
|
op.Description = description
|
||||||
@@ -400,6 +402,7 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// addr
|
// addr
|
||||||
|
var isOSS = false
|
||||||
if IsNotNull(origin.Addr) {
|
if IsNotNull(origin.Addr) {
|
||||||
var addr = &serverconfigs.NetworkAddressConfig{}
|
var addr = &serverconfigs.NetworkAddressConfig{}
|
||||||
err = json.Unmarshal(origin.Addr, addr)
|
err = json.Unmarshal(origin.Addr, addr)
|
||||||
@@ -407,10 +410,11 @@ func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
config.Addr = addr
|
config.Addr = addr
|
||||||
|
isOSS = ossconfigs.IsOSSProtocol(string(addr.Protocol))
|
||||||
}
|
}
|
||||||
|
|
||||||
// oss
|
// oss
|
||||||
if IsNotNull(origin.Oss) {
|
if isOSS && IsNotNull(origin.Oss) {
|
||||||
var ossConfig = ossconfigs.NewOSSConfig()
|
var ossConfig = ossconfigs.NewOSSConfig()
|
||||||
err = json.Unmarshal(origin.Oss, ossConfig)
|
err = json.Unmarshal(origin.Oss, ossConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(tx *dbs.Tx, reverseProxyI
|
|||||||
config.AutoFlush = reverseProxy.AutoFlush == 1
|
config.AutoFlush = reverseProxy.AutoFlush == 1
|
||||||
config.FollowRedirects = reverseProxy.FollowRedirects == 1
|
config.FollowRedirects = reverseProxy.FollowRedirects == 1
|
||||||
config.Retry50X = reverseProxy.Retry50X
|
config.Retry50X = reverseProxy.Retry50X
|
||||||
|
config.Retry40X = reverseProxy.Retry40X
|
||||||
|
|
||||||
var schedulingConfig = &serverconfigs.SchedulingConfig{}
|
var schedulingConfig = &serverconfigs.SchedulingConfig{}
|
||||||
if IsNotNull(reverseProxy.Scheduling) {
|
if IsNotNull(reverseProxy.Scheduling) {
|
||||||
@@ -219,7 +220,8 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI
|
|||||||
op.AdminId = adminId
|
op.AdminId = adminId
|
||||||
op.UserId = userId
|
op.UserId = userId
|
||||||
op.RequestHostType = serverconfigs.RequestHostTypeProxyServer
|
op.RequestHostType = serverconfigs.RequestHostTypeProxyServer
|
||||||
op.Retry50X = true
|
op.Retry50X = false
|
||||||
|
op.Retry40X = false
|
||||||
|
|
||||||
defaultHeaders := []string{"X-Real-IP", "X-Forwarded-For", "X-Forwarded-By", "X-Forwarded-Host", "X-Forwarded-Proto"}
|
defaultHeaders := []string{"X-Real-IP", "X-Forwarded-For", "X-Forwarded-By", "X-Forwarded-Host", "X-Forwarded-Proto"}
|
||||||
defaultHeadersJSON, err := json.Marshal(defaultHeaders)
|
defaultHeadersJSON, err := json.Marshal(defaultHeaders)
|
||||||
@@ -428,7 +430,8 @@ func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx,
|
|||||||
maxIdleConns int32,
|
maxIdleConns int32,
|
||||||
proxyProtocolJSON []byte,
|
proxyProtocolJSON []byte,
|
||||||
followRedirects bool,
|
followRedirects bool,
|
||||||
retry50X bool) error {
|
retry50X bool,
|
||||||
|
retry40X bool) error {
|
||||||
if reverseProxyId <= 0 {
|
if reverseProxyId <= 0 {
|
||||||
return errors.New("invalid reverseProxyId")
|
return errors.New("invalid reverseProxyId")
|
||||||
}
|
}
|
||||||
@@ -494,6 +497,7 @@ func (this *ReverseProxyDAO) UpdateReverseProxy(tx *dbs.Tx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
op.Retry50X = retry50X
|
op.Retry50X = retry50X
|
||||||
|
op.Retry40X = retry40X
|
||||||
|
|
||||||
err = this.Save(tx, op)
|
err = this.Save(tx, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const (
|
|||||||
ReverseProxyField_ProxyProtocol dbs.FieldName = "proxyProtocol" // Proxy Protocol配置
|
ReverseProxyField_ProxyProtocol dbs.FieldName = "proxyProtocol" // Proxy Protocol配置
|
||||||
ReverseProxyField_FollowRedirects dbs.FieldName = "followRedirects" // 回源跟随
|
ReverseProxyField_FollowRedirects dbs.FieldName = "followRedirects" // 回源跟随
|
||||||
ReverseProxyField_Retry50X dbs.FieldName = "retry50X" // 启用50X重试
|
ReverseProxyField_Retry50X dbs.FieldName = "retry50X" // 启用50X重试
|
||||||
|
ReverseProxyField_Retry40X dbs.FieldName = "retry40X" // 启用40X重试
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReverseProxy 反向代理配置
|
// ReverseProxy 反向代理配置
|
||||||
@@ -57,6 +58,7 @@ type ReverseProxy struct {
|
|||||||
ProxyProtocol dbs.JSON `field:"proxyProtocol"` // Proxy Protocol配置
|
ProxyProtocol dbs.JSON `field:"proxyProtocol"` // Proxy Protocol配置
|
||||||
FollowRedirects uint8 `field:"followRedirects"` // 回源跟随
|
FollowRedirects uint8 `field:"followRedirects"` // 回源跟随
|
||||||
Retry50X bool `field:"retry50X"` // 启用50X重试
|
Retry50X bool `field:"retry50X"` // 启用50X重试
|
||||||
|
Retry40X bool `field:"retry40X"` // 启用40X重试
|
||||||
}
|
}
|
||||||
|
|
||||||
type ReverseProxyOperator struct {
|
type ReverseProxyOperator struct {
|
||||||
@@ -85,6 +87,7 @@ type ReverseProxyOperator struct {
|
|||||||
ProxyProtocol any // Proxy Protocol配置
|
ProxyProtocol any // Proxy Protocol配置
|
||||||
FollowRedirects any // 回源跟随
|
FollowRedirects any // 回源跟随
|
||||||
Retry50X any // 启用50X重试
|
Retry50X any // 启用50X重试
|
||||||
|
Retry40X any // 启用40X重试
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReverseProxyOperator() *ReverseProxyOperator {
|
func NewReverseProxyOperator() *ReverseProxyOperator {
|
||||||
|
|||||||
@@ -2045,11 +2045,12 @@ func (this *ServerDAO) GenDNSName(tx *dbs.Tx) (string, error) {
|
|||||||
|
|
||||||
// FindLatestServers 查询最近访问的服务
|
// FindLatestServers 查询最近访问的服务
|
||||||
func (this *ServerDAO) FindLatestServers(tx *dbs.Tx, size int64) (result []*Server, err error) {
|
func (this *ServerDAO) FindLatestServers(tx *dbs.Tx, size int64) (result []*Server, err error) {
|
||||||
itemTable := SharedLatestItemDAO.Table
|
var itemTable = SharedLatestItemDAO.Table
|
||||||
itemType := LatestItemTypeServer
|
var itemType = LatestItemTypeServer
|
||||||
_, err = this.Query(tx).
|
_, err = this.Query(tx).
|
||||||
Result(this.Table+".id", this.Table+".name").
|
Result(this.Table+".id", this.Table+".name").
|
||||||
Join(SharedLatestItemDAO, dbs.QueryJoinRight, this.Table+".id="+itemTable+".itemId AND "+itemTable+".itemType='"+itemType+"'").
|
Join(SharedLatestItemDAO, dbs.QueryJoinRight, this.Table+".id="+itemTable+".itemId AND "+itemTable+".itemType='"+itemType+"'").
|
||||||
|
Where(itemTable + ".updatedAt<=UNIX_TIMESTAMP()"). // VERY IMPORTANT
|
||||||
Asc("CEIL((UNIX_TIMESTAMP() - " + itemTable + ".updatedAt) / (7 * 86400))"). // 优先一个星期以内的
|
Asc("CEIL((UNIX_TIMESTAMP() - " + itemTable + ".updatedAt) / (7 * 86400))"). // 优先一个星期以内的
|
||||||
Desc(itemTable + ".count").
|
Desc(itemTable + ".count").
|
||||||
State(NodeClusterStateEnabled).
|
State(NodeClusterStateEnabled).
|
||||||
|
|||||||
@@ -10,26 +10,26 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// CopyServerConfigToServers 拷贝服务配置到一组服务
|
// CopyServerConfigToServers 拷贝服务配置到一组服务
|
||||||
func (this *ServerDAO) CopyServerConfigToServers(tx *dbs.Tx, fromServerId int64, toServerIds []int64, configCode serverconfigs.ConfigCode) error {
|
func (this *ServerDAO) CopyServerConfigToServers(tx *dbs.Tx, fromServerId int64, toServerIds []int64, configCode serverconfigs.ConfigCode, wafCopyRegions bool) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyServerConfigToGroups 拷贝服务配置到分组
|
// CopyServerConfigToGroups 拷贝服务配置到分组
|
||||||
func (this *ServerDAO) CopyServerConfigToGroups(tx *dbs.Tx, fromServerId int64, groupIds []int64, configCode string) error {
|
func (this *ServerDAO) CopyServerConfigToGroups(tx *dbs.Tx, fromServerId int64, groupIds []int64, configCode string, wafCopyRegions bool) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyServerConfigToCluster 拷贝服务配置到集群
|
// CopyServerConfigToCluster 拷贝服务配置到集群
|
||||||
func (this *ServerDAO) CopyServerConfigToCluster(tx *dbs.Tx, fromServerId int64, clusterId int64, configCode string) error {
|
func (this *ServerDAO) CopyServerConfigToCluster(tx *dbs.Tx, fromServerId int64, clusterId int64, configCode string, wafCopyRegions bool) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyServerConfigToUser 拷贝服务配置到用户
|
// CopyServerConfigToUser 拷贝服务配置到用户
|
||||||
func (this *ServerDAO) CopyServerConfigToUser(tx *dbs.Tx, fromServerId int64, userId int64, configCode string) error {
|
func (this *ServerDAO) CopyServerConfigToUser(tx *dbs.Tx, fromServerId int64, userId int64, configCode string, wafCopyRegions bool) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyServerUAMConfigs 复制UAM设置
|
// CopyServerUAMConfigs 复制UAM设置
|
||||||
func (this *ServerDAO) CopyServerUAMConfigs(tx *dbs.Tx, fromServerId int64, toServerIds []int64) error {
|
func (this *ServerDAO) CopyServerUAMConfigs(tx *dbs.Tx, fromServerId int64, toServerIds []int64, wafCopyRegions bool) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ func (this *SSLCertDAO) ComposeCertConfig(tx *dbs.Tx, certId int64, ignoreData b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CountCerts 计算符合条件的证书数量
|
// CountCerts 计算符合条件的证书数量
|
||||||
func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string) (int64, error) {
|
func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string, userOnly bool) (int64, error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(SSLCertStateEnabled)
|
State(SSLCertStateEnabled)
|
||||||
if isCA {
|
if isCA {
|
||||||
@@ -308,8 +308,12 @@ func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isEx
|
|||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
query.Attr("userId", userId)
|
query.Attr("userId", userId)
|
||||||
} else {
|
} else {
|
||||||
// 只查询管理员上传的
|
if userOnly {
|
||||||
query.Attr("userId", 0)
|
query.Gt("userId", 0)
|
||||||
|
} else {
|
||||||
|
// 只查询管理员上传的
|
||||||
|
query.Attr("userId", 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 域名
|
// 域名
|
||||||
@@ -322,7 +326,7 @@ func (this *SSLCertDAO) CountCerts(tx *dbs.Tx, isCA bool, isAvailable bool, isEx
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListCertIds 列出符合条件的证书
|
// ListCertIds 列出符合条件的证书
|
||||||
func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string, offset int64, size int64) (certIds []int64, err error) {
|
func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isExpired bool, expiringDays int64, keyword string, userId int64, domains []string, userOnly bool, offset int64, size int64) (certIds []int64, err error) {
|
||||||
var query = this.Query(tx).
|
var query = this.Query(tx).
|
||||||
State(SSLCertStateEnabled)
|
State(SSLCertStateEnabled)
|
||||||
if isCA {
|
if isCA {
|
||||||
@@ -345,8 +349,12 @@ func (this *SSLCertDAO) ListCertIds(tx *dbs.Tx, isCA bool, isAvailable bool, isE
|
|||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
query.Attr("userId", userId)
|
query.Attr("userId", userId)
|
||||||
} else {
|
} else {
|
||||||
// 只查询管理员上传的
|
if userOnly {
|
||||||
query.Attr("userId", 0)
|
query.Gt("userId", 0)
|
||||||
|
} else {
|
||||||
|
// 只查询管理员上传的
|
||||||
|
query.Attr("userId", 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 域名
|
// 域名
|
||||||
@@ -434,6 +442,14 @@ func (this *SSLCertDAO) CheckUserCert(tx *dbs.Tx, certId int64, userId int64) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindCertUserId 查找证书所属用户ID
|
||||||
|
func (this *SSLCertDAO) FindCertUserId(tx *dbs.Tx, certId int64) (userId int64, err error) {
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(certId).
|
||||||
|
Result("userId").
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateCertUser 修改证书所属用户
|
// UpdateCertUser 修改证书所属用户
|
||||||
func (this *SSLCertDAO) UpdateCertUser(tx *dbs.Tx, certId int64, userId int64) error {
|
func (this *SSLCertDAO) UpdateCertUser(tx *dbs.Tx, certId int64, userId int64) error {
|
||||||
if certId <= 0 || userId <= 0 {
|
if certId <= 0 || userId <= 0 {
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ func (this *ServerDomainHourlyStatDAO) IncreaseHourlyStat(tx *dbs.Tx, clusterId
|
|||||||
if len(hour) != 10 {
|
if len(hour) != 10 {
|
||||||
return errors.New("invalid hour '" + hour + "'")
|
return errors.New("invalid hour '" + hour + "'")
|
||||||
}
|
}
|
||||||
if len(domain) == 0 {
|
if len(domain) == 0 || len(domain) > 64 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := this.Query(tx).
|
err := this.Query(tx).
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/zero"
|
"github.com/TeaOSLab/EdgeAPI/internal/zero"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/systemconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/userconfigs"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
@@ -126,23 +125,6 @@ func (this *SysSettingDAO) CompareInt64Setting(tx *dbs.Tx, code string, anotherV
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadGlobalConfig 读取全局配置
|
|
||||||
func (this *SysSettingDAO) ReadGlobalConfig(tx *dbs.Tx) (*serverconfigs.GlobalConfig, error) {
|
|
||||||
globalConfigData, err := this.ReadSetting(tx, systemconfigs.SettingCodeServerGlobalConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(globalConfigData) == 0 {
|
|
||||||
return &serverconfigs.GlobalConfig{}, nil
|
|
||||||
}
|
|
||||||
config := &serverconfigs.GlobalConfig{}
|
|
||||||
err = json.Unmarshal(globalConfigData, config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadAdminUIConfig 读取管理员界面配置
|
// ReadAdminUIConfig 读取管理员界面配置
|
||||||
func (this *SysSettingDAO) ReadAdminUIConfig(tx *dbs.Tx, cacheMap *utils.CacheMap) (*systemconfigs.AdminUIConfig, error) {
|
func (this *SysSettingDAO) ReadAdminUIConfig(tx *dbs.Tx, cacheMap *utils.CacheMap) (*systemconfigs.AdminUIConfig, error) {
|
||||||
var cacheKey = this.Table + ":ReadAdminUIConfig"
|
var cacheKey = this.Table + ":ReadAdminUIConfig"
|
||||||
|
|||||||
@@ -428,6 +428,20 @@ func (this *UserDAO) CheckUserEmailPassword(tx *dbs.Tx, verifiedEmail string, en
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserMobilePassword 检查邮箱+密码
|
||||||
|
func (this *UserDAO) CheckUserMobilePassword(tx *dbs.Tx, verifiedEmail string, encryptedPassword string) (int64, error) {
|
||||||
|
if len(verifiedEmail) == 0 || len(encryptedPassword) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Attr("verifiedMobile", verifiedEmail).
|
||||||
|
Attr("password", encryptedPassword).
|
||||||
|
Attr("state", UserStateEnabled).
|
||||||
|
Attr("isOn", true).
|
||||||
|
ResultPk().
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserClusterId 查找用户所在集群
|
// FindUserClusterId 查找用户所在集群
|
||||||
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
|
func (this *UserDAO) FindUserClusterId(tx *dbs.Tx, userId int64) (int64, error) {
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
@@ -663,7 +677,7 @@ func (this *UserDAO) RenewUserServersState(tx *dbs.Tx, userId int64) (bool, erro
|
|||||||
// FindUserIdWithVerifiedEmail 使用验证后Email查找用户ID
|
// FindUserIdWithVerifiedEmail 使用验证后Email查找用户ID
|
||||||
func (this *UserDAO) FindUserIdWithVerifiedEmail(tx *dbs.Tx, verifiedEmail string) (int64, error) {
|
func (this *UserDAO) FindUserIdWithVerifiedEmail(tx *dbs.Tx, verifiedEmail string) (int64, error) {
|
||||||
if len(verifiedEmail) == 0 {
|
if len(verifiedEmail) == 0 {
|
||||||
|
return 0, nil
|
||||||
}
|
}
|
||||||
return this.Query(tx).
|
return this.Query(tx).
|
||||||
ResultPk().
|
ResultPk().
|
||||||
@@ -672,6 +686,18 @@ func (this *UserDAO) FindUserIdWithVerifiedEmail(tx *dbs.Tx, verifiedEmail strin
|
|||||||
FindInt64Col(0)
|
FindInt64Col(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindUserIdWithVerifiedMobile 使用验证后手机号码查找用户ID
|
||||||
|
func (this *UserDAO) FindUserIdWithVerifiedMobile(tx *dbs.Tx, verifiedMobile string) (int64, error) {
|
||||||
|
if len(verifiedMobile) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
ResultPk().
|
||||||
|
State(UserStateEnabled).
|
||||||
|
Attr("verifiedMobile", verifiedMobile).
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateUserVerifiedEmail 修改已激活邮箱
|
// UpdateUserVerifiedEmail 修改已激活邮箱
|
||||||
func (this *UserDAO) UpdateUserVerifiedEmail(tx *dbs.Tx, userId int64, verifiedEmail string) error {
|
func (this *UserDAO) UpdateUserVerifiedEmail(tx *dbs.Tx, userId int64, verifiedEmail string) error {
|
||||||
if userId <= 0 {
|
if userId <= 0 {
|
||||||
@@ -684,6 +710,18 @@ func (this *UserDAO) UpdateUserVerifiedEmail(tx *dbs.Tx, userId int64, verifiedE
|
|||||||
UpdateQuickly()
|
UpdateQuickly()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateUserVerifiedMobile 修改已激活手机号码
|
||||||
|
func (this *UserDAO) UpdateUserVerifiedMobile(tx *dbs.Tx, userId int64, verifiedMobile string) error {
|
||||||
|
if userId <= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(userId).
|
||||||
|
Set("verifiedMobile", verifiedMobile).
|
||||||
|
Set("mobileIsVerified", true).
|
||||||
|
UpdateQuickly()
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserBandwidthAlgoForView 获取用户浏览用的带宽算法
|
// FindUserBandwidthAlgoForView 获取用户浏览用的带宽算法
|
||||||
func (this *UserDAO) FindUserBandwidthAlgoForView(tx *dbs.Tx, userId int64, uiConfig *systemconfigs.UserUIConfig) (bandwidthAlgo string, err error) {
|
func (this *UserDAO) FindUserBandwidthAlgoForView(tx *dbs.Tx, userId int64, uiConfig *systemconfigs.UserUIConfig) (bandwidthAlgo string, err error) {
|
||||||
bandwidthAlgo, err = this.Query(tx).
|
bandwidthAlgo, err = this.Query(tx).
|
||||||
|
|||||||
28
internal/db/models/user_mobile_verification_dao.go
Normal file
28
internal/db/models/user_mobile_verification_dao.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
|
"github.com/iwind/TeaGo/Tea"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserMobileVerificationDAO dbs.DAO
|
||||||
|
|
||||||
|
func NewUserMobileVerificationDAO() *UserMobileVerificationDAO {
|
||||||
|
return dbs.NewDAO(&UserMobileVerificationDAO{
|
||||||
|
DAOObject: dbs.DAOObject{
|
||||||
|
DB: Tea.Env,
|
||||||
|
Table: "edgeUserMobileVerifications",
|
||||||
|
Model: new(UserMobileVerification),
|
||||||
|
PkName: "id",
|
||||||
|
},
|
||||||
|
}).(*UserMobileVerificationDAO)
|
||||||
|
}
|
||||||
|
|
||||||
|
var SharedUserMobileVerificationDAO *UserMobileVerificationDAO
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
dbs.OnReady(func() {
|
||||||
|
SharedUserMobileVerificationDAO = NewUserMobileVerificationDAO()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package models
|
package models_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
41
internal/db/models/user_mobile_verification_model.go
Normal file
41
internal/db/models/user_mobile_verification_model.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
|
const (
|
||||||
|
UserMobileVerificationField_Id dbs.FieldName = "id" // ID
|
||||||
|
UserMobileVerificationField_Mobile dbs.FieldName = "mobile" // 手机号码
|
||||||
|
UserMobileVerificationField_UserId dbs.FieldName = "userId" // 用户ID
|
||||||
|
UserMobileVerificationField_Code dbs.FieldName = "code" // 激活码
|
||||||
|
UserMobileVerificationField_CreatedAt dbs.FieldName = "createdAt" // 创建时间
|
||||||
|
UserMobileVerificationField_IsSent dbs.FieldName = "isSent" // 是否已发送
|
||||||
|
UserMobileVerificationField_IsVerified dbs.FieldName = "isVerified" // 是否已激活
|
||||||
|
UserMobileVerificationField_Day dbs.FieldName = "day" // YYYYMMDD
|
||||||
|
)
|
||||||
|
|
||||||
|
// UserMobileVerification 邮箱激活邮件队列
|
||||||
|
type UserMobileVerification struct {
|
||||||
|
Id uint64 `field:"id"` // ID
|
||||||
|
Mobile string `field:"mobile"` // 手机号码
|
||||||
|
UserId uint64 `field:"userId"` // 用户ID
|
||||||
|
Code string `field:"code"` // 激活码
|
||||||
|
CreatedAt uint64 `field:"createdAt"` // 创建时间
|
||||||
|
IsSent bool `field:"isSent"` // 是否已发送
|
||||||
|
IsVerified bool `field:"isVerified"` // 是否已激活
|
||||||
|
Day string `field:"day"` // YYYYMMDD
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserMobileVerificationOperator struct {
|
||||||
|
Id any // ID
|
||||||
|
Mobile any // 手机号码
|
||||||
|
UserId any // 用户ID
|
||||||
|
Code any // 激活码
|
||||||
|
CreatedAt any // 创建时间
|
||||||
|
IsSent any // 是否已发送
|
||||||
|
IsVerified any // 是否已激活
|
||||||
|
Day any // YYYYMMDD
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserMobileVerificationOperator() *UserMobileVerificationOperator {
|
||||||
|
return &UserMobileVerificationOperator{}
|
||||||
|
}
|
||||||
@@ -10,6 +10,7 @@ const (
|
|||||||
UserField_Fullname dbs.FieldName = "fullname" // 真实姓名
|
UserField_Fullname dbs.FieldName = "fullname" // 真实姓名
|
||||||
UserField_Mobile dbs.FieldName = "mobile" // 手机号
|
UserField_Mobile dbs.FieldName = "mobile" // 手机号
|
||||||
UserField_VerifiedMobile dbs.FieldName = "verifiedMobile" // 已验证手机号
|
UserField_VerifiedMobile dbs.FieldName = "verifiedMobile" // 已验证手机号
|
||||||
|
UserField_MobileIsVerified dbs.FieldName = "mobileIsVerified" // 手机号是否已验证
|
||||||
UserField_Tel dbs.FieldName = "tel" // 联系电话
|
UserField_Tel dbs.FieldName = "tel" // 联系电话
|
||||||
UserField_Remark dbs.FieldName = "remark" // 备注
|
UserField_Remark dbs.FieldName = "remark" // 备注
|
||||||
UserField_Email dbs.FieldName = "email" // 邮箱地址
|
UserField_Email dbs.FieldName = "email" // 邮箱地址
|
||||||
@@ -47,6 +48,7 @@ type User struct {
|
|||||||
Fullname string `field:"fullname"` // 真实姓名
|
Fullname string `field:"fullname"` // 真实姓名
|
||||||
Mobile string `field:"mobile"` // 手机号
|
Mobile string `field:"mobile"` // 手机号
|
||||||
VerifiedMobile string `field:"verifiedMobile"` // 已验证手机号
|
VerifiedMobile string `field:"verifiedMobile"` // 已验证手机号
|
||||||
|
MobileIsVerified uint8 `field:"mobileIsVerified"` // 手机号是否已验证
|
||||||
Tel string `field:"tel"` // 联系电话
|
Tel string `field:"tel"` // 联系电话
|
||||||
Remark string `field:"remark"` // 备注
|
Remark string `field:"remark"` // 备注
|
||||||
Email string `field:"email"` // 邮箱地址
|
Email string `field:"email"` // 邮箱地址
|
||||||
@@ -83,6 +85,7 @@ type UserOperator struct {
|
|||||||
Fullname any // 真实姓名
|
Fullname any // 真实姓名
|
||||||
Mobile any // 手机号
|
Mobile any // 手机号
|
||||||
VerifiedMobile any // 已验证手机号
|
VerifiedMobile any // 已验证手机号
|
||||||
|
MobileIsVerified any // 手机号是否已验证
|
||||||
Tel any // 联系电话
|
Tel any // 联系电话
|
||||||
Remark any // 备注
|
Remark any // 备注
|
||||||
Email any // 邮箱地址
|
Email any // 邮箱地址
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func FindAllProviderTypes() []maps.Map {
|
|||||||
typeMaps = append(typeMaps, maps.Map{
|
typeMaps = append(typeMaps, maps.Map{
|
||||||
"name": "自定义HTTP DNS",
|
"name": "自定义HTTP DNS",
|
||||||
"code": ProviderTypeCustomHTTP,
|
"code": ProviderTypeCustomHTTP,
|
||||||
"description": "通过自定义的HTTP接口提供DNS服务。",
|
"description": "通过自定义的HTTP接口提供DNS服务,具体使用方法请参考官网文档:https://goedge.cn/docs/DNS/CustomHTTP.md ",
|
||||||
})
|
})
|
||||||
return typeMaps
|
return typeMaps
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,36 +189,6 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterMessageServiceServer(server, instance)
|
pb.RegisterMessageServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageRecipientService{}).(*services.MessageRecipientService)
|
|
||||||
pb.RegisterMessageRecipientServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageReceiverService{}).(*services.MessageReceiverService)
|
|
||||||
pb.RegisterMessageReceiverServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageRecipientGroupService{}).(*services.MessageRecipientGroupService)
|
|
||||||
pb.RegisterMessageRecipientGroupServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageMediaInstanceService{}).(*services.MessageMediaInstanceService)
|
|
||||||
pb.RegisterMessageMediaInstanceServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageTaskService{}).(*services.MessageTaskService)
|
|
||||||
pb.RegisterMessageTaskServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MessageTaskLogService{}).(*services.MessageTaskLogService)
|
|
||||||
pb.RegisterMessageTaskLogServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.NodeGroupService{}).(*services.NodeGroupService)
|
var instance = this.serviceInstance(&services.NodeGroupService{}).(*services.NodeGroupService)
|
||||||
pb.RegisterNodeGroupServiceServer(server, instance)
|
pb.RegisterNodeGroupServiceServer(server, instance)
|
||||||
@@ -454,11 +424,6 @@ func (this *APINode) registerServices(server *grpc.Server) {
|
|||||||
pb.RegisterNodeClusterFirewallActionServiceServer(server, instance)
|
pb.RegisterNodeClusterFirewallActionServiceServer(server, instance)
|
||||||
this.rest(instance)
|
this.rest(instance)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
var instance = this.serviceInstance(&services.MonitorNodeService{}).(*services.MonitorNodeService)
|
|
||||||
pb.RegisterMonitorNodeServiceServer(server, instance)
|
|
||||||
this.rest(instance)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
var instance = this.serviceInstance(&services.AuthorityNodeService{}).(*services.AuthorityNodeService)
|
var instance = this.serviceInstance(&services.AuthorityNodeService{}).(*services.AuthorityNodeService)
|
||||||
pb.RegisterAuthorityNodeServiceServer(server, instance)
|
pb.RegisterAuthorityNodeServiceServer(server, instance)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *
|
|||||||
req.UserId = userId
|
req.UserId = userId
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := acmemodels.SharedACMETaskDAO.CountAllEnabledACMETasks(tx, req.UserId, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword)
|
count, err := acmemodels.SharedACMETaskDAO.CountAllEnabledACMETasks(tx, req.UserId, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, req.UserOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.L
|
|||||||
req.UserId = userId
|
req.UserId = userId
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks, err := acmemodels.SharedACMETaskDAO.ListEnabledACMETasks(tx, req.UserId, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, req.Offset, req.Size)
|
tasks, err := acmemodels.SharedACMETaskDAO.ListEnabledACMETasks(tx, req.UserId, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, req.UserOnly, req.Offset, req.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -255,7 +255,7 @@ func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateA
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
canAccess, err := acmemodels.SharedACMETaskDAO.CheckACMETask(tx, userId, req.AcmeTaskId)
|
canAccess, err := acmemodels.SharedACMETaskDAO.CheckUserACMETask(tx, userId, req.AcmeTaskId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -279,7 +279,7 @@ func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteA
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
canAccess, err := acmemodels.SharedACMETaskDAO.CheckACMETask(tx, userId, req.AcmeTaskId)
|
canAccess, err := acmemodels.SharedACMETaskDAO.CheckUserACMETask(tx, userId, req.AcmeTaskId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -303,7 +303,7 @@ func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETas
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
canAccess, err := acmemodels.SharedACMETaskDAO.CheckACMETask(tx, userId, req.AcmeTaskId)
|
canAccess, err := acmemodels.SharedACMETaskDAO.CheckUserACMETask(tx, userId, req.AcmeTaskId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -329,7 +329,7 @@ func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.Fi
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
canAccess, err := acmemodels.SharedACMETaskDAO.CheckACMETask(tx, userId, req.AcmeTaskId)
|
canAccess, err := acmemodels.SharedACMETaskDAO.CheckUserACMETask(tx, userId, req.AcmeTaskId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -440,3 +440,40 @@ func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.Fi
|
|||||||
SslCert: pbCert,
|
SslCert: pbCert,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindACMETaskUser 查找任务所属用户
|
||||||
|
func (this *ACMETaskService) FindACMETaskUser(ctx context.Context, req *pb.FindACMETaskUserRequest) (*pb.FindACMETaskUserResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
userId, err := acmemodels.SharedACMETaskDAO.FindACMETaskUserId(tx, req.AcmeTaskId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if userId <= 0 {
|
||||||
|
return &pb.FindACMETaskUserResponse{User: nil}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if user == nil {
|
||||||
|
return &pb.FindACMETaskUserResponse{
|
||||||
|
User: &pb.User{
|
||||||
|
Id: userId,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindACMETaskUserResponse{
|
||||||
|
User: &pb.User{
|
||||||
|
Id: userId,
|
||||||
|
Username: user.Username,
|
||||||
|
Fullname: user.Fullname,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ func (this *APINodeService) DeleteAPINode(ctx context.Context, req *pb.DeleteAPI
|
|||||||
|
|
||||||
// FindAllEnabledAPINodes 列出所有可用API节点
|
// FindAllEnabledAPINodes 列出所有可用API节点
|
||||||
func (this *APINodeService) FindAllEnabledAPINodes(ctx context.Context, req *pb.FindAllEnabledAPINodesRequest) (*pb.FindAllEnabledAPINodesResponse, error) {
|
func (this *APINodeService) FindAllEnabledAPINodes(ctx context.Context, req *pb.FindAllEnabledAPINodesRequest) (*pb.FindAllEnabledAPINodesResponse, error) {
|
||||||
_, _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeNode, rpcutils.UserTypeMonitor, rpcutils.UserTypeDNS, rpcutils.UserTypeAuthority)
|
_, _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeNode, rpcutils.UserTypeDNS, rpcutils.UserTypeAuthority)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,12 +95,6 @@ func (this *BaseService) ValidateUserNode(ctx context.Context, canRest bool) (us
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateMonitorNode 校验监控节点
|
|
||||||
func (this *BaseService) ValidateMonitorNode(ctx context.Context) (nodeId int64, err error) {
|
|
||||||
_, _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeMonitor)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateAuthorityNode 校验认证节点
|
// ValidateAuthorityNode 校验认证节点
|
||||||
func (this *BaseService) ValidateAuthorityNode(ctx context.Context) (nodeId int64, err error) {
|
func (this *BaseService) ValidateAuthorityNode(ctx context.Context) (nodeId int64, err error) {
|
||||||
_, _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAuthority)
|
_, _, nodeId, err = rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAuthority)
|
||||||
@@ -111,7 +105,7 @@ func (this *BaseService) ValidateAuthorityNode(ctx context.Context) (nodeId int6
|
|||||||
func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) {
|
func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.UserType) (role rpcutils.UserType, nodeIntId int64, err error) {
|
||||||
// 默认包含大部分节点
|
// 默认包含大部分节点
|
||||||
if len(roles) == 0 {
|
if len(roles) == 0 {
|
||||||
roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeReport, rpcutils.UserTypeMonitor, rpcutils.UserTypeLog, rpcutils.UserTypeAPI}
|
roles = []rpcutils.UserType{rpcutils.UserTypeNode, rpcutils.UserTypeCluster, rpcutils.UserTypeAdmin, rpcutils.UserTypeUser, rpcutils.UserTypeDNS, rpcutils.UserTypeReport, rpcutils.UserTypeLog, rpcutils.UserTypeAPI}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
@@ -195,8 +189,6 @@ func (this *BaseService) ValidateNodeId(ctx context.Context, roles ...rpcutils.U
|
|||||||
nodeIntId, err = models.SharedUserNodeDAO.FindEnabledUserNodeIdWithUniqueId(nil, nodeId)
|
nodeIntId, err = models.SharedUserNodeDAO.FindEnabledUserNodeIdWithUniqueId(nil, nodeId)
|
||||||
case rpcutils.UserTypeAdmin:
|
case rpcutils.UserTypeAdmin:
|
||||||
nodeIntId = 0
|
nodeIntId = 0
|
||||||
case rpcutils.UserTypeMonitor:
|
|
||||||
nodeIntId, err = models.SharedMonitorNodeDAO.FindEnabledMonitorNodeIdWithUniqueId(nil, nodeId)
|
|
||||||
case rpcutils.UserTypeDNS:
|
case rpcutils.UserTypeDNS:
|
||||||
nodeIntId, err = models.SharedNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId)
|
nodeIntId, err = models.SharedNSNodeDAO.FindEnabledNodeIdWithUniqueId(nil, nodeId)
|
||||||
case rpcutils.UserTypeReport:
|
case rpcutils.UserTypeReport:
|
||||||
|
|||||||
@@ -31,9 +31,11 @@ func (this *HTTPAccessLogService) CreateHTTPAccessLogs(ctx context.Context, req
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
err = models.SharedHTTPAccessLogDAO.CreateHTTPAccessLogs(tx, req.HttpAccessLogs)
|
if this.canWriteAccessLogsToDB() {
|
||||||
if err != nil {
|
err = models.SharedHTTPAccessLogDAO.CreateHTTPAccessLogs(tx, req.HttpAccessLogs)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = this.writeAccessLogsToPolicy(req.HttpAccessLogs)
|
err = this.writeAccessLogsToPolicy(req.HttpAccessLogs)
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ package services
|
|||||||
|
|
||||||
import "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
import "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
|
||||||
|
func (this *HTTPAccessLogService) canWriteAccessLogsToDB() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (this *HTTPAccessLogService) writeAccessLogsToPolicy(pbAccessLogs []*pb.HTTPAccessLog) error {
|
func (this *HTTPAccessLogService) writeAccessLogsToPolicy(pbAccessLogs []*pb.HTTPAccessLog) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func (this *HTTPFirewallRuleSetService) FindEnabledHTTPFirewallRuleSetConfig(ctx
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
config, err := models.SharedHTTPFirewallRuleSetDAO.ComposeFirewallRuleSet(tx, req.FirewallRuleSetId)
|
config, err := models.SharedHTTPFirewallRuleSetDAO.ComposeFirewallRuleSet(tx, req.FirewallRuleSetId, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
||||||
"github.com/iwind/TeaGo/types"
|
"github.com/iwind/TeaGo/types"
|
||||||
)
|
)
|
||||||
@@ -30,7 +32,7 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH
|
|||||||
const maxBodyLength = 32 * 1024
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
switch req.BodyType {
|
switch req.BodyType {
|
||||||
case shared.BodyTypeURL:
|
case serverconfigs.HTTPPageBodyTypeURL:
|
||||||
if len(req.Url) > maxURLLength {
|
if len(req.Url) > maxURLLength {
|
||||||
return nil, errors.New("'url' too long")
|
return nil, errors.New("'url' too long")
|
||||||
}
|
}
|
||||||
@@ -41,7 +43,18 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH
|
|||||||
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
req.Body = ""
|
req.Body = ""
|
||||||
}
|
}
|
||||||
case shared.BodyTypeHTML:
|
case serverconfigs.HTTPPageBodyTypeRedirectURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case serverconfigs.HTTPPageBodyTypeHTML:
|
||||||
if len(req.Body) > maxBodyLength {
|
if len(req.Body) > maxBodyLength {
|
||||||
return nil, errors.New("'body' too long")
|
return nil, errors.New("'body' too long")
|
||||||
}
|
}
|
||||||
@@ -53,7 +66,35 @@ func (this *HTTPPageService) CreateHTTPPage(ctx context.Context, req *pb.CreateH
|
|||||||
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
var exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(req.ExceptURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ExceptURLPatternsJSON, &exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, pattern := range exceptURLPatterns {
|
||||||
|
err = pattern.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(req.OnlyURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.OnlyURLPatternsJSON, &onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, pattern := range onlyURLPatterns {
|
||||||
|
err = pattern.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pageId, err := models.SharedHTTPPageDAO.CreatePage(tx, userId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus), exceptURLPatterns, onlyURLPatterns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -82,7 +123,7 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH
|
|||||||
const maxBodyLength = 32 * 1024
|
const maxBodyLength = 32 * 1024
|
||||||
|
|
||||||
switch req.BodyType {
|
switch req.BodyType {
|
||||||
case shared.BodyTypeURL:
|
case serverconfigs.HTTPPageBodyTypeURL:
|
||||||
if len(req.Url) > maxURLLength {
|
if len(req.Url) > maxURLLength {
|
||||||
return nil, errors.New("'url' too long")
|
return nil, errors.New("'url' too long")
|
||||||
}
|
}
|
||||||
@@ -93,7 +134,18 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH
|
|||||||
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
req.Body = ""
|
req.Body = ""
|
||||||
}
|
}
|
||||||
case shared.BodyTypeHTML:
|
case serverconfigs.HTTPPageBodyTypeRedirectURL:
|
||||||
|
if len(req.Url) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if !regexputils.HTTPProtocol.MatchString(req.Url) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
req.Body = ""
|
||||||
|
}
|
||||||
|
case serverconfigs.HTTPPageBodyTypeHTML:
|
||||||
if len(req.Body) > maxBodyLength {
|
if len(req.Body) > maxBodyLength {
|
||||||
return nil, errors.New("'body' too long")
|
return nil, errors.New("'body' too long")
|
||||||
}
|
}
|
||||||
@@ -105,7 +157,35 @@ func (this *HTTPPageService) UpdateHTTPPage(ctx context.Context, req *pb.UpdateH
|
|||||||
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
return nil, errors.New("invalid 'bodyType': " + req.BodyType)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus))
|
var exceptURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(req.ExceptURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.ExceptURLPatternsJSON, &exceptURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, pattern := range exceptURLPatterns {
|
||||||
|
err = pattern.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var onlyURLPatterns = []*shared.URLPattern{}
|
||||||
|
if len(req.OnlyURLPatternsJSON) > 0 {
|
||||||
|
err = json.Unmarshal(req.OnlyURLPatternsJSON, &onlyURLPatterns)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, pattern := range onlyURLPatterns {
|
||||||
|
err = pattern.Init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("validate url pattern '"+pattern.Pattern+"' failed: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.SharedHTTPPageDAO.UpdatePage(tx, req.HttpPageId, req.StatusList, req.BodyType, req.Url, req.Body, types.Int(req.NewStatus), exceptURLPatterns, onlyURLPatterns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
"github.com/TeaOSLab/EdgeAPI/internal/utils/regexputils"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
"github.com/iwind/TeaGo/dbs"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -365,7 +364,7 @@ func (this *HTTPWebService) UpdateHTTPWebShutdown(ctx context.Context, req *pb.U
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch shutdownConfig.BodyType {
|
switch shutdownConfig.BodyType {
|
||||||
case shared.BodyTypeURL:
|
case serverconfigs.HTTPPageBodyTypeURL:
|
||||||
if len(shutdownConfig.URL) > maxURLLength {
|
if len(shutdownConfig.URL) > maxURLLength {
|
||||||
return nil, errors.New("'url' too long")
|
return nil, errors.New("'url' too long")
|
||||||
}
|
}
|
||||||
@@ -376,7 +375,18 @@ func (this *HTTPWebService) UpdateHTTPWebShutdown(ctx context.Context, req *pb.U
|
|||||||
if len(shutdownConfig.Body) > maxBodyLength { // we keep short body for user experience
|
if len(shutdownConfig.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
shutdownConfig.Body = ""
|
shutdownConfig.Body = ""
|
||||||
}
|
}
|
||||||
case shared.BodyTypeHTML:
|
case serverconfigs.HTTPPageBodyTypeRedirectURL:
|
||||||
|
if len(shutdownConfig.URL) > maxURLLength {
|
||||||
|
return nil, errors.New("'url' too long")
|
||||||
|
}
|
||||||
|
if shutdownConfig.IsOn /** validate when it's on **/ && !regexputils.HTTPProtocol.MatchString(shutdownConfig.URL) {
|
||||||
|
return nil, errors.New("invalid 'url' format")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(shutdownConfig.Body) > maxBodyLength { // we keep short body for user experience
|
||||||
|
shutdownConfig.Body = ""
|
||||||
|
}
|
||||||
|
case serverconfigs.HTTPPageBodyTypeHTML:
|
||||||
if len(shutdownConfig.Body) > maxBodyLength {
|
if len(shutdownConfig.Body) > maxBodyLength {
|
||||||
return nil, errors.New("'body' too long")
|
return nil, errors.New("'body' too long")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,187 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageMediaInstanceService 消息媒介实例服务
|
|
||||||
type MessageMediaInstanceService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMessageMediaInstance 创建消息媒介实例
|
|
||||||
func (this *MessageMediaInstanceService) CreateMessageMediaInstance(ctx context.Context, req *pb.CreateMessageMediaInstanceRequest) (*pb.CreateMessageMediaInstanceResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
params := maps.Map{}
|
|
||||||
if len(req.ParamsJSON) > 0 {
|
|
||||||
err = json.Unmarshal(req.ParamsJSON, ¶ms)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
instanceId, err := models.SharedMessageMediaInstanceDAO.CreateMediaInstance(tx, req.Name, req.MediaType, params, req.Description, req.RateJSON, req.HashLife)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreateMessageMediaInstanceResponse{MessageMediaInstanceId: instanceId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageMediaInstance 修改消息实例
|
|
||||||
func (this *MessageMediaInstanceService) UpdateMessageMediaInstance(ctx context.Context, req *pb.UpdateMessageMediaInstanceRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
params := maps.Map{}
|
|
||||||
if len(req.ParamsJSON) > 0 {
|
|
||||||
err = json.Unmarshal(req.ParamsJSON, ¶ms)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageMediaInstanceDAO.UpdateMediaInstance(tx, req.MessageMediaInstanceId, req.Name, req.MediaType, params, req.Description, req.RateJSON, req.HashLife, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMessageMediaInstance 删除媒介实例
|
|
||||||
func (this *MessageMediaInstanceService) DeleteMessageMediaInstance(ctx context.Context, req *pb.DeleteMessageMediaInstanceRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageMediaInstanceDAO.DisableMessageMediaInstance(tx, req.MessageMediaInstanceId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledMessageMediaInstances 计算媒介实例数量
|
|
||||||
func (this *MessageMediaInstanceService) CountAllEnabledMessageMediaInstances(ctx context.Context, req *pb.CountAllEnabledMessageMediaInstancesRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
count, err := models.SharedMessageMediaInstanceDAO.CountAllEnabledMediaInstances(tx, req.MediaType, req.Keyword)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListEnabledMessageMediaInstances 列出单页媒介实例
|
|
||||||
func (this *MessageMediaInstanceService) ListEnabledMessageMediaInstances(ctx context.Context, req *pb.ListEnabledMessageMediaInstancesRequest) (*pb.ListEnabledMessageMediaInstancesResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
instances, err := models.SharedMessageMediaInstanceDAO.ListAllEnabledMediaInstances(tx, req.MediaType, req.Keyword, req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbInstances := []*pb.MessageMediaInstance{}
|
|
||||||
for _, instance := range instances {
|
|
||||||
// 媒介
|
|
||||||
media, err := models.SharedMessageMediaDAO.FindEnabledMediaWithType(tx, instance.MediaType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if media == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbMedia := &pb.MessageMedia{
|
|
||||||
Id: int64(media.Id),
|
|
||||||
Type: media.Type,
|
|
||||||
Name: media.Name,
|
|
||||||
Description: media.Description,
|
|
||||||
UserDescription: media.UserDescription,
|
|
||||||
IsOn: media.IsOn,
|
|
||||||
}
|
|
||||||
|
|
||||||
pbInstances = append(pbInstances, &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
IsOn: instance.IsOn,
|
|
||||||
MessageMedia: pbMedia,
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
Description: instance.Description,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.ListEnabledMessageMediaInstancesResponse{MessageMediaInstances: pbInstances}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMessageMediaInstance 查找单个媒介实例信息
|
|
||||||
func (this *MessageMediaInstanceService) FindEnabledMessageMediaInstance(ctx context.Context, req *pb.FindEnabledMessageMediaInstanceRequest) (*pb.FindEnabledMessageMediaInstanceResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, req.MessageMediaInstanceId, cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil {
|
|
||||||
return &pb.FindEnabledMessageMediaInstanceResponse{MessageMediaInstance: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介
|
|
||||||
media, err := models.SharedMessageMediaDAO.FindEnabledMediaWithType(tx, instance.MediaType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if media == nil {
|
|
||||||
return &pb.FindEnabledMessageMediaInstanceResponse{MessageMediaInstance: nil}, nil
|
|
||||||
}
|
|
||||||
pbMedia := &pb.MessageMedia{
|
|
||||||
Id: int64(media.Id),
|
|
||||||
Type: media.Type,
|
|
||||||
Name: media.Name,
|
|
||||||
Description: media.Description,
|
|
||||||
UserDescription: media.UserDescription,
|
|
||||||
IsOn: media.IsOn,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindEnabledMessageMediaInstanceResponse{MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
IsOn: instance.IsOn,
|
|
||||||
MessageMedia: pbMedia,
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
Description: instance.Description,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
HashLife: types.Int32(instance.HashLife),
|
|
||||||
}}, nil
|
|
||||||
}
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageReceiverService 消息对象接收人
|
|
||||||
type MessageReceiverService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageReceivers 创建接收者
|
|
||||||
func (this *MessageReceiverService) UpdateMessageReceivers(ctx context.Context, req *pb.UpdateMessageReceiversRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(req.Role) == 0 {
|
|
||||||
req.Role = nodeconfigs.NodeRoleNode
|
|
||||||
}
|
|
||||||
|
|
||||||
params := maps.Map{}
|
|
||||||
if len(req.ParamsJSON) > 0 {
|
|
||||||
err = json.Unmarshal(req.ParamsJSON, ¶ms)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = this.RunTx(func(tx *dbs.Tx) error {
|
|
||||||
err = models.SharedMessageReceiverDAO.DisableReceivers(tx, req.NodeClusterId, req.NodeId, req.ServerId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for messageType, options := range req.RecipientOptions {
|
|
||||||
for _, option := range options.RecipientOptions {
|
|
||||||
_, err := models.SharedMessageReceiverDAO.CreateReceiver(tx, req.Role, req.NodeClusterId, req.NodeId, req.ServerId, messageType, params, option.MessageRecipientId, option.MessageRecipientGroupId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindAllEnabledMessageReceivers 查找接收者
|
|
||||||
func (this *MessageReceiverService) FindAllEnabledMessageReceivers(ctx context.Context, req *pb.FindAllEnabledMessageReceiversRequest) (*pb.FindAllEnabledMessageReceiversResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(req.Role) == 0 {
|
|
||||||
req.Role = nodeconfigs.NodeRoleNode
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
receivers, err := models.SharedMessageReceiverDAO.FindAllEnabledReceivers(tx, req.Role, req.NodeClusterId, req.NodeId, req.ServerId, "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbReceivers := []*pb.MessageReceiver{}
|
|
||||||
for _, receiver := range receivers {
|
|
||||||
var pbRecipient *pb.MessageRecipient = nil
|
|
||||||
|
|
||||||
// 接收人
|
|
||||||
if receiver.RecipientId > 0 {
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, int64(receiver.RecipientId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 管理员
|
|
||||||
admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, int64(recipient.AdminId))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if admin == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 接收人
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
Admin: &pb.Admin{
|
|
||||||
Id: int64(admin.Id),
|
|
||||||
Fullname: admin.Fullname,
|
|
||||||
Username: admin.Username,
|
|
||||||
IsOn: admin.IsOn,
|
|
||||||
},
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
IsOn: instance.IsOn,
|
|
||||||
},
|
|
||||||
IsOn: recipient.IsOn,
|
|
||||||
MessageRecipientGroups: nil,
|
|
||||||
Description: "",
|
|
||||||
User: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 接收人分组
|
|
||||||
var pbRecipientGroup *pb.MessageRecipientGroup = nil
|
|
||||||
if receiver.RecipientGroupId > 0 {
|
|
||||||
group, err := models.SharedMessageRecipientGroupDAO.FindEnabledMessageRecipientGroup(tx, int64(receiver.RecipientGroupId))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if group == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbRecipientGroup = &pb.MessageRecipientGroup{
|
|
||||||
Id: int64(group.Id),
|
|
||||||
Name: group.Name,
|
|
||||||
IsOn: group.IsOn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pbReceivers = append(pbReceivers, &pb.MessageReceiver{
|
|
||||||
Id: int64(receiver.Id),
|
|
||||||
ClusterId: int64(receiver.ClusterId),
|
|
||||||
NodeId: int64(receiver.NodeId),
|
|
||||||
ServerId: int64(receiver.ServerId),
|
|
||||||
Type: receiver.Type,
|
|
||||||
ParamsJSON: receiver.Params,
|
|
||||||
MessageRecipient: pbRecipient,
|
|
||||||
MessageRecipientGroup: pbRecipientGroup,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return &pb.FindAllEnabledMessageReceiversResponse{MessageReceivers: pbReceivers}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMessageReceiver 删除接收者
|
|
||||||
func (this *MessageReceiverService) DeleteMessageReceiver(ctx context.Context, req *pb.DeleteMessageReceiverRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageReceiverDAO.DisableMessageReceiver(tx, req.MessageReceiverId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledMessageReceivers 计算接收者数量
|
|
||||||
func (this *MessageReceiverService) CountAllEnabledMessageReceivers(ctx context.Context, req *pb.CountAllEnabledMessageReceiversRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(req.Role) == 0 {
|
|
||||||
req.Role = nodeconfigs.NodeRoleNode
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
count, err := models.SharedMessageReceiverDAO.CountAllEnabledReceivers(tx, req.Role, req.NodeClusterId, req.NodeId, req.ServerId, "")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
@@ -1,235 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageRecipientService 消息接收人服务
|
|
||||||
type MessageRecipientService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMessageRecipient 创建接收人
|
|
||||||
func (this *MessageRecipientService) CreateMessageRecipient(ctx context.Context, req *pb.CreateMessageRecipientRequest) (*pb.CreateMessageRecipientResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
recipientId, err := models.SharedMessageRecipientDAO.CreateRecipient(tx, req.AdminId, req.MessageMediaInstanceId, req.User, req.MessageRecipientGroupIds, req.Description, req.TimeFrom, req.TimeTo)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreateMessageRecipientResponse{MessageRecipientId: recipientId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageRecipient 修改接收人
|
|
||||||
func (this *MessageRecipientService) UpdateMessageRecipient(ctx context.Context, req *pb.UpdateMessageRecipientRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageRecipientDAO.UpdateRecipient(tx, req.MessageRecipientId, req.AdminId, req.MessageMediaInstanceId, req.User, req.MessageRecipientGroupIds, req.Description, req.TimeFrom, req.TimeTo, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMessageRecipient 删除接收人
|
|
||||||
func (this *MessageRecipientService) DeleteMessageRecipient(ctx context.Context, req *pb.DeleteMessageRecipientRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageRecipientDAO.DisableMessageRecipient(tx, req.MessageRecipientId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledMessageRecipients 计算接收人数量
|
|
||||||
func (this *MessageRecipientService) CountAllEnabledMessageRecipients(ctx context.Context, req *pb.CountAllEnabledMessageRecipientsRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
count, err := models.SharedMessageRecipientDAO.CountAllEnabledRecipients(tx, req.AdminId, req.MessageRecipientGroupId, req.MediaType, req.Keyword)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListEnabledMessageRecipients 列出单页接收人
|
|
||||||
func (this *MessageRecipientService) ListEnabledMessageRecipients(ctx context.Context, req *pb.ListEnabledMessageRecipientsRequest) (*pb.ListEnabledMessageRecipientsResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
recipients, err := models.SharedMessageRecipientDAO.ListAllEnabledRecipients(tx, req.AdminId, req.MessageRecipientGroupId, req.MediaType, req.Keyword, req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbRecipients := []*pb.MessageRecipient{}
|
|
||||||
for _, recipient := range recipients {
|
|
||||||
// admin
|
|
||||||
admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, int64(recipient.AdminId))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if admin == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbAdmin := &pb.Admin{
|
|
||||||
Id: int64(admin.Id),
|
|
||||||
Fullname: admin.Fullname,
|
|
||||||
Username: admin.Username,
|
|
||||||
IsOn: admin.IsOn,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介实例
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbInstance := &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
IsOn: instance.IsOn,
|
|
||||||
Name: instance.Name,
|
|
||||||
Description: instance.Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分组
|
|
||||||
pbGroups := []*pb.MessageRecipientGroup{}
|
|
||||||
groupIds := recipient.DecodeGroupIds()
|
|
||||||
if len(groupIds) > 0 {
|
|
||||||
for _, groupId := range groupIds {
|
|
||||||
group, err := models.SharedMessageRecipientGroupDAO.FindEnabledMessageRecipientGroup(tx, groupId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if group != nil {
|
|
||||||
pbGroups = append(pbGroups, &pb.MessageRecipientGroup{
|
|
||||||
Id: int64(group.Id),
|
|
||||||
Name: group.Name,
|
|
||||||
IsOn: group.IsOn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pbRecipients = append(pbRecipients, &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
Admin: pbAdmin,
|
|
||||||
User: recipient.User,
|
|
||||||
MessageMediaInstance: pbInstance,
|
|
||||||
IsOn: recipient.IsOn,
|
|
||||||
MessageRecipientGroups: pbGroups,
|
|
||||||
Description: recipient.Description,
|
|
||||||
TimeFrom: recipient.TimeFrom,
|
|
||||||
TimeTo: recipient.TimeTo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.ListEnabledMessageRecipientsResponse{MessageRecipients: pbRecipients}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMessageRecipient 查找单个接收人信息
|
|
||||||
func (this *MessageRecipientService) FindEnabledMessageRecipient(ctx context.Context, req *pb.FindEnabledMessageRecipientRequest) (*pb.FindEnabledMessageRecipientResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, req.MessageRecipientId, cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient == nil {
|
|
||||||
return &pb.FindEnabledMessageRecipientResponse{MessageRecipient: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// admin
|
|
||||||
admin, err := models.SharedAdminDAO.FindEnabledAdmin(tx, int64(recipient.AdminId))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if admin == nil {
|
|
||||||
return &pb.FindEnabledMessageRecipientResponse{MessageRecipient: nil}, nil
|
|
||||||
}
|
|
||||||
pbAdmin := &pb.Admin{
|
|
||||||
Id: int64(admin.Id),
|
|
||||||
Fullname: admin.Fullname,
|
|
||||||
Username: admin.Username,
|
|
||||||
IsOn: admin.IsOn,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介实例
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil {
|
|
||||||
return &pb.FindEnabledMessageRecipientResponse{MessageRecipient: nil}, nil
|
|
||||||
}
|
|
||||||
pbInstance := &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
IsOn: instance.IsOn,
|
|
||||||
Name: instance.Name,
|
|
||||||
Description: instance.Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分组
|
|
||||||
pbGroups := []*pb.MessageRecipientGroup{}
|
|
||||||
groupIds := recipient.DecodeGroupIds()
|
|
||||||
if len(groupIds) > 0 {
|
|
||||||
for _, groupId := range groupIds {
|
|
||||||
group, err := models.SharedMessageRecipientGroupDAO.FindEnabledMessageRecipientGroup(tx, groupId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if group != nil {
|
|
||||||
pbGroups = append(pbGroups, &pb.MessageRecipientGroup{
|
|
||||||
Id: int64(group.Id),
|
|
||||||
Name: group.Name,
|
|
||||||
IsOn: group.IsOn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindEnabledMessageRecipientResponse{MessageRecipient: &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
User: recipient.User,
|
|
||||||
Admin: pbAdmin,
|
|
||||||
MessageMediaInstance: pbInstance,
|
|
||||||
IsOn: recipient.IsOn,
|
|
||||||
MessageRecipientGroups: pbGroups,
|
|
||||||
Description: recipient.Description,
|
|
||||||
TimeFrom: recipient.TimeFrom,
|
|
||||||
TimeTo: recipient.TimeTo,
|
|
||||||
}}, nil
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 消息接收人分组
|
|
||||||
type MessageRecipientGroupService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建分组
|
|
||||||
func (this *MessageRecipientGroupService) CreateMessageRecipientGroup(ctx context.Context, req *pb.CreateMessageRecipientGroupRequest) (*pb.CreateMessageRecipientGroupResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
groupId, err := models.SharedMessageRecipientGroupDAO.CreateGroup(tx, req.Name)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreateMessageRecipientGroupResponse{MessageRecipientGroupId: groupId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 修改分组
|
|
||||||
func (this *MessageRecipientGroupService) UpdateMessageRecipientGroup(ctx context.Context, req *pb.UpdateMessageRecipientGroupRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageRecipientGroupDAO.UpdateGroup(tx, req.MessageRecipientGroupId, req.Name, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找所有可用的分组
|
|
||||||
func (this *MessageRecipientGroupService) FindAllEnabledMessageRecipientGroups(ctx context.Context, req *pb.FindAllEnabledMessageRecipientGroupsRequest) (*pb.FindAllEnabledMessageRecipientGroupsResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
groups, err := models.SharedMessageRecipientGroupDAO.FindAllEnabledGroups(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbGroups := []*pb.MessageRecipientGroup{}
|
|
||||||
for _, group := range groups {
|
|
||||||
pbGroups = append(pbGroups, &pb.MessageRecipientGroup{
|
|
||||||
Id: int64(group.Id),
|
|
||||||
Name: group.Name,
|
|
||||||
IsOn: group.IsOn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindAllEnabledMessageRecipientGroupsResponse{MessageRecipientGroups: pbGroups}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除分组
|
|
||||||
func (this *MessageRecipientGroupService) DeleteMessageRecipientGroup(ctx context.Context, req *pb.DeleteMessageRecipientGroupRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageRecipientGroupDAO.DisableMessageRecipientGroup(tx, req.MessageRecipientGroupId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找单个分组信息
|
|
||||||
func (this *MessageRecipientGroupService) FindEnabledMessageRecipientGroup(ctx context.Context, req *pb.FindEnabledMessageRecipientGroupRequest) (*pb.FindEnabledMessageRecipientGroupResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
group, err := models.SharedMessageRecipientGroupDAO.FindEnabledMessageRecipientGroup(tx, req.MessageRecipientGroupId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if group == nil {
|
|
||||||
return &pb.FindEnabledMessageRecipientGroupResponse{MessageRecipientGroup: nil}, nil
|
|
||||||
}
|
|
||||||
pbGroup := &pb.MessageRecipientGroup{
|
|
||||||
Id: int64(group.Id),
|
|
||||||
IsOn: group.IsOn,
|
|
||||||
Name: group.Name,
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledMessageRecipientGroupResponse{MessageRecipientGroup: pbGroup}, nil
|
|
||||||
}
|
|
||||||
@@ -1,409 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"github.com/iwind/TeaGo/maps"
|
|
||||||
"github.com/iwind/TeaGo/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageTaskService 消息发送任务服务
|
|
||||||
type MessageTaskService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMessageTask 创建任务
|
|
||||||
func (this *MessageTaskService) CreateMessageTask(ctx context.Context, req *pb.CreateMessageTaskRequest) (*pb.CreateMessageTaskResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
taskId, err := models.SharedMessageTaskDAO.CreateMessageTask(tx, req.RecipientId, req.InstanceId, req.User, req.Subject, req.Body, req.IsPrimary)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pb.CreateMessageTaskResponse{MessageTaskId: taskId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindSendingMessageTasks 查找要发送的任务
|
|
||||||
func (this *MessageTaskService) FindSendingMessageTasks(ctx context.Context, req *pb.FindSendingMessageTasksRequest) (*pb.FindSendingMessageTasksResponse, error) {
|
|
||||||
_, err := this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
tasks, err := models.SharedMessageTaskDAO.FindSendingMessageTasks(tx, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pbTasks := []*pb.MessageTask{}
|
|
||||||
for _, task := range tasks {
|
|
||||||
var pbRecipient *pb.MessageRecipient
|
|
||||||
if task.RecipientId > 0 {
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, int64(task.RecipientId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient == nil || !recipient.IsOn {
|
|
||||||
// 如果发送人已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
User: recipient.User,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else { // 没有指定既定的接收人
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(task.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: 0,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pbTasks = append(pbTasks, &pb.MessageTask{
|
|
||||||
Id: int64(task.Id),
|
|
||||||
MessageRecipient: pbRecipient,
|
|
||||||
User: task.User,
|
|
||||||
Subject: task.Subject,
|
|
||||||
Body: task.Body,
|
|
||||||
CreatedAt: int64(task.CreatedAt),
|
|
||||||
Status: types.Int32(task.Status),
|
|
||||||
SentAt: int64(task.SentAt),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return &pb.FindSendingMessageTasksResponse{MessageTasks: pbTasks}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMessageTaskStatus 修改任务状态
|
|
||||||
func (this *MessageTaskService) UpdateMessageTaskStatus(ctx context.Context, req *pb.UpdateMessageTaskStatusRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
resultJSON := []byte{}
|
|
||||||
if req.Result != nil {
|
|
||||||
resultJSON, err = json.Marshal(maps.Map{
|
|
||||||
"isOk": req.Result.IsOk,
|
|
||||||
"error": req.Result.Error,
|
|
||||||
"response": req.Result.Response,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = models.SharedMessageTaskDAO.UpdateMessageTaskStatus(tx, req.MessageTaskId, int(req.Status), resultJSON)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建发送记录
|
|
||||||
if (int(req.Status) == models.MessageTaskStatusSuccess || int(req.Status) == models.MessageTaskStatusFailed) && req.Result != nil {
|
|
||||||
err = models.SharedMessageTaskLogDAO.CreateLog(tx, req.MessageTaskId, req.Result.IsOk, req.Result.Error, req.Result.Response)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMessageTask 删除消息任务
|
|
||||||
func (this *MessageTaskService) DeleteMessageTask(ctx context.Context, req *pb.DeleteMessageTaskRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, req.MessageTaskId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMessageTask 读取消息任务状态
|
|
||||||
func (this *MessageTaskService) FindEnabledMessageTask(ctx context.Context, req *pb.FindEnabledMessageTaskRequest) (*pb.FindEnabledMessageTaskResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
task, err := models.SharedMessageTaskDAO.FindEnabledMessageTask(tx, req.MessageTaskId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if task == nil {
|
|
||||||
return &pb.FindEnabledMessageTaskResponse{MessageTask: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var pbRecipient *pb.MessageRecipient
|
|
||||||
if task.RecipientId > 0 {
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, int64(task.RecipientId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient == nil || !recipient.IsOn {
|
|
||||||
// 如果发送人已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledMessageTaskResponse{MessageTask: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledMessageTaskResponse{MessageTask: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else { // 没有指定既定的接收人
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(task.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledMessageTaskResponse{MessageTask: nil}, nil
|
|
||||||
}
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: 0,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = &pb.MessageTaskResult{}
|
|
||||||
if len(task.Result) > 0 {
|
|
||||||
err = json.Unmarshal(task.Result, result)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindEnabledMessageTaskResponse{MessageTask: &pb.MessageTask{
|
|
||||||
Id: int64(task.Id),
|
|
||||||
MessageRecipient: pbRecipient,
|
|
||||||
User: task.User,
|
|
||||||
Subject: task.Subject,
|
|
||||||
Body: task.Body,
|
|
||||||
CreatedAt: int64(task.CreatedAt),
|
|
||||||
Status: int32(task.Status),
|
|
||||||
SentAt: int64(task.SentAt),
|
|
||||||
Result: result,
|
|
||||||
}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountMessageTasksWithStatus 计算某个状态的消息任务数量
|
|
||||||
func (this *MessageTaskService) CountMessageTasksWithStatus(ctx context.Context, req *pb.CountMessageTasksWithStatusRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
count, err := models.SharedMessageTaskDAO.CountMessageTasksWithStatus(tx, types.Int(req.Status))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMessageTasksWithStatus 根据状态列出某页任务
|
|
||||||
func (this *MessageTaskService) ListMessageTasksWithStatus(ctx context.Context, req *pb.ListMessageTasksWithStatusRequest) (*pb.ListMessageTasksWithStatusResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
tasks, err := models.SharedMessageTaskDAO.ListMessageTasksWithStatus(tx, types.Int(req.Status), req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pbTasks = []*pb.MessageTask{}
|
|
||||||
for _, task := range tasks {
|
|
||||||
var pbRecipient *pb.MessageRecipient
|
|
||||||
if task.RecipientId > 0 {
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, int64(task.RecipientId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient == nil || !recipient.IsOn {
|
|
||||||
// 如果发送人已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(recipient.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
User: recipient.User,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
} else { // 没有指定既定的接收人
|
|
||||||
// 媒介
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(task.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil || !instance.IsOn {
|
|
||||||
// 如果媒介实例已经删除或者禁用,则删除此消息
|
|
||||||
err = models.SharedMessageTaskDAO.DisableMessageTask(tx, int64(task.Id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: 0,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
MessageMedia: &pb.MessageMedia{
|
|
||||||
Type: instance.MediaType,
|
|
||||||
},
|
|
||||||
ParamsJSON: instance.Params,
|
|
||||||
RateJSON: instance.Rate,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = &pb.MessageTaskResult{}
|
|
||||||
if len(task.Result) > 0 {
|
|
||||||
err = json.Unmarshal(task.Result, result)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pbTasks = append(pbTasks, &pb.MessageTask{
|
|
||||||
Id: int64(task.Id),
|
|
||||||
MessageRecipient: pbRecipient,
|
|
||||||
User: task.User,
|
|
||||||
Subject: task.Subject,
|
|
||||||
Body: task.Body,
|
|
||||||
CreatedAt: int64(task.CreatedAt),
|
|
||||||
Status: types.Int32(task.Status),
|
|
||||||
SentAt: int64(task.SentAt),
|
|
||||||
Result: result,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.ListMessageTasksWithStatusResponse{MessageTasks: pbTasks}, nil
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MessageTaskLogService 消息发送日志相关服务
|
|
||||||
type MessageTaskLogService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountMessageTaskLogs 计算日志数量
|
|
||||||
func (this *MessageTaskLogService) CountMessageTaskLogs(ctx context.Context, req *pb.CountMessageTaskLogsRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var tx = this.NullTx()
|
|
||||||
count, err := models.SharedMessageTaskLogDAO.CountLogs(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListMessageTaskLogs 列出当页日志
|
|
||||||
func (this *MessageTaskLogService) ListMessageTaskLogs(ctx context.Context, req *pb.ListMessageTaskLogsRequest) (*pb.ListMessageTaskLogsResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var tx = this.NullTx()
|
|
||||||
var cacheMap = utils.NewCacheMap()
|
|
||||||
logs, err := models.SharedMessageTaskLogDAO.ListLogs(tx, req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pbLogs := []*pb.MessageTaskLog{}
|
|
||||||
for _, log := range logs {
|
|
||||||
task, err := models.SharedMessageTaskDAO.FindEnabledMessageTask(tx, int64(log.TaskId))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if task == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var pbRecipient *pb.MessageRecipient
|
|
||||||
if task.RecipientId > 0 {
|
|
||||||
recipient, err := models.SharedMessageRecipientDAO.FindEnabledMessageRecipient(tx, int64(task.RecipientId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if recipient != nil {
|
|
||||||
pbRecipient = &pb.MessageRecipient{
|
|
||||||
Id: int64(recipient.Id),
|
|
||||||
User: recipient.User,
|
|
||||||
}
|
|
||||||
task.InstanceId = recipient.InstanceId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
instance, err := models.SharedMessageMediaInstanceDAO.FindEnabledMessageMediaInstance(tx, int64(task.InstanceId), cacheMap)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if instance == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pbLogs = append(pbLogs, &pb.MessageTaskLog{
|
|
||||||
Id: int64(log.Id),
|
|
||||||
CreatedAt: int64(log.CreatedAt),
|
|
||||||
IsOk: log.IsOk,
|
|
||||||
Error: log.Error,
|
|
||||||
Response: log.Response,
|
|
||||||
MessageTask: &pb.MessageTask{
|
|
||||||
Id: int64(task.Id),
|
|
||||||
MessageRecipient: pbRecipient,
|
|
||||||
MessageMediaInstance: &pb.MessageMediaInstance{
|
|
||||||
Id: int64(instance.Id),
|
|
||||||
Name: instance.Name,
|
|
||||||
},
|
|
||||||
User: task.User,
|
|
||||||
Subject: task.Subject,
|
|
||||||
Body: task.Body,
|
|
||||||
CreatedAt: int64(task.CreatedAt),
|
|
||||||
Status: int32(task.Status),
|
|
||||||
SentAt: int64(task.SentAt),
|
|
||||||
Result: nil,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return &pb.ListMessageTaskLogsResponse{MessageTaskLogs: pbLogs}, nil
|
|
||||||
}
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
package services
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/errors"
|
|
||||||
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
|
||||||
"google.golang.org/grpc/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
type MonitorNodeService struct {
|
|
||||||
BaseService
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateMonitorNode 创建监控节点
|
|
||||||
func (this *MonitorNodeService) CreateMonitorNode(ctx context.Context, req *pb.CreateMonitorNodeRequest) (*pb.CreateMonitorNodeResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodeId, err := models.SharedMonitorNodeDAO.CreateMonitorNode(tx, req.Name, req.Description, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.CreateMonitorNodeResponse{MonitorNodeId: nodeId}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMonitorNode 修改监控节点
|
|
||||||
func (this *MonitorNodeService) UpdateMonitorNode(ctx context.Context, req *pb.UpdateMonitorNodeRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
err = models.SharedMonitorNodeDAO.UpdateMonitorNode(tx, req.MonitorNodeId, req.Name, req.Description, req.IsOn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteMonitorNode 删除监控节点
|
|
||||||
func (this *MonitorNodeService) DeleteMonitorNode(ctx context.Context, req *pb.DeleteMonitorNodeRequest) (*pb.RPCSuccess, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
err = models.SharedMonitorNodeDAO.DisableMonitorNode(tx, req.MonitorNodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindAllEnabledMonitorNodes 列出所有可用监控节点
|
|
||||||
func (this *MonitorNodeService) FindAllEnabledMonitorNodes(ctx context.Context, req *pb.FindAllEnabledMonitorNodesRequest) (*pb.FindAllEnabledMonitorNodesResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodes, err := models.SharedMonitorNodeDAO.FindAllEnabledMonitorNodes(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := []*pb.MonitorNode{}
|
|
||||||
for _, node := range nodes {
|
|
||||||
result = append(result, &pb.MonitorNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.FindAllEnabledMonitorNodesResponse{MonitorNodes: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountAllEnabledMonitorNodes 计算监控节点数量
|
|
||||||
func (this *MonitorNodeService) CountAllEnabledMonitorNodes(ctx context.Context, req *pb.CountAllEnabledMonitorNodesRequest) (*pb.RPCCountResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
count, err := models.SharedMonitorNodeDAO.CountAllEnabledMonitorNodes(tx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.SuccessCount(count)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListEnabledMonitorNodes 列出单页的监控节点
|
|
||||||
func (this *MonitorNodeService) ListEnabledMonitorNodes(ctx context.Context, req *pb.ListEnabledMonitorNodesRequest) (*pb.ListEnabledMonitorNodesResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
nodes, err := models.SharedMonitorNodeDAO.ListEnabledMonitorNodes(tx, req.Offset, req.Size)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := []*pb.MonitorNode{}
|
|
||||||
for _, node := range nodes {
|
|
||||||
result = append(result, &pb.MonitorNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
StatusJSON: node.Status,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pb.ListEnabledMonitorNodesResponse{MonitorNodes: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindEnabledMonitorNode 根据ID查找节点
|
|
||||||
func (this *MonitorNodeService) FindEnabledMonitorNode(ctx context.Context, req *pb.FindEnabledMonitorNodeRequest) (*pb.FindEnabledMonitorNodeResponse, error) {
|
|
||||||
_, err := this.ValidateAdmin(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
node, err := models.SharedMonitorNodeDAO.FindEnabledMonitorNode(tx, req.MonitorNodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
return &pb.FindEnabledMonitorNodeResponse{MonitorNode: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
result := &pb.MonitorNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
}
|
|
||||||
return &pb.FindEnabledMonitorNodeResponse{MonitorNode: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FindCurrentMonitorNode 获取当前监控节点的版本
|
|
||||||
func (this *MonitorNodeService) FindCurrentMonitorNode(ctx context.Context, req *pb.FindCurrentMonitorNodeRequest) (*pb.FindCurrentMonitorNodeResponse, error) {
|
|
||||||
_, err := this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("context: need 'nodeId'")
|
|
||||||
}
|
|
||||||
nodeIds := md.Get("nodeid")
|
|
||||||
if len(nodeIds) == 0 {
|
|
||||||
return nil, errors.New("invalid 'nodeId'")
|
|
||||||
}
|
|
||||||
nodeId := nodeIds[0]
|
|
||||||
node, err := models.SharedMonitorNodeDAO.FindEnabledMonitorNodeWithUniqueId(tx, nodeId)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
return &pb.FindCurrentMonitorNodeResponse{MonitorNode: nil}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
result := &pb.MonitorNode{
|
|
||||||
Id: int64(node.Id),
|
|
||||||
IsOn: node.IsOn,
|
|
||||||
UniqueId: node.UniqueId,
|
|
||||||
Secret: node.Secret,
|
|
||||||
Name: node.Name,
|
|
||||||
Description: node.Description,
|
|
||||||
}
|
|
||||||
return &pb.FindCurrentMonitorNodeResponse{MonitorNode: result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateMonitorNodeStatus 更新节点状态
|
|
||||||
func (this *MonitorNodeService) UpdateMonitorNodeStatus(ctx context.Context, req *pb.UpdateMonitorNodeStatusRequest) (*pb.RPCSuccess, error) {
|
|
||||||
// 校验节点
|
|
||||||
_, nodeId, err := this.ValidateNodeId(ctx, rpcutils.UserTypeMonitor)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if req.MonitorNodeId > 0 {
|
|
||||||
nodeId = req.MonitorNodeId
|
|
||||||
}
|
|
||||||
|
|
||||||
if nodeId <= 0 {
|
|
||||||
return nil, errors.New("'nodeId' should be greater than 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
var tx = this.NullTx()
|
|
||||||
|
|
||||||
err = models.SharedMonitorNodeDAO.UpdateNodeStatus(tx, nodeId, req.StatusJSON)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return this.Success()
|
|
||||||
}
|
|
||||||
@@ -2066,7 +2066,7 @@ func (this *NodeService) FindEnabledNodeConfigInfo(ctx context.Context, req *pb.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// thresholds
|
// thresholds
|
||||||
countThresholds, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, nodeconfigs.NodeRoleNode, 0, req.NodeId)
|
countThresholds, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, nodeconfigs.NodeRoleNode, int64(node.ClusterId), req.NodeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ func (this *NodeClusterService) CreateNodeCluster(ctx context.Context, req *pb.C
|
|||||||
req.DnsTTL = 0
|
req.DnsTTL = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
clusterId, err = models.SharedNodeClusterDAO.CreateCluster(tx, adminId, req.Name, req.NodeGrantId, req.InstallDir, req.DnsDomainId, req.DnsName, req.DnsTTL, req.HttpCachePolicyId, req.HttpFirewallPolicyId, systemServices, serverGlobalConfig, req.AutoInstallNftables)
|
clusterId, err = models.SharedNodeClusterDAO.CreateCluster(tx, adminId, req.Name, req.NodeGrantId, req.InstallDir, req.DnsDomainId, req.DnsName, req.DnsTTL, req.HttpCachePolicyId, req.HttpFirewallPolicyId, systemServices, serverGlobalConfig, req.AutoInstallNftables, req.AutoSystemTuning)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ func (this *NodeClusterService) UpdateNodeCluster(ctx context.Context, req *pb.U
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig, req.AutoRemoteStart, req.AutoInstallNftables, sshParams)
|
err = models.SharedNodeClusterDAO.UpdateCluster(tx, req.NodeClusterId, req.Name, req.NodeGrantId, req.InstallDir, req.TimeZone, req.NodeMaxThreads, req.AutoOpenPorts, clockConfig, req.AutoRemoteStart, req.AutoInstallNftables, sshParams, req.AutoSystemTuning)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -233,6 +233,7 @@ func (this *NodeClusterService) FindEnabledNodeCluster(ctx context.Context, req
|
|||||||
ClockJSON: cluster.Clock,
|
ClockJSON: cluster.Clock,
|
||||||
AutoRemoteStart: cluster.AutoRemoteStart,
|
AutoRemoteStart: cluster.AutoRemoteStart,
|
||||||
AutoInstallNftables: cluster.AutoInstallNftables,
|
AutoInstallNftables: cluster.AutoInstallNftables,
|
||||||
|
AutoSystemTuning: cluster.AutoSystemTuning,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,15 +964,21 @@ func (this *NodeClusterService) FindFreePortInNodeCluster(ctx context.Context, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
globalConfig, err := models.SharedSysSettingDAO.ReadGlobalConfig(tx)
|
|
||||||
|
// 检查端口
|
||||||
|
globalServerConfig, err := models.SharedNodeClusterDAO.FindClusterGlobalServerConfig(tx, req.NodeClusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查端口
|
var portMin, portMax int
|
||||||
portMin := globalConfig.TCPAll.PortRangeMin
|
var denyPorts []int
|
||||||
portMax := globalConfig.TCPAll.PortRangeMax
|
|
||||||
denyPorts := globalConfig.TCPAll.DenyPorts
|
if globalServerConfig != nil {
|
||||||
|
portMin = globalServerConfig.TCPAll.PortRangeMin
|
||||||
|
portMax = globalServerConfig.TCPAll.PortRangeMax
|
||||||
|
denyPorts = globalServerConfig.TCPAll.DenyPorts
|
||||||
|
}
|
||||||
|
|
||||||
if portMin == 0 && portMax == 0 {
|
if portMin == 0 && portMax == 0 {
|
||||||
portMin = 10_000
|
portMin = 10_000
|
||||||
@@ -1190,6 +1197,9 @@ func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Con
|
|||||||
result.Http3IsOn = http3Policy.IsOn
|
result.Http3IsOn = http3Policy.IsOn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 网络安全策略
|
||||||
|
result.HasNetworkSecurityPolicy = cluster.HasNetworkSecurityPolicy()
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,13 @@ import (
|
|||||||
func (this *NodeClusterService) FindNodeClusterHTTP3Policy(ctx context.Context, req *pb.FindNodeClusterHTTP3PolicyRequest) (*pb.FindNodeClusterHTTP3PolicyResponse, error) {
|
func (this *NodeClusterService) FindNodeClusterHTTP3Policy(ctx context.Context, req *pb.FindNodeClusterHTTP3PolicyRequest) (*pb.FindNodeClusterHTTP3PolicyResponse, error) {
|
||||||
return nil, this.NotImplementedYet()
|
return nil, this.NotImplementedYet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeClusterNetworkSecurityPolicy 获取集群的网络安全策略
|
||||||
|
func (this *NodeClusterService) FindNodeClusterNetworkSecurityPolicy(ctx context.Context, req *pb.FindNodeClusterNetworkSecurityPolicyRequest) (*pb.FindNodeClusterNetworkSecurityPolicyResponse, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateNodeClusterNetworkSecurityPolicy 修改集群的网络安全策略
|
||||||
|
func (this *NodeClusterService) UpdateNodeClusterNetworkSecurityPolicy(ctx context.Context, req *pb.UpdateNodeClusterNetworkSecurityPolicyRequest) (*pb.RPCSuccess, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,3 +52,8 @@ func (this *NodeService) CopyNodeActionsToNodeCluster(ctx context.Context, req *
|
|||||||
func (this *NodeService) FindNodeTOAConfig(ctx context.Context, req *pb.FindNodeTOAConfigRequest) (*pb.FindNodeTOAConfigResponse, error) {
|
func (this *NodeService) FindNodeTOAConfig(ctx context.Context, req *pb.FindNodeTOAConfigRequest) (*pb.FindNodeTOAConfigResponse, error) {
|
||||||
return nil, this.NotImplementedYet()
|
return nil, this.NotImplementedYet()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindNodeNetworkSecurityPolicy 查找节点的网络安全策略
|
||||||
|
func (this *NodeService) FindNodeNetworkSecurityPolicy(ctx context.Context, req *pb.FindNodeNetworkSecurityPolicyRequest) (*pb.FindNodeNetworkSecurityPolicyResponse, error) {
|
||||||
|
return nil, this.NotImplementedYet()
|
||||||
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ func (this *ReverseProxyService) UpdateReverseProxy(ctx context.Context, req *pb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = models.SharedReverseProxyDAO.UpdateReverseProxy(tx, req.ReverseProxyId, types.Int8(req.RequestHostType), req.RequestHost, req.RequestHostExcludingPort, req.RequestURI, req.StripPrefix, req.AutoFlush, req.AddHeaders, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.ProxyProtocolJSON, req.FollowRedirects, req.Retry50X)
|
err = models.SharedReverseProxyDAO.UpdateReverseProxy(tx, req.ReverseProxyId, types.Int8(req.RequestHostType), req.RequestHost, req.RequestHostExcludingPort, req.RequestURI, req.StripPrefix, req.AutoFlush, req.AddHeaders, connTimeout, readTimeout, idleTimeout, req.MaxConns, req.MaxIdleConns, req.ProxyProtocolJSON, req.FollowRedirects, req.Retry50X, req.Retry40X)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,12 +118,12 @@ func (this *ServerService) CreateServer(ctx context.Context, req *pb.CreateServe
|
|||||||
var auditingServerNamesJSON = []byte("[]")
|
var auditingServerNamesJSON = []byte("[]")
|
||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
// 如果域名不为空的时候需要审核
|
// 如果域名不为空的时候需要审核
|
||||||
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" {
|
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" && req.NodeClusterId > 0 {
|
||||||
globalConfig, err := models.SharedSysSettingDAO.ReadGlobalConfig(tx)
|
globalServerConfig, err := models.SharedNodeClusterDAO.FindClusterGlobalServerConfig(tx, req.NodeClusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn {
|
if globalServerConfig != nil && globalServerConfig.HTTPAll.DomainAuditingIsOn {
|
||||||
isAuditing = true
|
isAuditing = true
|
||||||
serverNamesJSON = []byte("[]")
|
serverNamesJSON = []byte("[]")
|
||||||
auditingServerNamesJSON = req.ServerNamesJSON
|
auditingServerNamesJSON = req.ServerNamesJSON
|
||||||
@@ -259,11 +259,12 @@ func (this *ServerService) CreateBasicHTTPServer(ctx context.Context, req *pb.Cr
|
|||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
// 如果域名不为空的时候需要审核
|
// 如果域名不为空的时候需要审核
|
||||||
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" {
|
if len(serverNamesJSON) > 0 && string(serverNamesJSON) != "[]" {
|
||||||
globalConfig, err := models.SharedSysSettingDAO.ReadGlobalConfig(tx)
|
globalServerConfig, err := models.SharedNodeClusterDAO.FindClusterGlobalServerConfig(tx, req.NodeClusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn {
|
|
||||||
|
if globalServerConfig != nil && globalServerConfig.HTTPAll.DomainAuditingIsOn {
|
||||||
isAuditing = true
|
isAuditing = true
|
||||||
serverNamesJSON = []byte("[]")
|
serverNamesJSON = []byte("[]")
|
||||||
auditingServerNamesJSON = serverNamesJSON
|
auditingServerNamesJSON = serverNamesJSON
|
||||||
@@ -1091,22 +1092,31 @@ func (this *ServerService) UpdateServerNames(ctx context.Context, req *pb.Update
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 是否需要审核
|
// 是否需要审核
|
||||||
globalConfig, err := models.SharedSysSettingDAO.ReadGlobalConfig(tx)
|
clusterId, err := models.SharedServerDAO.FindServerClusterId(tx, req.ServerId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if globalConfig != nil && globalConfig.HTTPAll.DomainAuditingIsOn {
|
if clusterId > 0 {
|
||||||
err = models.SharedServerDAO.UpdateAuditingServerNames(tx, req.ServerId, true, req.ServerNamesJSON)
|
globalServerConfig, err := models.SharedNodeClusterDAO.FindClusterGlobalServerConfig(tx, clusterId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if globalServerConfig != nil && globalServerConfig.HTTPAll.DomainAuditingIsOn {
|
||||||
|
err = models.SharedServerDAO.UpdateAuditingServerNames(tx, req.ServerId, true, req.ServerNamesJSON)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// 发送审核通知
|
// 发送审核通知
|
||||||
err = models.SharedMessageDAO.CreateMessage(tx, 0, 0, models.MessageTypeServerNamesRequireAuditing, models.MessageLevelWarning, "有新的网站域名需要审核", "有新的网站域名需要审核", maps.Map{
|
err = models.SharedMessageDAO.CreateMessage(tx, 0, 0, models.MessageTypeServerNamesRequireAuditing, models.MessageLevelWarning, "有新的网站域名需要审核", "有新的网站域名需要审核", maps.Map{
|
||||||
"serverId": req.ServerId,
|
"serverId": req.ServerId,
|
||||||
}.AsJSON())
|
}.AsJSON())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2987,7 +2997,7 @@ func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopySer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = models.SharedServerDAO.CopyServerConfigToServers(tx, req.ServerId, req.TargetServerIds, req.ConfigCode)
|
err = models.SharedServerDAO.CopyServerConfigToServers(tx, req.ServerId, req.TargetServerIds, req.ConfigCode, req.WafCopyRegions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3004,7 +3014,7 @@ func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopySer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = models.SharedServerDAO.CopyServerConfigToGroups(tx, req.ServerId, req.TargetServerGroupIds, req.ConfigCode)
|
err = models.SharedServerDAO.CopyServerConfigToGroups(tx, req.ServerId, req.TargetServerGroupIds, req.ConfigCode, req.WafCopyRegions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3016,7 +3026,7 @@ func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopySer
|
|||||||
if req.TargetClusterId <= 0 {
|
if req.TargetClusterId <= 0 {
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
err = models.SharedServerDAO.CopyServerConfigToCluster(tx, req.ServerId, req.TargetClusterId, req.ConfigCode)
|
err = models.SharedServerDAO.CopyServerConfigToCluster(tx, req.ServerId, req.TargetClusterId, req.ConfigCode, req.WafCopyRegions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3035,7 +3045,7 @@ func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopySer
|
|||||||
// 只能同步到自己的网站
|
// 只能同步到自己的网站
|
||||||
req.TargetUserId = userId
|
req.TargetUserId = userId
|
||||||
}
|
}
|
||||||
err = models.SharedServerDAO.CopyServerConfigToUser(tx, req.ServerId, req.TargetUserId, req.ConfigCode)
|
err = models.SharedServerDAO.CopyServerConfigToUser(tx, req.ServerId, req.TargetUserId, req.ConfigCode, req.WafCopyRegions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -3043,3 +3053,43 @@ func (this *ServerService) CopyServerConfig(ctx context.Context, req *pb.CopySer
|
|||||||
|
|
||||||
return this.Success()
|
return this.Success()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindServerAuditingPrompt 获取域名审核时的提示文字
|
||||||
|
func (this *ServerService) FindServerAuditingPrompt(ctx context.Context, req *pb.FindServerAuditingPromptRequest) (*pb.FindServerAuditingPromptResponse, error) {
|
||||||
|
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
if userId > 0 {
|
||||||
|
err = models.SharedServerDAO.CheckUserServer(tx, userId, req.ServerId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterId, err := models.SharedServerDAO.FindServerClusterId(tx, req.ServerId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if clusterId <= 0 {
|
||||||
|
return &pb.FindServerAuditingPromptResponse{
|
||||||
|
PromptText: "",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
globalServerConfig, err := models.SharedNodeClusterDAO.FindClusterGlobalServerConfig(tx, clusterId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if globalServerConfig != nil {
|
||||||
|
return &pb.FindServerAuditingPromptResponse{
|
||||||
|
PromptText: globalServerConfig.HTTPAll.DomainAuditingPrompt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindServerAuditingPromptResponse{
|
||||||
|
PromptText: "",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -414,6 +414,17 @@ func (this *ServerStatBoardService) ComposeServerStatNodeBoard(ctx context.Conte
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
networkPacketsValues, err := models.SharedNodeValueDAO.ListValues(tx, "node", req.NodeId, nodeconfigs.NodeValueItemNetworkPackets, nodeconfigs.NodeValueRangeMinute)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, v := range networkPacketsValues {
|
||||||
|
result.NetworkPacketsValues = append(result.NetworkPacketsValues, &pb.NodeValue{
|
||||||
|
ValueJSON: v.Value,
|
||||||
|
CreatedAt: int64(v.CreatedAt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
cacheDirValues, err := models.SharedNodeValueDAO.ListValues(tx, "node", req.NodeId, nodeconfigs.NodeValueItemCacheDir, nodeconfigs.NodeValueRangeMinute)
|
cacheDirValues, err := models.SharedNodeValueDAO.ListValues(tx, "node", req.NodeId, nodeconfigs.NodeValueItemCacheDir, nodeconfigs.NodeValueRangeMinute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ func (this *SSLCertService) CountSSLCerts(ctx context.Context, req *pb.CountSSLC
|
|||||||
return nil, errors.New("invalid user")
|
return nil, errors.New("invalid user")
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := models.SharedSSLCertDAO.CountCerts(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains)
|
count, err := models.SharedSSLCertDAO.CountCerts(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains, req.UserOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -215,7 +215,7 @@ func (this *SSLCertService) ListSSLCerts(ctx context.Context, req *pb.ListSSLCer
|
|||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
certIds, err := models.SharedSSLCertDAO.ListCertIds(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains, req.Offset, req.Size)
|
certIds, err := models.SharedSSLCertDAO.ListCertIds(tx, req.IsCA, req.IsAvailable, req.IsExpired, int64(req.ExpiringDays), req.Keyword, userId, req.Domains, req.UserOnly, req.Offset, req.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -368,3 +368,40 @@ func (this *SSLCertService) ListUpdatedSSLCertOCSP(ctx context.Context, req *pb.
|
|||||||
SslCertOCSP: result,
|
SslCertOCSP: result,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindSSLCertUser 查找证书所属用户
|
||||||
|
func (this *SSLCertService) FindSSLCertUser(ctx context.Context, req *pb.FindSSLCertUserRequest) (*pb.FindSSLCertUserResponse, error) {
|
||||||
|
_, err := this.ValidateAdmin(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
userId, err := models.SharedSSLCertDAO.FindCertUserId(tx, req.SslCertId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if userId <= 0 {
|
||||||
|
return &pb.FindSSLCertUserResponse{User: nil}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := models.SharedUserDAO.FindEnabledBasicUser(tx, userId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if user == nil {
|
||||||
|
return &pb.FindSSLCertUserResponse{
|
||||||
|
User: &pb.User{
|
||||||
|
Id: userId,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.FindSSLCertUserResponse{
|
||||||
|
User: &pb.User{
|
||||||
|
Id: userId,
|
||||||
|
Username: user.Username,
|
||||||
|
Fullname: user.Fullname,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ type SysLockerService struct {
|
|||||||
// SysLockerLock 获得锁
|
// SysLockerLock 获得锁
|
||||||
func (this *SysLockerService) SysLockerLock(ctx context.Context, req *pb.SysLockerLockRequest) (*pb.SysLockerLockResponse, error) {
|
func (this *SysLockerService) SysLockerLock(ctx context.Context, req *pb.SysLockerLockRequest) (*pb.SysLockerLockResponse, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||||
if err != nil {
|
|
||||||
_, err = this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key := req.Key
|
key := req.Key
|
||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
@@ -44,12 +38,6 @@ func (this *SysLockerService) SysLockerLock(ctx context.Context, req *pb.SysLock
|
|||||||
// SysLockerUnlock 释放锁
|
// SysLockerUnlock 释放锁
|
||||||
func (this *SysLockerService) SysLockerUnlock(ctx context.Context, req *pb.SysLockerUnlockRequest) (*pb.RPCSuccess, error) {
|
func (this *SysLockerService) SysLockerUnlock(ctx context.Context, req *pb.SysLockerUnlockRequest) (*pb.RPCSuccess, error) {
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
_, userId, err := this.ValidateAdminAndUser(ctx, false)
|
||||||
if err != nil {
|
|
||||||
_, err = this.ValidateMonitorNode(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key := req.Key
|
key := req.Key
|
||||||
if userId > 0 {
|
if userId > 0 {
|
||||||
|
|||||||
@@ -241,28 +241,31 @@ func (this *UserService) FindEnabledUser(ctx context.Context, req *pb.FindEnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledUserResponse{User: &pb.User{
|
return &pb.FindEnabledUserResponse{
|
||||||
Id: int64(user.Id),
|
User: &pb.User{
|
||||||
Username: user.Username,
|
Id: int64(user.Id),
|
||||||
Fullname: user.Fullname,
|
Username: user.Username,
|
||||||
Mobile: user.Mobile,
|
Fullname: user.Fullname,
|
||||||
Tel: user.Tel,
|
Mobile: user.Mobile,
|
||||||
Email: user.Email,
|
Tel: user.Tel,
|
||||||
VerifiedEmail: user.VerifiedEmail,
|
Email: user.Email,
|
||||||
Remark: user.Remark,
|
VerifiedEmail: user.VerifiedEmail,
|
||||||
IsOn: user.IsOn,
|
VerifiedMobile: user.VerifiedMobile,
|
||||||
CreatedAt: int64(user.CreatedAt),
|
Remark: user.Remark,
|
||||||
RegisteredIP: user.RegisteredIP,
|
IsOn: user.IsOn,
|
||||||
IsVerified: user.IsVerified,
|
CreatedAt: int64(user.CreatedAt),
|
||||||
IsRejected: user.IsRejected,
|
RegisteredIP: user.RegisteredIP,
|
||||||
RejectReason: user.RejectReason,
|
IsVerified: user.IsVerified,
|
||||||
NodeCluster: pbCluster,
|
IsRejected: user.IsRejected,
|
||||||
IsIndividualIdentified: isIndividualIdentified,
|
RejectReason: user.RejectReason,
|
||||||
IsEnterpriseIdentified: isEnterpriseIdentified,
|
NodeCluster: pbCluster,
|
||||||
BandwidthAlgo: user.BandwidthAlgo,
|
IsIndividualIdentified: isIndividualIdentified,
|
||||||
OtpLogin: pbOtpAuth,
|
IsEnterpriseIdentified: isEnterpriseIdentified,
|
||||||
Lang: user.Lang,
|
BandwidthAlgo: user.BandwidthAlgo,
|
||||||
}}, nil
|
OtpLogin: pbOtpAuth,
|
||||||
|
Lang: user.Lang,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckUserUsername 检查用户名是否存在
|
// CheckUserUsername 检查用户名是否存在
|
||||||
@@ -312,11 +315,14 @@ func (this *UserService) LoginUser(ctx context.Context, req *pb.LoginUserRequest
|
|||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
// 邮箱登录
|
// 邮箱登录
|
||||||
|
var registerConfig *userconfigs.UserRegisterConfig
|
||||||
if strings.Contains(req.Username, "@") {
|
if strings.Contains(req.Username, "@") {
|
||||||
// 是否允许
|
// 是否允许
|
||||||
registerConfig, err := models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
if registerConfig == nil {
|
||||||
if err != nil {
|
registerConfig, err = models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if registerConfig != nil && registerConfig.EmailVerification.CanLogin {
|
if registerConfig != nil && registerConfig.EmailVerification.CanLogin {
|
||||||
userId, err := models.SharedUserDAO.CheckUserEmailPassword(tx, req.Username, req.Password)
|
userId, err := models.SharedUserDAO.CheckUserEmailPassword(tx, req.Username, req.Password)
|
||||||
@@ -332,6 +338,29 @@ func (this *UserService) LoginUser(ctx context.Context, req *pb.LoginUserRequest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 手机号登录
|
||||||
|
if utils.IsValidMobile(req.Username) {
|
||||||
|
// 是否允许
|
||||||
|
if registerConfig == nil {
|
||||||
|
registerConfig, err = models.SharedSysSettingDAO.ReadUserRegisterConfig(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if registerConfig != nil && registerConfig.MobileVerification.CanLogin {
|
||||||
|
userId, err := models.SharedUserDAO.CheckUserMobilePassword(tx, req.Username, req.Password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if userId > 0 {
|
||||||
|
return &pb.LoginUserResponse{
|
||||||
|
UserId: userId,
|
||||||
|
IsOk: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 用户名登录
|
// 用户名登录
|
||||||
userId, err := models.SharedUserDAO.CheckUserPassword(tx, req.Username, req.Password)
|
userId, err := models.SharedUserDAO.CheckUserPassword(tx, req.Username, req.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -840,6 +869,28 @@ func (this *UserService) CheckUserEmail(ctx context.Context, req *pb.CheckUserEm
|
|||||||
return &pb.CheckUserEmailResponse{Exists: false}, nil
|
return &pb.CheckUserEmailResponse{Exists: false}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckUserMobile 检查手机号码是否被使用
|
||||||
|
func (this *UserService) CheckUserMobile(ctx context.Context, req *pb.CheckUserMobileRequest) (*pb.CheckUserMobileResponse, error) {
|
||||||
|
userId, err := this.ValidateUserNode(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(req.Mobile) == 0 {
|
||||||
|
return nil, errors.New("'mobile' required")
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx = this.NullTx()
|
||||||
|
mobileOwnerUserId, err := models.SharedUserDAO.FindUserIdWithVerifiedMobile(tx, req.Mobile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if mobileOwnerUserId > 0 && userId != mobileOwnerUserId {
|
||||||
|
return &pb.CheckUserMobileResponse{Exists: true}, nil
|
||||||
|
}
|
||||||
|
return &pb.CheckUserMobileResponse{Exists: false}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// FindUserVerifiedEmailWithUsername 根据用户名查询用户绑定的邮箱
|
// FindUserVerifiedEmailWithUsername 根据用户名查询用户绑定的邮箱
|
||||||
func (this *UserService) FindUserVerifiedEmailWithUsername(ctx context.Context, req *pb.FindUserVerifiedEmailWithUsernameRequest) (*pb.FindUserVerifiedEmailWithUsernameResponse, error) {
|
func (this *UserService) FindUserVerifiedEmailWithUsername(ctx context.Context, req *pb.FindUserVerifiedEmailWithUsernameRequest) (*pb.FindUserVerifiedEmailWithUsernameResponse, error) {
|
||||||
_, err := this.ValidateUserNode(ctx, false)
|
_, err := this.ValidateUserNode(ctx, false)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ const (
|
|||||||
UserTypeProvider = "provider"
|
UserTypeProvider = "provider"
|
||||||
UserTypeNode = "node"
|
UserTypeNode = "node"
|
||||||
UserTypeCluster = "cluster"
|
UserTypeCluster = "cluster"
|
||||||
UserTypeMonitor = "monitor"
|
|
||||||
UserTypeStat = "stat"
|
UserTypeStat = "stat"
|
||||||
UserTypeDNS = "dns"
|
UserTypeDNS = "dns"
|
||||||
UserTypeLog = "log"
|
UserTypeLog = "log"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -60,6 +60,11 @@ var recordsTables = []*SQLRecordsTable{
|
|||||||
UniqueFields: []string{"agentId", "ip"},
|
UniqueFields: []string{"agentId", "ip"},
|
||||||
IgnoreId: true,
|
IgnoreId: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
TableName: "edgeMessageMedias",
|
||||||
|
UniqueFields: []string{"type"},
|
||||||
|
IgnoreId: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type sqlItem struct {
|
type sqlItem struct {
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ var upgradeFuncs = []*upgradeVersion{
|
|||||||
{
|
{
|
||||||
"1.2.9", upgradeV1_2_9,
|
"1.2.9", upgradeV1_2_9,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"1.2.10", upgradeV1_2_10,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpgradeSQLData 升级SQL数据
|
// UpgradeSQLData 升级SQL数据
|
||||||
@@ -749,3 +752,67 @@ func upgradeV1_2_1(db *dbs.DB) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 1.2.10
|
||||||
|
func upgradeV1_2_10(db *dbs.DB) error {
|
||||||
|
{
|
||||||
|
type OldGlobalConfig struct {
|
||||||
|
// HTTP & HTTPS相关配置
|
||||||
|
HTTPAll struct {
|
||||||
|
DomainAuditingIsOn bool `yaml:"domainAuditingIsOn" json:"domainAuditingIsOn"` // 域名是否需要审核
|
||||||
|
DomainAuditingPrompt string `yaml:"domainAuditingPrompt" json:"domainAuditingPrompt"` // 域名审核的提示
|
||||||
|
} `yaml:"httpAll" json:"httpAll"`
|
||||||
|
|
||||||
|
TCPAll struct {
|
||||||
|
PortRangeMin int `yaml:"portRangeMin" json:"portRangeMin"` // 最小端口
|
||||||
|
PortRangeMax int `yaml:"portRangeMax" json:"portRangeMax"` // 最大端口
|
||||||
|
DenyPorts []int `yaml:"denyPorts" json:"denyPorts"` // 禁止使用的端口
|
||||||
|
} `yaml:"tcpAll" json:"tcpAll"`
|
||||||
|
}
|
||||||
|
|
||||||
|
globalConfigValue, err := db.FindCol(0, "SELECT value FROM edgeSysSettings WHERE code='serverGlobalConfig'")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var globalConfigString = types.String(globalConfigValue)
|
||||||
|
if len(globalConfigString) > 0 {
|
||||||
|
var oldGlobalConfig = &OldGlobalConfig{}
|
||||||
|
err = json.Unmarshal([]byte(globalConfigString), oldGlobalConfig)
|
||||||
|
if err == nil { // we ignore error
|
||||||
|
ones, _, err := db.FindOnes("SELECT id,globalServerConfig FROM edgeNodeClusters")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, one := range ones {
|
||||||
|
var id = one.GetInt64("id")
|
||||||
|
var globalServerConfigData = []byte(one.GetString("globalServerConfig"))
|
||||||
|
if len(globalServerConfigData) > 32 {
|
||||||
|
var globalServerConfig = &serverconfigs.GlobalServerConfig{}
|
||||||
|
err = json.Unmarshal(globalServerConfigData, globalServerConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
globalServerConfig.HTTPAll.DomainAuditingIsOn = oldGlobalConfig.HTTPAll.DomainAuditingIsOn
|
||||||
|
globalServerConfig.HTTPAll.DomainAuditingPrompt = oldGlobalConfig.HTTPAll.DomainAuditingPrompt
|
||||||
|
|
||||||
|
globalServerConfig.TCPAll.DenyPorts = oldGlobalConfig.TCPAll.DenyPorts
|
||||||
|
globalServerConfig.TCPAll.PortRangeMin = oldGlobalConfig.TCPAll.PortRangeMin
|
||||||
|
globalServerConfig.TCPAll.PortRangeMax = oldGlobalConfig.TCPAll.PortRangeMax
|
||||||
|
|
||||||
|
globalServerConfigJSON, err := json.Marshal(globalServerConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = db.Exec("UPDATE edgeNodeClusters SET globalServerConfig=? WHERE id=?", globalServerConfigJSON, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -270,3 +270,22 @@ func TestUpgradeSQLData_v1_2_1(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log("ok")
|
t.Log("ok")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpgradeSQLData_v1_2_10(t *testing.T) {
|
||||||
|
db, err := dbs.NewInstanceFromConfig(&dbs.DBConfig{
|
||||||
|
Driver: "mysql",
|
||||||
|
Dsn: "root:123456@tcp(127.0.0.1:3306)/db_edge?charset=utf8mb4&timeout=30s",
|
||||||
|
Prefix: "edge",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
_ = db.Close()
|
||||||
|
}()
|
||||||
|
err = upgradeV1_2_10(db)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log("ok")
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
"github.com/iwind/TeaGo/maps"
|
"github.com/iwind/TeaGo/maps"
|
||||||
|
"github.com/iwind/TeaGo/types"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -127,8 +129,32 @@ func (this *HealthCheckClusterTask) Loop() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var message = "有" + numberutils.FormatInt(len(failedResults)) + "个节点IP在健康检查中出现问题"
|
var subject = "有" + numberutils.FormatInt(len(failedResults)) + "个节点IP在健康检查中出现问题"
|
||||||
err = models.NewMessageDAO().CreateClusterMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, models.MessageTypeHealthCheckFailed, models.MessageLevelError, message, message, failedResultsJSON)
|
var message = "有" + numberutils.FormatInt(len(failedResults)) + "个节点IP在健康检查中出现问题:"
|
||||||
|
var failedDescriptions = []string{}
|
||||||
|
var failedIndex int
|
||||||
|
for _, result := range results {
|
||||||
|
if result.IsOk || result.Node == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
failedIndex++
|
||||||
|
failedDescriptions = append(failedDescriptions, "节点"+types.String(failedIndex)+":"+result.Node.Name+",IP:"+result.NodeAddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxNodeDescriptions = 10
|
||||||
|
var isOverMax = false
|
||||||
|
if len(failedDescriptions) > maxNodeDescriptions {
|
||||||
|
failedDescriptions = failedDescriptions[:maxNodeDescriptions]
|
||||||
|
isOverMax = true
|
||||||
|
}
|
||||||
|
message += strings.Join(failedDescriptions, ";")
|
||||||
|
if isOverMax {
|
||||||
|
message += " ..."
|
||||||
|
} else {
|
||||||
|
message += "。"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = models.NewMessageDAO().CreateClusterMessage(nil, nodeconfigs.NodeRoleNode, this.clusterId, models.MessageTypeHealthCheckFailed, models.MessageLevelError, subject, subject, message, failedResultsJSON)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ func (this *NodeMonitorTask) MonitorCluster(cluster *models.NodeCluster) error {
|
|||||||
this.notifiedMap[nodeId] = time.Now().Unix()
|
this.notifiedMap[nodeId] = time.Now().Unix()
|
||||||
|
|
||||||
var subject = "节点\"" + node.Name + "\"已处于离线状态"
|
var subject = "节点\"" + node.Name + "\"已处于离线状态"
|
||||||
var msg = "集群'" + cluster.Name + "'节点\"" + node.Name + "\"已处于离线状态,请检查节点是否异常"
|
var msg = "集群 \"" + cluster.Name + "\" 节点 \"" + node.Name + "\" 已处于离线状态,请检查节点是否异常"
|
||||||
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, clusterId, int64(node.Id), models.MessageTypeNodeInactive, models.LevelError, subject, msg, nil, false)
|
err = models.SharedMessageDAO.CreateNodeMessage(nil, nodeconfigs.NodeRoleNode, clusterId, int64(node.Id), models.MessageTypeNodeInactive, models.LevelError, subject, msg, nil, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
12
internal/utils/mobile.go
Normal file
12
internal/utils/mobile.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
var mobileRegex = regexp.MustCompile(`^1\d{10}$`)
|
||||||
|
|
||||||
|
// IsValidMobile validate mobile number
|
||||||
|
func IsValidMobile(mobile string) bool {
|
||||||
|
return mobileRegex.MatchString(mobile)
|
||||||
|
}
|
||||||
17
internal/utils/mobile_test.go
Normal file
17
internal/utils/mobile_test.go
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package utils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/iwind/TeaGo/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsValidMobile(t *testing.T) {
|
||||||
|
var a = assert.NewAssertion(t)
|
||||||
|
a.IsFalse(utils.IsValidMobile("138"))
|
||||||
|
a.IsFalse(utils.IsValidMobile("1382222"))
|
||||||
|
a.IsFalse(utils.IsValidMobile("1381234567890"))
|
||||||
|
a.IsTrue(utils.IsValidMobile("13812345678"))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user