Compare commits

...

11 Commits

Author SHA1 Message Date
刘祥超
91ff73e4e4 更新用户节点版本 2021-06-27 22:22:11 +08:00
刘祥超
e68473a13f 更新SQL 2021-06-27 22:14:35 +08:00
刘祥超
5774beda6f 阶段性提交 2021-06-27 21:59:37 +08:00
刘祥超
4869c11d60 ip2region增加IP格式检查 2021-06-27 17:29:16 +08:00
刘祥超
4bc6f93902 统计时创建系统、浏览器信息时加锁 2021-06-27 15:17:18 +08:00
刘祥超
ce4e079752 修复WAF用户检查的Bug 2021-06-27 08:31:10 +08:00
刘祥超
488df3d150 服务列表可以搜索端口号 2021-06-25 11:05:02 +08:00
刘祥超
109e129cc5 ACME申请证书时可以设置回调URL 2021-06-24 09:27:39 +08:00
刘祥超
447f89399f 更新SQL 2021-06-23 13:13:26 +08:00
刘祥超
206c12c746 实现公用的IP名单 2021-06-23 13:12:54 +08:00
刘祥超
3c14310e3a 变更版本 2021-06-21 14:43:51 +08:00
46 changed files with 1316 additions and 155 deletions

View File

@@ -39,7 +39,7 @@ func TestRequest_Run_DNS(t *testing.T) {
req := NewRequest(&Task{
User: user,
Type: TaskTypeDNS,
AuthType: AuthTypeDNS,
DNSProvider: dnsProvider,
DNSDomain: "yun4s.cn",
Domains: []string{"yun4s.cn"},
@@ -74,9 +74,9 @@ func TestRequest_Run_HTTP(t *testing.T) {
}
req := NewRequest(&Task{
User: user,
Type: TaskTypeHTTP,
Domains: []string{"teaos.cn", "www.teaos.cn", "meloy.cn"},
User: user,
AuthType: AuthTypeHTTP,
Domains: []string{"teaos.cn", "www.teaos.cn", "meloy.cn"},
})
certData, keyData, err := req.runHTTP()
if err != nil {

View File

@@ -1,7 +1,7 @@
package teaconst
const (
Version = "0.2.3"
Version = "0.2.4"
ProductName = "Edge API"
ProcessName = "edge-api"
@@ -18,8 +18,8 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点
NodeVersion = "0.2.3"
UserNodeVersion = "0.0.8"
NodeVersion = "0.2.4"
UserNodeVersion = "0.0.9"
AuthorityNodeVersion = "0.0.2"
MonitorNodeVersion = "0.0.2"
DNSNodeVersion = "0.0.1"

View File

@@ -1,6 +1,7 @@
package acme
import (
"bytes"
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/acme"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
@@ -8,13 +9,17 @@ import (
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/dnsclients"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/sslconfigs"
"github.com/go-acme/lego/v4/registration"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http"
"time"
)
@@ -44,7 +49,7 @@ func init() {
})
}
// 启用条目
// EnableACMETask 启用条目
func (this *ACMETaskDAO) EnableACMETask(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -53,7 +58,7 @@ func (this *ACMETaskDAO) EnableACMETask(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableACMETask 禁用条目
func (this *ACMETaskDAO) DisableACMETask(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -62,7 +67,7 @@ func (this *ACMETaskDAO) DisableACMETask(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledACMETask 查找启用中的条目
func (this *ACMETaskDAO) FindEnabledACMETask(tx *dbs.Tx, id int64) (*ACMETask, error) {
result, err := this.Query(tx).
Pk(id).
@@ -74,7 +79,7 @@ func (this *ACMETaskDAO) FindEnabledACMETask(tx *dbs.Tx, id int64) (*ACMETask, e
return result.(*ACMETask), err
}
// 计算某个ACME用户相关的任务数量
// CountACMETasksWithACMEUserId 计算某个ACME用户相关的任务数量
func (this *ACMETaskDAO) CountACMETasksWithACMEUserId(tx *dbs.Tx, acmeUserId int64) (int64, error) {
return this.Query(tx).
State(ACMETaskStateEnabled).
@@ -82,7 +87,7 @@ func (this *ACMETaskDAO) CountACMETasksWithACMEUserId(tx *dbs.Tx, acmeUserId int
Count()
}
// 计算某个DNS服务商相关的任务数量
// CountACMETasksWithDNSProviderId 计算某个DNS服务商相关的任务数量
func (this *ACMETaskDAO) CountACMETasksWithDNSProviderId(tx *dbs.Tx, dnsProviderId int64) (int64, error) {
return this.Query(tx).
State(ACMETaskStateEnabled).
@@ -90,7 +95,7 @@ func (this *ACMETaskDAO) CountACMETasksWithDNSProviderId(tx *dbs.Tx, dnsProvider
Count()
}
// 停止某个证书相关任务
// DisableAllTasksWithCertId 停止某个证书相关任务
func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) error {
_, err := this.Query(tx).
Attr("certId", certId).
@@ -99,7 +104,7 @@ func (this *ACMETaskDAO) DisableAllTasksWithCertId(tx *dbs.Tx, certId int64) err
return err
}
// 计算所有任务数量
// CountAllEnabledACMETasks 计算所有任务数量
func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string) (int64, error) {
query := dbutils.NewQuery(tx, this, adminId, userId)
if isAvailable || isExpired || expiringDays > 0 {
@@ -130,7 +135,7 @@ func (this *ACMETaskDAO) CountAllEnabledACMETasks(tx *dbs.Tx, adminId int64, use
Count()
}
// 列出单页任务
// ListEnabledACMETasks 列出单页任务
func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId int64, isAvailable bool, isExpired bool, expiringDays int64, keyword string, offset int64, size int64) (result []*ACMETask, err error) {
query := dbutils.NewQuery(tx, this, adminId, userId)
if isAvailable || isExpired || expiringDays > 0 {
@@ -161,8 +166,8 @@ func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId
return
}
// 创建任务
func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64, authType acme.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) (int64, error) {
// CreateACMETask 创建任务
func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64, authType acme.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool, authURL string) (int64, error) {
op := NewACMETaskOperator()
op.AdminId = adminId
op.UserId = userId
@@ -182,6 +187,7 @@ func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64,
}
op.AutoRenew = autoRenew
op.AuthURL = authURL
op.IsOn = true
op.State = ACMETaskStateEnabled
err := this.Save(tx, op)
@@ -191,8 +197,8 @@ func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64,
return types.Int64(op.Id), nil
}
// 修改任务
func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool) error {
// UpdateACMETask 修改任务
func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool, authURL string) error {
if acmeTaskId <= 0 {
return errors.New("invalid acmeTaskId")
}
@@ -214,11 +220,12 @@ func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId
}
op.AutoRenew = autoRenew
op.AuthURL = authURL
err := this.Save(tx, op)
return err
}
// 检查权限
// CheckACMETask 检查权限
func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64, acmeTaskId int64) (bool, error) {
return dbutils.NewQuery(tx, this, adminId, userId).
State(ACMETaskStateEnabled).
@@ -226,7 +233,7 @@ func (this *ACMETaskDAO) CheckACMETask(tx *dbs.Tx, adminId int64, userId int64,
Exist()
}
// 设置任务关联的证书
// UpdateACMETaskCert 设置任务关联的证书
func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int64) error {
if taskId <= 0 {
return errors.New("invalid taskId")
@@ -239,7 +246,7 @@ func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int
return err
}
// 执行任务并记录日志
// RunTask 执行任务并记录日志
func (this *ACMETaskDAO) RunTask(tx *dbs.Tx, taskId int64) (isOk bool, errMsg string, resultCertId int64) {
isOk, errMsg, resultCertId = this.runTaskWithoutLog(tx, taskId)
@@ -350,7 +357,33 @@ func (this *ACMETaskDAO) runTaskWithoutLog(tx *dbs.Tx, taskId int64) (isOk bool,
acmeRequest.OnAuth(func(domain, token, keyAuth string) {
err := SharedACMEAuthenticationDAO.CreateAuth(tx, taskId, domain, token, keyAuth)
if err != nil {
logs.Println("[ACME]write authentication to database error: " + err.Error())
remotelogs.Error("ACME", "write authentication to database error: "+err.Error())
} else {
// 调用校验URL
if len(task.AuthURL) > 0 {
authJSON, err := json.Marshal(maps.Map{
"domain": domain,
"token": token,
"key": keyAuth,
})
if err != nil {
remotelogs.Error("ACME", "encode auth data failed: '"+task.AuthURL+"'")
} else {
client := utils.SharedHttpClient(5 * time.Second)
req, err := http.NewRequest(http.MethodPost, task.AuthURL, bytes.NewReader(authJSON))
req.Header.Set("Content-Type", "application/json")
if err != nil {
remotelogs.Error("ACME", "parse auth url failed '"+task.AuthURL+"': "+err.Error())
} else {
resp, err := client.Do(req)
if err != nil {
remotelogs.Error("ACME", "call auth url failed '"+task.AuthURL+"': "+err.Error())
} else {
_ = resp.Body.Close()
}
}
}
}
}
})
certData, keyData, err := acmeRequest.Run()

View File

@@ -1,6 +1,6 @@
package acme
// ACME任务
// ACMETask ACME任务
type ACMETask struct {
Id uint64 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
@@ -15,6 +15,7 @@ type ACMETask struct {
CertId uint64 `field:"certId"` // 生成的证书ID
AutoRenew uint8 `field:"autoRenew"` // 是否自动更新
AuthType string `field:"authType"` // 认证类型
AuthURL string `field:"authURL"` // 认证URL
}
type ACMETaskOperator struct {
@@ -31,6 +32,7 @@ type ACMETaskOperator struct {
CertId interface{} // 生成的证书ID
AutoRenew interface{} // 是否自动更新
AuthType interface{} // 认证类型
AuthURL interface{} // 认证URL
}
func NewACMETaskOperator() *ACMETaskOperator {

View File

@@ -35,7 +35,7 @@ func init() {
})
}
// 启用条目
// EnableClientBrowser 启用条目
func (this *ClientBrowserDAO) EnableClientBrowser(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
@@ -44,7 +44,7 @@ func (this *ClientBrowserDAO) EnableClientBrowser(tx *dbs.Tx, id uint32) error {
return err
}
// 禁用条目
// DisableClientBrowser 禁用条目
func (this *ClientBrowserDAO) DisableClientBrowser(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
@@ -53,7 +53,7 @@ func (this *ClientBrowserDAO) DisableClientBrowser(tx *dbs.Tx, id uint32) error
return err
}
// 查找启用中的条目
// FindEnabledClientBrowser 查找启用中的条目
func (this *ClientBrowserDAO) FindEnabledClientBrowser(tx *dbs.Tx, id int64) (*ClientBrowser, error) {
result, err := this.Query(tx).
Pk(id).
@@ -65,7 +65,7 @@ func (this *ClientBrowserDAO) FindEnabledClientBrowser(tx *dbs.Tx, id int64) (*C
return result.(*ClientBrowser), err
}
// 根据主键查找名称
// FindClientBrowserName 根据主键查找名称
func (this *ClientBrowserDAO) FindClientBrowserName(tx *dbs.Tx, id uint32) (string, error) {
return this.Query(tx).
Pk(id).
@@ -73,7 +73,7 @@ func (this *ClientBrowserDAO) FindClientBrowserName(tx *dbs.Tx, id uint32) (stri
FindStringCol("")
}
// 根据浏览器名称查找浏览器ID
// FindBrowserIdWithNameCacheable 根据浏览器名称查找浏览器ID
func (this *ClientBrowserDAO) FindBrowserIdWithNameCacheable(tx *dbs.Tx, browserName string) (int64, error) {
SharedCacheLocker.RLock()
browserId, ok := clientBrowserNameAndIdCacheMap[browserName]
@@ -102,8 +102,23 @@ func (this *ClientBrowserDAO) FindBrowserIdWithNameCacheable(tx *dbs.Tx, browser
return browserId, nil
}
// 创建浏览器
// CreateBrowser 创建浏览器
func (this *ClientBrowserDAO) CreateBrowser(tx *dbs.Tx, browserName string) (int64, error) {
SharedCacheLocker.Lock()
defer SharedCacheLocker.Unlock()
// 检查是否已经创建
browserId, err := this.Query(tx).
Attr("name", browserName).
ResultPk().
FindInt64Col(0)
if err != nil {
return 0, err
}
if browserId > 0 {
return browserId, nil
}
op := NewClientBrowserOperator()
op.Name = browserName
codes := []string{browserName}

View File

@@ -35,7 +35,7 @@ func init() {
})
}
// 启用条目
// EnableClientSystem 启用条目
func (this *ClientSystemDAO) EnableClientSystem(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
@@ -44,7 +44,7 @@ func (this *ClientSystemDAO) EnableClientSystem(tx *dbs.Tx, id uint32) error {
return err
}
// 禁用条目
// DisableClientSystem 禁用条目
func (this *ClientSystemDAO) DisableClientSystem(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
@@ -53,7 +53,7 @@ func (this *ClientSystemDAO) DisableClientSystem(tx *dbs.Tx, id uint32) error {
return err
}
// 查找启用中的条目
// FindEnabledClientSystem 查找启用中的条目
func (this *ClientSystemDAO) FindEnabledClientSystem(tx *dbs.Tx, id int64) (*ClientSystem, error) {
result, err := this.Query(tx).
Pk(id).
@@ -65,7 +65,7 @@ func (this *ClientSystemDAO) FindEnabledClientSystem(tx *dbs.Tx, id int64) (*Cli
return result.(*ClientSystem), err
}
// 根据主键查找名称
// FindClientSystemName 根据主键查找名称
func (this *ClientSystemDAO) FindClientSystemName(tx *dbs.Tx, id uint32) (string, error) {
return this.Query(tx).
Pk(id).
@@ -73,7 +73,7 @@ func (this *ClientSystemDAO) FindClientSystemName(tx *dbs.Tx, id uint32) (string
FindStringCol("")
}
// 根据操作系统名称查找系统ID
// FindSystemIdWithNameCacheable 根据操作系统名称查找系统ID
func (this *ClientSystemDAO) FindSystemIdWithNameCacheable(tx *dbs.Tx, systemName string) (int64, error) {
SharedCacheLocker.RLock()
systemId, ok := clientSystemNameAndIdCacheMap[systemName]
@@ -102,8 +102,23 @@ func (this *ClientSystemDAO) FindSystemIdWithNameCacheable(tx *dbs.Tx, systemNam
return systemId, nil
}
// 创建浏览器
// CreateSystem 创建浏览器
func (this *ClientSystemDAO) CreateSystem(tx *dbs.Tx, systemName string) (int64, error) {
SharedCacheLocker.Lock()
defer SharedCacheLocker.Unlock()
// 检查是否已经创建
systemId, err := this.Query(tx).
Attr("name", systemName).
ResultPk().
FindInt64Col(0)
if err != nil {
return 0, err
}
if systemId > 0 {
return systemId, nil
}
op := NewClientSystemOperator()
op.Name = systemName

View File

@@ -39,7 +39,7 @@ func init() {
})
}
// 启用条目
// EnableDBNode 启用条目
func (this *DBNodeDAO) EnableDBNode(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -48,7 +48,7 @@ func (this *DBNodeDAO) EnableDBNode(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableDBNode 禁用条目
func (this *DBNodeDAO) DisableDBNode(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -57,7 +57,7 @@ func (this *DBNodeDAO) DisableDBNode(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledDBNode 查找启用中的条目
func (this *DBNodeDAO) FindEnabledDBNode(tx *dbs.Tx, id int64) (*DBNode, error) {
result, err := this.Query(tx).
Pk(id).
@@ -71,7 +71,7 @@ func (this *DBNodeDAO) FindEnabledDBNode(tx *dbs.Tx, id int64) (*DBNode, error)
return node, nil
}
// 根据主键查找名称
// FindDBNodeName 根据主键查找名称
func (this *DBNodeDAO) FindDBNodeName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -79,14 +79,14 @@ func (this *DBNodeDAO) FindDBNodeName(tx *dbs.Tx, id int64) (string, error) {
FindStringCol("")
}
// 计算可用的节点数量
// CountAllEnabledNodes 计算可用的节点数量
func (this *DBNodeDAO) CountAllEnabledNodes(tx *dbs.Tx) (int64, error) {
return this.Query(tx).
State(DBNodeStateEnabled).
Count()
}
// 获取单页的节点
// ListEnabledNodes 获取单页的节点
func (this *DBNodeDAO) ListEnabledNodes(tx *dbs.Tx, offset int64, size int64) (result []*DBNode, err error) {
_, err = this.Query(tx).
State(DBNodeStateEnabled).
@@ -101,7 +101,7 @@ func (this *DBNodeDAO) ListEnabledNodes(tx *dbs.Tx, offset int64, size int64) (r
return
}
// 创建节点
// CreateDBNode 创建节点
func (this *DBNodeDAO) CreateDBNode(tx *dbs.Tx, isOn bool, name string, description string, host string, port int32, database string, username string, password string, charset string) (int64, error) {
op := NewDBNodeOperator()
op.State = NodeStateEnabled
@@ -121,7 +121,7 @@ func (this *DBNodeDAO) CreateDBNode(tx *dbs.Tx, isOn bool, name string, descript
return types.Int64(op.Id), nil
}
// 修改节点
// UpdateNode 修改节点
func (this *DBNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, isOn bool, name string, description string, host string, port int32, database string, username string, password string, charset string) error {
if nodeId <= 0 {
return errors.New("invalid nodeId")
@@ -141,7 +141,7 @@ func (this *DBNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, isOn bool, name stri
return err
}
// 查找所有可用的数据库节点
// FindAllEnabledAndOnDBNodes 查找所有可用的数据库节点
func (this *DBNodeDAO) FindAllEnabledAndOnDBNodes(tx *dbs.Tx) (result []*DBNode, err error) {
_, err = this.Query(tx).
State(DBNodeStateEnabled).
@@ -155,7 +155,7 @@ func (this *DBNodeDAO) FindAllEnabledAndOnDBNodes(tx *dbs.Tx) (result []*DBNode,
return
}
// 加密密码
// EncodePassword 加密密码
func (this *DBNodeDAO) EncodePassword(password string) string {
if strings.HasPrefix(password, DBNodePasswordEncodedPrefix) {
return password
@@ -164,7 +164,7 @@ func (this *DBNodeDAO) EncodePassword(password string) string {
return DBNodePasswordEncodedPrefix + encodedString
}
// 解密密码
// DecodePassword 解密密码
func (this *DBNodeDAO) DecodePassword(password string) string {
if !strings.HasPrefix(password, DBNodePasswordEncodedPrefix) {
return password

View File

@@ -320,7 +320,21 @@ func (this *HTTPFirewallPolicyDAO) CheckUserFirewallPolicy(tx *dbs.Tx, userId in
return nil
}
// TODO 检查是否为用户Server所使用
// 检查是否为用户Server所使用
webIds, err := SharedHTTPWebDAO.FindAllWebIdsWithHTTPFirewallPolicyId(tx, firewallPolicyId)
if err != nil {
return err
}
for _, webId := range webIds {
err := SharedHTTPWebDAO.CheckUserWeb(tx, userId, webId)
if err != nil {
if err != ErrNotFound {
return err
}
} else {
return nil
}
}
return ErrNotFound
}
@@ -330,7 +344,7 @@ func (this *HTTPFirewallPolicyDAO) FindEnabledFirewallPolicyIdsWithIPListId(tx *
ones, err := this.Query(tx).
ResultPk().
State(HTTPFirewallPolicyStateEnabled).
Where("(JSON_CONTAINS(inbound, :listQuery, '$.whiteListRef') OR JSON_CONTAINS(inbound, :listQuery, '$.blackListRef') )").
Where("(JSON_CONTAINS(inbound, :listQuery, '$.whiteListRef') OR JSON_CONTAINS(inbound, :listQuery, '$.blackListRef') OR JSON_CONTAINS(inbound, :listQuery, '$.publicWhiteListRefs') OR JSON_CONTAINS(inbound, :listQuery, '$.publicBlackListRefs'))").
Param("listQuery", maps.Map{"isOn": true, "listId": ipListId}.AsJSON()).
FindAll()
if err != nil {

View File

@@ -37,12 +37,12 @@ func init() {
})
}
// 初始化
// Init 初始化
func (this *HTTPFirewallRuleGroupDAO) Init() {
_ = this.DAOObject.Init()
}
// 启用条目
// EnableHTTPFirewallRuleGroup 启用条目
func (this *HTTPFirewallRuleGroupDAO) EnableHTTPFirewallRuleGroup(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -51,7 +51,7 @@ func (this *HTTPFirewallRuleGroupDAO) EnableHTTPFirewallRuleGroup(tx *dbs.Tx, id
return err
}
// 禁用条目
// DisableHTTPFirewallRuleGroup 禁用条目
func (this *HTTPFirewallRuleGroupDAO) DisableHTTPFirewallRuleGroup(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -60,7 +60,7 @@ func (this *HTTPFirewallRuleGroupDAO) DisableHTTPFirewallRuleGroup(tx *dbs.Tx, i
return err
}
// 查找启用中的条目
// FindEnabledHTTPFirewallRuleGroup 查找启用中的条目
func (this *HTTPFirewallRuleGroupDAO) FindEnabledHTTPFirewallRuleGroup(tx *dbs.Tx, id int64) (*HTTPFirewallRuleGroup, error) {
result, err := this.Query(tx).
Pk(id).
@@ -72,7 +72,7 @@ func (this *HTTPFirewallRuleGroupDAO) FindEnabledHTTPFirewallRuleGroup(tx *dbs.T
return result.(*HTTPFirewallRuleGroup), err
}
// 根据主键查找名称
// FindHTTPFirewallRuleGroupName 根据主键查找名称
func (this *HTTPFirewallRuleGroupDAO) FindHTTPFirewallRuleGroupName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -80,7 +80,7 @@ func (this *HTTPFirewallRuleGroupDAO) FindHTTPFirewallRuleGroupName(tx *dbs.Tx,
FindStringCol("")
}
// 组合配置
// ComposeFirewallRuleGroup 组合配置
func (this *HTTPFirewallRuleGroupDAO) ComposeFirewallRuleGroup(tx *dbs.Tx, groupId int64) (*firewallconfigs.HTTPFirewallRuleGroup, error) {
group, err := this.FindEnabledHTTPFirewallRuleGroup(tx, groupId)
if err != nil {
@@ -117,7 +117,7 @@ func (this *HTTPFirewallRuleGroupDAO) ComposeFirewallRuleGroup(tx *dbs.Tx, group
return config, nil
}
// 从配置中创建分组
// CreateGroupFromConfig 从配置中创建分组
func (this *HTTPFirewallRuleGroupDAO) CreateGroupFromConfig(tx *dbs.Tx, groupConfig *firewallconfigs.HTTPFirewallRuleGroup) (int64, error) {
op := NewHTTPFirewallRuleGroupOperator()
op.IsOn = groupConfig.IsOn
@@ -150,7 +150,7 @@ func (this *HTTPFirewallRuleGroupDAO) CreateGroupFromConfig(tx *dbs.Tx, groupCon
return types.Int64(op.Id), nil
}
// 修改开启状态
// UpdateGroupIsOn 修改开启状态
func (this *HTTPFirewallRuleGroupDAO) UpdateGroupIsOn(tx *dbs.Tx, groupId int64, isOn bool) error {
_, err := this.Query(tx).
Pk(groupId).
@@ -162,7 +162,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroupIsOn(tx *dbs.Tx, groupId int64,
return this.NotifyUpdate(tx, groupId)
}
// 创建分组
// CreateGroup 创建分组
func (this *HTTPFirewallRuleGroupDAO) CreateGroup(tx *dbs.Tx, isOn bool, name string, description string) (int64, error) {
op := NewHTTPFirewallRuleGroupOperator()
op.State = HTTPFirewallRuleStateEnabled
@@ -176,7 +176,7 @@ func (this *HTTPFirewallRuleGroupDAO) CreateGroup(tx *dbs.Tx, isOn bool, name st
return types.Int64(op.Id), nil
}
// 修改分组
// UpdateGroup 修改分组
func (this *HTTPFirewallRuleGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, isOn bool, name string, description string) error {
if groupId <= 0 {
return errors.New("invalid groupId")
@@ -193,7 +193,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, isO
return this.NotifyUpdate(tx, groupId)
}
// 修改分组中的规则集
// UpdateGroupSets 修改分组中的规则集
func (this *HTTPFirewallRuleGroupDAO) UpdateGroupSets(tx *dbs.Tx, groupId int64, setsJSON []byte) error {
if groupId <= 0 {
return errors.New("invalid groupId")
@@ -208,7 +208,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroupSets(tx *dbs.Tx, groupId int64,
return this.NotifyUpdate(tx, groupId)
}
// 根据规则集查找规则分组
// FindRuleGroupIdWithRuleSetId 根据规则集查找规则分组
func (this *HTTPFirewallRuleGroupDAO) FindRuleGroupIdWithRuleSetId(tx *dbs.Tx, setId int64) (int64, error) {
return this.Query(tx).
State(HTTPFirewallRuleStateEnabled).
@@ -218,7 +218,7 @@ func (this *HTTPFirewallRuleGroupDAO) FindRuleGroupIdWithRuleSetId(tx *dbs.Tx, s
FindInt64Col(0)
}
// 检查用户所属分组
// CheckUserRuleGroup 检查用户所属分组
func (this *HTTPFirewallRuleGroupDAO) CheckUserRuleGroup(tx *dbs.Tx, userId int64, groupId int64) error {
policyId, err := SharedHTTPFirewallPolicyDAO.FindEnabledFirewallPolicyIdWithRuleGroupId(tx, groupId)
if err != nil {
@@ -230,7 +230,7 @@ func (this *HTTPFirewallRuleGroupDAO) CheckUserRuleGroup(tx *dbs.Tx, userId int6
return SharedHTTPFirewallPolicyDAO.CheckUserFirewallPolicy(tx, userId, policyId)
}
// 通知更新
// NotifyUpdate 通知更新
func (this *HTTPFirewallRuleGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
policyId, err := SharedHTTPFirewallPolicyDAO.FindEnabledFirewallPolicyIdWithRuleGroupId(tx, groupId)
if err != nil {

View File

@@ -46,7 +46,7 @@ func init() {
})
}
// 启用条目
// EnableIPItem 启用条目
func (this *IPItemDAO) EnableIPItem(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -55,7 +55,7 @@ func (this *IPItemDAO) EnableIPItem(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableIPItem 禁用条目
func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64) error {
version, err := SharedIPListDAO.IncreaseVersion(tx)
if err != nil {
@@ -74,7 +74,7 @@ func (this *IPItemDAO) DisableIPItem(tx *dbs.Tx, id int64) error {
return this.NotifyUpdate(tx, id)
}
// 查找启用中的条目
// FindEnabledIPItem 查找启用中的条目
func (this *IPItemDAO) FindEnabledIPItem(tx *dbs.Tx, id int64) (*IPItem, error) {
result, err := this.Query(tx).
Pk(id).
@@ -86,7 +86,7 @@ func (this *IPItemDAO) FindEnabledIPItem(tx *dbs.Tx, id int64) (*IPItem, error)
return result.(*IPItem), err
}
// 创建IP
// CreateIPItem 创建IP
func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx, listId int64, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) (int64, error) {
version, err := SharedIPListDAO.IncreaseVersion(tx)
if err != nil {
@@ -121,7 +121,7 @@ func (this *IPItemDAO) CreateIPItem(tx *dbs.Tx, listId int64, ipFrom string, ipT
return itemId, nil
}
// 修改IP
// UpdateIPItem 修改IP
func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipTo string, expiredAt int64, reason string, itemType IPItemType, eventLevel string) error {
if itemId <= 0 {
return errors.New("invalid itemId")
@@ -165,7 +165,7 @@ func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipT
return this.NotifyUpdate(tx, itemId)
}
// 计算IP数量
// CountIPItemsWithListId 计算IP数量
func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64) (int64, error) {
return this.Query(tx).
State(IPItemStateEnabled).
@@ -173,7 +173,7 @@ func (this *IPItemDAO) CountIPItemsWithListId(tx *dbs.Tx, listId int64) (int64,
Count()
}
// 查找IP列表
// ListIPItemsWithListId 查找IP列表
func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, offset int64, size int64) (result []*IPItem, err error) {
_, err = this.Query(tx).
State(IPItemStateEnabled).
@@ -186,7 +186,7 @@ func (this *IPItemDAO) ListIPItemsWithListId(tx *dbs.Tx, listId int64, offset in
return
}
// 根据版本号查找IP列表
// ListIPItemsAfterVersion 根据版本号查找IP列表
func (this *IPItemDAO) ListIPItemsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*IPItem, err error) {
_, err = this.Query(tx).
// 这里不要设置状态参数,因为我们要知道哪些是删除的
@@ -200,7 +200,7 @@ func (this *IPItemDAO) ListIPItemsAfterVersion(tx *dbs.Tx, version int64, size i
return
}
// 查找IPItem对应的列表ID
// FindItemListId 查找IPItem对应的列表ID
func (this *IPItemDAO) FindItemListId(tx *dbs.Tx, itemId int64) (int64, error) {
return this.Query(tx).
Pk(itemId).
@@ -208,7 +208,7 @@ func (this *IPItemDAO) FindItemListId(tx *dbs.Tx, itemId int64) (int64, error) {
FindInt64Col(0)
}
// 查找包含某个IP的Item
// FindEnabledItemContainsIP 查找包含某个IP的Item
func (this *IPItemDAO) FindEnabledItemContainsIP(tx *dbs.Tx, listId int64, ip uint64) (*IPItem, error) {
query := this.Query(tx).
Attr("listId", listId).
@@ -229,7 +229,15 @@ func (this *IPItemDAO) FindEnabledItemContainsIP(tx *dbs.Tx, listId int64, ip ui
return one.(*IPItem), nil
}
// 通知更新
// ExistsEnabledItem 检查IP是否存在
func (this *IPItemDAO) ExistsEnabledItem(tx *dbs.Tx, itemId int64) (bool, error) {
return this.Query(tx).
Pk(itemId).
State(IPItemStateEnabled).
Exist()
}
// NotifyUpdate 通知更新
func (this *IPItemDAO) NotifyUpdate(tx *dbs.Tx, itemId int64) error {
// 获取ListId
listId, err := this.FindItemListId(tx, itemId)

View File

@@ -38,7 +38,7 @@ func init() {
})
}
// 启用条目
// EnableIPList 启用条目
func (this *IPListDAO) EnableIPList(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -47,7 +47,7 @@ func (this *IPListDAO) EnableIPList(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableIPList 禁用条目
func (this *IPListDAO) DisableIPList(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -56,7 +56,7 @@ func (this *IPListDAO) DisableIPList(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledIPList 查找启用中的条目
func (this *IPListDAO) FindEnabledIPList(tx *dbs.Tx, id int64) (*IPList, error) {
result, err := this.Query(tx).
Pk(id).
@@ -68,7 +68,7 @@ func (this *IPListDAO) FindEnabledIPList(tx *dbs.Tx, id int64) (*IPList, error)
return result.(*IPList), err
}
// 根据主键查找名称
// FindIPListName 根据主键查找名称
func (this *IPListDAO) FindIPListName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
@@ -76,7 +76,7 @@ func (this *IPListDAO) FindIPListName(tx *dbs.Tx, id int64) (string, error) {
FindStringCol("")
}
// 获取名单类型
// FindIPListTypeCacheable 获取名单类型
func (this *IPListDAO) FindIPListTypeCacheable(tx *dbs.Tx, listId int64) (string, error) {
// 检查缓存
SharedCacheLocker.RLock()
@@ -106,8 +106,8 @@ func (this *IPListDAO) FindIPListTypeCacheable(tx *dbs.Tx, listId int64) (string
return listType, nil
}
// 创建名单
func (this *IPListDAO) CreateIPList(tx *dbs.Tx, userId int64, listType ipconfigs.IPListType, name string, code string, timeoutJSON []byte) (int64, error) {
// CreateIPList 创建名单
func (this *IPListDAO) CreateIPList(tx *dbs.Tx, userId int64, listType ipconfigs.IPListType, name string, code string, timeoutJSON []byte, description string, isPublic bool) (int64, error) {
op := NewIPListOperator()
op.IsOn = true
op.UserId = userId
@@ -118,6 +118,8 @@ func (this *IPListDAO) CreateIPList(tx *dbs.Tx, userId int64, listType ipconfigs
if len(timeoutJSON) > 0 {
op.Timeout = timeoutJSON
}
op.Description = description
op.IsPublic = isPublic
err := this.Save(tx, op)
if err != nil {
return 0, err
@@ -125,8 +127,8 @@ func (this *IPListDAO) CreateIPList(tx *dbs.Tx, userId int64, listType ipconfigs
return types.Int64(op.Id), nil
}
// 修改名单
func (this *IPListDAO) UpdateIPList(tx *dbs.Tx, listId int64, name string, code string, timeoutJSON []byte) error {
// UpdateIPList 修改名单
func (this *IPListDAO) UpdateIPList(tx *dbs.Tx, listId int64, name string, code string, timeoutJSON []byte, description string) error {
if listId <= 0 {
return errors.New("invalid listId")
}
@@ -139,16 +141,17 @@ func (this *IPListDAO) UpdateIPList(tx *dbs.Tx, listId int64, name string, code
} else {
op.Timeout = "null"
}
op.Description = description
err := this.Save(tx, op)
return err
}
// 增加版本
// IncreaseVersion 增加版本
func (this *IPListDAO) IncreaseVersion(tx *dbs.Tx) (int64, error) {
return SharedSysLockerDAO.Increase(tx, "IP_LIST_VERSION", 1000000)
}
// 检查用户权限
// CheckUserIPList 检查用户权限
func (this *IPListDAO) CheckUserIPList(tx *dbs.Tx, userId int64, listId int64) error {
ok, err := this.Query(tx).
Pk(listId).
@@ -163,7 +166,49 @@ func (this *IPListDAO) CheckUserIPList(tx *dbs.Tx, userId int64, listId int64) e
return ErrNotFound
}
// 通知更新
// CountAllEnabledIPLists 计算名单数量
func (this *IPListDAO) CountAllEnabledIPLists(tx *dbs.Tx, listType string, isPublic bool, keyword string) (int64, error) {
var query = this.Query(tx).
State(IPListStateEnabled).
Attr("type", listType).
Attr("isPublic", isPublic)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR description LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
return query.Count()
}
// ListEnabledIPLists 列出单页名单
func (this *IPListDAO) ListEnabledIPLists(tx *dbs.Tx, listType string, isPublic bool, keyword string, offset int64, size int64) (result []*IPList, err error) {
var query = this.Query(tx).
State(IPListStateEnabled).
Attr("type", listType).
Attr("isPublic", isPublic)
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR description LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
_, err = query.Offset(offset).
Limit(size).
DescPk().
Slice(&result).
FindAll()
return
}
// ExistsEnabledIPList 检查IP名单是否存在
func (this *IPListDAO) ExistsEnabledIPList(tx *dbs.Tx, listId int64) (bool, error) {
if listId <= 0 {
return false, nil
}
return this.Query(tx).
Pk(listId).
State(IPListStateEnabled).
Exist()
}
// NotifyUpdate 通知更新
func (this *IPListDAO) NotifyUpdate(tx *dbs.Tx, listId int64, taskType NodeTaskType) error {
httpFirewallPolicyIds, err := SharedHTTPFirewallPolicyDAO.FindEnabledFirewallPolicyIdsWithIPListId(tx, listId)
if err != nil {

View File

@@ -1,32 +1,36 @@
package models
// IP名单
// IPList IP名单
type IPList struct {
Id uint32 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
Type string `field:"type"` // 类型
AdminId uint32 `field:"adminId"` // 用户ID
UserId uint32 `field:"userId"` // 用户ID
Name string `field:"name"` // 列表名
Code string `field:"code"` // 代号
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
Timeout string `field:"timeout"` // 默认超时时间
Actions string `field:"actions"` // IP触发的动作
Id uint32 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
Type string `field:"type"` // 类型
AdminId uint32 `field:"adminId"` // 用户ID
UserId uint32 `field:"userId"` // 用户ID
Name string `field:"name"` // 列表名
Code string `field:"code"` // 代号
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
Timeout string `field:"timeout"` // 默认超时时间
Actions string `field:"actions"` // IP触发的动作
Description string `field:"description"` // 描述
IsPublic uint8 `field:"isPublic"` // 是否公用
}
type IPListOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
Type interface{} // 类型
AdminId interface{} // 用户ID
UserId interface{} // 用户ID
Name interface{} // 列表名
Code interface{} // 代号
State interface{} // 状态
CreatedAt interface{} // 创建时间
Timeout interface{} // 默认超时时间
Actions interface{} // IP触发的动作
Id interface{} // ID
IsOn interface{} // 是否启用
Type interface{} // 类型
AdminId interface{} // 用户ID
UserId interface{} // 用户ID
Name interface{} // 列表名
Code interface{} // 代号
State interface{} // 状态
CreatedAt interface{} // 创建时间
Timeout interface{} // 默认超时时间
Actions interface{} // IP触发的动作
Description interface{} // 描述
IsPublic interface{} // 是否公用
}
func NewIPListOperator() *IPListOperator {

View File

@@ -0,0 +1,174 @@
package metrics
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
)
const (
MetricItemStateEnabled = 1 // 已启用
MetricItemStateDisabled = 0 // 已禁用
)
type MetricItemDAO dbs.DAO
func NewMetricItemDAO() *MetricItemDAO {
return dbs.NewDAO(&MetricItemDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeMetricItems",
Model: new(MetricItem),
PkName: "id",
},
}).(*MetricItemDAO)
}
var SharedMetricItemDAO *MetricItemDAO
func init() {
dbs.OnReady(func() {
SharedMetricItemDAO = NewMetricItemDAO()
})
}
// EnableMetricItem 启用条目
func (this *MetricItemDAO) EnableMetricItem(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", MetricItemStateEnabled).
Update()
return err
}
// DisableMetricItem 禁用条目
func (this *MetricItemDAO) DisableMetricItem(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", MetricItemStateDisabled).
Update()
return err
}
// FindEnabledMetricItem 查找启用中的条目
func (this *MetricItemDAO) FindEnabledMetricItem(tx *dbs.Tx, id int64) (*MetricItem, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", MetricItemStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*MetricItem), err
}
// FindMetricItemName 根据主键查找名称
func (this *MetricItemDAO) FindMetricItemName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
Result("name").
FindStringCol("")
}
// CreateItem 创建指标
func (this *MetricItemDAO) CreateItem(tx *dbs.Tx, code string, category string, name string, keys []string, period int32, periodUnit string, value string) (int64, error) {
op := NewMetricItemOperator()
op.Code = code
op.Category = category
op.Name = name
if len(keys) > 0 {
keysJSON, err := json.Marshal(keys)
if err != nil {
return 0, err
}
op.Keys = keysJSON
} else {
op.Keys = "[]"
}
op.Period = period
op.PeriodUnit = periodUnit
op.Value = value
op.IsOn = true
op.State = MetricItemStateEnabled
return this.SaveInt64(tx, op)
}
// UpdateItem 修改\指标
func (this *MetricItemDAO) UpdateItem(tx *dbs.Tx, itemId int64, name string, keys []string, period int32, periodUnit string, value string, isOn bool) error {
if itemId <= 0 {
return errors.New("invalid itemId")
}
op := NewMetricItemOperator()
op.Id = itemId
op.Name = name
if len(keys) > 0 {
keysJSON, err := json.Marshal(keys)
if err != nil {
return err
}
op.Keys = keysJSON
} else {
op.Keys = "[]"
}
op.Period = period
op.PeriodUnit = periodUnit
op.Value = value
op.IsOn = isOn
return this.Save(tx, op)
}
// CountEnabledItems 计算指标的数量
func (this *MetricItemDAO) CountEnabledItems(tx *dbs.Tx, category serverconfigs.MetricItemCategory) (int64, error) {
return this.Query(tx).
State(MetricItemStateEnabled).
Attr("userId", 0).
Attr("category", category).
Count()
}
// ListEnabledItems 列出单页指标
func (this *MetricItemDAO) ListEnabledItems(tx *dbs.Tx, category serverconfigs.MetricItemCategory, offset int64, size int64) (result []*MetricItem, err error) {
_, err = this.Query(tx).
State(MetricItemStateEnabled).
Attr("userId", 0).
Attr("category", category).
Offset(offset).
Limit(size).
DescPk().
Slice(&result).
FindAll()
return
}
// ComposeItemConfig 组合指标配置
func (this *MetricItemDAO) ComposeItemConfig(tx *dbs.Tx, itemId int64) (*serverconfigs.MetricItemConfig, error) {
if itemId <= 0 {
return nil, nil
}
one, err := this.Query(tx).
Pk(itemId).
State(MetricItemStateEnabled).
Find()
if err != nil {
return nil, err
}
if one == nil {
return nil, nil
}
var item = one.(*MetricItem)
var config = &serverconfigs.MetricItemConfig{
Id: int64(item.Id),
IsOn: item.IsOn == 1,
Period: types.Int(item.Period),
PeriodUnit: item.PeriodUnit,
Category: item.Category,
Value: item.Value,
Keys: item.DecodeKeys(),
}
return config, nil
}

View File

@@ -0,0 +1,6 @@
package metrics
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,36 @@
package metrics
// MetricItem 指标定义
type MetricItem struct {
Id uint64 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
Code string `field:"code"` // 代号(用来区分是否内置)
Category string `field:"category"` // 类型比如http, tcp等
AdminId uint32 `field:"adminId"` // 管理员ID
UserId uint32 `field:"userId"` // 用户ID
Name string `field:"name"` // 指标名称
Keys string `field:"keys"` // 统计的Key
Period uint32 `field:"period"` // 周期
PeriodUnit string `field:"periodUnit"` // 周期单位
Value string `field:"value"` // 值运算
State uint8 `field:"state"` // 状态
}
type MetricItemOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
Code interface{} // 代号(用来区分是否内置)
Category interface{} // 类型比如http, tcp等
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
Name interface{} // 指标名称
Keys interface{} // 统计的Key
Period interface{} // 周期
PeriodUnit interface{} // 周期单位
Value interface{} // 值运算
State interface{} // 状态
}
func NewMetricItemOperator() *MetricItemOperator {
return &MetricItemOperator{}
}

View File

@@ -0,0 +1,11 @@
package metrics
import "encoding/json"
func (this *MetricItem) DecodeKeys() []string {
var result []string
if len(this.Keys) > 0 {
_ = json.Unmarshal([]byte(this.Keys), &result)
}
return result
}

View File

@@ -0,0 +1,28 @@
package metrics
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
type MetricKeyDAO dbs.DAO
func NewMetricKeyDAO() *MetricKeyDAO {
return dbs.NewDAO(&MetricKeyDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeMetricKeys",
Model: new(MetricKey),
PkName: "id",
},
}).(*MetricKeyDAO)
}
var SharedMetricKeyDAO *MetricKeyDAO
func init() {
dbs.OnReady(func() {
SharedMetricKeyDAO = NewMetricKeyDAO()
})
}

View File

@@ -0,0 +1,6 @@
package metrics
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,20 @@
package metrics
// MetricKey 指标键值
type MetricKey struct {
Id uint64 `field:"id"` // ID
ItemId uint64 `field:"itemId"` // 指标ID
Value string `field:"value"` // 值
Hash string `field:"hash"` // 对值进行Hash
}
type MetricKeyOperator struct {
Id interface{} // ID
ItemId interface{} // 指标ID
Value interface{} // 值
Hash interface{} // 对值进行Hash
}
func NewMetricKeyOperator() *MetricKeyOperator {
return &MetricKeyOperator{}
}

View File

@@ -0,0 +1 @@
package metrics

View File

@@ -0,0 +1,28 @@
package metrics
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
type MetricStatDAO dbs.DAO
func NewMetricStatDAO() *MetricStatDAO {
return dbs.NewDAO(&MetricStatDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeMetricStats",
Model: new(MetricStat),
PkName: "id",
},
}).(*MetricStatDAO)
}
var SharedMetricStatDAO *MetricStatDAO
func init() {
dbs.OnReady(func() {
SharedMetricStatDAO = NewMetricStatDAO()
})
}

View File

@@ -0,0 +1,6 @@
package metrics
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,28 @@
package metrics
// MetricStat 指标统计数据
type MetricStat struct {
Id uint64 `field:"id"` // ID
ClusterId uint32 `field:"clusterId"` // 集群ID
NodeId uint32 `field:"nodeId"` // 节点ID
ServerId uint32 `field:"serverId"` // 服务ID
ItemId uint64 `field:"itemId"` // 指标
KeyId uint64 `field:"keyId"` // 指标键ID
Value float64 `field:"value"` // 数值
Minute string `field:"minute"` // 分钟值YYYYMMDDHHII
}
type MetricStatOperator struct {
Id interface{} // ID
ClusterId interface{} // 集群ID
NodeId interface{} // 节点ID
ServerId interface{} // 服务ID
ItemId interface{} // 指标
KeyId interface{} // 指标键ID
Value interface{} // 数值
Minute interface{} // 分钟值YYYYMMDDHHII
}
func NewMetricStatOperator() *MetricStatOperator {
return &MetricStatOperator{}
}

View File

@@ -0,0 +1 @@
package metrics

View File

@@ -0,0 +1,105 @@
package models
import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
NodeClusterMetricItemStateEnabled = 1 // 已启用
NodeClusterMetricItemStateDisabled = 0 // 已禁用
)
type NodeClusterMetricItemDAO dbs.DAO
func NewNodeClusterMetricItemDAO() *NodeClusterMetricItemDAO {
return dbs.NewDAO(&NodeClusterMetricItemDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNodeClusterMetricItems",
Model: new(NodeClusterMetricItem),
PkName: "id",
},
}).(*NodeClusterMetricItemDAO)
}
var SharedNodeClusterMetricItemDAO *NodeClusterMetricItemDAO
func init() {
dbs.OnReady(func() {
SharedNodeClusterMetricItemDAO = NewNodeClusterMetricItemDAO()
})
}
// EnableNodeClusterMetricItem 启用条目
func (this *NodeClusterMetricItemDAO) EnableNodeClusterMetricItem(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NodeClusterMetricItemStateEnabled).
Update()
return err
}
// DisableNodeClusterMetricItem 禁用条目
func (this *NodeClusterMetricItemDAO) DisableNodeClusterMetricItem(tx *dbs.Tx, id uint32) error {
_, err := this.Query(tx).
Pk(id).
Set("state", NodeClusterMetricItemStateDisabled).
Update()
return err
}
// FindEnabledNodeClusterMetricItem 查找启用中的条目
func (this *NodeClusterMetricItemDAO) FindEnabledNodeClusterMetricItem(tx *dbs.Tx, id uint32) (*NodeClusterMetricItem, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NodeClusterMetricItemStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NodeClusterMetricItem), err
}
// DisableClusterItem 禁用某个集群的指标
func (this *NodeClusterMetricItemDAO) DisableClusterItem(tx *dbs.Tx, clusterId int64, itemId int64) error {
return this.Query(tx).
Attr("clusterId", clusterId).
Attr("itemId", itemId).
State(NodeClusterMetricItemStateEnabled).
Set("state", NodeClusterMetricItemStateDisabled).
UpdateQuickly()
}
// EnableClusterItem 启用某个集群的指标
func (this *NodeClusterMetricItemDAO) EnableClusterItem(tx *dbs.Tx, clusterId int64, itemId int64) error {
if clusterId <= 0 || itemId <= 0 {
return errors.New("clusterId or itemId should not be 0")
}
var op = NewNodeClusterMetricItemOperator()
op.ClusterId = clusterId
op.ItemId = itemId
op.IsOn = true
return this.Save(tx, op)
}
// FindAllClusterItems 查找某个集群的指标
func (this *NodeClusterMetricItemDAO) FindAllClusterItems(tx *dbs.Tx, clusterId int64) (result []*NodeClusterMetricItem, err error) {
_, err = this.Query(tx).
Attr("clusterId", clusterId).
State(NodeClusterMetricItemStateEnabled).
DescPk().
Slice(&result).
FindAll()
return
}
// CountAllClusterItems 计算集群中指标数量
func (this *NodeClusterMetricItemDAO) CountAllClusterItems(tx *dbs.Tx, clusterId int64) (int64, error) {
return this.Query(tx).
Attr("clusterId", clusterId).
State(NodeClusterMetricItemStateEnabled).
Count()
}

View File

@@ -0,0 +1,6 @@
package models
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
)

View File

@@ -0,0 +1,22 @@
package models
// NodeClusterMetricItem 集群使用的指标
type NodeClusterMetricItem struct {
Id uint32 `field:"id"` // ID
IsOn uint8 `field:"isOn"` // 是否启用
ClusterId uint32 `field:"clusterId"` // 集群ID
ItemId uint64 `field:"itemId"` // 指标ID
State uint8 `field:"state"` // 是否启用
}
type NodeClusterMetricItemOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
ClusterId interface{} // 集群ID
ItemId interface{} // 指标ID
State interface{} // 是否启用
}
func NewNodeClusterMetricItemOperator() *NodeClusterMetricItemOperator {
return &NodeClusterMetricItemOperator{}
}

View File

@@ -0,0 +1 @@
package models

View File

@@ -640,6 +640,9 @@ func (this *NodeDAO) ComposeNodeConfig(tx *dbs.Tx, nodeId int64) (*nodeconfigs.N
}
}
// 指标
return config, nil
}

View File

@@ -214,6 +214,7 @@ func (this *NodeIPAddressDAO) FindNodeAccessIPAddresses(tx *dbs.Tx, nodeId int64
role = nodeconfigs.NodeRoleNode
}
_, err = this.Query(tx).
Attr("role", role).
Attr("nodeId", nodeId).
State(NodeIPAddressStateEnabled).
Attr("canAccess", true).

View File

@@ -171,11 +171,12 @@ func (this *NodeThresholdDAO) FindAllEnabledAndOnNodeThresholds(tx *dbs.Tx, role
}
// CountAllEnabledThresholds 计算阈值的数量
func (this *NodeThresholdDAO) CountAllEnabledThresholds(tx *dbs.Tx, clusterId int64, nodeId int64) (int64, error) {
func (this *NodeThresholdDAO) CountAllEnabledThresholds(tx *dbs.Tx, role string, clusterId int64, nodeId int64) (int64, error) {
if clusterId <= 0 && nodeId <= 0 {
return 0, nil
}
query := this.Query(tx)
query.Attr("role", role)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
"regexp"
"strconv"
"strings"
"time"
@@ -640,8 +641,14 @@ func (this *ServerDAO) CountAllEnabledServersMatch(tx *dbs.Tx, groupId int64, ke
Param("groupId", numberutils.FormatInt64(groupId))
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
if regexp.MustCompile(`^\d+$`).MatchString(keyword) {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
Param("portRange", maps.Map{"portRange": keyword}.AsJSON()).
Param("keyword", "%"+keyword+"%")
} else {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
}
if userId > 0 {
query.Attr("userId", userId)
@@ -674,8 +681,13 @@ func (this *ServerDAO) ListEnabledServersMatch(tx *dbs.Tx, offset int64, size in
Param("groupId", numberutils.FormatInt64(groupId))
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
if regexp.MustCompile(`^\d+$`).MatchString(keyword) {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword OR JSON_CONTAINS(http, :portRange, '$.listen') OR JSON_CONTAINS(https, :portRange, '$.listen') OR JSON_CONTAINS(tcp, :portRange, '$.listen') OR JSON_CONTAINS(tls, :portRange, '$.listen'))").
Param("portRange", string(maps.Map{"portRange": keyword}.AsJSON()))
} else {
query.Where("(name LIKE :keyword OR serverNames LIKE :keyword)").
Param("keyword", "%"+keyword+"%")
}
}
if userId > 0 {
query.Attr("userId", userId)

View File

@@ -5,6 +5,7 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/lionsoul2014/ip2region/binding/golang/ip2region"
"net"
"strings"
)
@@ -27,10 +28,13 @@ func (this *IP2RegionLibrary) Lookup(ip string) (*Result, error) {
return nil, errors.New("library has not been loaded")
}
// 暂不支持IPv6
// 支持IPv4
if strings.Contains(ip, ":") {
return nil, nil
}
if net.ParseIP(ip) == nil {
return nil, nil
}
defer func() {
// 防止panic发生

View File

@@ -24,6 +24,29 @@ func TestIP2RegionLibrary_Lookup(t *testing.T) {
logs.PrintAsJSON(result, t)
}
func TestIP2RegionLibrary_Lookup_Valid_IP(t *testing.T) {
library := &IP2RegionLibrary{}
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
if err != nil {
t.Fatal(err)
}
{
result, err := library.Lookup("114.240.223")
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(result, t)
}
{
result, err := library.Lookup("abc")
if err != nil {
t.Fatal(err)
}
logs.PrintAsJSON(result, t)
}
}
func TestIP2RegionLibrary_Memory(t *testing.T) {
library := &IP2RegionLibrary{}
err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")

View File

@@ -443,6 +443,16 @@ func (this *APINode) registerServices(server *grpc.Server) {
pb.RegisterHTTPAuthPolicyServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.MetricItemService{}).(*services.MetricItemService)
pb.RegisterMetricItemServiceServer(server, instance)
this.rest(instance)
}
{
instance := this.serviceInstance(&services.NodeClusterMetricItemService{}).(*services.NodeClusterMetricItemService)
pb.RegisterNodeClusterMetricItemServiceServer(server, instance)
this.rest(instance)
}
// TODO check service names
for serviceName := range server.GetServiceInfo() {

View File

@@ -10,12 +10,12 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// ACME任务相关服务
// ACMETaskService ACME任务相关服务
type ACMETaskService struct {
BaseService
}
// 计算某个ACME用户相关的任务数量
// CountAllEnabledACMETasksWithACMEUserId 计算某个ACME用户相关的任务数量
func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.Context, req *pb.CountAllEnabledACMETasksWithACMEUserIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -33,7 +33,7 @@ func (this *ACMETaskService) CountAllEnabledACMETasksWithACMEUserId(ctx context.
return this.SuccessCount(count)
}
// 计算跟某个DNS服务商相关的任务数量
// CountEnabledACMETasksWithDNSProviderId 计算跟某个DNS服务商相关的任务数量
func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.Context, req *pb.CountEnabledACMETasksWithDNSProviderIdRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -51,7 +51,7 @@ func (this *ACMETaskService) CountEnabledACMETasksWithDNSProviderId(ctx context.
return this.SuccessCount(count)
}
// 计算所有任务数量
// CountAllEnabledACMETasks 计算所有任务数量
func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *pb.CountAllEnabledACMETasksRequest) (*pb.RPCCountResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
if err != nil {
@@ -67,7 +67,7 @@ func (this *ACMETaskService) CountAllEnabledACMETasks(ctx context.Context, req *
return this.SuccessCount(count)
}
// 列出单页任务
// ListEnabledACMETasks 列出单页任务
func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.ListEnabledACMETasksRequest) (*pb.ListEnabledACMETasksResponse, error) {
_, _, err := this.ValidateAdminAndUser(ctx, 0, req.UserId)
if err != nil {
@@ -162,13 +162,14 @@ func (this *ACMETaskService) ListEnabledACMETasks(ctx context.Context, req *pb.L
SslCert: pbCert,
LatestACMETaskLog: pbTaskLog,
AuthType: task.AuthType,
AuthURL: task.AuthURL,
})
}
return &pb.ListEnabledACMETasksResponse{AcmeTasks: result}, nil
}
// 创建任务
// CreateACMETask 创建任务
func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateACMETaskRequest) (*pb.CreateACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -180,14 +181,14 @@ func (this *ACMETaskService) CreateACMETask(ctx context.Context, req *pb.CreateA
}
tx := this.NullTx()
taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew)
taskId, err := acmemodels.SharedACMETaskDAO.CreateACMETask(tx, adminId, userId, req.AuthType, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL)
if err != nil {
return nil, err
}
return &pb.CreateACMETaskResponse{AcmeTaskId: taskId}, nil
}
// 修改任务
// UpdateACMETask 修改任务
func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -204,14 +205,14 @@ func (this *ACMETaskService) UpdateACMETask(ctx context.Context, req *pb.UpdateA
return nil, this.PermissionError()
}
err = acmemodels.SharedACMETaskDAO.UpdateACMETask(tx, req.AcmeTaskId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew)
err = acmemodels.SharedACMETaskDAO.UpdateACMETask(tx, req.AcmeTaskId, req.AcmeUserId, req.DnsProviderId, req.DnsDomain, req.Domains, req.AutoRenew, req.AuthURL)
if err != nil {
return nil, err
}
return this.Success()
}
// 删除任务
// DeleteACMETask 删除任务
func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteACMETaskRequest) (*pb.RPCSuccess, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -235,7 +236,7 @@ func (this *ACMETaskService) DeleteACMETask(ctx context.Context, req *pb.DeleteA
return this.Success()
}
// 运行某个任务
// RunACMETask 运行某个任务
func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETaskRequest) (*pb.RunACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -261,7 +262,7 @@ func (this *ACMETaskService) RunACMETask(ctx context.Context, req *pb.RunACMETas
}, nil
}
// 查找单个任务信息
// FindEnabledACMETask 查找单个任务信息
func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.FindEnabledACMETaskRequest) (*pb.FindEnabledACMETaskResponse, error) {
adminId, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
if err != nil {
@@ -328,5 +329,6 @@ func (this *ACMETaskService) FindEnabledACMETask(ctx context.Context, req *pb.Fi
DnsProvider: pbProvider,
AcmeUser: pbACMEUser,
AuthType: task.AuthType,
AuthURL: task.AuthURL,
}}, nil
}

View File

@@ -7,12 +7,12 @@ import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// WAF规则分组相关服务
// HTTPFirewallRuleGroupService WAF规则分组相关服务
type HTTPFirewallRuleGroupService struct {
BaseService
}
// 设置是否启用分组
// UpdateHTTPFirewallRuleGroupIsOn 设置是否启用分组
func (this *HTTPFirewallRuleGroupService) UpdateHTTPFirewallRuleGroupIsOn(ctx context.Context, req *pb.UpdateHTTPFirewallRuleGroupIsOnRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -38,7 +38,7 @@ func (this *HTTPFirewallRuleGroupService) UpdateHTTPFirewallRuleGroupIsOn(ctx co
return this.Success()
}
// 创建分组
// CreateHTTPFirewallRuleGroup 创建分组
func (this *HTTPFirewallRuleGroupService) CreateHTTPFirewallRuleGroup(ctx context.Context, req *pb.CreateHTTPFirewallRuleGroupRequest) (*pb.CreateHTTPFirewallRuleGroupResponse, error) {
// 校验请求
_, _, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -55,7 +55,7 @@ func (this *HTTPFirewallRuleGroupService) CreateHTTPFirewallRuleGroup(ctx contex
return &pb.CreateHTTPFirewallRuleGroupResponse{FirewallRuleGroupId: groupId}, nil
}
// 修改分组
// UpdateHTTPFirewallRuleGroup 修改分组
func (this *HTTPFirewallRuleGroupService) UpdateHTTPFirewallRuleGroup(ctx context.Context, req *pb.UpdateHTTPFirewallRuleGroupRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -81,7 +81,7 @@ func (this *HTTPFirewallRuleGroupService) UpdateHTTPFirewallRuleGroup(ctx contex
return this.Success()
}
// 获取分组配置
// FindEnabledHTTPFirewallRuleGroupConfig 获取分组配置
func (this *HTTPFirewallRuleGroupService) FindEnabledHTTPFirewallRuleGroupConfig(ctx context.Context, req *pb.FindEnabledHTTPFirewallRuleGroupConfigRequest) (*pb.FindEnabledHTTPFirewallRuleGroupConfigResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -113,7 +113,7 @@ func (this *HTTPFirewallRuleGroupService) FindEnabledHTTPFirewallRuleGroupConfig
return &pb.FindEnabledHTTPFirewallRuleGroupConfigResponse{FirewallRuleGroupJSON: groupConfigJSON}, nil
}
// 获取分组信息
// FindEnabledHTTPFirewallRuleGroup 获取分组信息
func (this *HTTPFirewallRuleGroupService) FindEnabledHTTPFirewallRuleGroup(ctx context.Context, req *pb.FindEnabledHTTPFirewallRuleGroupRequest) (*pb.FindEnabledHTTPFirewallRuleGroupResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -152,7 +152,7 @@ func (this *HTTPFirewallRuleGroupService) FindEnabledHTTPFirewallRuleGroup(ctx c
}, nil
}
// 修改分组的规则集
// UpdateHTTPFirewallRuleGroupSets 修改分组的规则集
func (this *HTTPFirewallRuleGroupService) UpdateHTTPFirewallRuleGroupSets(ctx context.Context, req *pb.UpdateHTTPFirewallRuleGroupSetsRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)

View File

@@ -5,16 +5,17 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"net"
)
// IP条目相关服务
// IPItemService IP条目相关服务
type IPItemService struct {
BaseService
}
// 创建IP
// CreateIPItem 创建IP
func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPItemRequest) (*pb.CreateIPItemResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -59,7 +60,7 @@ func (this *IPItemService) CreateIPItem(ctx context.Context, req *pb.CreateIPIte
return &pb.CreateIPItemResponse{IpItemId: itemId}, nil
}
// 修改IP
// UpdateIPItem 修改IP
func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPItemRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -93,7 +94,7 @@ func (this *IPItemService) UpdateIPItem(ctx context.Context, req *pb.UpdateIPIte
return this.Success()
}
// 删除IP
// DeleteIPItem 删除IP
func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPItemRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -123,7 +124,7 @@ func (this *IPItemService) DeleteIPItem(ctx context.Context, req *pb.DeleteIPIte
return this.Success()
}
// 计算IP数量
// CountIPItemsWithListId 计算IP数量
func (this *IPItemService) CountIPItemsWithListId(ctx context.Context, req *pb.CountIPItemsWithListIdRequest) (*pb.RPCCountResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -147,7 +148,7 @@ func (this *IPItemService) CountIPItemsWithListId(ctx context.Context, req *pb.C
return this.SuccessCount(count)
}
// 列出单页的IP
// ListIPItemsWithListId 列出单页的IP
func (this *IPItemService) ListIPItemsWithListId(ctx context.Context, req *pb.ListIPItemsWithListIdRequest) (*pb.ListIPItemsWithListIdResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -189,7 +190,7 @@ func (this *IPItemService) ListIPItemsWithListId(ctx context.Context, req *pb.Li
return &pb.ListIPItemsWithListIdResponse{IpItems: result}, nil
}
// 查找单个IP
// FindEnabledIPItem 查找单个IP
func (this *IPItemService) FindEnabledIPItem(ctx context.Context, req *pb.FindEnabledIPItemRequest) (*pb.FindEnabledIPItemResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -230,7 +231,7 @@ func (this *IPItemService) FindEnabledIPItem(ctx context.Context, req *pb.FindEn
}}, nil
}
// 根据版本列出一组IP
// ListIPItemsAfterVersion 根据版本列出一组IP
func (this *IPItemService) ListIPItemsAfterVersion(ctx context.Context, req *pb.ListIPItemsAfterVersionRequest) (*pb.ListIPItemsAfterVersionResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin, rpcutils.UserTypeNode)
@@ -273,3 +274,82 @@ func (this *IPItemService) ListIPItemsAfterVersion(ctx context.Context, req *pb.
return &pb.ListIPItemsAfterVersionResponse{IpItems: result}, nil
}
// CheckIPItemStatus 检查IP状态
func (this *IPItemService) CheckIPItemStatus(ctx context.Context, req *pb.CheckIPItemStatusRequest) (*pb.CheckIPItemStatusResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
// 校验IP
ip := net.ParseIP(req.Ip)
if len(ip) == 0 {
return &pb.CheckIPItemStatusResponse{
IsOk: false,
Error: "请输入正确的IP",
}, nil
}
ipLong := utils.IP2Long(req.Ip)
tx := this.NullTx()
// 名单类型
list, err := models.SharedIPListDAO.FindEnabledIPList(tx, req.IpListId)
if err != nil {
return nil, err
}
if list == nil {
return &pb.CheckIPItemStatusResponse{
IsOk: false,
Error: "IP名单不存在",
}, nil
}
var isAllowed = list.Type == "white"
// 检查IP名单
item, err := models.SharedIPItemDAO.FindEnabledItemContainsIP(tx, req.IpListId, ipLong)
if err != nil {
return nil, err
}
if item != nil {
return &pb.CheckIPItemStatusResponse{
IsOk: true,
Error: "",
IsFound: true,
IsAllowed: isAllowed,
IpItem: &pb.IPItem{
Id: int64(item.Id),
IpFrom: item.IpFrom,
IpTo: item.IpTo,
ExpiredAt: int64(item.ExpiredAt),
Reason: item.Reason,
Type: item.Type,
EventLevel: item.EventLevel,
},
}, nil
}
return &pb.CheckIPItemStatusResponse{
IsOk: true,
Error: "",
IsFound: false,
IsAllowed: false,
IpItem: nil,
}, nil
}
// ExistsEnabledIPItem 检查IP是否存在
func (this *IPItemService) ExistsEnabledIPItem(ctx context.Context, req *pb.ExistsEnabledIPItemRequest) (*pb.ExistsEnabledIPItemResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
b, err := models.SharedIPItemDAO.ExistsEnabledItem(tx, req.IpItemId)
if err != nil {
return nil, err
}
return &pb.ExistsEnabledIPItemResponse{Exists: b}, nil
}

View File

@@ -3,16 +3,15 @@ package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// IP名单相关服务
// IPListService IP名单相关服务
type IPListService struct {
BaseService
}
// 创建IP列表
// CreateIPList 创建IP列表
func (this *IPListService) CreateIPList(ctx context.Context, req *pb.CreateIPListRequest) (*pb.CreateIPListResponse, error) {
// 校验请求
_, userId, err := this.ValidateAdminAndUser(ctx, 0, 0)
@@ -22,34 +21,34 @@ func (this *IPListService) CreateIPList(ctx context.Context, req *pb.CreateIPLis
tx := this.NullTx()
listId, err := models.SharedIPListDAO.CreateIPList(tx, userId, req.Type, req.Name, req.Code, req.TimeoutJSON)
listId, err := models.SharedIPListDAO.CreateIPList(tx, userId, req.Type, req.Name, req.Code, req.TimeoutJSON, req.Description, req.IsPublic)
if err != nil {
return nil, err
}
return &pb.CreateIPListResponse{IpListId: listId}, nil
}
// 修改IP列表
// UpdateIPList 修改IP列表
func (this *IPListService) UpdateIPList(ctx context.Context, req *pb.UpdateIPListRequest) (*pb.RPCSuccess, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
tx := this.NullTx()
err = models.SharedIPListDAO.UpdateIPList(tx, req.IpListId, req.Name, req.Code, req.TimeoutJSON)
err = models.SharedIPListDAO.UpdateIPList(tx, req.IpListId, req.Name, req.Code, req.TimeoutJSON, req.Description)
if err != nil {
return nil, err
}
return this.Success()
}
// 查找IP列表
// FindEnabledIPList 查找IP列表
func (this *IPListService) FindEnabledIPList(ctx context.Context, req *pb.FindEnabledIPListRequest) (*pb.FindEnabledIPListResponse, error) {
// 校验请求
_, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin)
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
@@ -70,5 +69,79 @@ func (this *IPListService) FindEnabledIPList(ctx context.Context, req *pb.FindEn
Name: list.Name,
Code: list.Code,
TimeoutJSON: []byte(list.Timeout),
Description: list.Description,
}}, nil
}
// CountAllEnabledIPLists 计算名单数量
func (this *IPListService) CountAllEnabledIPLists(ctx context.Context, req *pb.CountAllEnabledIPListsRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
count, err := models.SharedIPListDAO.CountAllEnabledIPLists(tx, req.Type, req.IsPublic, req.Keyword)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// ListEnabledIPLists 列出单页名单
func (this *IPListService) ListEnabledIPLists(ctx context.Context, req *pb.ListEnabledIPListsRequest) (*pb.ListEnabledIPListsResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
lists, err := models.SharedIPListDAO.ListEnabledIPLists(tx, req.Type, req.IsPublic, req.Keyword, req.Offset, req.Size)
if err != nil {
return nil, err
}
var pbLists []*pb.IPList
for _, list := range lists {
pbLists = append(pbLists, &pb.IPList{
Id: int64(list.Id),
IsOn: list.IsOn == 1,
Type: list.Type,
Name: list.Name,
Code: list.Code,
TimeoutJSON: []byte(list.Timeout),
IsPublic: list.IsPublic == 1,
Description: list.Description,
})
}
return &pb.ListEnabledIPListsResponse{IpLists: pbLists}, nil
}
// DeleteIPList 删除IP名单
func (this *IPListService) DeleteIPList(ctx context.Context, req *pb.DeleteIPListRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = models.SharedIPListDAO.DisableIPList(tx, req.IpListId)
if err != nil {
return nil, err
}
return this.Success()
}
// ExistsEnabledIPList 检查IPList是否存在
func (this *IPListService) ExistsEnabledIPList(ctx context.Context, req *pb.ExistsEnabledIPListRequest) (*pb.ExistsEnabledIPListResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
b, err := models.SharedIPListDAO.ExistsEnabledIPList(tx, req.IpListId)
if err != nil {
return nil, err
}
return &pb.ExistsEnabledIPListResponse{Exists: b}, nil
}

View File

@@ -0,0 +1,132 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/metrics"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types"
)
// MetricItemService 指标相关服务
type MetricItemService struct {
BaseService
}
// CreateMetricItem 创建指标
func (this *MetricItemService) CreateMetricItem(ctx context.Context, req *pb.CreateMetricItemRequest) (*pb.CreateMetricItemResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
itemId, err := metrics.SharedMetricItemDAO.CreateItem(tx, req.Code, req.Category, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value)
if err != nil {
return nil, err
}
return &pb.CreateMetricItemResponse{MetricItemId: itemId}, nil
}
// UpdateMetricItem 修改指标
func (this *MetricItemService) UpdateMetricItem(ctx context.Context, req *pb.UpdateMetricItemRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = metrics.SharedMetricItemDAO.UpdateItem(tx, req.MetricItemId, req.Name, req.Keys, req.Period, req.PeriodUnit, req.Value, req.IsOn)
if err != nil {
return nil, err
}
return this.Success()
}
// FindEnabledMetricItem 查找单个指标信息
func (this *MetricItemService) FindEnabledMetricItem(ctx context.Context, req *pb.FindEnabledMetricItemRequest) (*pb.FindEnabledMetricItemResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
item, err := metrics.SharedMetricItemDAO.FindEnabledMetricItem(tx, req.MetricItemId)
if err != nil {
return nil, err
}
if item == nil {
return &pb.FindEnabledMetricItemResponse{MetricItem: nil}, nil
}
return &pb.FindEnabledMetricItemResponse{MetricItem: &pb.MetricItem{
Id: int64(item.Id),
IsOn: item.IsOn == 1,
Code: item.Code,
Category: item.Category,
Name: item.Name,
Keys: item.DecodeKeys(),
Period: types.Int32(item.Period),
PeriodUnit: item.PeriodUnit,
Value: item.Value,
}}, nil
}
// CountAllEnabledMetricItems 计算指标数量
func (this *MetricItemService) CountAllEnabledMetricItems(ctx context.Context, req *pb.CountAllEnabledMetricItemsRequest) (*pb.RPCCountResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
count, err := metrics.SharedMetricItemDAO.CountEnabledItems(tx, req.Category)
if err != nil {
return nil, err
}
return this.SuccessCount(count)
}
// ListEnabledMetricItems 列出单页指标
func (this *MetricItemService) ListEnabledMetricItems(ctx context.Context, req *pb.ListEnabledMetricItemsRequest) (*pb.ListEnabledMetricItemsResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
items, err := metrics.SharedMetricItemDAO.ListEnabledItems(tx, req.Category, req.Offset, req.Size)
if err != nil {
return nil, err
}
var pbItems = []*pb.MetricItem{}
for _, item := range items {
pbItems = append(pbItems, &pb.MetricItem{
Id: int64(item.Id),
IsOn: item.IsOn == 1,
Code: item.Code,
Category: item.Category,
Name: item.Name,
Keys: item.DecodeKeys(),
Period: types.Int32(item.Period),
PeriodUnit: item.PeriodUnit,
Value: item.Value,
})
}
return &pb.ListEnabledMetricItemsResponse{MetricItems: pbItems}, nil
}
// DeleteMetricItem 删除指标
func (this *MetricItemService) DeleteMetricItem(ctx context.Context, req *pb.DeleteMetricItemRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = metrics.SharedMetricItemDAO.DisableMetricItem(tx, req.MetricItemId)
if err != nil {
return nil, err
}
return this.Success()
}

View File

@@ -9,7 +9,9 @@ import (
"github.com/TeaOSLab/EdgeAPI/internal/errors"
rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
"github.com/TeaOSLab/EdgeAPI/internal/tasks"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
@@ -887,3 +889,74 @@ func (this *NodeClusterService) FindLatestNodeClusters(ctx context.Context, req
}
return &pb.FindLatestNodeClustersResponse{NodeClusters: pbClusters}, nil
}
// FindEnabledNodeClusterConfigInfo 取得集群的配置概要信息
func (this *NodeClusterService) FindEnabledNodeClusterConfigInfo(ctx context.Context, req *pb.FindEnabledNodeClusterConfigInfoRequest) (*pb.FindEnabledNodeClusterConfigInfoResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
cluster, err := models.SharedNodeClusterDAO.FindEnabledNodeCluster(tx, req.NodeClusterId)
if err != nil {
return nil, err
}
if cluster == nil {
return &pb.FindEnabledNodeClusterConfigInfoResponse{}, nil
}
var result = &pb.FindEnabledNodeClusterConfigInfoResponse{}
// health check
if len(cluster.HealthCheck) > 0 {
healthCheckConfig := &serverconfigs.HealthCheckConfig{}
err = json.Unmarshal([]byte(cluster.HealthCheck), healthCheckConfig)
if err != nil {
return nil, err
}
result.HealthCheckIsOn = healthCheckConfig.IsOn
}
// firewall actions
countFirewallActions, err := models.SharedNodeClusterFirewallActionDAO.CountAllEnabledFirewallActions(tx, req.NodeClusterId)
if err != nil {
return nil, err
}
result.HasFirewallActions = countFirewallActions > 0
// thresholds
countThresholds, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, "node", req.NodeClusterId, 0)
if err != nil {
return nil, err
}
result.HasThresholds = countThresholds > 0
// message receivers
countReceivers, err := models.SharedMessageReceiverDAO.CountAllEnabledReceivers(tx, models.MessageTaskTarget{
ClusterId: req.NodeClusterId,
}, "")
if err != nil {
return nil, err
}
result.HasMessageReceivers = countReceivers > 0
// toa
if len(cluster.Toa) > 0 {
var toaConfig = &nodeconfigs.TOAConfig{}
err = json.Unmarshal([]byte(cluster.Toa), toaConfig)
if err != nil {
return nil, err
}
result.IsTOAEnabled = toaConfig.IsOn
}
// metric items
countMetricItems, err := models.SharedNodeClusterMetricItemDAO.CountAllClusterItems(tx, req.NodeClusterId)
if err != nil {
return nil, err
}
result.HasMetricItems = countMetricItems > 0
return result, nil
}

View File

@@ -0,0 +1,81 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package services
import (
"context"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/metrics"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types"
)
// NodeClusterMetricItemService 集群指标
type NodeClusterMetricItemService struct {
BaseService
}
// EnableNodeClusterMetricItem 启用某个指标
func (this *NodeClusterMetricItemService) EnableNodeClusterMetricItem(ctx context.Context, req *pb.EnableNodeClusterMetricItemRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = models.SharedNodeClusterMetricItemDAO.EnableClusterItem(tx, req.NodeClusterId, req.MetricItemId)
if err != nil {
return nil, err
}
return this.Success()
}
// DisableNodeClusterMetricItem 禁用某个指标
func (this *NodeClusterMetricItemService) DisableNodeClusterMetricItem(ctx context.Context, req *pb.DisableNodeClusterMetricItemRequest) (*pb.RPCSuccess, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
err = models.SharedNodeClusterMetricItemDAO.DisableClusterItem(tx, req.NodeClusterId, req.MetricItemId)
if err != nil {
return nil, err
}
return this.Success()
}
// FindAllNodeClusterMetricItems 查找集群中所有指标
func (this *NodeClusterMetricItemService) FindAllNodeClusterMetricItems(ctx context.Context, req *pb.FindAllNodeClusterMetricItemsRequest) (*pb.FindAllNodeClusterMetricItemsResponse, error) {
_, err := this.ValidateAdmin(ctx, 0)
if err != nil {
return nil, err
}
var tx = this.NullTx()
clusterItems, err := models.SharedNodeClusterMetricItemDAO.FindAllClusterItems(tx, req.NodeClusterId)
if err != nil {
return nil, err
}
var pbItems = []*pb.MetricItem{}
for _, clusterItem := range clusterItems {
item, err := metrics.SharedMetricItemDAO.FindEnabledMetricItem(tx, int64(clusterItem.ItemId))
if err != nil {
return nil, err
}
if item != nil {
pbItems = append(pbItems, &pb.MetricItem{
Id: int64(item.Id),
IsOn: item.IsOn == 1,
Code: item.Code,
Category: item.Category,
Name: item.Name,
Keys: item.DecodeKeys(),
Period: types.Int32(item.Period),
PeriodUnit: item.PeriodUnit,
Value: item.Value,
})
}
}
return &pb.FindAllNodeClusterMetricItemsResponse{MetricItems: pbItems}, nil
}

View File

@@ -114,7 +114,7 @@ func (this *NodeThresholdService) CountAllEnabledNodeThresholds(ctx context.Cont
}
var tx = this.NullTx()
count, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, req.NodeClusterId, req.NodeId)
count, err := models.SharedNodeThresholdDAO.CountAllEnabledThresholds(tx, req.Role, req.NodeClusterId, req.NodeId)
if err != nil {
return nil, err
}

View File

@@ -1303,7 +1303,6 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
return err
}
if systemId == 0 {
// TODO 失败时,需要查询一次确认是否已添加
systemId, err = models.SharedClientSystemDAO.CreateSystem(tx, result.Name)
if err != nil {
return err
@@ -1332,7 +1331,6 @@ func (this *ServerService) UploadServerHTTPRequestStat(ctx context.Context, req
return err
}
if browserId == 0 {
// TODO 失败时,需要查询一次确认是否已添加
browserId, err = models.SharedClientBrowserDAO.CreateBrowser(tx, result.Name)
if err != nil {
return err

File diff suppressed because one or more lines are too long

53
internal/utils/http.go Normal file
View File

@@ -0,0 +1,53 @@
package utils
import (
"crypto/tls"
"io/ioutil"
"net/http"
"net/http/httputil"
"sync"
"time"
)
// HTTP请求客户端管理
var timeoutClientMap = map[time.Duration]*http.Client{} // timeout => Client
var timeoutClientLocker = sync.Mutex{}
// DumpResponse 导出响应
func DumpResponse(resp *http.Response) (header []byte, body []byte, err error) {
header, err = httputil.DumpResponse(resp, false)
body, err = ioutil.ReadAll(resp.Body)
return
}
// NewHTTPClient 获取一个新的Client
func NewHTTPClient(timeout time.Duration) *http.Client {
return &http.Client{
Timeout: timeout,
Transport: &http.Transport{
MaxIdleConns: 4096,
MaxIdleConnsPerHost: 32,
MaxConnsPerHost: 32,
IdleConnTimeout: 2 * time.Minute,
ExpectContinueTimeout: 1 * time.Second,
TLSHandshakeTimeout: 0,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
}
// SharedHttpClient 获取一个公用的Client
func SharedHttpClient(timeout time.Duration) *http.Client {
timeoutClientLocker.Lock()
defer timeoutClientLocker.Unlock()
client, ok := timeoutClientMap[timeout]
if ok {
return client
}
client = NewHTTPClient(timeout)
timeoutClientMap[timeout] = client
return client
}