Compare commits

...

50 Commits

Author SHA1 Message Date
刘祥超
004e640321 修复升级数据库时主键可能冲突的问题 2022-08-15 00:02:38 +08:00
刘祥超
7ad315ae4b IP库管理阶段性提交(未完成) 2022-08-14 20:03:01 +08:00
刘祥超
ba938e5361 新版IP库管理阶段性提交(未完成) 2022-08-13 23:55:48 +08:00
刘祥超
9ddf02a0e6 更新TeaGo 2022-08-11 11:52:35 +08:00
刘祥超
ebcbd5690d 删除不必要的文件 2022-08-09 18:30:23 +08:00
刘祥超
bbca766fa4 删除不必要的文件 2022-08-09 17:35:35 +08:00
刘祥超
99c7819d3a 更新SQL 2022-08-07 19:04:16 +08:00
刘祥超
08bb3e66f8 修改版本号为0.5.0 2022-08-07 19:02:19 +08:00
刘祥超
9159820742 只有发送过离线通知的节点才会发送恢复在线通知 2022-08-07 17:28:54 +08:00
刘祥超
1a565b2ebb 优化代码/启用的日志策略排在最前面 2022-08-07 15:10:05 +08:00
刘祥超
98847c53ea 更新SQL 2022-08-06 20:31:28 +08:00
刘祥超
14bafc8f20 优化代码 2022-08-06 20:28:32 +08:00
刘祥超
58a5bd0092 优化代码 2022-08-05 21:05:34 +08:00
刘祥超
4f1ce52f6a 优化代码 2022-08-05 19:25:31 +08:00
刘祥超
14ba7f6899 优化访问日志策略测试时的失败提示 2022-08-05 19:11:21 +08:00
刘祥超
e582e37c06 优化代码 2022-08-05 14:45:56 +08:00
刘祥超
6a3fa9f0ca 删除不必要的文件 2022-08-05 14:40:42 +08:00
刘祥超
e0a9965fed 简化API 2022-08-04 19:36:25 +08:00
刘祥超
481fa8cd2d 增加查找使用某个证书的NS集群数量的API 2022-08-04 16:25:09 +08:00
刘祥超
95349dc457 允许用户标记上传文件状态 2022-08-04 16:01:07 +08:00
刘祥超
fc839f96d2 优化代码 2022-08-04 15:12:39 +08:00
刘祥超
0414cc02e8 优化代码 2022-08-04 11:41:42 +08:00
刘祥超
b8babaae39 更新SQL 2022-08-03 10:45:09 +08:00
刘祥超
285ce1b312 延长节点执行任务超时时间 2022-08-01 18:57:19 +08:00
刘祥超
c309da81ae 服务带宽API增加按月、按日查询接口 2022-08-01 15:40:57 +08:00
刘祥超
c325fde52b 更新SQL 2022-08-01 11:01:51 +08:00
刘祥超
0f69b45d25 修改用户节点版本号为0.4.0 2022-08-01 11:00:52 +08:00
刘祥超
e02084ba5d 增加用户订单相关表 2022-07-31 19:56:56 +08:00
刘祥超
642b23dbb7 优化代码 2022-07-30 16:28:28 +08:00
刘祥超
b1dc385c87 自动转换用户提交的域名为小写 2022-07-30 16:25:16 +08:00
刘祥超
89a69e3165 删除集群的时候同时删除相关节点运行日志 2022-07-28 09:47:01 +08:00
刘祥超
530954dd6c EdgeDNS:访问日志增加集群和记录类型筛选 2022-07-27 20:19:29 +08:00
刘祥超
33635f7a1b 智能DNS支持自定义端口 2022-07-27 16:56:17 +08:00
刘祥超
8ac964e805 优化远程安装程序 2022-07-27 08:35:15 +08:00
刘祥超
a1519baf0f 远程升级节点时,如果老的文件不存在,则不提示 2022-07-26 20:10:50 +08:00
刘祥超
e6e32a39bb 修改DNS节点版本为0.2.5 2022-07-26 11:15:22 +08:00
刘祥超
d828b7f8a4 修改版本号为0.4.11 2022-07-26 08:57:48 +08:00
刘祥超
07b377c2fb 用户状态发生变化时,同步服务状态 2022-07-24 17:13:05 +08:00
刘祥超
33a3795773 用户增加OTP认证设置 2022-07-24 16:14:56 +08:00
刘祥超
bddb3cae96 用户列表中显示实名审核状态 2022-07-24 11:57:42 +08:00
刘祥超
6a525c2b82 相关接口增加实名认证状态字段 2022-07-24 11:28:59 +08:00
刘祥超
3a137c1c3f 提交SQL 2022-07-24 10:08:40 +08:00
刘祥超
19867568a9 可以重置用户实名认证状态 2022-07-24 10:08:08 +08:00
刘祥超
c2600b911b 优化代码/实现基础的实名认证功能 2022-07-24 09:56:27 +08:00
刘祥超
fe511ae7e5 优化代码 2022-07-22 15:05:30 +08:00
刘祥超
876c631c85 优化代码 2022-07-22 14:35:17 +08:00
刘祥超
a4cc138ef3 API节点自动生成实例代号,用来外界查询多个API节点实例是否为同一个 2022-07-21 19:21:11 +08:00
刘祥超
3f9a7a8a49 升级gosock 2022-07-21 16:30:19 +08:00
刘祥超
09d8ef00c2 API节点状态中增加主程序位置信息 2022-07-21 15:23:08 +08:00
刘祥超
b4f77ddc63 修改版本为v0.4.10 2022-07-20 18:14:27 +08:00
315 changed files with 5773 additions and 7545 deletions

3
.gitignore vendored
View File

@@ -1,2 +1,3 @@
*_plus.go
*-plus.sh
*-plus.sh
*_plus_test.go

View File

@@ -88,6 +88,7 @@ function build() {
mkdir "$DIST"/bin
mkdir "$DIST"/configs
mkdir "$DIST"/logs
mkdir "$DIST"/data
fi
cp "$ROOT"/configs/api.template.yaml "$DIST"/configs/
cp "$ROOT"/configs/db.template.yaml "$DIST"/configs/

View File

@@ -161,6 +161,20 @@ func main() {
}
}
})
app.On("instance", func() {
var sock = gosock.NewTmpSock(teaconst.ProcessName)
reply, err := sock.Send(&gosock.Command{Code: "instance"})
if err != nil {
fmt.Println("[ERROR]" + err.Error())
} else {
replyJSON, err := json.MarshalIndent(reply.Params, "", " ")
if err != nil {
fmt.Println("[ERROR]marshal result failed: " + err.Error())
} else {
fmt.Println(string(replyJSON))
}
}
})
app.Run(func() {
nodes.NewAPINode().Start()

6
go.mod
View File

@@ -12,8 +12,8 @@ require (
github.com/go-acme/lego/v4 v4.5.2
github.com/go-sql-driver/mysql v1.5.0
github.com/golang/protobuf v1.5.2
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3
github.com/iwind/TeaGo v0.0.0-20220811034530-657e3f15b79e
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62
github.com/mozillazg/go-pinyin v0.18.0
github.com/pkg/sftp v1.12.0
github.com/shirou/gopsutil/v3 v3.22.2
@@ -21,7 +21,7 @@ require (
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
google.golang.org/grpc v1.45.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gopkg.in/yaml.v3 v3.0.1
)
require (

6
go.sum
View File

@@ -239,8 +239,12 @@ github.com/iwind/TeaGo v0.0.0-20210411134150-ddf57e240c2f/go.mod h1:KU4mS7QNiZ7Q
github.com/iwind/TeaGo v0.0.0-20220304043459-0dd944a5b475/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570 h1:zqz2FiMMkSHXWO1EsTRJDPTwX9xQ4uuyD5GAE4JGlhM=
github.com/iwind/TeaGo v0.0.0-20220408111647-f36b9bba3570/go.mod h1:HRHK0zoC/og3c9/hKosD9yYVMTnnzm3PgXUdhRYHaLc=
github.com/iwind/TeaGo v0.0.0-20220811034530-657e3f15b79e h1:cw4b6ecXdXvLd45YSstD8r9ClcnVK4ljZMZCept2aOk=
github.com/iwind/TeaGo v0.0.0-20220811034530-657e3f15b79e/go.mod h1:fi/Pq+/5m2HZoseM+39dMF57ANXRt6w4PkGu3NXPc5s=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3 h1:aBSonas7vFcgTj9u96/bWGILGv1ZbUSTLiOzcI1ZT6c=
github.com/iwind/gosock v0.0.0-20210722083328-12b2d66abec3/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62 h1:HJH6RDheAY156DnIfJSD/bEvqyXzsZuE2gzs8PuUjoo=
github.com/iwind/gosock v0.0.0-20220505115348-f88412125a62/go.mod h1:H5Q7SXwbx3a97ecJkaS2sD77gspzE7HFUafBO0peEyA=
github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/jarcoal/httpmock v1.0.6/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -787,6 +791,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@@ -1,71 +0,0 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package accesslogs
import (
"encoding/json"
"fmt"
"github.com/TeaOSLab/EdgeCommon/pkg/configutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"strconv"
"time"
)
type BaseStorage struct {
isOk bool
version int
firewallOnly bool
}
func (this *BaseStorage) SetVersion(version int) {
this.version = version
}
func (this *BaseStorage) Version() int {
return this.version
}
func (this *BaseStorage) IsOk() bool {
return this.isOk
}
func (this *BaseStorage) SetOk(isOk bool) {
this.isOk = isOk
}
func (this *BaseStorage) SetFirewallOnly(firewallOnly bool) {
this.firewallOnly = firewallOnly
}
// Marshal 对日志进行编码
func (this *BaseStorage) Marshal(accessLog *pb.HTTPAccessLog) ([]byte, error) {
return json.Marshal(accessLog)
}
// FormatVariables 格式化字符串中的变量
func (this *BaseStorage) FormatVariables(s string) string {
var now = time.Now()
return configutils.ParseVariables(s, func(varName string) (value string) {
switch varName {
case "year":
return strconv.Itoa(now.Year())
case "month":
return fmt.Sprintf("%02d", now.Month())
case "week":
_, week := now.ISOWeek()
return fmt.Sprintf("%02d", week)
case "day":
return fmt.Sprintf("%02d", now.Day())
case "hour":
return fmt.Sprintf("%02d", now.Hour())
case "minute":
return fmt.Sprintf("%02d", now.Minute())
case "second":
return fmt.Sprintf("%02d", now.Second())
case "date":
return fmt.Sprintf("%d%02d%02d", now.Year(), now.Month(), now.Day())
}
return varName
})
}

View File

@@ -1,99 +0,0 @@
package accesslogs
import (
"bytes"
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/logs"
"os/exec"
"sync"
)
// CommandStorage 通过命令行存储
type CommandStorage struct {
BaseStorage
config *serverconfigs.AccessLogCommandStorageConfig
writeLocker sync.Mutex
}
func NewCommandStorage(config *serverconfigs.AccessLogCommandStorageConfig) *CommandStorage {
return &CommandStorage{config: config}
}
func (this *CommandStorage) Config() interface{} {
return this.config
}
// Start 启动
func (this *CommandStorage) Start() error {
if len(this.config.Command) == 0 {
return errors.New("'command' should not be empty")
}
return nil
}
// 写入日志
func (this *CommandStorage) Write(accessLogs []*pb.HTTPAccessLog) error {
if len(accessLogs) == 0 {
return nil
}
this.writeLocker.Lock()
defer this.writeLocker.Unlock()
cmd := exec.Command(this.config.Command, this.config.Args...)
if len(this.config.Dir) > 0 {
cmd.Dir = this.config.Dir
}
stdout := bytes.NewBuffer([]byte{})
cmd.Stdout = stdout
w, err := cmd.StdinPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
for _, accessLog := range accessLogs {
if this.firewallOnly && accessLog.FirewallPolicyId == 0 {
continue
}
data, err := this.Marshal(accessLog)
if err != nil {
logs.Error(err)
continue
}
_, err = w.Write(data)
if err != nil {
logs.Error(err)
}
_, err = w.Write([]byte("\n"))
if err != nil {
logs.Error(err)
}
}
_ = w.Close()
err = cmd.Wait()
if err != nil {
logs.Error(err)
if stdout.Len() > 0 {
logs.Error(errors.New(string(stdout.Bytes())))
}
}
return nil
}
// Close 关闭
func (this *CommandStorage) Close() error {
return nil
}

View File

@@ -1,63 +0,0 @@
package accesslogs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"os"
"os/exec"
"testing"
"time"
)
func TestCommandStorage_Write(t *testing.T) {
php, err := exec.LookPath("php")
if err != nil { // not found php, so we can not test
t.Log("php:", err)
return
}
cwd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
before := time.Now()
storage := NewCommandStorage(&serverconfigs.AccessLogCommandStorageConfig{
Command: php,
Args: []string{cwd + "/tests/command_storage.php"},
})
err = storage.Start()
if err != nil {
t.Fatal(err)
}
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestMethod: "GET",
RequestPath: "/hello",
},
{
RequestMethod: "GET",
RequestPath: "/world",
},
{
RequestMethod: "GET",
RequestPath: "/lu",
},
{
RequestMethod: "GET",
RequestPath: "/ping",
},
})
if err != nil {
t.Fatal(err)
}
err = storage.Close()
if err != nil {
t.Fatal(err)
}
t.Log(time.Since(before).Seconds(), "seconds")
}

View File

@@ -1,131 +0,0 @@
package accesslogs
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"io/ioutil"
"net/http"
"regexp"
"strings"
"time"
)
// ESStorage ElasticSearch存储策略
type ESStorage struct {
BaseStorage
config *serverconfigs.AccessLogESStorageConfig
}
func NewESStorage(config *serverconfigs.AccessLogESStorageConfig) *ESStorage {
return &ESStorage{config: config}
}
func (this *ESStorage) Config() interface{} {
return this.config
}
// Start 开启
func (this *ESStorage) Start() error {
if len(this.config.Endpoint) == 0 {
return errors.New("'endpoint' should not be nil")
}
if !regexp.MustCompile(`(?i)^(http|https)://`).MatchString(this.config.Endpoint) {
this.config.Endpoint = "http://" + this.config.Endpoint
}
if len(this.config.Index) == 0 {
return errors.New("'index' should not be nil")
}
if len(this.config.MappingType) == 0 {
return errors.New("'mappingType' should not be nil")
}
return nil
}
// 写入日志
func (this *ESStorage) Write(accessLogs []*pb.HTTPAccessLog) error {
if len(accessLogs) == 0 {
return nil
}
bulk := &strings.Builder{}
indexName := this.FormatVariables(this.config.Index)
typeName := this.FormatVariables(this.config.MappingType)
for _, accessLog := range accessLogs {
if this.firewallOnly && accessLog.FirewallPolicyId == 0 {
continue
}
if len(accessLog.RequestId) == 0 {
continue
}
opData, err := json.Marshal(map[string]interface{}{
"index": map[string]interface{}{
"_index": indexName,
"_type": typeName,
"_id": accessLog.RequestId,
},
})
if err != nil {
remotelogs.Error("ACCESS_LOG_ES_STORAGE", "write failed: "+err.Error())
continue
}
data, err := this.Marshal(accessLog)
if err != nil {
remotelogs.Error("ACCESS_LOG_ES_STORAGE", "marshal data failed: "+err.Error())
continue
}
bulk.Write(opData)
bulk.WriteString("\n")
bulk.Write(data)
bulk.WriteString("\n")
}
if bulk.Len() == 0 {
return nil
}
req, err := http.NewRequest(http.MethodPost, this.config.Endpoint+"/_bulk", strings.NewReader(bulk.String()))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("User-Agent", strings.ReplaceAll(teaconst.ProductName, " ", "-")+"/"+teaconst.Version)
if len(this.config.Username) > 0 || len(this.config.Password) > 0 {
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(this.config.Username+":"+this.config.Password)))
}
client := utils.SharedHttpClient(10 * time.Second)
defer func() {
_ = req.Body.Close()
}()
resp, err := client.Do(req)
if err != nil {
return err
}
defer func() {
_ = resp.Body.Close()
}()
if resp.StatusCode != http.StatusOK {
bodyData, _ := ioutil.ReadAll(resp.Body)
return errors.New("ElasticSearch response status code: " + fmt.Sprintf("%d", resp.StatusCode) + " content: " + string(bodyData))
}
return nil
}
// Close 关闭
func (this *ESStorage) Close() error {
return nil
}

View File

@@ -1,53 +0,0 @@
package accesslogs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"testing"
"time"
)
func TestESStorage_Write(t *testing.T) {
storage := NewESStorage(&serverconfigs.AccessLogESStorageConfig{
Endpoint: "http://127.0.0.1:9200",
Index: "logs",
MappingType: "accessLogs",
Username: "hello",
Password: "world",
})
err := storage.Start()
if err != nil {
t.Fatal(err)
}
{
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestMethod: "POST",
RequestPath: "/1",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
TimeISO8601: "2018-07-23T22:23:35+08:00",
Header: map[string]*pb.Strings{
"Content-Type": {Values: []string{"text/html"}},
},
},
{
RequestMethod: "GET",
RequestPath: "/2",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
TimeISO8601: "2018-07-23T22:23:35+08:00",
Header: map[string]*pb.Strings{
"Content-Type": {Values: []string{"text/css"}},
},
},
})
if err != nil {
t.Fatal(err)
}
}
err = storage.Close()
if err != nil {
t.Fatal(err)
}
}

View File

@@ -1,130 +0,0 @@
package accesslogs
import (
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/logs"
"os"
"path/filepath"
"sync"
)
// FileStorage 文件存储策略
type FileStorage struct {
BaseStorage
config *serverconfigs.AccessLogFileStorageConfig
writeLocker sync.Mutex
files map[string]*os.File // path => *File
filesLocker sync.Mutex
}
func NewFileStorage(config *serverconfigs.AccessLogFileStorageConfig) *FileStorage {
return &FileStorage{
config: config,
}
}
func (this *FileStorage) Config() interface{} {
return this.config
}
// Start 开启
func (this *FileStorage) Start() error {
if len(this.config.Path) == 0 {
return errors.New("'path' should not be empty")
}
this.files = map[string]*os.File{}
return nil
}
// Write 写入日志
func (this *FileStorage) Write(accessLogs []*pb.HTTPAccessLog) error {
if len(accessLogs) == 0 {
return nil
}
fp := this.fp()
if fp == nil {
return errors.New("file pointer should not be nil")
}
this.writeLocker.Lock()
defer this.writeLocker.Unlock()
for _, accessLog := range accessLogs {
if this.firewallOnly && accessLog.FirewallPolicyId == 0 {
continue
}
data, err := this.Marshal(accessLog)
if err != nil {
logs.Error(err)
continue
}
_, err = fp.Write(data)
if err != nil {
_ = this.Close()
break
}
_, _ = fp.WriteString("\n")
}
return nil
}
// Close 关闭
func (this *FileStorage) Close() error {
this.filesLocker.Lock()
defer this.filesLocker.Unlock()
var resultErr error
for _, f := range this.files {
err := f.Close()
if err != nil {
resultErr = err
}
}
return resultErr
}
func (this *FileStorage) fp() *os.File {
path := this.FormatVariables(this.config.Path)
this.filesLocker.Lock()
defer this.filesLocker.Unlock()
fp, ok := this.files[path]
if ok {
return fp
}
// 关闭其他的文件
for _, f := range this.files {
_ = f.Close()
}
// 是否创建文件目录
if this.config.AutoCreate {
dir := filepath.Dir(path)
_, err := os.Stat(dir)
if os.IsNotExist(err) {
err = os.MkdirAll(dir, 0777)
if err != nil {
logs.Error(err)
return nil
}
}
}
// 打开新文件
fp, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
logs.Error(err)
return nil
}
this.files[path] = fp
return fp
}

View File

@@ -1,70 +0,0 @@
package accesslogs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/Tea"
"testing"
"time"
)
func TestFileStorage_Write(t *testing.T) {
storage := NewFileStorage(&serverconfigs.AccessLogFileStorageConfig{
Path: Tea.Root + "/logs/access-${date}.log",
})
err := storage.Start()
if err != nil {
t.Fatal(err)
}
{
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestPath: "/hello",
},
{
RequestPath: "/world",
},
})
if err != nil {
t.Fatal(err)
}
}
{
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestPath: "/1",
},
{
RequestPath: "/2",
},
})
if err != nil {
t.Fatal(err)
}
}
{
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestMethod: "POST",
RequestPath: "/1",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
},
{
RequestMethod: "GET",
RequestPath: "/2",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
},
})
if err != nil {
t.Fatal(err)
}
}
err = storage.Close()
if err != nil {
t.Fatal(err)
}
}

View File

@@ -1,33 +0,0 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package accesslogs
import "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
// StorageInterface 日志存储接口
type StorageInterface interface {
// Version 获取版本
Version() int
// SetVersion 设置版本
SetVersion(version int)
// SetFirewallOnly 设置是否只处理防火墙相关的访问日志
SetFirewallOnly(firewallOnly bool)
IsOk() bool
SetOk(ok bool)
// Config 获取配置
Config() interface{}
// Start 开启
Start() error
// Write 写入日志
Write(accessLogs []*pb.HTTPAccessLog) error
// Close 关闭
Close() error
}

View File

@@ -1,185 +0,0 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package accesslogs
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/types"
"sync"
"time"
)
var SharedStorageManager = NewStorageManager()
type StorageManager struct {
storageMap map[int64]StorageInterface // policyId => Storage
locker sync.Mutex
}
func NewStorageManager() *StorageManager {
return &StorageManager{
storageMap: map[int64]StorageInterface{},
}
}
func (this *StorageManager) Start() {
var ticker = time.NewTicker(1 * time.Minute)
if Tea.IsTesting() {
ticker = time.NewTicker(5 * time.Second)
}
// 启动时执行一次
var err = this.Loop()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "update error: "+err.Error())
}
// 循环执行
for range ticker.C {
err := this.Loop()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "update error: "+err.Error())
}
}
}
// Loop 更新
func (this *StorageManager) Loop() error {
policies, err := models.SharedHTTPAccessLogPolicyDAO.FindAllEnabledAndOnPolicies(nil)
if err != nil {
return err
}
var policyIds = []int64{}
for _, policy := range policies {
if policy.IsOn {
policyIds = append(policyIds, int64(policy.Id))
}
}
this.locker.Lock()
defer this.locker.Unlock()
// 关闭不用的
for policyId, storage := range this.storageMap {
if !lists.ContainsInt64(policyIds, policyId) {
err := storage.Close()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "close '"+types.String(policyId)+"' failed: "+err.Error())
}
delete(this.storageMap, policyId)
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "remove '"+types.String(policyId)+"'")
}
}
for _, policy := range policies {
var policyId = int64(policy.Id)
storage, ok := this.storageMap[policyId]
if ok {
// 检查配置是否有变更
if types.Int(policy.Version) != storage.Version() {
err = storage.Close()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "close policy '"+types.String(policyId)+"' failed: "+err.Error())
// 继续往下执行
}
if len(policy.Options) > 0 {
err = json.Unmarshal(policy.Options, storage.Config())
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "unmarshal policy '"+types.String(policyId)+"' config failed: "+err.Error())
storage.SetOk(false)
continue
}
}
storage.SetVersion(types.Int(policy.Version))
storage.SetFirewallOnly(policy.FirewallOnly == 1)
err := storage.Start()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "start policy '"+types.String(policyId)+"' failed: "+err.Error())
continue
}
storage.SetOk(true)
remotelogs.Println("ACCESS_LOG_STORAGE_MANAGER", "restart policy '"+types.String(policyId)+"'")
}
} else {
storage, err := this.createStorage(policy.Type, policy.Options)
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "create policy '"+types.String(policyId)+"' failed: "+err.Error())
continue
}
storage.SetVersion(types.Int(policy.Version))
storage.SetFirewallOnly(policy.FirewallOnly == 1)
this.storageMap[policyId] = storage
err = storage.Start()
if err != nil {
remotelogs.Error("ACCESS_LOG_STORAGE_MANAGER", "start policy '"+types.String(policyId)+"' failed: "+err.Error())
continue
}
storage.SetOk(true)
remotelogs.Println("ACCESS_LOG_STORAGE_MANAGER", "start policy '"+types.String(policyId)+"'")
}
}
return nil
}
func (this *StorageManager) createStorage(storageType string, optionsJSON []byte) (StorageInterface, error) {
switch storageType {
case serverconfigs.AccessLogStorageTypeFile:
var config = &serverconfigs.AccessLogFileStorageConfig{}
if len(optionsJSON) > 0 {
err := json.Unmarshal(optionsJSON, config)
if err != nil {
return nil, err
}
}
return NewFileStorage(config), nil
case serverconfigs.AccessLogStorageTypeES:
var config = &serverconfigs.AccessLogESStorageConfig{}
if len(optionsJSON) > 0 {
err := json.Unmarshal(optionsJSON, config)
if err != nil {
return nil, err
}
}
return NewESStorage(config), nil
case serverconfigs.AccessLogStorageTypeTCP:
var config = &serverconfigs.AccessLogTCPStorageConfig{}
if len(optionsJSON) > 0 {
err := json.Unmarshal(optionsJSON, config)
if err != nil {
return nil, err
}
}
return NewTCPStorage(config), nil
case serverconfigs.AccessLogStorageTypeSyslog:
var config = &serverconfigs.AccessLogSyslogStorageConfig{}
if len(optionsJSON) > 0 {
err := json.Unmarshal(optionsJSON, config)
if err != nil {
return nil, err
}
}
return NewSyslogStorage(config), nil
case serverconfigs.AccessLogStorageTypeCommand:
var config = &serverconfigs.AccessLogCommandStorageConfig{}
if len(optionsJSON) > 0 {
err := json.Unmarshal(optionsJSON, config)
if err != nil {
return nil, err
}
}
return NewCommandStorage(config), nil
}
return nil, errors.New("invalid policy type '" + storageType + "'")
}

View File

@@ -1,17 +0,0 @@
package accesslogs
import (
"github.com/iwind/TeaGo/dbs"
"testing"
)
func TestStorageManager_Loop(t *testing.T) {
dbs.NotifyReady()
var storage = NewStorageManager()
err := storage.Loop()
if err != nil {
t.Fatal(err)
}
t.Log(storage.storageMap)
}

View File

@@ -1,15 +0,0 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
//go:build !plus
// +build !plus
package accesslogs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// 写入日志
func (this *StorageManager) Write(policyId int64, accessLogs []*pb.HTTPAccessLog) error {
return nil
}

View File

@@ -1,146 +0,0 @@
package accesslogs
import (
"bytes"
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/logs"
"os/exec"
"runtime"
"strconv"
)
type SyslogStorageProtocol = string
const (
SyslogStorageProtocolTCP SyslogStorageProtocol = "tcp"
SyslogStorageProtocolUDP SyslogStorageProtocol = "udp"
SyslogStorageProtocolNone SyslogStorageProtocol = "none"
SyslogStorageProtocolSocket SyslogStorageProtocol = "socket"
)
type SyslogStoragePriority = int
// SyslogStorage syslog存储策略
type SyslogStorage struct {
BaseStorage
config *serverconfigs.AccessLogSyslogStorageConfig
exe string
}
func NewSyslogStorage(config *serverconfigs.AccessLogSyslogStorageConfig) *SyslogStorage {
return &SyslogStorage{config: config}
}
func (this *SyslogStorage) Config() interface{} {
return this.config
}
// Start 开启
func (this *SyslogStorage) Start() error {
if runtime.GOOS != "linux" {
return errors.New("'syslog' storage only works on linux")
}
exe, err := exec.LookPath("logger")
if err != nil {
return err
}
this.exe = exe
return nil
}
// 写入日志
func (this *SyslogStorage) Write(accessLogs []*pb.HTTPAccessLog) error {
if len(accessLogs) == 0 {
return nil
}
args := []string{}
if len(this.config.Tag) > 0 {
args = append(args, "-t", this.config.Tag)
}
if this.config.Priority >= 0 {
args = append(args, "-p", strconv.Itoa(this.config.Priority))
}
switch this.config.Protocol {
case SyslogStorageProtocolTCP:
args = append(args, "-T")
if len(this.config.ServerAddr) > 0 {
args = append(args, "-n", this.config.ServerAddr)
}
if this.config.ServerPort > 0 {
args = append(args, "-P", strconv.Itoa(this.config.ServerPort))
}
case SyslogStorageProtocolUDP:
args = append(args, "-d")
if len(this.config.ServerAddr) > 0 {
args = append(args, "-n", this.config.ServerAddr)
}
if this.config.ServerPort > 0 {
args = append(args, "-P", strconv.Itoa(this.config.ServerPort))
}
case SyslogStorageProtocolSocket:
args = append(args, "-u")
args = append(args, this.config.Socket)
case SyslogStorageProtocolNone:
// do nothing
}
args = append(args, "-S", "10240")
var cmd = exec.Command(this.exe, args...)
var stderrBuffer = &bytes.Buffer{}
cmd.Stderr = stderrBuffer
w, err := cmd.StdinPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
for _, accessLog := range accessLogs {
if this.firewallOnly && accessLog.FirewallPolicyId == 0 {
continue
}
data, err := this.Marshal(accessLog)
if err != nil {
remotelogs.Error("ACCESS_LOG_POLICY_SYSLOG", "marshal accesslog failed: "+err.Error())
continue
}
_, err = w.Write(data)
if err != nil {
logs.Error(err)
}
_, err = w.Write([]byte("\n"))
if err != nil {
remotelogs.Error("ACCESS_LOG_POLICY_SYSLOG", "write accesslog failed: "+err.Error())
}
}
_ = w.Close()
err = cmd.Wait()
if err != nil {
return errors.New("send syslog failed: " + err.Error() + ", stderr: " + stderrBuffer.String())
}
return nil
}
// Close 关闭
func (this *SyslogStorage) Close() error {
return nil
}

View File

@@ -1,114 +0,0 @@
package accesslogs
import (
"errors"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/logs"
"net"
"sync"
)
// TCPStorage TCP存储策略
type TCPStorage struct {
BaseStorage
config *serverconfigs.AccessLogTCPStorageConfig
writeLocker sync.Mutex
connLocker sync.Mutex
conn net.Conn
}
func NewTCPStorage(config *serverconfigs.AccessLogTCPStorageConfig) *TCPStorage {
return &TCPStorage{config: config}
}
func (this *TCPStorage) Config() interface{} {
return this.config
}
// Start 开启
func (this *TCPStorage) Start() error {
if len(this.config.Network) == 0 {
return errors.New("'network' should not be empty")
}
if len(this.config.Addr) == 0 {
return errors.New("'addr' should not be empty")
}
return nil
}
// 写入日志
func (this *TCPStorage) Write(accessLogs []*pb.HTTPAccessLog) error {
if len(accessLogs) == 0 {
return nil
}
err := this.connect()
if err != nil {
return err
}
conn := this.conn
if conn == nil {
return errors.New("connection should not be nil")
}
this.writeLocker.Lock()
defer this.writeLocker.Unlock()
for _, accessLog := range accessLogs {
if this.firewallOnly && accessLog.FirewallPolicyId == 0 {
continue
}
data, err := this.Marshal(accessLog)
if err != nil {
logs.Error(err)
continue
}
_, err = conn.Write(data)
if err != nil {
_ = this.Close()
break
}
_, err = conn.Write([]byte("\n"))
if err != nil {
_ = this.Close()
break
}
}
return nil
}
// Close 关闭
func (this *TCPStorage) Close() error {
this.connLocker.Lock()
defer this.connLocker.Unlock()
if this.conn != nil {
err := this.conn.Close()
this.conn = nil
return err
}
return nil
}
func (this *TCPStorage) connect() error {
this.connLocker.Lock()
defer this.connLocker.Unlock()
if this.conn != nil {
return nil
}
conn, err := net.Dial(this.config.Network, this.config.Addr)
if err != nil {
return err
}
this.conn = conn
return nil
}

View File

@@ -1,72 +0,0 @@
package accesslogs
import (
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"net"
"testing"
"time"
)
func TestTCPStorage_Write(t *testing.T) {
go func() {
server, err := net.Listen("tcp", "127.0.0.1:9981")
if err != nil {
t.Error(err)
return
}
for {
conn, err := server.Accept()
if err != nil {
break
}
buf := make([]byte, 1024)
for {
n, err := conn.Read(buf)
if n > 0 {
t.Log(string(buf[:n]))
}
if err != nil {
break
}
}
break
}
_ = server.Close()
}()
storage := NewTCPStorage(&serverconfigs.AccessLogTCPStorageConfig{
Network: "tcp",
Addr: "127.0.0.1:9981",
})
err := storage.Start()
if err != nil {
t.Fatal(err)
}
{
err = storage.Write([]*pb.HTTPAccessLog{
{
RequestMethod: "POST",
RequestPath: "/1",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
},
{
RequestMethod: "GET",
RequestPath: "/2",
TimeLocal: time.Now().Format("2/Jan/2006:15:04:05 -0700"),
},
})
if err != nil {
t.Fatal(err)
}
}
time.Sleep(2 * time.Second)
err = storage.Close()
if err != nil {
t.Fatal(err)
}
}

View File

@@ -1,24 +0,0 @@
<?php
// test command storage
// open access log file
$fp = fopen("/tmp/goedge-command-storage.log", "a+");
// read access logs from stdin
$stdin = fopen("php://stdin", "r");
while(true) {
if (feof($stdin)) {
break;
}
$line = fgets($stdin);
// write to access log file
fwrite($fp, $line);
}
// close file pointers
fclose($fp);
fclose($stdin);
?>

View File

@@ -10,7 +10,7 @@ import (
"github.com/go-acme/lego/v4/challenge/dns01"
"github.com/go-acme/lego/v4/lego"
acmelog "github.com/go-acme/lego/v4/log"
"io/ioutil"
"io"
"log"
"testing"
@@ -50,7 +50,7 @@ func (this *MyProvider) CleanUp(domain, token, keyAuth string) error {
// 参考 https://go-acme.github.io/lego/usage/library/
func TestGenerate(t *testing.T) {
acmelog.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
acmelog.Logger = log.New(io.Discard, "", log.LstdFlags)
// 生成私钥
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
@@ -94,7 +94,7 @@ func TestGenerate(t *testing.T) {
}
func TestGenerate_EAB(t *testing.T) {
acmelog.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
acmelog.Logger = log.New(io.Discard, "", log.LstdFlags)
// 生成私钥
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)

View File

@@ -8,7 +8,7 @@ import (
"github.com/go-acme/lego/v4/lego"
acmelog "github.com/go-acme/lego/v4/log"
"github.com/go-acme/lego/v4/registration"
"io/ioutil"
"io"
"log"
)
@@ -55,7 +55,7 @@ func (this *Request) Run() (certData []byte, keyData []byte, err error) {
func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
if !this.debug {
acmelog.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
acmelog.Logger = log.New(io.Discard, "", log.LstdFlags)
}
if this.task.User == nil {
@@ -138,7 +138,7 @@ func (this *Request) runDNS() (certData []byte, keyData []byte, err error) {
func (this *Request) runHTTP() (certData []byte, keyData []byte, err error) {
if !this.debug {
acmelog.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
acmelog.Logger = log.New(io.Discard, "", log.LstdFlags)
}
if this.task.User == nil {

View File

@@ -4,7 +4,6 @@ import (
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
"github.com/iwind/TeaGo/Tea"
"gopkg.in/yaml.v3"
"io/ioutil"
"os"
"path/filepath"
)
@@ -42,7 +41,7 @@ func SharedAPIConfig() (*APIConfig, error) {
var data []byte
var err error
for _, path := range paths {
data, err = ioutil.ReadFile(path)
data, err = os.ReadFile(path)
if err == nil {
if path == localFile {
isFromLocal = true
@@ -63,7 +62,7 @@ func SharedAPIConfig() (*APIConfig, error) {
if !isFromLocal {
// 恢复文件
_ = ioutil.WriteFile(localFile, data, 0666)
_ = os.WriteFile(localFile, data, 0666)
}
// 恢复数据库文件
@@ -80,9 +79,9 @@ func SharedAPIConfig() (*APIConfig, error) {
for _, path := range paths {
_, err := os.Stat(path)
if err == nil {
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err == nil {
_ = ioutil.WriteFile(dbConfigFile, data, 0666)
_ = os.WriteFile(dbConfigFile, data, 0666)
break
}
}
@@ -122,14 +121,14 @@ func (this *APIConfig) WriteFile(path string) error {
for _, backupDir := range backupDirs {
stat, err := os.Stat(backupDir)
if err == nil && stat.IsDir() {
_ = ioutil.WriteFile(backupDir+"/"+filename, data, 0666)
_ = os.WriteFile(backupDir+"/"+filename, data, 0666)
} else if err != nil && os.IsNotExist(err) {
err = os.Mkdir(backupDir, 0777)
if err == nil {
_ = ioutil.WriteFile(backupDir+"/"+filename, data, 0666)
_ = os.WriteFile(backupDir+"/"+filename, data, 0666)
}
}
}
return ioutil.WriteFile(path, data, 0666)
return os.WriteFile(path, data, 0666)
}

View File

@@ -1,7 +1,7 @@
package teaconst
const (
Version = "0.4.9"
Version = "0.5.0"
ProductName = "Edge API"
ProcessName = "edge-api"
@@ -18,11 +18,11 @@ const (
// 其他节点版本号,用来检测是否有需要升级的节点
NodeVersion = "0.4.9"
UserNodeVersion = "0.3.5"
NodeVersion = "0.5.0"
UserNodeVersion = "0.4.0"
AuthorityNodeVersion = "0.0.2"
MonitorNodeVersion = "0.0.4"
DNSNodeVersion = "0.2.4"
DNSNodeVersion = "0.2.5"
ReportNodeVersion = "0.1.1"
// SQLVersion SQL版本号

View File

@@ -2,9 +2,18 @@
package teaconst
var (
IsPlus = false
MaxNodes int32 = 0
NodeId int64 = 0
Debug = false
import (
"crypto/sha1"
"fmt"
"github.com/iwind/TeaGo/rands"
"github.com/iwind/TeaGo/types"
"time"
)
var (
IsPlus = false
MaxNodes int32 = 0
NodeId int64 = 0
Debug = false
InstanceCode = fmt.Sprintf("%x", sha1.Sum([]byte("INSTANCE"+types.String(time.Now().UnixNano())+"@"+types.String(rands.Int64()))))
)

View File

@@ -0,0 +1,33 @@
package accounts
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
OrderMethodStateEnabled = 1 // 已启用
OrderMethodStateDisabled = 0 // 已禁用
)
type OrderMethodDAO dbs.DAO
func NewOrderMethodDAO() *OrderMethodDAO {
return dbs.NewDAO(&OrderMethodDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeOrderMethods",
Model: new(OrderMethod),
PkName: "id",
},
}).(*OrderMethodDAO)
}
var SharedOrderMethodDAO *OrderMethodDAO
func init() {
dbs.OnReady(func() {
SharedOrderMethodDAO = NewOrderMethodDAO()
})
}

View File

@@ -1,4 +1,4 @@
package nameservers
package accounts_test
import (
_ "github.com/go-sql-driver/mysql"

View File

@@ -0,0 +1,36 @@
package accounts
import "github.com/iwind/TeaGo/dbs"
// OrderMethod 订单支付方式
type OrderMethod struct {
Id uint32 `field:"id"` // ID
Name string `field:"name"` // 名称
IsOn bool `field:"isOn"` // 是否启用
Description string `field:"description"` // 描述
ParentCode string `field:"parentCode"` // 内置的父级代号
Code string `field:"code"` // 代号
Url string `field:"url"` // URL
Secret string `field:"secret"` // 密钥
Params dbs.JSON `field:"params"` // 参数
Order uint32 `field:"order"` // 排序
State uint8 `field:"state"` // 状态
}
type OrderMethodOperator struct {
Id interface{} // ID
Name interface{} // 名称
IsOn interface{} // 是否启用
Description interface{} // 描述
ParentCode interface{} // 内置的父级代号
Code interface{} // 代号
Url interface{} // URL
Secret interface{} // 密钥
Params interface{} // 参数
Order interface{} // 排序
State interface{} // 状态
}
func NewOrderMethodOperator() *OrderMethodOperator {
return &OrderMethodOperator{}
}

View File

@@ -0,0 +1 @@
package accounts

View File

@@ -0,0 +1,33 @@
package accounts
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
UserOrderStateEnabled = 1 // 已启用
UserOrderStateDisabled = 0 // 已禁用
)
type UserOrderDAO dbs.DAO
func NewUserOrderDAO() *UserOrderDAO {
return dbs.NewDAO(&UserOrderDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeUserOrders",
Model: new(UserOrder),
PkName: "id",
},
}).(*UserOrderDAO)
}
var SharedUserOrderDAO *UserOrderDAO
func init() {
dbs.OnReady(func() {
SharedUserOrderDAO = NewUserOrderDAO()
})
}

View File

@@ -1,4 +1,4 @@
package nameservers
package accounts_test
import (
_ "github.com/go-sql-driver/mysql"

View File

@@ -0,0 +1,28 @@
package accounts
import (
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
type UserOrderLogDAO dbs.DAO
func NewUserOrderLogDAO() *UserOrderLogDAO {
return dbs.NewDAO(&UserOrderLogDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeUserOrderLogs",
Model: new(UserOrderLog),
PkName: "id",
},
}).(*UserOrderLogDAO)
}
var SharedUserOrderLogDAO *UserOrderLogDAO
func init() {
dbs.OnReady(func() {
SharedUserOrderLogDAO = NewUserOrderLogDAO()
})
}

View File

@@ -1,4 +1,4 @@
package nameservers
package accounts_test
import (
_ "github.com/go-sql-driver/mysql"

View File

@@ -0,0 +1,28 @@
package accounts
import "github.com/iwind/TeaGo/dbs"
// UserOrderLog 订单日志
type UserOrderLog struct {
Id uint64 `field:"id"` // ID
AdminId uint64 `field:"adminId"` // 管理员ID
UserId uint64 `field:"userId"` // 用户ID
OrderId uint64 `field:"orderId"` // 订单ID
Status string `field:"status"` // 状态
Snapshot dbs.JSON `field:"snapshot"` // 状态快照
CreatedAt uint64 `field:"createdAt"` // 创建时间
}
type UserOrderLogOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
UserId interface{} // 用户ID
OrderId interface{} // 订单ID
Status interface{} // 状态
Snapshot interface{} // 状态快照
CreatedAt interface{} // 创建时间
}
func NewUserOrderLogOperator() *UserOrderLogOperator {
return &UserOrderLogOperator{}
}

View File

@@ -0,0 +1 @@
package accounts

View File

@@ -0,0 +1,40 @@
package accounts
import "github.com/iwind/TeaGo/dbs"
// UserOrder 用户订单
type UserOrder struct {
Id uint64 `field:"id"` // 用户订单
UserId uint64 `field:"userId"` // 用户ID
Code string `field:"code"` // 订单号
Type string `field:"type"` // 订单类型
MethodId uint32 `field:"methodId"` // 支付方式
Status string `field:"status"` // 订单状态
Amount float64 `field:"amount"` // 金额
Params dbs.JSON `field:"params"` // 附加参数
ExpiredAt uint64 `field:"expiredAt"` // 过期时间
CreatedAt uint64 `field:"createdAt"` // 创建时间
CancelledAt uint64 `field:"cancelledAt"` // 取消时间
FinishedAt uint64 `field:"finishedAt"` // 结束时间
State uint8 `field:"state"` // 状态
}
type UserOrderOperator struct {
Id interface{} // 用户订单
UserId interface{} // 用户ID
Code interface{} // 订单号
Type interface{} // 订单类型
MethodId interface{} // 支付方式
Status interface{} // 订单状态
Amount interface{} // 金额
Params interface{} // 附加参数
ExpiredAt interface{} // 过期时间
CreatedAt interface{} // 创建时间
CancelledAt interface{} // 取消时间
FinishedAt interface{} // 结束时间
State interface{} // 状态
}
func NewUserOrderOperator() *UserOrderOperator {
return &UserOrderOperator{}
}

View File

@@ -0,0 +1 @@
package accounts

View File

@@ -29,7 +29,7 @@ func init() {
// 创建认证信息
func (this *ACMEAuthenticationDAO) CreateAuth(tx *dbs.Tx, taskId int64, domain string, token string, key string) error {
op := NewACMEAuthenticationOperator()
var op = NewACMEAuthenticationOperator()
op.TaskId = taskId
op.Domain = domain
op.Token = token

View File

@@ -169,7 +169,7 @@ func (this *ACMETaskDAO) ListEnabledACMETasks(tx *dbs.Tx, adminId int64, userId
// CreateACMETask 创建任务
func (this *ACMETaskDAO) CreateACMETask(tx *dbs.Tx, adminId int64, userId int64, authType acmeutils.AuthType, acmeUserId int64, dnsProviderId int64, dnsDomain string, domains []string, autoRenew bool, authURL string) (int64, error) {
op := NewACMETaskOperator()
var op = NewACMETaskOperator()
op.AdminId = adminId
op.UserId = userId
op.AuthType = authType
@@ -204,7 +204,7 @@ func (this *ACMETaskDAO) UpdateACMETask(tx *dbs.Tx, acmeTaskId int64, acmeUserId
return errors.New("invalid acmeTaskId")
}
op := NewACMETaskOperator()
var op = NewACMETaskOperator()
op.Id = acmeTaskId
op.AcmeUserId = acmeUserId
op.DnsProviderId = dnsProviderId
@@ -240,7 +240,7 @@ func (this *ACMETaskDAO) UpdateACMETaskCert(tx *dbs.Tx, taskId int64, certId int
return errors.New("invalid taskId")
}
op := NewACMETaskOperator()
var op = NewACMETaskOperator()
op.Id = taskId
op.CertId = certId
err := this.Save(tx, op)

View File

@@ -29,7 +29,7 @@ func init() {
// 生成日志
func (this *ACMETaskLogDAO) CreateACMETaskLog(tx *dbs.Tx, taskId int64, isOk bool, errMsg string) error {
op := NewACMETaskLogOperator()
var op = NewACMETaskLogOperator()
op.TaskId = taskId
op.Error = errMsg
op.IsOk = isOk

View File

@@ -83,7 +83,7 @@ func (this *ACMEUserDAO) CreateACMEUser(tx *dbs.Tx, adminId int64, userId int64,
}
privateKeyText := base64.StdEncoding.EncodeToString(privateKeyData)
op := NewACMEUserOperator()
var op = NewACMEUserOperator()
op.AdminId = adminId
op.UserId = userId
op.ProviderCode = providerCode
@@ -104,7 +104,7 @@ func (this *ACMEUserDAO) UpdateACMEUser(tx *dbs.Tx, acmeUserId int64, descriptio
if acmeUserId <= 0 {
return errors.New("invalid acmeUserId")
}
op := NewACMEUserOperator()
var op = NewACMEUserOperator()
op.Id = acmeUserId
op.Description = description
err := this.Save(tx, op)
@@ -116,7 +116,7 @@ func (this *ACMEUserDAO) UpdateACMEUserRegistration(tx *dbs.Tx, acmeUserId int64
if acmeUserId <= 0 {
return errors.New("invalid acmeUserId")
}
op := NewACMEUserOperator()
var op = NewACMEUserOperator()
op.Id = acmeUserId
op.Registration = registrationJSON
err := this.Save(tx, op)

View File

@@ -63,6 +63,19 @@ func (this *AdminDAO) FindEnabledAdmin(tx *dbs.Tx, id int64) (*Admin, error) {
return result.(*Admin), err
}
// FindBasicAdmin 查找管理员基本信息
func (this *AdminDAO) FindBasicAdmin(tx *dbs.Tx, id int64) (*Admin, error) {
result, err := this.Query(tx).
Result("id", "username", "fullname").
Pk(id).
Attr("state", AdminStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*Admin), err
}
// ExistEnabledAdmin 检查管理员是否存在
func (this *AdminDAO) ExistEnabledAdmin(tx *dbs.Tx, adminId int64) (bool, error) {
return this.Query(tx).
@@ -115,7 +128,7 @@ func (this *AdminDAO) UpdateAdminPassword(tx *dbs.Tx, adminId int64, password st
if adminId <= 0 {
return errors.New("invalid adminId")
}
op := NewAdminOperator()
var op = NewAdminOperator()
op.Id = adminId
op.Password = stringutil.Md5(password)
err := this.Save(tx, op)
@@ -124,7 +137,7 @@ func (this *AdminDAO) UpdateAdminPassword(tx *dbs.Tx, adminId int64, password st
// CreateAdmin 创建管理员
func (this *AdminDAO) CreateAdmin(tx *dbs.Tx, username string, canLogin bool, password string, fullname string, isSuper bool, modulesJSON []byte) (int64, error) {
op := NewAdminOperator()
var op = NewAdminOperator()
op.IsOn = true
op.State = AdminStateEnabled
op.Username = username
@@ -149,7 +162,7 @@ func (this *AdminDAO) UpdateAdminInfo(tx *dbs.Tx, adminId int64, fullname string
if adminId <= 0 {
return errors.New("invalid adminId")
}
op := NewAdminOperator()
var op = NewAdminOperator()
op.Id = adminId
op.Fullname = fullname
err := this.Save(tx, op)
@@ -161,7 +174,7 @@ func (this *AdminDAO) UpdateAdmin(tx *dbs.Tx, adminId int64, username string, ca
if adminId <= 0 {
return errors.New("invalid adminId")
}
op := NewAdminOperator()
var op = NewAdminOperator()
op.Id = adminId
op.Fullname = fullname
op.Username = username
@@ -198,7 +211,7 @@ func (this *AdminDAO) UpdateAdminLogin(tx *dbs.Tx, adminId int64, username strin
if adminId <= 0 {
return errors.New("invalid adminId")
}
op := NewAdminOperator()
var op = NewAdminOperator()
op.Id = adminId
op.Username = username
if len(password) > 0 {
@@ -213,7 +226,7 @@ func (this *AdminDAO) UpdateAdminModules(tx *dbs.Tx, adminId int64, allowModules
if adminId <= 0 {
return errors.New("invalid adminId")
}
op := NewAdminOperator()
var op = NewAdminOperator()
op.Id = adminId
op.Modules = allowModulesJSON
err := this.Save(tx, op)

View File

@@ -14,23 +14,23 @@ type Admin struct {
UpdatedAt uint64 `field:"updatedAt"` // 修改时间
State uint8 `field:"state"` // 状态
Modules dbs.JSON `field:"modules"` // 允许的模块
CanLogin uint8 `field:"canLogin"` // 是否可以登录
CanLogin bool `field:"canLogin"` // 是否可以登录
Theme string `field:"theme"` // 模板设置
}
type AdminOperator struct {
Id interface{} // ID
IsOn interface{} // 是否启用
Username interface{} // 用户名
Password interface{} // 密码
Fullname interface{} // 全名
IsSuper interface{} // 是否为超级管理员
CreatedAt interface{} // 创建时间
UpdatedAt interface{} // 修改时间
State interface{} // 状态
Modules interface{} // 允许的模块
CanLogin interface{} // 是否可以登录
Theme interface{} // 模板设置
Id any // ID
IsOn any // 是否启用
Username any // 用户名
Password any // 密码
Fullname any // 全名
IsSuper any // 是否为超级管理员
CreatedAt any // 创建时间
UpdatedAt any // 修改时间
State any // 状态
Modules any // 允许的模块
CanLogin any // 是否可以登录
Theme any // 模板设置
}
func NewAdminOperator() *AdminOperator {

View File

@@ -56,7 +56,7 @@ func (this *APIAccessTokenDAO) GenerateAccessToken(tx *dbs.Tx, adminId int64, us
token = rands.String(128) // TODO 增强安全性,将来使用 base64_encode(encrypt(salt+random)) 算法来代替
expiresAt = time.Now().Unix() + 7200
op := NewAPIAccessTokenOperator()
var op = NewAPIAccessTokenOperator()
if accessToken != nil {
op.Id = accessToken.(*APIAccessToken).Id

View File

@@ -134,7 +134,7 @@ func (this *APINodeDAO) CreateAPINode(tx *dbs.Tx, name string, description strin
return
}
op := NewAPINodeOperator()
var op = NewAPINodeOperator()
op.IsOn = isOn
op.UniqueId = uniqueId
op.Secret = secret

View File

@@ -112,7 +112,7 @@ func (this *ApiTokenDAO) FindEnabledTokenWithRole(tx *dbs.Tx, role string) (*Api
// CreateAPIToken 保存API Token
func (this *ApiTokenDAO) CreateAPIToken(tx *dbs.Tx, nodeId string, secret string, role nodeconfigs.NodeRole) error {
op := NewApiTokenOperator()
var op = NewApiTokenOperator()
op.NodeId = nodeId
op.Secret = secret
op.Role = role

View File

@@ -1,13 +1,9 @@
package authority
import (
"encoding/json"
teaconst "github.com/TeaOSLab/EdgeAPI/internal/const"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
timeutil "github.com/iwind/TeaGo/utils/time"
"time"
)
type AuthorityKeyDAO dbs.DAO
@@ -33,63 +29,3 @@ func init() {
_, _ = SharedAuthorityKeyDAO.IsPlus(nil)
})
}
// UpdateKey 设置Key
func (this *AuthorityKeyDAO) UpdateKey(tx *dbs.Tx, value string, dayFrom string, dayTo string, hostname string, macAddresses []string, company string) error {
one, err := this.Query(tx).
AscPk().
Find()
if err != nil {
return err
}
op := NewAuthorityKeyOperator()
if one != nil {
op.Id = one.(*AuthorityKey).Id
}
op.Value = value
op.DayFrom = dayFrom
op.DayTo = dayTo
op.Hostname = hostname
if len(macAddresses) == 0 {
macAddresses = []string{}
}
macAddressesJSON, err := json.Marshal(macAddresses)
if err != nil {
return err
}
op.MacAddresses = macAddressesJSON
op.Company = company
op.UpdatedAt = time.Now().Unix()
return this.Save(tx, op)
}
// ReadKey 读取Key
func (this *AuthorityKeyDAO) ReadKey(tx *dbs.Tx) (key *AuthorityKey, err error) {
one, err := this.Query(tx).
AscPk().
Find()
if err != nil {
return nil, err
}
if one == nil {
return nil, nil
}
key = one.(*AuthorityKey)
// 顺便更新相关变量
if key.DayTo >= timeutil.Format("Y-m-d") {
teaconst.IsPlus = true
}
return
}
// ResetKey 重置Key
func (this *AuthorityKeyDAO) ResetKey(tx *dbs.Tx) error {
_, err := this.Query(tx).
Delete()
return err
}

View File

@@ -1,23 +0,0 @@
package authority
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"testing"
)
func TestAuthorityKeyDAO_UpdateValue(t *testing.T) {
err := NewAuthorityKeyDAO().UpdateKey(nil, "12345678", "", "", "", []string{}, "")
if err != nil {
t.Fatal(err)
}
t.Log("ok")
}
func TestAuthorityKeyDAO_ReadValue(t *testing.T) {
value, err := NewAuthorityKeyDAO().ReadKey(nil)
if err != nil {
t.Fatal(err)
}
t.Log(value)
}

View File

@@ -120,7 +120,7 @@ func (this *AuthorityNodeDAO) CreateAuthorityNode(tx *dbs.Tx, name string, descr
return
}
op := NewAuthorityNodeOperator()
var op = NewAuthorityNodeOperator()
op.IsOn = isOn
op.UniqueId = uniqueId
op.Secret = secret
@@ -141,7 +141,7 @@ func (this *AuthorityNodeDAO) UpdateAuthorityNode(tx *dbs.Tx, nodeId int64, name
return errors.New("invalid nodeId")
}
op := NewAuthorityNodeOperator()
var op = NewAuthorityNodeOperator()
op.Id = nodeId
op.Name = name
op.Description = description

View File

@@ -125,7 +125,7 @@ func (this *ClientBrowserDAO) CreateBrowser(tx *dbs.Tx, browserName string) (int
return browserId, nil
}
op := NewClientBrowserOperator()
var op = NewClientBrowserOperator()
op.Name = browserName
codes := []string{browserName}
codesJSON, err := json.Marshal(codes)

View File

@@ -125,7 +125,7 @@ func (this *ClientSystemDAO) CreateSystem(tx *dbs.Tx, systemName string) (int64,
return systemId, nil
}
op := NewClientSystemOperator()
var op = NewClientSystemOperator()
op.Name = systemName
codes := []string{systemName}

View File

@@ -109,7 +109,7 @@ func (this *DBNodeDAO) ListEnabledNodes(tx *dbs.Tx, offset int64, size int64) (r
// 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()
var op = NewDBNodeOperator()
op.State = NodeStateEnabled
op.IsOn = isOn
op.Name = name
@@ -132,7 +132,7 @@ func (this *DBNodeDAO) UpdateNode(tx *dbs.Tx, nodeId int64, isOn bool, name stri
if nodeId <= 0 {
return errors.New("invalid nodeId")
}
op := NewDBNodeOperator()
var op = NewDBNodeOperator()
op.Id = nodeId
op.IsOn = isOn
op.Name = name

View File

@@ -91,7 +91,7 @@ func (this *DNSDomainDAO) FindDNSDomainName(tx *dbs.Tx, id int64) (string, error
// CreateDomain 创建域名
func (this *DNSDomainDAO) CreateDomain(tx *dbs.Tx, adminId int64, userId int64, providerId int64, name string) (int64, error) {
op := NewDNSDomainOperator()
var op = NewDNSDomainOperator()
op.ProviderId = providerId
op.AdminId = adminId
op.UserId = userId
@@ -111,7 +111,7 @@ func (this *DNSDomainDAO) UpdateDomain(tx *dbs.Tx, domainId int64, name string,
if domainId <= 0 {
return errors.New("invalid domainId")
}
op := NewDNSDomainOperator()
var op = NewDNSDomainOperator()
op.Id = domainId
op.Name = name
op.IsOn = isOn
@@ -146,7 +146,7 @@ func (this *DNSDomainDAO) UpdateDomainData(tx *dbs.Tx, domainId int64, data stri
if domainId <= 0 {
return errors.New("invalid domainId")
}
op := NewDNSDomainOperator()
var op = NewDNSDomainOperator()
op.Id = domainId
op.Data = data
err := this.Save(tx, op)
@@ -158,7 +158,7 @@ func (this *DNSDomainDAO) UpdateDomainRecords(tx *dbs.Tx, domainId int64, record
if domainId <= 0 {
return errors.New("invalid domainId")
}
op := NewDNSDomainOperator()
var op = NewDNSDomainOperator()
op.Id = domainId
op.Records = recordsJSON
op.DataUpdatedAt = time.Now().Unix()
@@ -171,7 +171,7 @@ func (this *DNSDomainDAO) UpdateDomainRoutes(tx *dbs.Tx, domainId int64, routesJ
if domainId <= 0 {
return errors.New("invalid domainId")
}
op := NewDNSDomainOperator()
var op = NewDNSDomainOperator()
op.Id = domainId
op.Routes = routesJSON
op.DataUpdatedAt = time.Now().Unix()

View File

@@ -68,7 +68,7 @@ func (this *DNSProviderDAO) FindEnabledDNSProvider(tx *dbs.Tx, id int64) (*DNSPr
// CreateDNSProvider 创建服务商
func (this *DNSProviderDAO) CreateDNSProvider(tx *dbs.Tx, adminId int64, userId int64, providerType string, name string, apiParamsJSON []byte) (int64, error) {
op := NewDNSProviderOperator()
var op = NewDNSProviderOperator()
op.AdminId = adminId
op.UserId = userId
op.Type = providerType
@@ -90,7 +90,7 @@ func (this *DNSProviderDAO) UpdateDNSProvider(tx *dbs.Tx, dnsProviderId int64, n
return errors.New("invalid dnsProviderId")
}
op := NewDNSProviderOperator()
var op = NewDNSProviderOperator()
op.Id = dnsProviderId
op.Name = name

View File

@@ -143,7 +143,7 @@ func (this *DNSTaskDAO) UpdateDNSTaskError(tx *dbs.Tx, taskId int64, err string)
if taskId <= 0 {
return errors.New("invalid taskId")
}
op := NewDNSTaskOperator()
var op = NewDNSTaskOperator()
op.Id = taskId
op.IsDone = true
op.Error = err
@@ -156,7 +156,7 @@ func (this *DNSTaskDAO) UpdateDNSTaskDone(tx *dbs.Tx, taskId int64) error {
if taskId <= 0 {
return errors.New("invalid taskId")
}
op := NewDNSTaskOperator()
var op = NewDNSTaskOperator()
op.Id = taskId
op.IsDone = true
op.IsOk = true

View File

@@ -29,9 +29,9 @@ func init() {
})
}
// 创建文件Chunk
// CreateFileChunk 创建文件Chunk
func (this *FileChunkDAO) CreateFileChunk(tx *dbs.Tx, fileId int64, data []byte) (int64, error) {
op := NewFileChunkOperator()
var op = NewFileChunkOperator()
op.FileId = fileId
op.Data = data
err := this.Save(tx, op)
@@ -41,7 +41,7 @@ func (this *FileChunkDAO) CreateFileChunk(tx *dbs.Tx, fileId int64, data []byte)
return types.Int64(op.Id), nil
}
// 列出所有的文件Chunk
// FindAllFileChunks 列出所有的文件Chunk
func (this *FileChunkDAO) FindAllFileChunks(tx *dbs.Tx, fileId int64) (result []*FileChunk, err error) {
_, err = this.Query(tx).
Attr("fileId", fileId).
@@ -51,7 +51,7 @@ func (this *FileChunkDAO) FindAllFileChunks(tx *dbs.Tx, fileId int64) (result []
return
}
// 读取文件的所有片段ID
// FindAllFileChunkIds 读取文件的所有片段ID
func (this *FileChunkDAO) FindAllFileChunkIds(tx *dbs.Tx, fileId int64) ([]int64, error) {
ones, err := this.Query(tx).
Attr("fileId", fileId).
@@ -68,7 +68,7 @@ func (this *FileChunkDAO) FindAllFileChunkIds(tx *dbs.Tx, fileId int64) ([]int64
return result, nil
}
// 删除以前的文件
// DeleteFileChunks 删除以前的文件
func (this *FileChunkDAO) DeleteFileChunks(tx *dbs.Tx, fileId int64) error {
if fileId <= 0 {
return errors.New("invalid fileId")
@@ -79,7 +79,7 @@ func (this *FileChunkDAO) DeleteFileChunks(tx *dbs.Tx, fileId int64) error {
return err
}
// 根据ID查找片段
// FindFileChunk 根据ID查找片段
func (this *FileChunkDAO) FindFileChunk(tx *dbs.Tx, chunkId int64) (*FileChunk, error) {
one, err := this.Query(tx).
Pk(chunkId).

View File

@@ -65,7 +65,7 @@ func (this *FileDAO) FindEnabledFile(tx *dbs.Tx, id int64) (*File, error) {
}
// CreateFile 创建文件
func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, businessType, description string, filename string, size int64, isPublic bool) (int64, error) {
func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, businessType string, description string, filename string, size int64, mimeType string, isPublic bool) (int64, error) {
var op = NewFileOperator()
op.AdminId = adminId
op.UserId = userId
@@ -76,6 +76,7 @@ func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, busines
op.Filename = filename
op.IsPublic = isPublic
op.Code = utils.Sha1RandomString()
op.MimeType = mimeType
err := this.Save(tx, op)
if err != nil {
return 0, err
@@ -84,6 +85,21 @@ func (this *FileDAO) CreateFile(tx *dbs.Tx, adminId int64, userId int64, busines
return types.Int64(op.Id), nil
}
// CheckUserFile 检查用户ID
func (this *FileDAO) CheckUserFile(tx *dbs.Tx, userId int64, fileId int64) error {
b, err := this.Query(tx).
Pk(fileId).
Attr("userId", userId).
Exist()
if err != nil {
return err
}
if !b {
return ErrNotFound
}
return nil
}
// UpdateFileIsFinished 将文件置为已完成
func (this *FileDAO) UpdateFileIsFinished(tx *dbs.Tx, fileId int64) error {
_, err := this.Query(tx).

View File

@@ -9,6 +9,7 @@ type File struct {
Description string `field:"description"` // 文件描述
Filename string `field:"filename"` // 文件名
Size uint32 `field:"size"` // 文件尺寸
MimeType string `field:"mimeType"` // Mime类型
CreatedAt uint64 `field:"createdAt"` // 创建时间
Order uint32 `field:"order"` // 排序
Type string `field:"type"` // 类型
@@ -25,6 +26,7 @@ type FileOperator struct {
Description interface{} // 文件描述
Filename interface{} // 文件名
Size interface{} // 文件尺寸
MimeType interface{} // Mime类型
CreatedAt interface{} // 创建时间
Order interface{} // 排序
Type interface{} // 类型

View File

@@ -93,7 +93,6 @@ func init() {
}
})
})
}
func NewHTTPAccessLogDAO() *HTTPAccessLogDAO {

View File

@@ -87,6 +87,7 @@ func (this *HTTPAccessLogPolicyDAO) CountAllEnabledPolicies(tx *dbs.Tx) (int64,
func (this *HTTPAccessLogPolicyDAO) ListEnabledPolicies(tx *dbs.Tx, offset int64, size int64) (result []*HTTPAccessLogPolicy, err error) {
_, err = this.Query(tx).
State(HTTPAccessLogPolicyStateEnabled).
Desc("isOn").
DescPk().
Offset(offset).
Limit(size).

View File

@@ -69,7 +69,7 @@ func (this *HTTPAuthPolicyDAO) FindEnabledHTTPAuthPolicy(tx *dbs.Tx, id int64) (
// CreateHTTPAuthPolicy 创建策略
func (this *HTTPAuthPolicyDAO) CreateHTTPAuthPolicy(tx *dbs.Tx, name string, methodType string, paramsJSON []byte) (int64, error) {
op := NewHTTPAuthPolicyOperator()
var op = NewHTTPAuthPolicyOperator()
op.Name = name
op.Type = methodType
op.Params = paramsJSON
@@ -83,7 +83,7 @@ func (this *HTTPAuthPolicyDAO) UpdateHTTPAuthPolicy(tx *dbs.Tx, policyId int64,
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPAuthPolicyOperator()
var op = NewHTTPAuthPolicyOperator()
op.Id = policyId
op.Name = name
op.Params = paramsJSON

View File

@@ -113,7 +113,7 @@ func (this *HTTPBrotliPolicyDAO) ComposeBrotliConfig(tx *dbs.Tx, policyId int64)
// CreatePolicy 创建策略
func (this *HTTPBrotliPolicyDAO) CreatePolicy(tx *dbs.Tx, level int, minLengthJSON []byte, maxLengthJSON []byte, condsJSON []byte) (int64, error) {
op := NewHTTPBrotliPolicyOperator()
var op = NewHTTPBrotliPolicyOperator()
op.State = HTTPBrotliPolicyStateEnabled
op.IsOn = true
op.Level = level
@@ -138,7 +138,7 @@ func (this *HTTPBrotliPolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, level
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPBrotliPolicyOperator()
var op = NewHTTPBrotliPolicyOperator()
op.Id = policyId
op.Level = level
if len(minLengthJSON) > 0 {

View File

@@ -97,7 +97,7 @@ func (this *HTTPCachePolicyDAO) FindAllEnabledCachePolicies(tx *dbs.Tx) (result
// CreateCachePolicy 创建缓存策略
func (this *HTTPCachePolicyDAO) CreateCachePolicy(tx *dbs.Tx, isOn bool, name string, description string, capacityJSON []byte, maxKeys int64, maxSizeJSON []byte, storageType string, storageOptionsJSON []byte, syncCompressionCache bool) (int64, error) {
op := NewHTTPCachePolicyOperator()
var op = NewHTTPCachePolicyOperator()
op.State = HTTPCachePolicyStateEnabled
op.IsOn = isOn
op.Name = name
@@ -209,7 +209,7 @@ func (this *HTTPCachePolicyDAO) UpdateCachePolicy(tx *dbs.Tx, policyId int64, is
return errors.New("invalid policyId")
}
op := NewHTTPCachePolicyOperator()
var op = NewHTTPCachePolicyOperator()
op.Id = policyId
op.IsOn = isOn
op.Name = name

View File

@@ -12,23 +12,23 @@ type HTTPCacheTask struct {
Day string `field:"day"` // 创建日期YYYYMMDD
IsDone bool `field:"isDone"` // 是否已完成
IsOk bool `field:"isOk"` // 是否完全成功
IsReady uint8 `field:"isReady"` // 是否已准备好
IsReady bool `field:"isReady"` // 是否已准备好
Description string `field:"description"` // 描述
}
type HTTPCacheTaskOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
Type interface{} // 任务类型purge|fetch
KeyType interface{} // Key类型
State interface{} // 状态
CreatedAt interface{} // 创建时间
DoneAt interface{} // 完成时间
Day interface{} // 创建日期YYYYMMDD
IsDone interface{} // 是否已完成
IsOk interface{} // 是否完全成功
IsReady interface{} // 是否已准备好
Description interface{} // 描述
Id any // ID
UserId any // 用户ID
Type any // 任务类型purge|fetch
KeyType any // Key类型
State any // 状态
CreatedAt any // 创建时间
DoneAt any // 完成时间
Day any // 创建日期YYYYMMDD
IsDone any // 是否已完成
IsOk any // 是否完全成功
IsReady any // 是否已准备好
Description any // 描述
}
func NewHTTPCacheTaskOperator() *HTTPCacheTaskOperator {

View File

@@ -113,7 +113,7 @@ func (this *HTTPDeflatePolicyDAO) ComposeDeflateConfig(tx *dbs.Tx, policyId int6
// CreatePolicy 创建策略
func (this *HTTPDeflatePolicyDAO) CreatePolicy(tx *dbs.Tx, level int, minLengthJSON []byte, maxLengthJSON []byte, condsJSON []byte) (int64, error) {
op := NewHTTPDeflatePolicyOperator()
var op = NewHTTPDeflatePolicyOperator()
op.State = HTTPDeflatePolicyStateEnabled
op.IsOn = true
op.Level = level
@@ -138,7 +138,7 @@ func (this *HTTPDeflatePolicyDAO) UpdatePolicy(tx *dbs.Tx, policyId int64, level
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPDeflatePolicyOperator()
var op = NewHTTPDeflatePolicyOperator()
op.Id = policyId
op.Level = level
if len(minLengthJSON) > 0 {

View File

@@ -121,7 +121,7 @@ func (this *HTTPFastcgiDAO) ComposeFastcgiConfig(tx *dbs.Tx, fastcgiId int64) (*
// CreateFastcgi 创建Fastcgi
func (this *HTTPFastcgiDAO) CreateFastcgi(tx *dbs.Tx, adminId int64, userId int64, isOn bool, address string, paramsJSON []byte, readTimeoutJSON []byte, connTimeoutJSON []byte, poolSize int32, pathInfoPattern string) (int64, error) {
op := NewHTTPFastcgiOperator()
var op = NewHTTPFastcgiOperator()
op.AdminId = adminId
op.UserId = userId
op.IsOn = isOn
@@ -147,7 +147,7 @@ func (this *HTTPFastcgiDAO) UpdateFastcgi(tx *dbs.Tx, fastcgiId int64, isOn bool
if fastcgiId <= 0 {
return errors.New("invalid 'fastcgiId'")
}
op := NewHTTPFastcgiOperator()
var op = NewHTTPFastcgiOperator()
op.Id = fastcgiId
op.IsOn = isOn
op.Address = address

View File

@@ -233,7 +233,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInboundAndOutbound(tx *db
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPFirewallPolicyOperator()
var op = NewHTTPFirewallPolicyOperator()
op.Id = policyId
if len(inboundJSON) > 0 {
op.Inbound = inboundJSON
@@ -262,7 +262,7 @@ func (this *HTTPFirewallPolicyDAO) UpdateFirewallPolicyInbound(tx *dbs.Tx, polic
if policyId <= 0 {
return errors.New("invalid policyId")
}
op := NewHTTPFirewallPolicyOperator()
var op = NewHTTPFirewallPolicyOperator()
op.Id = policyId
if len(inboundJSON) > 0 {
op.Inbound = inboundJSON

View File

@@ -116,7 +116,7 @@ func (this *HTTPFirewallRuleDAO) ComposeFirewallRule(tx *dbs.Tx, ruleId int64) (
// CreateOrUpdateRuleFromConfig 从配置中配置规则
func (this *HTTPFirewallRuleDAO) CreateOrUpdateRuleFromConfig(tx *dbs.Tx, ruleConfig *firewallconfigs.HTTPFirewallRule) (int64, error) {
op := NewHTTPFirewallRuleOperator()
var op = NewHTTPFirewallRuleOperator()
op.Id = ruleConfig.Id
op.State = HTTPFirewallRuleStateEnabled
op.IsOn = ruleConfig.IsOn

View File

@@ -120,7 +120,7 @@ func (this *HTTPFirewallRuleGroupDAO) ComposeFirewallRuleGroup(tx *dbs.Tx, group
// CreateGroupFromConfig 从配置中创建分组
func (this *HTTPFirewallRuleGroupDAO) CreateGroupFromConfig(tx *dbs.Tx, groupConfig *firewallconfigs.HTTPFirewallRuleGroup) (int64, error) {
op := NewHTTPFirewallRuleGroupOperator()
var op = NewHTTPFirewallRuleGroupOperator()
op.IsOn = groupConfig.IsOn
op.Name = groupConfig.Name
op.Description = groupConfig.Description
@@ -166,7 +166,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroupIsOn(tx *dbs.Tx, groupId int64,
// CreateGroup 创建分组
func (this *HTTPFirewallRuleGroupDAO) CreateGroup(tx *dbs.Tx, isOn bool, name string, code string, description string) (int64, error) {
op := NewHTTPFirewallRuleGroupOperator()
var op = NewHTTPFirewallRuleGroupOperator()
op.State = HTTPFirewallRuleStateEnabled
op.IsOn = isOn
op.Name = name
@@ -184,7 +184,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, isO
if groupId <= 0 {
return errors.New("invalid groupId")
}
op := NewHTTPFirewallRuleGroupOperator()
var op = NewHTTPFirewallRuleGroupOperator()
op.Id = groupId
op.IsOn = isOn
op.Name = name
@@ -202,7 +202,7 @@ func (this *HTTPFirewallRuleGroupDAO) UpdateGroupSets(tx *dbs.Tx, groupId int64,
if groupId <= 0 {
return errors.New("invalid groupId")
}
op := NewHTTPFirewallRuleGroupOperator()
var op = NewHTTPFirewallRuleGroupOperator()
op.Id = groupId
op.Sets = setRefsJSON
err := this.Save(tx, op)

View File

@@ -133,7 +133,7 @@ func (this *HTTPFirewallRuleSetDAO) ComposeFirewallRuleSet(tx *dbs.Tx, setId int
// CreateOrUpdateSetFromConfig 从配置中创建规则集
func (this *HTTPFirewallRuleSetDAO) CreateOrUpdateSetFromConfig(tx *dbs.Tx, setConfig *firewallconfigs.HTTPFirewallRuleSet) (int64, error) {
op := NewHTTPFirewallRuleSetOperator()
var op = NewHTTPFirewallRuleSetOperator()
op.State = HTTPFirewallRuleSetStateEnabled
op.Id = setConfig.Id
op.IsOn = setConfig.IsOn

View File

@@ -121,7 +121,7 @@ func (this *HTTPGzipDAO) ComposeGzipConfig(tx *dbs.Tx, gzipId int64) (*servercon
// CreateGzip 创建Gzip
func (this *HTTPGzipDAO) CreateGzip(tx *dbs.Tx, level int, minLengthJSON []byte, maxLengthJSON []byte, condsJSON []byte) (int64, error) {
op := NewHTTPGzipOperator()
var op = NewHTTPGzipOperator()
op.State = HTTPGzipStateEnabled
op.IsOn = true
op.Level = level
@@ -146,7 +146,7 @@ func (this *HTTPGzipDAO) UpdateGzip(tx *dbs.Tx, gzipId int64, level int, minLeng
if gzipId <= 0 {
return errors.New("invalid gzipId")
}
op := NewHTTPGzipOperator()
var op = NewHTTPGzipOperator()
op.Id = gzipId
op.Level = level
if len(minLengthJSON) > 0 {

View File

@@ -81,7 +81,7 @@ func (this *HTTPHeaderDAO) FindHTTPHeaderName(tx *dbs.Tx, id int64) (string, err
// CreateHeader 创建Header
func (this *HTTPHeaderDAO) CreateHeader(tx *dbs.Tx, userId int64, name string, value string, status []int, disableRedirect bool, shouldAppend bool, shouldReplace bool, replaceValues []*shared.HTTPHeaderReplaceValue, methods []string, domains []string) (int64, error) {
op := NewHTTPHeaderOperator()
var op = NewHTTPHeaderOperator()
op.UserId = userId
op.State = HTTPHeaderStateEnabled
op.IsOn = true
@@ -156,7 +156,7 @@ func (this *HTTPHeaderDAO) UpdateHeader(tx *dbs.Tx, headerId int64, name string,
return errors.New("invalid headerId")
}
op := NewHTTPHeaderOperator()
var op = NewHTTPHeaderOperator()
op.Id = headerId
op.Name = name
op.Value = value

View File

@@ -77,7 +77,7 @@ func (this *HTTPHeaderPolicyDAO) FindEnabledHTTPHeaderPolicy(tx *dbs.Tx, id int6
// CreateHeaderPolicy 创建策略
func (this *HTTPHeaderPolicyDAO) CreateHeaderPolicy(tx *dbs.Tx) (int64, error) {
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.IsOn = true
op.State = HTTPHeaderPolicyStateEnabled
err := this.Save(tx, op)
@@ -93,7 +93,7 @@ func (this *HTTPHeaderPolicyDAO) UpdateAddingHeaders(tx *dbs.Tx, policyId int64,
return errors.New("invalid policyId")
}
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.Id = policyId
op.AddHeaders = headersJSON
err := this.Save(tx, op)
@@ -109,7 +109,7 @@ func (this *HTTPHeaderPolicyDAO) UpdateSettingHeaders(tx *dbs.Tx, policyId int64
return errors.New("invalid policyId")
}
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.Id = policyId
op.SetHeaders = headersJSON
err := this.Save(tx, op)
@@ -125,7 +125,7 @@ func (this *HTTPHeaderPolicyDAO) UpdateReplacingHeaders(tx *dbs.Tx, policyId int
return errors.New("invalid policyId")
}
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.Id = policyId
op.ReplaceHeaders = headersJSON
err := this.Save(tx, op)
@@ -141,7 +141,7 @@ func (this *HTTPHeaderPolicyDAO) UpdateAddingTrailers(tx *dbs.Tx, policyId int64
return errors.New("invalid policyId")
}
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.Id = policyId
op.AddTrailers = headersJSON
err := this.Save(tx, op)
@@ -162,7 +162,7 @@ func (this *HTTPHeaderPolicyDAO) UpdateDeletingHeaders(tx *dbs.Tx, policyId int6
return err
}
op := NewHTTPHeaderPolicyOperator()
var op = NewHTTPHeaderPolicyOperator()
op.Id = policyId
op.DeleteHeaders = string(namesJSON)
err = this.Save(tx, op)

View File

@@ -87,7 +87,7 @@ func (this *HTTPLocationDAO) FindHTTPLocationName(tx *dbs.Tx, id int64) (string,
// CreateLocation 创建路由规则
func (this *HTTPLocationDAO) CreateLocation(tx *dbs.Tx, parentId int64, name string, pattern string, description string, isBreak bool, condsJSON []byte, domains []string) (int64, error) {
op := NewHTTPLocationOperator()
var op = NewHTTPLocationOperator()
op.IsOn = true
op.State = HTTPLocationStateEnabled
op.ParentId = parentId
@@ -121,7 +121,7 @@ func (this *HTTPLocationDAO) UpdateLocation(tx *dbs.Tx, locationId int64, name s
if locationId <= 0 {
return errors.New("invalid locationId")
}
op := NewHTTPLocationOperator()
var op = NewHTTPLocationOperator()
op.Id = locationId
op.Name = name
op.Pattern = pattern
@@ -257,7 +257,7 @@ func (this *HTTPLocationDAO) UpdateLocationReverseProxy(tx *dbs.Tx, locationId i
if locationId <= 0 {
return errors.New("invalid locationId")
}
op := NewHTTPLocationOperator()
var op = NewHTTPLocationOperator()
op.Id = locationId
op.ReverseProxy = JSONBytes(reverseProxyJSON)
err := this.Save(tx, op)
@@ -281,7 +281,7 @@ func (this *HTTPLocationDAO) UpdateLocationWeb(tx *dbs.Tx, locationId int64, web
if locationId <= 0 {
return errors.New("invalid locationId")
}
op := NewHTTPLocationOperator()
var op = NewHTTPLocationOperator()
op.Id = locationId
op.WebId = webId
err := this.Save(tx, op)

View File

@@ -78,7 +78,7 @@ func (this *HTTPPageDAO) FindEnabledHTTPPage(tx *dbs.Tx, id int64) (*HTTPPage, e
// 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) {
op := NewHTTPPageOperator()
var op = NewHTTPPageOperator()
op.UserId = userId
op.IsOn = true
op.State = HTTPPageStateEnabled
@@ -108,7 +108,7 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin
return errors.New("invalid pageId")
}
op := NewHTTPPageOperator()
var op = NewHTTPPageOperator()
op.Id = pageId
op.IsOn = true
op.State = HTTPPageStateEnabled

View File

@@ -125,7 +125,7 @@ func (this *HTTPRewriteRuleDAO) ComposeRewriteRule(tx *dbs.Tx, rewriteRuleId int
// CreateRewriteRule 创建规则
func (this *HTTPRewriteRuleDAO) CreateRewriteRule(tx *dbs.Tx, pattern string, replace string, mode string, redirectStatus int, isBreak bool, proxyHost string, withQuery bool, isOn bool, condsJSON []byte) (int64, error) {
op := NewHTTPRewriteRuleOperator()
var op = NewHTTPRewriteRuleOperator()
op.State = HTTPRewriteRuleStateEnabled
op.IsOn = isOn
@@ -150,7 +150,7 @@ func (this *HTTPRewriteRuleDAO) UpdateRewriteRule(tx *dbs.Tx, rewriteRuleId int6
if rewriteRuleId <= 0 {
return errors.New("invalid rewriteRuleId")
}
op := NewHTTPRewriteRuleOperator()
var op = NewHTTPRewriteRuleOperator()
op.Id = rewriteRuleId
op.IsOn = isOn
op.Pattern = pattern

View File

@@ -466,7 +466,7 @@ func (this *HTTPWebDAO) ComposeWebConfig(tx *dbs.Tx, webId int64, cacheMap *util
// CreateWeb 创建Web配置
func (this *HTTPWebDAO) CreateWeb(tx *dbs.Tx, adminId int64, userId int64, rootJSON []byte) (int64, error) {
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.State = HTTPWebStateEnabled
op.AdminId = adminId
op.UserId = userId
@@ -485,7 +485,7 @@ func (this *HTTPWebDAO) UpdateWeb(tx *dbs.Tx, webId int64, rootJSON []byte) erro
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Root = JSONBytes(rootJSON)
err := this.Save(tx, op)
@@ -501,7 +501,7 @@ func (this *HTTPWebDAO) UpdateWebCompression(tx *dbs.Tx, webId int64, compressio
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Compression = JSONBytes(compressionConfig)
err := this.Save(tx, op)
@@ -517,7 +517,7 @@ func (this *HTTPWebDAO) UpdateWebWebP(tx *dbs.Tx, webId int64, webpConfig []byte
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Webp = JSONBytes(webpConfig)
err := this.Save(tx, op)
@@ -548,7 +548,7 @@ func (this *HTTPWebDAO) UpdateWebCharset(tx *dbs.Tx, webId int64, charsetJSON []
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Charset = JSONBytes(charsetJSON)
err := this.Save(tx, op)
@@ -564,7 +564,7 @@ func (this *HTTPWebDAO) UpdateWebRequestHeaderPolicy(tx *dbs.Tx, webId int64, he
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.RequestHeader = JSONBytes(headerPolicyJSON)
err := this.Save(tx, op)
@@ -580,7 +580,7 @@ func (this *HTTPWebDAO) UpdateWebResponseHeaderPolicy(tx *dbs.Tx, webId int64, h
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.ResponseHeader = JSONBytes(headerPolicyJSON)
err := this.Save(tx, op)
@@ -596,7 +596,7 @@ func (this *HTTPWebDAO) UpdateWebPages(tx *dbs.Tx, webId int64, pagesJSON []byte
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Pages = JSONBytes(pagesJSON)
err := this.Save(tx, op)
@@ -612,7 +612,7 @@ func (this *HTTPWebDAO) UpdateWebShutdown(tx *dbs.Tx, webId int64, shutdownJSON
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Shutdown = JSONBytes(shutdownJSON)
err := this.Save(tx, op)
@@ -628,7 +628,7 @@ func (this *HTTPWebDAO) UpdateWebAccessLogConfig(tx *dbs.Tx, webId int64, access
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.AccessLog = JSONBytes(accessLogJSON)
err := this.Save(tx, op)
@@ -644,7 +644,7 @@ func (this *HTTPWebDAO) UpdateWebStat(tx *dbs.Tx, webId int64, statJSON []byte)
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Stat = JSONBytes(statJSON)
err := this.Save(tx, op)
@@ -660,7 +660,7 @@ func (this *HTTPWebDAO) UpdateWebCache(tx *dbs.Tx, webId int64, cacheJSON []byte
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Cache = JSONBytes(cacheJSON)
err := this.Save(tx, op)
@@ -676,7 +676,7 @@ func (this *HTTPWebDAO) UpdateWebFirewall(tx *dbs.Tx, webId int64, firewallJSON
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Firewall = JSONBytes(firewallJSON)
err := this.Save(tx, op)
@@ -692,7 +692,7 @@ func (this *HTTPWebDAO) UpdateWebLocations(tx *dbs.Tx, webId int64, locationsJSO
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Locations = JSONBytes(locationsJSON)
err := this.Save(tx, op)
@@ -708,7 +708,7 @@ func (this *HTTPWebDAO) UpdateWebRedirectToHTTPS(tx *dbs.Tx, webId int64, redire
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.RedirectToHttps = JSONBytes(redirectToHTTPSJSON)
err := this.Save(tx, op)
@@ -724,7 +724,7 @@ func (this *HTTPWebDAO) UpdateWebsocket(tx *dbs.Tx, webId int64, websocketJSON [
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Websocket = JSONBytes(websocketJSON)
err := this.Save(tx, op)
@@ -740,7 +740,7 @@ func (this *HTTPWebDAO) UpdateWebFastcgi(tx *dbs.Tx, webId int64, fastcgiJSON []
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Fastcgi = JSONBytes(fastcgiJSON)
err := this.Save(tx, op)
@@ -756,7 +756,7 @@ func (this *HTTPWebDAO) UpdateWebRewriteRules(tx *dbs.Tx, webId int64, rewriteRu
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.RewriteRules = JSONBytes(rewriteRulesJSON)
err := this.Save(tx, op)
@@ -772,7 +772,7 @@ func (this *HTTPWebDAO) UpdateWebAuth(tx *dbs.Tx, webId int64, authJSON []byte)
if webId <= 0 {
return errors.New("invalid webId")
}
op := NewHTTPWebOperator()
var op = NewHTTPWebOperator()
op.Id = webId
op.Auth = JSONBytes(authJSON)
err := this.Save(tx, op)

View File

@@ -110,7 +110,7 @@ func (this *HTTPWebsocketDAO) ComposeWebsocketConfig(tx *dbs.Tx, websocketId int
// CreateWebsocket 创建Websocket配置
func (this *HTTPWebsocketDAO) CreateWebsocket(tx *dbs.Tx, handshakeTimeoutJSON []byte, allowAllOrigins bool, allowedOrigins []string, requestSameOrigin bool, requestOrigin string) (websocketId int64, err error) {
op := NewHTTPWebsocketOperator()
var op = NewHTTPWebsocketOperator()
op.IsOn = true
op.State = HTTPWebsocketStateEnabled
if len(handshakeTimeoutJSON) > 0 {
@@ -135,7 +135,7 @@ func (this *HTTPWebsocketDAO) UpdateWebsocket(tx *dbs.Tx, websocketId int64, han
if websocketId <= 0 {
return errors.New("invalid websocketId")
}
op := NewHTTPWebsocketOperator()
var op = NewHTTPWebsocketOperator()
op.Id = websocketId
if len(handshakeTimeoutJSON) > 0 {
op.HandshakeTimeout = handshakeTimeoutJSON

View File

@@ -330,7 +330,7 @@ func (this *IPItemDAO) UpdateIPItem(tx *dbs.Tx, itemId int64, ipFrom string, ipT
return err
}
op := NewIPItemOperator()
var op = NewIPItemOperator()
op.Id = itemId
op.IpFrom = ipFrom
op.IpTo = ipTo

View File

@@ -33,7 +33,7 @@ func init() {
})
}
// 启用条目
// EnableIPLibrary 启用条目
func (this *IPLibraryDAO) EnableIPLibrary(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -42,7 +42,7 @@ func (this *IPLibraryDAO) EnableIPLibrary(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableIPLibrary 禁用条目
func (this *IPLibraryDAO) DisableIPLibrary(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -51,7 +51,7 @@ func (this *IPLibraryDAO) DisableIPLibrary(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledIPLibrary 查找启用中的条目
func (this *IPLibraryDAO) FindEnabledIPLibrary(tx *dbs.Tx, id int64) (*IPLibrary, error) {
result, err := this.Query(tx).
Pk(id).
@@ -63,7 +63,7 @@ func (this *IPLibraryDAO) FindEnabledIPLibrary(tx *dbs.Tx, id int64) (*IPLibrary
return result.(*IPLibrary), err
}
// 查找某个类型的IP库列表
// FindAllEnabledIPLibrariesWithType 查找某个类型的IP库列表
func (this *IPLibraryDAO) FindAllEnabledIPLibrariesWithType(tx *dbs.Tx, libraryType string) (result []*IPLibrary, err error) {
_, err = this.Query(tx).
State(IPLibraryStateEnabled).
@@ -74,7 +74,7 @@ func (this *IPLibraryDAO) FindAllEnabledIPLibrariesWithType(tx *dbs.Tx, libraryT
return
}
// 查找某个类型的最新的IP库
// FindLatestIPLibraryWithType 查找某个类型的最新的IP库
func (this *IPLibraryDAO) FindLatestIPLibraryWithType(tx *dbs.Tx, libraryType string) (*IPLibrary, error) {
one, err := this.Query(tx).
State(IPLibraryStateEnabled).
@@ -90,9 +90,9 @@ func (this *IPLibraryDAO) FindLatestIPLibraryWithType(tx *dbs.Tx, libraryType st
return one.(*IPLibrary), nil
}
// 创建新的IP库
// CreateIPLibrary 创建新的IP库
func (this *IPLibraryDAO) CreateIPLibrary(tx *dbs.Tx, libraryType string, fileId int64) (int64, error) {
op := NewIPLibraryOperator()
var op = NewIPLibraryOperator()
op.Type = libraryType
op.FileId = fileId
op.State = IPLibraryStateEnabled

View File

@@ -0,0 +1,572 @@
package models
import (
"encoding/json"
"errors"
"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
"github.com/TeaOSLab/EdgeAPI/internal/utils"
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
"github.com/iwind/TeaGo/types"
"io"
"os"
"time"
)
const (
IPLibraryFileStateEnabled = 1 // 已启用
IPLibraryFileStateDisabled = 0 // 已禁用
)
type IPLibraryFileDAO dbs.DAO
func NewIPLibraryFileDAO() *IPLibraryFileDAO {
return dbs.NewDAO(&IPLibraryFileDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeIPLibraryFiles",
Model: new(IPLibraryFile),
PkName: "id",
},
}).(*IPLibraryFileDAO)
}
var SharedIPLibraryFileDAO *IPLibraryFileDAO
func init() {
dbs.OnReady(func() {
SharedIPLibraryFileDAO = NewIPLibraryFileDAO()
})
}
// EnableIPLibraryFile 启用条目
func (this *IPLibraryFileDAO) EnableIPLibraryFile(tx *dbs.Tx, id uint64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", IPLibraryFileStateEnabled).
Update()
return err
}
// DisableIPLibraryFile 禁用条目
func (this *IPLibraryFileDAO) DisableIPLibraryFile(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
Set("state", IPLibraryFileStateDisabled).
Update()
return err
}
// FindEnabledIPLibraryFile 查找启用中的条目
func (this *IPLibraryFileDAO) FindEnabledIPLibraryFile(tx *dbs.Tx, id int64) (*IPLibraryFile, error) {
result, err := this.Query(tx).
Pk(id).
State(IPLibraryFileStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*IPLibraryFile), err
}
// CreateLibraryFile 创建文件
func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
var op = NewIPLibraryFileOperator()
op.Template = template
if emptyValues == nil {
emptyValues = []string{}
}
emptyValuesJSON, err := json.Marshal(emptyValues)
if err != nil {
return 0, err
}
op.EmptyValues = emptyValuesJSON
op.FileId = fileId
if countries == nil {
countries = []string{}
}
countriesJSON, err := json.Marshal(countries)
if err != nil {
return 0, err
}
op.Countries = countriesJSON
if provinces == nil {
provinces = [][2]string{}
}
provincesJSON, err := json.Marshal(provinces)
if err != nil {
return 0, err
}
op.Provinces = provincesJSON
if cities == nil {
cities = [][3]string{}
}
citiesJSON, err := json.Marshal(cities)
if err != nil {
return 0, err
}
op.Cities = citiesJSON
if towns == nil {
towns = [][4]string{}
}
townsJSON, err := json.Marshal(towns)
if err != nil {
return 0, err
}
op.Towns = townsJSON
if providers == nil {
providers = []string{}
}
providersJSON, err := json.Marshal(providers)
if err != nil {
return 0, err
}
op.Providers = providersJSON
op.IsFinished = false
op.State = IPLibraryFileStateEnabled
return this.SaveInt64(tx, op)
}
// FindAllUnfinishedLibraryFiles 查找所有未完成的文件
func (this *IPLibraryFileDAO) FindAllUnfinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
_, err = this.Query(tx).
State(IPLibraryFileStateEnabled).
Result("id", "fileId", "createdAt"). // 这里不需要其他信息
Attr("isFinished", false).
DescPk().
Slice(&result).
FindAll()
return
}
// UpdateLibraryFileIsFinished 设置文件为已完成
func (this *IPLibraryFileDAO) UpdateLibraryFileIsFinished(tx *dbs.Tx, fileId int64) error {
return this.Query(tx).
Pk(fileId).
Set("isFinished", true).
UpdateQuickly()
}
// FindLibraryFileCountries 获取IP库中的国家/地区
func (this *IPLibraryFileDAO) FindLibraryFileCountries(tx *dbs.Tx, fileId int64) ([]string, error) {
countriesJSON, err := this.Query(tx).
Result("countries").
Pk(fileId).
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(countriesJSON) {
return nil, nil
}
var result = []string{}
err = json.Unmarshal(countriesJSON, &result)
if err != nil {
return nil, err
}
return result, nil
}
// FindLibraryFileProvinces 获取IP库中的省份
func (this *IPLibraryFileDAO) FindLibraryFileProvinces(tx *dbs.Tx, fileId int64) ([][2]string, error) {
provincesJSON, err := this.Query(tx).
Result("provinces").
Pk(fileId).
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(provincesJSON) {
return nil, nil
}
var result = [][2]string{}
err = json.Unmarshal(provincesJSON, &result)
if err != nil {
return nil, err
}
return result, nil
}
// FindLibraryFileCities 获取IP库中的城市
func (this *IPLibraryFileDAO) FindLibraryFileCities(tx *dbs.Tx, fileId int64) ([][3]string, error) {
citiesJSON, err := this.Query(tx).
Result("cities").
Pk(fileId).
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(citiesJSON) {
return nil, nil
}
var result = [][3]string{}
err = json.Unmarshal(citiesJSON, &result)
if err != nil {
return nil, err
}
return result, nil
}
// FindLibraryFileTowns 获取IP库中的区县
func (this *IPLibraryFileDAO) FindLibraryFileTowns(tx *dbs.Tx, fileId int64) ([][4]string, error) {
townsJSON, err := this.Query(tx).
Result("towns").
Pk(fileId).
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(townsJSON) {
return nil, nil
}
var result = [][4]string{}
err = json.Unmarshal(townsJSON, &result)
if err != nil {
return nil, err
}
return result, nil
}
// FindLibraryFileProviders 获取IP库中的ISP运营商
func (this *IPLibraryFileDAO) FindLibraryFileProviders(tx *dbs.Tx, fileId int64) ([]string, error) {
providersJSON, err := this.Query(tx).
Result("providers").
Pk(fileId).
FindJSONCol()
if err != nil {
return nil, err
}
if IsNull(providersJSON) {
return nil, nil
}
var result = []string{}
err = json.Unmarshal(providersJSON, &result)
if err != nil {
return nil, err
}
return result, nil
}
func (this *IPLibraryFileDAO) GenerateIPLibrary(tx *dbs.Tx, libraryFileId int64) error {
one, err := this.Query(tx).Pk(libraryFileId).Find()
if err != nil {
return err
}
if one == nil {
return errors.New("the library file not found")
}
var libraryFile = one.(*IPLibraryFile)
template, err := iplibrary.NewTemplate(libraryFile.Template)
if err != nil {
return errors.New("create template from '" + libraryFile.Template + "' failed: " + err.Error())
}
var fileId = int64(libraryFile.FileId)
if fileId == 0 {
return errors.New("the library file has not been uploaded yet")
}
var dir = Tea.Root + "/data"
stat, err := os.Stat(dir)
if err != nil {
if os.IsNotExist(err) {
err = os.Mkdir(dir, 0777)
if err != nil {
return errors.New("can not open dir '" + dir + "' to write: " + err.Error())
}
} else {
return errors.New("can not open dir '" + dir + "' to write: " + err.Error())
}
} else if !stat.IsDir() {
_ = os.Remove(dir)
err = os.Mkdir(dir, 0777)
if err != nil {
return errors.New("can not open dir '" + dir + "' to write: " + err.Error())
}
}
// TODO 删除以往生成的文件,但要考虑到文件正在被别的任务所使用
// 国家
dbCountries, err := regions.SharedRegionCountryDAO.FindAllCountries(tx)
if err != nil {
return err
}
var countries = []*iplibrary.Country{}
for _, country := range dbCountries {
countries = append(countries, &iplibrary.Country{
Id: int64(country.Id),
Name: country.DisplayName(),
Codes: country.AllCodes(),
})
}
// 省份
dbProvinces, err := regions.SharedRegionProvinceDAO.FindAllEnabledProvinces(tx)
if err != nil {
return err
}
var provinces = []*iplibrary.Province{}
for _, province := range dbProvinces {
provinces = append(provinces, &iplibrary.Province{
Id: int64(province.Id),
Name: province.DisplayName(),
Codes: province.AllCodes(),
})
}
// 城市
dbCities, err := regions.SharedRegionCityDAO.FindAllEnabledCities(tx)
if err != nil {
return err
}
var cities = []*iplibrary.City{}
for _, city := range dbCities {
cities = append(cities, &iplibrary.City{
Id: int64(city.Id),
Name: city.DisplayName(),
Codes: city.AllCodes(),
})
}
// 区县
dbTowns, err := regions.SharedRegionTownDAO.FindAllRegionTowns(tx)
if err != nil {
return err
}
var towns = []*iplibrary.Town{}
for _, town := range dbTowns {
towns = append(towns, &iplibrary.Town{
Id: int64(town.Id),
Name: town.DisplayName(),
Codes: town.AllCodes(),
})
}
// ISP运营商
dbProviders, err := regions.SharedRegionProviderDAO.FindAllEnabledProviders(tx)
if err != nil {
return err
}
var providers = []*iplibrary.Provider{}
for _, provider := range dbProviders {
providers = append(providers, &iplibrary.Provider{
Id: int64(provider.Id),
Name: provider.DisplayName(),
Codes: provider.AllCodes(),
})
}
var libraryCode = utils.Sha1RandomString() // 每次都生成新的code
var filePath = dir + "/" + this.composeFilename(libraryFileId, libraryCode)
writer, err := iplibrary.NewFileWriter(filePath, &iplibrary.Meta{
Author: "", // 将来用户可以自行填写
CreatedAt: time.Now().Unix(),
Countries: countries,
Provinces: provinces,
Cities: cities,
Towns: towns,
Providers: providers,
})
if err != nil {
return err
}
defer func() {
_ = writer.Close()
}()
err = writer.WriteMeta()
if err != nil {
return errors.New("write meta failed: " + err.Error())
}
chunkIds, err := SharedFileChunkDAO.FindAllFileChunkIds(tx, fileId)
if err != nil {
return err
}
// countries etc ...
var countryMap = map[string]int64{} // countryName => countryId
for _, country := range dbCountries {
for _, code := range country.AllCodes() {
countryMap[code] = int64(country.Id)
}
}
var provinceMap = map[string]int64{} // countryId_provinceName => provinceId
for _, province := range dbProvinces {
for _, code := range province.AllCodes() {
provinceMap[types.String(province.CountryId)+"_"+code] = int64(province.Id)
}
}
var cityMap = map[string]int64{} // provinceId_cityName => cityId
for _, city := range dbCities {
for _, code := range city.AllCodes() {
cityMap[types.String(city.ProvinceId)+"_"+code] = int64(city.Id)
}
}
var townMap = map[string]int64{} // cityId_townName => townId
for _, town := range dbTowns {
for _, code := range town.AllCodes() {
townMap[types.String(town.CityId)+"_"+code] = int64(town.Id)
}
}
var providerMap = map[string]int64{} // providerName => providerId
for _, provider := range dbProviders {
for _, code := range provider.AllCodes() {
providerMap[code] = int64(provider.Id)
}
}
dataParser, err := iplibrary.NewParser(&iplibrary.ParserConfig{
Template: template,
EmptyValues: libraryFile.DecodeEmptyValues(),
Iterator: func(values map[string]string) error {
var ipFrom = values["ipFrom"]
var ipTo = values["ipTo"]
var countryName = values["country"]
var provinceName = values["province"]
var cityName = values["city"]
var townName = values["town"]
var providerName = values["provider"]
var countryId = countryMap[countryName]
var provinceId int64
var cityId int64 = 0
var townId int64 = 0
var providerId = providerMap[providerName]
if countryId > 0 {
provinceId = provinceMap[types.String(countryId)+"_"+provinceName]
if provinceId > 0 {
cityId = cityMap[types.String(provinceId)+"_"+cityName]
if cityId > 0 {
townId = townMap[types.String(cityId)+"_"+townName]
}
}
}
err = writer.Write(ipFrom, ipTo, countryId, provinceId, cityId, townId, providerId)
if err != nil {
return errors.New("write failed: " + err.Error())
}
return nil
},
})
if err != nil {
return err
}
for _, chunkId := range chunkIds {
chunk, err := SharedFileChunkDAO.FindFileChunk(tx, chunkId)
if err != nil {
return err
}
if chunk == nil {
return errors.New("invalid chunk file, please upload again")
}
dataParser.Write(chunk.Data)
err = dataParser.Parse()
if err != nil {
return err
}
}
err = writer.Close()
if err != nil {
return err
}
// 将生成的内容写入到文件
stat, err = os.Stat(filePath)
if err != nil {
return errors.New("stat generated file failed: " + err.Error())
}
generatedFileId, err := SharedFileDAO.CreateFile(tx, 0, 0, "ipLibraryFile", "", libraryCode+".db", stat.Size(), "", false)
if err != nil {
return err
}
fp, err := os.Open(filePath)
if err != nil {
return errors.New("open generated file failed: " + err.Error())
}
var buf = make([]byte, 256*1024)
for {
n, err := fp.Read(buf)
if n > 0 {
_, err = SharedFileChunkDAO.CreateFileChunk(tx, generatedFileId, buf[:n])
if err != nil {
return err
}
}
if err != nil {
if err != io.EOF {
return err
}
break
}
}
err = SharedFileDAO.UpdateFileIsFinished(tx, generatedFileId)
if err != nil {
return err
}
// 设置code
err = this.Query(tx).
Pk(libraryFileId).
Set("code", libraryCode).
Set("isFinished", true).
Set("generatedFileId", generatedFileId).
Set("generatedAt", time.Now().Unix()).
UpdateQuickly()
if err != nil {
return err
}
return nil
}
// 组合IP库文件名
func (this *IPLibraryFileDAO) composeFilename(libraryFileId int64, code string) string {
return "ip-library-" + types.String(libraryFileId) + "-" + code + ".db"
}

View File

@@ -0,0 +1,19 @@
package models_test
import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
_ "github.com/go-sql-driver/mysql"
_ "github.com/iwind/TeaGo/bootstrap"
"github.com/iwind/TeaGo/dbs"
"testing"
)
func TestIPLibraryFileDAO_GenerateIPLibrary(t *testing.T) {
dbs.NotifyReady()
var tx *dbs.Tx
err := models.SharedIPLibraryFileDAO.GenerateIPLibrary(tx, 3)
if err != nil {
t.Fatal(err)
}
}

View File

@@ -0,0 +1,44 @@
package models
import "github.com/iwind/TeaGo/dbs"
// IPLibraryFile IP库上传的文件
type IPLibraryFile struct {
Id uint64 `field:"id"` // ID
FileId uint64 `field:"fileId"` // 原始文件ID
Template string `field:"template"` // 模板
EmptyValues dbs.JSON `field:"emptyValues"` // 空值列表
GeneratedFileId uint64 `field:"generatedFileId"` // 生成的文件ID
GeneratedAt uint64 `field:"generatedAt"` // 生成时间
IsFinished bool `field:"isFinished"` // 是否已经完成
Countries dbs.JSON `field:"countries"` // 国家/地区
Provinces dbs.JSON `field:"provinces"` // 省份
Cities dbs.JSON `field:"cities"` // 城市
Towns dbs.JSON `field:"towns"` // 区县
Providers dbs.JSON `field:"providers"` // ISP服务商
Code string `field:"code"` // 文件代号
CreatedAt uint64 `field:"createdAt"` // 上传时间
State uint8 `field:"state"` // 状态
}
type IPLibraryFileOperator struct {
Id any // ID
FileId any // 原始文件ID
Template any // 模板
EmptyValues any // 空值列表
GeneratedFileId any // 生成的文件ID
GeneratedAt any // 生成时间
IsFinished any // 是否已经完成
Countries any // 国家/地区
Provinces any // 省份
Cities any // 城市
Towns any // 区县
Providers any // ISP服务商
Code any // 文件代号
CreatedAt any // 上传时间
State any // 状态
}
func NewIPLibraryFileOperator() *IPLibraryFileOperator {
return &IPLibraryFileOperator{}
}

View File

@@ -0,0 +1,69 @@
package models
import "encoding/json"
func (this *IPLibraryFile) DecodeCountries() []string {
var countries = []string{}
if IsNotNull(this.Countries) {
err := json.Unmarshal(this.Countries, &countries)
if err != nil {
// ignore error
}
}
return countries
}
func (this *IPLibraryFile) DecodeProvinces() [][2]string {
var provinces = [][2]string{}
if IsNotNull(this.Provinces) {
err := json.Unmarshal(this.Provinces, &provinces)
if err != nil {
// ignore error
}
}
return provinces
}
func (this *IPLibraryFile) DecodeCities() [][3]string {
var cities = [][3]string{}
if IsNotNull(this.Cities) {
err := json.Unmarshal(this.Cities, &cities)
if err != nil {
// ignore error
}
}
return cities
}
func (this *IPLibraryFile) DecodeTowns() [][4]string {
var towns = [][4]string{}
if IsNotNull(this.Towns) {
err := json.Unmarshal(this.Towns, &towns)
if err != nil {
// ignore error
}
}
return towns
}
func (this *IPLibraryFile) DecodeProviders() []string {
var providers = []string{}
if IsNotNull(this.Providers) {
err := json.Unmarshal(this.Providers, &providers)
if err != nil {
// ignore error
}
}
return providers
}
func (this *IPLibraryFile) DecodeEmptyValues() []string {
var result = []string{}
if IsNotNull(this.EmptyValues) {
err := json.Unmarshal(this.EmptyValues, &result)
if err != nil {
// ignore error
}
}
return result
}

View File

@@ -1,22 +1,26 @@
package models
// IP库
// IPLibrary IP库
type IPLibrary struct {
Id uint32 `field:"id"` // ID
AdminId uint32 `field:"adminId"` // 管理员ID
FileId uint32 `field:"fileId"` // 文件ID
Type string `field:"type"` // 类型
Name string `field:"name"` // 名称
IsPublic bool `field:"isPublic"` // 是否公用
State uint8 `field:"state"` // 状态
CreatedAt uint64 `field:"createdAt"` // 创建时间
}
type IPLibraryOperator struct {
Id interface{} // ID
AdminId interface{} // 管理员ID
FileId interface{} // 文件ID
Type interface{} // 类型
State interface{} // 状态
CreatedAt interface{} // 创建时间
Id any // ID
AdminId any // 管理员ID
FileId any // 文件ID
Type any // 类型
Name any // 名称
IsPublic any // 是否公用
State any // 状态
CreatedAt any // 创建时间
}
func NewIPLibraryOperator() *IPLibraryOperator {

View File

@@ -165,7 +165,7 @@ func (this *IPListDAO) UpdateIPList(tx *dbs.Tx, listId int64, name string, code
if listId <= 0 {
return errors.New("invalid listId")
}
op := NewIPListOperator()
var op = NewIPListOperator()
op.Id = listId
op.Name = name
op.Code = code

View File

@@ -36,7 +36,7 @@ func init() {
// CreateLog 创建管理员日志
func (this *LogDAO) CreateLog(tx *dbs.Tx, adminType string, adminId int64, level string, description string, action string, ip string) error {
op := NewLogOperator()
var op = NewLogOperator()
op.Level = level
op.Description = description
op.Action = action

View File

@@ -40,7 +40,7 @@ func init() {
})
}
// 启用条目
// EnableLogin 启用条目
func (this *LoginDAO) EnableLogin(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -49,7 +49,7 @@ func (this *LoginDAO) EnableLogin(tx *dbs.Tx, id int64) error {
return err
}
// 禁用条目
// DisableLogin 禁用条目
func (this *LoginDAO) DisableLogin(tx *dbs.Tx, id int64) error {
_, err := this.Query(tx).
Pk(id).
@@ -58,7 +58,7 @@ func (this *LoginDAO) DisableLogin(tx *dbs.Tx, id int64) error {
return err
}
// 查找启用中的条目
// FindEnabledLogin 查找启用中的条目
func (this *LoginDAO) FindEnabledLogin(tx *dbs.Tx, id int64) (*Login, error) {
result, err := this.Query(tx).
Pk(id).
@@ -70,7 +70,7 @@ func (this *LoginDAO) FindEnabledLogin(tx *dbs.Tx, id int64) (*Login, error) {
return result.(*Login), err
}
// 创建认证
// CreateLogin 创建认证
func (this *LoginDAO) CreateLogin(tx *dbs.Tx, Id int64, loginType LoginType, params maps.Map) (int64, error) {
if Id <= 0 {
return 0, errors.New("invalid Id")
@@ -78,7 +78,7 @@ func (this *LoginDAO) CreateLogin(tx *dbs.Tx, Id int64, loginType LoginType, par
if params == nil {
params = maps.Map{}
}
op := NewLoginOperator()
var op = NewLoginOperator()
op.Id = Id
op.Type = loginType
op.Params = params.AsJSON()
@@ -87,23 +87,34 @@ func (this *LoginDAO) CreateLogin(tx *dbs.Tx, Id int64, loginType LoginType, par
return this.SaveInt64(tx, op)
}
// 修改认证
func (this *LoginDAO) UpdateLogin(tx *dbs.Tx, adminId int64, loginType LoginType, params maps.Map, isOn bool) error {
// UpdateLogin 修改认证
func (this *LoginDAO) UpdateLogin(tx *dbs.Tx, adminId int64, userId int64, loginType LoginType, params maps.Map, isOn bool) error {
if adminId <= 0 && userId <= 0 {
return errors.New("invalid adminId and userId")
}
// 是否已经存在
loginId, err := this.Query(tx).
Attr("adminId", adminId).
var query = this.Query(tx).
Attr("type", loginType).
State(LoginStateEnabled).
ResultPk().
FindInt64Col(0)
ResultPk()
if adminId > 0 {
query.Attr("adminId", adminId)
} else if userId > 0 {
query.Attr("userId", userId)
}
loginId, err := query.FindInt64Col(0)
if err != nil {
return err
}
op := NewLoginOperator()
var op = NewLoginOperator()
if loginId > 0 {
op.Id = loginId
} else {
op.AdminId = adminId
op.UserId = userId
op.Type = loginType
op.State = LoginStateEnabled
}
@@ -117,35 +128,54 @@ func (this *LoginDAO) UpdateLogin(tx *dbs.Tx, adminId int64, loginType LoginType
return this.Save(tx, op)
}
// 禁用相关认证
func (this *LoginDAO) DisableLoginWithAdminId(tx *dbs.Tx, adminId int64, loginType LoginType) error {
_, err := this.Query(tx).
Attr("adminId", adminId).
// DisableLoginWithType 禁用相关认证
func (this *LoginDAO) DisableLoginWithType(tx *dbs.Tx, adminId int64, userId int64, loginType LoginType) error {
var query = this.Query(tx).
Attr("type", loginType).
Set("isOn", false).
Set("isOn", false)
if adminId > 0 {
query.Attr("adminId", adminId)
} else if userId > 0 {
query.Attr("userId", userId)
}
_, err := query.
Update()
return err
}
// 查找管理员相关的认证
func (this *LoginDAO) FindEnabledLoginWithAdminId(tx *dbs.Tx, adminId int64, loginType LoginType) (*Login, error) {
one, err := this.Query(tx).
Attr("adminId", adminId).
// FindEnabledLoginWithType 查找管理员和用户相关的认证
func (this *LoginDAO) FindEnabledLoginWithType(tx *dbs.Tx, adminId int64, userId int64, loginType LoginType) (*Login, error) {
var query = this.Query(tx).
Attr("type", loginType).
State(LoginStateEnabled).
Find()
State(LoginStateEnabled)
if adminId > 0 {
query.Attr("adminId", adminId)
} else if userId > 0 {
query.Attr("userId", userId)
}
one, err := query.Find()
if err != nil || one == nil {
return nil, err
}
return one.(*Login), nil
}
// 检查某个认证是否启用
func (this *LoginDAO) CheckLoginIsOn(tx *dbs.Tx, adminId int64, loginType LoginType) (bool, error) {
return this.Query(tx).
Attr("adminId", adminId).
// CheckLoginIsOn 检查某个认证是否启用
func (this *LoginDAO) CheckLoginIsOn(tx *dbs.Tx, adminId int64, userId int64, loginType LoginType) (bool, error) {
var query = this.Query(tx).
Attr("type", loginType).
State(LoginStateEnabled).
Attr("isOn", true).
Exist()
Attr("isOn", true)
if adminId > 0 {
query.Attr("adminId", adminId)
} else if userId > 0 {
query.Attr("userId", userId)
}
return query.Exist()
}

View File

@@ -154,7 +154,7 @@ func (this *MessageDAO) CreateNodeMessage(tx *dbs.Tx, role string, clusterId int
// CreateMessage 创建普通消息
func (this *MessageDAO) CreateMessage(tx *dbs.Tx, adminId int64, userId int64, messageType MessageType, level string, subject string, body string, paramsJSON []byte) error {
op := NewMessageOperator()
var op = NewMessageOperator()
op.AdminId = adminId
op.UserId = userId
op.Type = messageType
@@ -230,7 +230,7 @@ func (this *MessageDAO) UpdateMessageRead(tx *dbs.Tx, messageId int64, b bool) e
if messageId <= 0 {
return errors.New("invalid messageId")
}
op := NewMessageOperator()
var op = NewMessageOperator()
op.Id = messageId
op.IsRead = b
err := this.Save(tx, op)
@@ -286,7 +286,7 @@ func (this *MessageDAO) createMessage(tx *dbs.Tx, role string, clusterId int64,
// TODO 检查同样的消息最近是否发送过
// 创建新消息
op := NewMessageOperator()
var op = NewMessageOperator()
op.AdminId = 0 // TODO
op.UserId = 0 // TODO
op.Role = role

View File

@@ -104,7 +104,7 @@ func (this *MessageMediaDAO) UpdateMessageMedias(tx *dbs.Tx, mediaMaps []maps.Ma
if err != nil {
return err
}
op := NewMessageMediaOperator()
var op = NewMessageMediaOperator()
if mediaId > 0 {
op.Id = mediaId
}

View File

@@ -84,7 +84,7 @@ func (this *MessageMediaInstanceDAO) FindEnabledMessageMediaInstance(tx *dbs.Tx,
// CreateMediaInstance 创建媒介实例
func (this *MessageMediaInstanceDAO) CreateMediaInstance(tx *dbs.Tx, name string, mediaType string, params maps.Map, description string, rateJSON []byte, hashLifeSeconds int32) (int64, error) {
op := NewMessageMediaInstanceOperator()
var op = NewMessageMediaInstanceOperator()
op.Name = name
op.MediaType = mediaType
@@ -116,7 +116,7 @@ func (this *MessageMediaInstanceDAO) UpdateMediaInstance(tx *dbs.Tx, instanceId
return errors.New("invalid instanceId")
}
op := NewMessageMediaInstanceOperator()
var op = NewMessageMediaInstanceOperator()
op.Id = instanceId
op.Name = name
op.MediaType = mediaType

View File

@@ -76,7 +76,7 @@ func (this *MessageReceiverDAO) DisableReceivers(tx *dbs.Tx, clusterId int64, no
// CreateReceiver 创建接收人
func (this *MessageReceiverDAO) CreateReceiver(tx *dbs.Tx, role string, clusterId int64, nodeId int64, serverId int64, messageType MessageType, params maps.Map, recipientId int64, recipientGroupId int64) (int64, error) {
op := NewMessageReceiverOperator()
var op = NewMessageReceiverOperator()
op.Role = role
op.ClusterId = clusterId
op.NodeId = nodeId

View File

@@ -86,7 +86,7 @@ func (this *MessageRecipientDAO) FindEnabledMessageRecipient(tx *dbs.Tx, recipie
// CreateRecipient 创建接收人
func (this *MessageRecipientDAO) CreateRecipient(tx *dbs.Tx, adminId int64, instanceId int64, user string, groupIds []int64, description string, timeFrom string, timeTo string) (int64, error) {
op := NewMessageRecipientOperator()
var op = NewMessageRecipientOperator()
op.AdminId = adminId
op.InstanceId = instanceId
op.User = user
@@ -122,7 +122,7 @@ func (this *MessageRecipientDAO) UpdateRecipient(tx *dbs.Tx, recipientId int64,
return errors.New("invalid recipientId")
}
op := NewMessageRecipientOperator()
var op = NewMessageRecipientOperator()
op.Id = recipientId
op.AdminId = adminId
op.InstanceId = instanceId

View File

@@ -73,7 +73,7 @@ func (this *MessageRecipientGroupDAO) FindMessageRecipientGroupName(tx *dbs.Tx,
// 创建分组
func (this *MessageRecipientGroupDAO) CreateGroup(tx *dbs.Tx, name string) (int64, error) {
op := NewMessageRecipientGroupOperator()
var op = NewMessageRecipientGroupOperator()
op.Name = name
op.IsOn = true
op.State = MessageRecipientStateEnabled
@@ -85,7 +85,7 @@ func (this *MessageRecipientGroupDAO) UpdateGroup(tx *dbs.Tx, groupId int64, nam
if groupId <= 0 {
return errors.New("invalid groupId")
}
op := NewMessageRecipientGroupOperator()
var op = NewMessageRecipientGroupOperator()
op.Id = groupId
op.Name = name
op.IsOn = isOn

View File

@@ -131,7 +131,7 @@ func (this *MessageTaskDAO) CreateMessageTask(tx *dbs.Tx, recipientId int64, ins
}
}
op := NewMessageTaskOperator()
var op = NewMessageTaskOperator()
op.RecipientId = recipientId
op.InstanceId = instanceId
op.Hash = hash
@@ -190,7 +190,7 @@ func (this *MessageTaskDAO) UpdateMessageTaskStatus(tx *dbs.Tx, taskId int64, st
if taskId <= 0 {
return errors.New("invalid taskId")
}
op := NewMessageTaskOperator()
var op = NewMessageTaskOperator()
op.Id = taskId
op.Status = status
op.SentAt = time.Now().Unix()

View File

@@ -49,7 +49,7 @@ func init() {
// CreateLog 创建日志
func (this *MessageTaskLogDAO) CreateLog(tx *dbs.Tx, taskId int64, isOk bool, errMsg string, response string) error {
op := NewMessageTaskLogOperator()
var op = NewMessageTaskLogOperator()
op.TaskId = taskId
op.IsOk = isOk
op.Error = errMsg

View File

@@ -75,7 +75,7 @@ func (this *MetricChartDAO) FindMetricChartName(tx *dbs.Tx, chartId int64) (stri
// CreateChart 创建图表
func (this *MetricChartDAO) CreateChart(tx *dbs.Tx, itemId int64, name string, chartType string, widthDiv int32, maxItems int32, params maps.Map, ignoreEmptyKeys bool, ignoredKeys []string) (int64, error) {
op := NewMetricChartOperator()
var op = NewMetricChartOperator()
op.ItemId = itemId
op.Name = name
op.Type = chartType
@@ -112,7 +112,7 @@ func (this *MetricChartDAO) UpdateChart(tx *dbs.Tx, chartId int64, name string,
if chartId <= 0 {
return errors.New("invalid chartId")
}
op := NewMetricChartOperator()
var op = NewMetricChartOperator()
op.Id = chartId
op.Name = name
op.Type = chartType

View File

@@ -123,7 +123,7 @@ func (this *MonitorNodeDAO) CreateMonitorNode(tx *dbs.Tx, name string, descripti
return
}
op := NewMonitorNodeOperator()
var op = NewMonitorNodeOperator()
op.IsOn = isOn
op.UniqueId = uniqueId
op.Secret = secret
@@ -144,7 +144,7 @@ func (this *MonitorNodeDAO) UpdateMonitorNode(tx *dbs.Tx, nodeId int64, name str
return errors.New("invalid nodeId")
}
op := NewMonitorNodeOperator()
var op = NewMonitorNodeOperator()
op.Id = nodeId
op.Name = name
op.Description = description

View File

@@ -1,290 +0,0 @@
package nameservers
import (
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
dbutils "github.com/TeaOSLab/EdgeAPI/internal/db/utils"
"github.com/TeaOSLab/EdgeAPI/internal/errors"
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
_ "github.com/go-sql-driver/mysql"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/dbs"
)
const (
NSDomainStateEnabled = 1 // 已启用
NSDomainStateDisabled = 0 // 已禁用
)
type NSDomainDAO dbs.DAO
func NewNSDomainDAO() *NSDomainDAO {
return dbs.NewDAO(&NSDomainDAO{
DAOObject: dbs.DAOObject{
DB: Tea.Env,
Table: "edgeNSDomains",
Model: new(NSDomain),
PkName: "id",
},
}).(*NSDomainDAO)
}
var SharedNSDomainDAO *NSDomainDAO
func init() {
dbs.OnReady(func() {
SharedNSDomainDAO = NewNSDomainDAO()
})
}
// EnableNSDomain 启用条目
func (this *NSDomainDAO) EnableNSDomain(tx *dbs.Tx, domainId int64) error {
_, err := this.Query(tx).
Pk(domainId).
Set("state", NSDomainStateEnabled).
Update()
if err != nil {
return err
}
return this.NotifyUpdate(tx, domainId)
}
// DisableNSDomain 禁用条目
func (this *NSDomainDAO) DisableNSDomain(tx *dbs.Tx, domainId int64) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
_, err = this.Query(tx).
Pk(domainId).
Set("state", NSDomainStateDisabled).
Set("version", version).
Update()
if err != nil {
return err
}
return this.NotifyUpdate(tx, domainId)
}
// FindEnabledNSDomain 查找启用中的条目
func (this *NSDomainDAO) FindEnabledNSDomain(tx *dbs.Tx, id int64) (*NSDomain, error) {
result, err := this.Query(tx).
Pk(id).
Attr("state", NSDomainStateEnabled).
Find()
if result == nil {
return nil, err
}
return result.(*NSDomain), err
}
// FindNSDomainName 根据主键查找名称
func (this *NSDomainDAO) FindNSDomainName(tx *dbs.Tx, id int64) (string, error) {
return this.Query(tx).
Pk(id).
Result("name").
FindStringCol("")
}
// CreateDomain 创建域名
func (this *NSDomainDAO) CreateDomain(tx *dbs.Tx, clusterId int64, userId int64, name string) (int64, error) {
version, err := this.IncreaseVersion(tx)
if err != nil {
return 0, err
}
op := NewNSDomainOperator()
op.ClusterId = clusterId
op.UserId = userId
op.Name = name
op.Version = version
op.IsOn = true
op.State = NSDomainStateEnabled
domainId, err := this.SaveInt64(tx, op)
if err != nil {
return 0, err
}
err = this.NotifyUpdate(tx, domainId)
if err != nil {
return domainId, err
}
return domainId, nil
}
// UpdateDomain 修改域名
func (this *NSDomainDAO) UpdateDomain(tx *dbs.Tx, domainId int64, clusterId int64, userId int64, isOn bool) error {
if domainId <= 0 {
return errors.New("invalid domainId")
}
oldClusterId, err := this.Query(tx).
Pk(domainId).
Result("clusterId").
FindInt64Col(0)
if err != nil {
return err
}
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
op := NewNSDomainOperator()
op.Id = domainId
op.ClusterId = clusterId
op.UserId = userId
op.IsOn = isOn
op.Version = version
err = this.Save(tx, op)
if err != nil {
return err
}
// 通知更新
if oldClusterId > 0 && oldClusterId != clusterId {
err = models.SharedNSClusterDAO.NotifyUpdate(tx, oldClusterId)
if err != nil {
return err
}
}
return this.NotifyUpdate(tx, domainId)
}
// CountAllEnabledDomains 计算域名数量
func (this *NSDomainDAO) CountAllEnabledDomains(tx *dbs.Tx, clusterId int64, userId int64, keyword string) (int64, error) {
query := this.Query(tx)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {
query.Where("clusterId IN (SELECT id FROM " + models.SharedNSClusterDAO.Table + " WHERE state=1)")
}
if userId > 0 {
query.Attr("userId", userId)
} else {
query.Where("(userId=0 OR userId IN (SELECT id FROM " + models.SharedUserDAO.Table + " WHERE state=1))")
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", dbutils.QuoteLike(keyword))
}
return query.
State(NSDomainStateEnabled).
Count()
}
// ListEnabledDomains 列出单页域名
func (this *NSDomainDAO) ListEnabledDomains(tx *dbs.Tx, clusterId int64, userId int64, keyword string, offset int64, size int64) (result []*NSDomain, err error) {
query := this.Query(tx)
if clusterId > 0 {
query.Attr("clusterId", clusterId)
} else {
query.Where("clusterId IN (SELECT id FROM " + models.SharedNSClusterDAO.Table + " WHERE state=1)")
}
if userId > 0 {
query.Attr("userId", userId)
} else {
query.Where("(userId=0 OR userId IN (SELECT id FROM " + models.SharedUserDAO.Table + " WHERE state=1))")
}
if len(keyword) > 0 {
query.Where("(name LIKE :keyword)").
Param("keyword", dbutils.QuoteLike(keyword))
}
_, err = query.
State(NSDomainStateEnabled).
DescPk().
Offset(offset).
Limit(size).
Slice(&result).
FindAll()
return
}
// IncreaseVersion 增加版本
func (this *NSDomainDAO) IncreaseVersion(tx *dbs.Tx) (int64, error) {
return models.SharedSysLockerDAO.Increase(tx, "NS_DOMAIN_VERSION", 1)
}
// ListDomainsAfterVersion 列出某个版本后的域名
func (this *NSDomainDAO) ListDomainsAfterVersion(tx *dbs.Tx, version int64, size int64) (result []*NSDomain, err error) {
if size <= 0 {
size = 10000
}
_, err = this.Query(tx).
Gte("version", version).
Limit(size).
Asc("version").
Slice(&result).
FindAll()
return
}
// FindDomainIdWithName 根据名称查找域名
func (this *NSDomainDAO) FindDomainIdWithName(tx *dbs.Tx, clusterId int64, name string) (int64, error) {
return this.Query(tx).
Attr("clusterId", clusterId).
Attr("name", name).
State(NSDomainStateEnabled).
ResultPk().
FindInt64Col(0)
}
// FindEnabledDomainTSIG 获取TSIG配置
func (this *NSDomainDAO) FindEnabledDomainTSIG(tx *dbs.Tx, domainId int64) ([]byte, error) {
tsig, err := this.Query(tx).
Pk(domainId).
Result("tsig").
FindStringCol("")
if err != nil {
return nil, err
}
return []byte(tsig), nil
}
// UpdateDomainTSIG 修改TSIG配置
func (this *NSDomainDAO) UpdateDomainTSIG(tx *dbs.Tx, domainId int64, tsigJSON []byte) error {
version, err := this.IncreaseVersion(tx)
if err != nil {
return err
}
err = this.Query(tx).
Pk(domainId).
Set("tsig", tsigJSON).
Set("version", version).
UpdateQuickly()
if err != nil {
return err
}
return this.NotifyUpdate(tx, domainId)
}
// FindEnabledDomainClusterId 获取域名的集群ID
func (this *NSDomainDAO) FindEnabledDomainClusterId(tx *dbs.Tx, domainId int64) (int64, error) {
return this.Query(tx).
Pk(domainId).
State(NSDomainStateEnabled).
Result("clusterId").
FindInt64Col(0)
}
// NotifyUpdate 通知更改
func (this *NSDomainDAO) NotifyUpdate(tx *dbs.Tx, domainId int64) error {
clusterId, err := this.Query(tx).
Result("clusterId").
Pk(domainId).
FindInt64Col(0)
if err != nil {
return err
}
if clusterId > 0 {
return models.SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleDNS, clusterId, 0, models.NSNodeTaskTypeDomainChanged)
}
return nil
}

View File

@@ -0,0 +1,24 @@
package nameservers
// NSDomainGroup 域名分组
type NSDomainGroup struct {
Id uint64 `field:"id"` // ID
UserId uint64 `field:"userId"` // 用户ID
Name string `field:"name"` // 分组名称
IsOn bool `field:"isOn"` // 是否启用
Order uint32 `field:"order"` // 排序
State uint8 `field:"state"` // 状态
}
type NSDomainGroupOperator struct {
Id interface{} // ID
UserId interface{} // 用户ID
Name interface{} // 分组名称
IsOn interface{} // 是否启用
Order interface{} // 排序
State interface{} // 状态
}
func NewNSDomainGroupOperator() *NSDomainGroupOperator {
return &NSDomainGroupOperator{}
}

Some files were not shown because too many files have changed in this diff Show More