mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2026-01-03 22:06:36 +08:00
阶段性提交
This commit is contained in:
@@ -1 +1,8 @@
|
||||
package models
|
||||
|
||||
import "strconv"
|
||||
|
||||
// 地址
|
||||
func (this *APINode) Address() string {
|
||||
return this.Host + ":" + strconv.Itoa(int(this.Port))
|
||||
}
|
||||
|
||||
53
internal/db/models/file_chunk_dao.go
Normal file
53
internal/db/models/file_chunk_dao.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
type FileChunkDAO dbs.DAO
|
||||
|
||||
func NewFileChunkDAO() *FileChunkDAO {
|
||||
return dbs.NewDAO(&FileChunkDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeFileChunks",
|
||||
Model: new(FileChunk),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*FileChunkDAO)
|
||||
}
|
||||
|
||||
var SharedFileChunkDAO = NewFileChunkDAO()
|
||||
|
||||
// 创建文件Chunk
|
||||
func (this *FileChunkDAO) CreateFileChunk(fileId int, data []byte) error {
|
||||
op := NewFileChunkOperator()
|
||||
op.FileId = fileId
|
||||
op.Data = data
|
||||
_, err := this.Save(op)
|
||||
return err
|
||||
}
|
||||
|
||||
// 列出所有的文件Chunk
|
||||
func (this *FileChunkDAO) FindAllFileChunks(fileId int) (result []*FileChunk, err error) {
|
||||
_, err = this.Query().
|
||||
Attr("fileId", fileId).
|
||||
AscPk().
|
||||
Slice(&result).
|
||||
FindAll()
|
||||
return
|
||||
}
|
||||
|
||||
// 删除以前的文件
|
||||
func (this *FileChunkDAO) DeleteFileChunks(fileId int) error {
|
||||
if fileId <= 0 {
|
||||
return errors.New("invalid fileId")
|
||||
}
|
||||
_, err := this.Query().
|
||||
Attr("fileId", fileId).
|
||||
Delete()
|
||||
return err
|
||||
}
|
||||
5
internal/db/models/file_chunk_dao_test.go
Normal file
5
internal/db/models/file_chunk_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
18
internal/db/models/file_chunk_model.go
Normal file
18
internal/db/models/file_chunk_model.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package models
|
||||
|
||||
//
|
||||
type FileChunk struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
FileId uint32 `field:"fileId"` // 文件ID
|
||||
Data string `field:"data"` // 分块内容
|
||||
}
|
||||
|
||||
type FileChunkOperator struct {
|
||||
Id interface{} // ID
|
||||
FileId interface{} // 文件ID
|
||||
Data interface{} // 分块内容
|
||||
}
|
||||
|
||||
func NewFileChunkOperator() *FileChunkOperator {
|
||||
return &FileChunkOperator{}
|
||||
}
|
||||
1
internal/db/models/file_chunk_model_ext.go
Normal file
1
internal/db/models/file_chunk_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
141
internal/db/models/file_dao.go
Normal file
141
internal/db/models/file_dao.go
Normal file
@@ -0,0 +1,141 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"mime/multipart"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
FileStateEnabled = 1 // 已启用
|
||||
FileStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type FileDAO dbs.DAO
|
||||
|
||||
func NewFileDAO() *FileDAO {
|
||||
return dbs.NewDAO(&FileDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeFiles",
|
||||
Model: new(File),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*FileDAO)
|
||||
}
|
||||
|
||||
var SharedFileDAO = NewFileDAO()
|
||||
|
||||
// 启用条目
|
||||
func (this *FileDAO) EnableFile(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", FileStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *FileDAO) DisableFile(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", FileStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *FileDAO) FindEnabledFile(id int64) (*File, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", FileStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*File), err
|
||||
}
|
||||
|
||||
// 创建文件
|
||||
func (this *FileDAO) CreateFileFromReader(businessType, description string, filename string, body *multipart.FileHeader, order int) (int, error) {
|
||||
file, err := body.Open()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
op := NewFileOperator()
|
||||
op.Type = businessType
|
||||
op.Description = description
|
||||
op.State = FileStateEnabled
|
||||
op.Size = body.Size
|
||||
op.Order = order
|
||||
op.Filename = filename
|
||||
_, err = this.Save(op)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
fileId := types.Int(op.Id)
|
||||
|
||||
// 保存chunk
|
||||
buf := make([]byte, 512*1024)
|
||||
for {
|
||||
n, err := file.Read(buf)
|
||||
if n > 0 {
|
||||
err1 := SharedFileChunkDAO.CreateFileChunk(fileId, buf[:n])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return fileId, nil
|
||||
}
|
||||
|
||||
// 创建一个空文件
|
||||
func (this *FileDAO) UploadLocalFile(businessType string, localFile string, filename string) (fileId int, err error) {
|
||||
reader, err := os.Open(localFile)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func() {
|
||||
_ = reader.Close()
|
||||
}()
|
||||
stat, err := reader.Stat()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
op := NewFileOperator()
|
||||
op.Type = businessType
|
||||
op.Filename = filename
|
||||
op.Size = stat.Size()
|
||||
op.State = FileStateEnabled
|
||||
_, err = this.Save(op)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fileId = types.Int(op.Id)
|
||||
|
||||
buf := make([]byte, 512*1024)
|
||||
for {
|
||||
n, err := reader.Read(buf)
|
||||
if n > 0 {
|
||||
err1 := SharedFileChunkDAO.CreateFileChunk(fileId, buf[:n])
|
||||
if err1 != nil {
|
||||
return 0, err1
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return fileId, nil
|
||||
}
|
||||
5
internal/db/models/file_dao_test.go
Normal file
5
internal/db/models/file_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
28
internal/db/models/file_model.go
Normal file
28
internal/db/models/file_model.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
//
|
||||
type File struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
Description string `field:"description"` // 文件描述
|
||||
Filename string `field:"filename"` // 文件名
|
||||
Size uint32 `field:"size"` // 文件尺寸
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
Order uint32 `field:"order"` // 排序
|
||||
Type string `field:"type"` // 类型
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type FileOperator struct {
|
||||
Id interface{} // ID
|
||||
Description interface{} // 文件描述
|
||||
Filename interface{} // 文件名
|
||||
Size interface{} // 文件尺寸
|
||||
CreatedAt interface{} // 创建时间
|
||||
Order interface{} // 排序
|
||||
Type interface{} // 类型
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewFileOperator() *FileOperator {
|
||||
return &FileOperator{}
|
||||
}
|
||||
1
internal/db/models/file_model_ext.go
Normal file
1
internal/db/models/file_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
65
internal/db/models/http_cache_policy_dao.go
Normal file
65
internal/db/models/http_cache_policy_dao.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
HTTPCachePolicyStateEnabled = 1 // 已启用
|
||||
HTTPCachePolicyStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type HTTPCachePolicyDAO dbs.DAO
|
||||
|
||||
func NewHTTPCachePolicyDAO() *HTTPCachePolicyDAO {
|
||||
return dbs.NewDAO(&HTTPCachePolicyDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeHTTPCachePolicies",
|
||||
Model: new(HTTPCachePolicy),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*HTTPCachePolicyDAO)
|
||||
}
|
||||
|
||||
var SharedHTTPCachePolicyDAO = NewHTTPCachePolicyDAO()
|
||||
|
||||
// 启用条目
|
||||
func (this *HTTPCachePolicyDAO) EnableHTTPCachePolicy(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", HTTPCachePolicyStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *HTTPCachePolicyDAO) DisableHTTPCachePolicy(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", HTTPCachePolicyStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *HTTPCachePolicyDAO) FindEnabledHTTPCachePolicy(id int64) (*HTTPCachePolicy, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", HTTPCachePolicyStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*HTTPCachePolicy), err
|
||||
}
|
||||
|
||||
// 根据主键查找名称
|
||||
func (this *HTTPCachePolicyDAO) FindHTTPCachePolicyName(id int64) (string, error) {
|
||||
return this.Query().
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
5
internal/db/models/http_cache_policy_dao_test.go
Normal file
5
internal/db/models/http_cache_policy_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
44
internal/db/models/http_cache_policy_model.go
Normal file
44
internal/db/models/http_cache_policy_model.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package models
|
||||
|
||||
//
|
||||
type HTTPCachePolicy struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||
UserId uint32 `field:"userId"` // 用户ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 名称
|
||||
Key string `field:"key"` // 缓存Key规则
|
||||
Capacity string `field:"capacity"` // 容量数据
|
||||
Life string `field:"life"` // 有效期
|
||||
Status string `field:"status"` // HTTP状态码列表
|
||||
MaxSize string `field:"maxSize"` // 最大尺寸
|
||||
SkipCacheControlValues string `field:"skipCacheControlValues"` // 忽略的cache-control
|
||||
SkipSetCookie uint8 `field:"skipSetCookie"` // 是否忽略Set-Cookie Header
|
||||
EnableRequestCachePragma uint8 `field:"enableRequestCachePragma"` // 是否支持客户端的Pragma: no-cache
|
||||
Cond string `field:"cond"` // 请求条件
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type HTTPCachePolicyOperator struct {
|
||||
Id interface{} // ID
|
||||
AdminId interface{} // 管理员ID
|
||||
UserId interface{} // 用户ID
|
||||
IsOn interface{} // 是否启用
|
||||
Name interface{} // 名称
|
||||
Key interface{} // 缓存Key规则
|
||||
Capacity interface{} // 容量数据
|
||||
Life interface{} // 有效期
|
||||
Status interface{} // HTTP状态码列表
|
||||
MaxSize interface{} // 最大尺寸
|
||||
SkipCacheControlValues interface{} // 忽略的cache-control
|
||||
SkipSetCookie interface{} // 是否忽略Set-Cookie Header
|
||||
EnableRequestCachePragma interface{} // 是否支持客户端的Pragma: no-cache
|
||||
Cond interface{} // 请求条件
|
||||
CreatedAt interface{} // 创建时间
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewHTTPCachePolicyOperator() *HTTPCachePolicyOperator {
|
||||
return &HTTPCachePolicyOperator{}
|
||||
}
|
||||
1
internal/db/models/http_cache_policy_model_ext.go
Normal file
1
internal/db/models/http_cache_policy_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
65
internal/db/models/http_header_dao.go
Normal file
65
internal/db/models/http_header_dao.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
)
|
||||
|
||||
const (
|
||||
HTTPHeaderStateEnabled = 1 // 已启用
|
||||
HTTPHeaderStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type HTTPHeaderDAO dbs.DAO
|
||||
|
||||
func NewHTTPHeaderDAO() *HTTPHeaderDAO {
|
||||
return dbs.NewDAO(&HTTPHeaderDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeHTTPHeaders",
|
||||
Model: new(HTTPHeader),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*HTTPHeaderDAO)
|
||||
}
|
||||
|
||||
var SharedHTTPHeaderDAO = NewHTTPHeaderDAO()
|
||||
|
||||
// 启用条目
|
||||
func (this *HTTPHeaderDAO) EnableHTTPHeader(id uint32) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", HTTPHeaderStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *HTTPHeaderDAO) DisableHTTPHeader(id uint32) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", HTTPHeaderStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *HTTPHeaderDAO) FindEnabledHTTPHeader(id uint32) (*HTTPHeader, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", HTTPHeaderStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*HTTPHeader), err
|
||||
}
|
||||
|
||||
// 根据主键查找名称
|
||||
func (this *HTTPHeaderDAO) FindHTTPHeaderName(id uint32) (string, error) {
|
||||
return this.Query().
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
5
internal/db/models/http_header_dao_test.go
Normal file
5
internal/db/models/http_header_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
32
internal/db/models/http_header_model.go
Normal file
32
internal/db/models/http_header_model.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package models
|
||||
|
||||
//
|
||||
type HTTPHeader struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||
UserId uint32 `field:"userId"` // 用户ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 名称
|
||||
Value string `field:"value"` // 值
|
||||
Order uint32 `field:"order"` // 排序
|
||||
Status string `field:"status"` // 状态码设置
|
||||
State uint8 `field:"state"` // 状态
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
}
|
||||
|
||||
type HTTPHeaderOperator struct {
|
||||
Id interface{} // ID
|
||||
AdminId interface{} // 管理员ID
|
||||
UserId interface{} // 用户ID
|
||||
IsOn interface{} // 是否启用
|
||||
Name interface{} // 名称
|
||||
Value interface{} // 值
|
||||
Order interface{} // 排序
|
||||
Status interface{} // 状态码设置
|
||||
State interface{} // 状态
|
||||
CreatedAt interface{} // 创建时间
|
||||
}
|
||||
|
||||
func NewHTTPHeaderOperator() *HTTPHeaderOperator {
|
||||
return &HTTPHeaderOperator{}
|
||||
}
|
||||
1
internal/db/models/http_header_model_ext.go
Normal file
1
internal/db/models/http_header_model_ext.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
@@ -1,6 +1,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
@@ -12,6 +13,10 @@ import (
|
||||
const (
|
||||
NodeStateEnabled = 1 // 已启用
|
||||
NodeStateDisabled = 0 // 已禁用
|
||||
|
||||
NodeInstallStateAll = 0 // 全部
|
||||
NodeInstallStateInstalled = 1 // 已安装
|
||||
NodeInstallStateNotInstalled = 2 // 未安装
|
||||
)
|
||||
|
||||
type NodeDAO dbs.DAO
|
||||
@@ -177,7 +182,7 @@ func (this *NodeDAO) CountAllEnabledNodes() (int64, error) {
|
||||
}
|
||||
|
||||
// 列出单页节点
|
||||
func (this *NodeDAO) ListEnabledNodesMatch(offset int64, size int64, clusterId int64) (result []*Node, err error) {
|
||||
func (this *NodeDAO) ListEnabledNodesMatch(offset int64, size int64, clusterId int64, installState int8) (result []*Node, err error) {
|
||||
query := this.Query().
|
||||
State(NodeStateEnabled).
|
||||
Offset(offset).
|
||||
@@ -185,10 +190,21 @@ func (this *NodeDAO) ListEnabledNodesMatch(offset int64, size int64, clusterId i
|
||||
DescPk().
|
||||
Slice(&result)
|
||||
|
||||
// 集群
|
||||
if clusterId > 0 {
|
||||
query.Attr("clusterId", clusterId)
|
||||
}
|
||||
|
||||
// 安装状态
|
||||
switch installState {
|
||||
case NodeInstallStateAll:
|
||||
// 不做任何事情
|
||||
case NodeInstallStateInstalled:
|
||||
query.Attr("isInstalled", 1)
|
||||
case NodeInstallStateNotInstalled:
|
||||
query.Attr("isInstalled", 0)
|
||||
}
|
||||
|
||||
_, err = query.FindAll()
|
||||
return
|
||||
}
|
||||
@@ -250,12 +266,25 @@ func (this *NodeDAO) FindAllNodeIdsMatch(clusterId int64) (result []int64, err e
|
||||
}
|
||||
|
||||
// 计算节点数量
|
||||
func (this *NodeDAO) CountAllEnabledNodesMatch(clusterId int64) (int64, error) {
|
||||
func (this *NodeDAO) CountAllEnabledNodesMatch(clusterId int64, installState int8) (int64, error) {
|
||||
query := this.Query()
|
||||
query.State(NodeStateEnabled)
|
||||
|
||||
// 集群
|
||||
if clusterId > 0 {
|
||||
query.Attr("clusterId", clusterId)
|
||||
}
|
||||
|
||||
// 安装状态
|
||||
switch installState {
|
||||
case NodeInstallStateAll:
|
||||
// 不做任何事情
|
||||
case NodeInstallStateInstalled:
|
||||
query.Attr("isInstalled", 1)
|
||||
case NodeInstallStateNotInstalled:
|
||||
query.Attr("isInstalled", 0)
|
||||
}
|
||||
|
||||
return query.Count()
|
||||
}
|
||||
|
||||
@@ -273,6 +302,47 @@ func (this *NodeDAO) UpdateNodeIsInstalled(nodeId int64, isInstalled bool) error
|
||||
_, err := this.Query().
|
||||
Pk(nodeId).
|
||||
Set("isInstalled", isInstalled).
|
||||
Set("installStatus", "null"). // 重置安装状态
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查询节点的安装状态
|
||||
func (this *NodeDAO) FindNodeInstallStatus(nodeId int64) (*NodeInstallStatus, error) {
|
||||
installStatus, err := this.Query().
|
||||
Pk(nodeId).
|
||||
Result("installStatus").
|
||||
FindStringCol("")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(installStatus) == 0 {
|
||||
return NewNodeInstallStatus(), nil
|
||||
}
|
||||
|
||||
status := &NodeInstallStatus{}
|
||||
err = json.Unmarshal([]byte(installStatus), status)
|
||||
return status, err
|
||||
}
|
||||
|
||||
// 修改节点的安装状态
|
||||
func (this *NodeDAO) UpdateNodeInstallStatus(nodeId int64, status *NodeInstallStatus) error {
|
||||
if status == nil {
|
||||
_, err := this.Query().
|
||||
Pk(nodeId).
|
||||
Set("installStatus", "null").
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := json.Marshal(status)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = this.Query().
|
||||
Pk(nodeId).
|
||||
Set("installStatus", string(data)).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
15
internal/db/models/node_install_status.go
Normal file
15
internal/db/models/node_install_status.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
// 节点安装状态
|
||||
type NodeInstallStatus struct {
|
||||
IsRunning bool `json:"isRunning"` // 是否在运行
|
||||
IsFinished bool `json:"isFinished"` // 是否已结束
|
||||
IsOk bool `json:"isOk"` // 是否正确安装
|
||||
Error string `json:"error"` // 错误信息
|
||||
UpdatedAt int64 `json:"updatedAt"` // 更新时间,安装过程中需要每隔N秒钟更新这个状态,以便于让系统知道安装仍在进行中
|
||||
Steps []*NodeInstallStatusStep `json:"steps"` // 步骤
|
||||
}
|
||||
|
||||
func NewNodeInstallStatus() *NodeInstallStatus {
|
||||
return &NodeInstallStatus{}
|
||||
}
|
||||
7
internal/db/models/node_install_status_step.go
Normal file
7
internal/db/models/node_install_status_step.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package models
|
||||
|
||||
type NodeInstallStatusStep struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Percent int `json:"percent"`
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
const (
|
||||
NodeLoginStateEnabled = 1 // 已启用
|
||||
NodeLoginStateDisabled = 0 // 已禁用
|
||||
|
||||
NodeLoginTypeSSH = "ssh"
|
||||
)
|
||||
|
||||
type NodeLoginDAO dbs.DAO
|
||||
|
||||
@@ -1 +1,25 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// 解析SSH登录参数
|
||||
func (this *NodeLogin) DecodeSSHParams() (*NodeLoginSSHParams, error) {
|
||||
if this.Type != NodeLoginTypeSSH {
|
||||
return nil, errors.New("invalid login type '" + this.Type + "'")
|
||||
}
|
||||
|
||||
if len(this.Params) == 0 || this.Params == "null" {
|
||||
return nil, errors.New("'params' should not be empty")
|
||||
}
|
||||
|
||||
params := &NodeLoginSSHParams{}
|
||||
err := json.Unmarshal([]byte(this.Params), params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return params, nil
|
||||
}
|
||||
|
||||
7
internal/db/models/node_login_params_ssh.go
Normal file
7
internal/db/models/node_login_params_ssh.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package models
|
||||
|
||||
type NodeLoginSSHParams struct {
|
||||
GrantId int64 `json:"grantId"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
}
|
||||
@@ -17,6 +17,7 @@ type Node struct {
|
||||
LatestVersion uint32 `field:"latestVersion"` // 最后版本号
|
||||
InstallDir string `field:"installDir"` // 安装目录
|
||||
IsInstalled uint8 `field:"isInstalled"` // 是否已安装
|
||||
InstallStatus string `field:"installStatus"` // 安装状态
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
@@ -36,6 +37,7 @@ type NodeOperator struct {
|
||||
LatestVersion interface{} // 最后版本号
|
||||
InstallDir interface{} // 安装目录
|
||||
IsInstalled interface{} // 是否已安装
|
||||
InstallStatus interface{} // 安装状态
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,27 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 安装状态
|
||||
func (this *Node) DecodeInstallStatus() (*NodeInstallStatus, error) {
|
||||
if len(this.InstallStatus) == 0 || this.InstallStatus == "null" {
|
||||
return NewNodeInstallStatus(), nil
|
||||
}
|
||||
status := &NodeInstallStatus{}
|
||||
err := json.Unmarshal([]byte(this.InstallStatus), status)
|
||||
if err != nil {
|
||||
return NewNodeInstallStatus(), err
|
||||
}
|
||||
|
||||
// 如果N秒钟没有更新状态,则认为不在运行
|
||||
if status.IsRunning && status.UpdatedAt < time.Now().Unix()-10 {
|
||||
status.IsRunning = false
|
||||
status.IsFinished = true
|
||||
status.Error = "timeout"
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
97
internal/db/models/origin_server_dao.go
Normal file
97
internal/db/models/origin_server_dao.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
)
|
||||
|
||||
const (
|
||||
OriginServerStateEnabled = 1 // 已启用
|
||||
OriginServerStateDisabled = 0 // 已禁用
|
||||
)
|
||||
|
||||
type OriginServerDAO dbs.DAO
|
||||
|
||||
func NewOriginServerDAO() *OriginServerDAO {
|
||||
return dbs.NewDAO(&OriginServerDAO{
|
||||
DAOObject: dbs.DAOObject{
|
||||
DB: Tea.Env,
|
||||
Table: "edgeOriginServers",
|
||||
Model: new(OriginServer),
|
||||
PkName: "id",
|
||||
},
|
||||
}).(*OriginServerDAO)
|
||||
}
|
||||
|
||||
var SharedOriginServerDAO = NewOriginServerDAO()
|
||||
|
||||
// 启用条目
|
||||
func (this *OriginServerDAO) EnableOriginServer(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", OriginServerStateEnabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 禁用条目
|
||||
func (this *OriginServerDAO) DisableOriginServer(id int64) error {
|
||||
_, err := this.Query().
|
||||
Pk(id).
|
||||
Set("state", OriginServerStateDisabled).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找启用中的条目
|
||||
func (this *OriginServerDAO) FindEnabledOriginServer(id int64) (*OriginServer, error) {
|
||||
result, err := this.Query().
|
||||
Pk(id).
|
||||
Attr("state", OriginServerStateEnabled).
|
||||
Find()
|
||||
if result == nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*OriginServer), err
|
||||
}
|
||||
|
||||
// 根据主键查找名称
|
||||
func (this *OriginServerDAO) FindOriginServerName(id int64) (string, error) {
|
||||
return this.Query().
|
||||
Pk(id).
|
||||
Result("name").
|
||||
FindStringCol("")
|
||||
}
|
||||
|
||||
// 创建源站
|
||||
func (this *OriginServerDAO) CreateOriginServer(name string, addrJSON string, description string) (originId int64, err error) {
|
||||
op := NewOriginServerOperator()
|
||||
op.IsOn = true
|
||||
op.Name = name
|
||||
op.Addr = addrJSON
|
||||
op.Description = description
|
||||
op.State = OriginServerStateEnabled
|
||||
_, err = this.Save(op)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return types.Int64(op.Id), nil
|
||||
}
|
||||
|
||||
// 修改源站
|
||||
func (this *OriginServerDAO) UpdateOriginServer(originId int64, name string, addrJSON string, description string) error {
|
||||
if originId <= 0 {
|
||||
return errors.New("invalid originId")
|
||||
}
|
||||
op := NewOriginServerOperator()
|
||||
op.Id = originId
|
||||
op.Name = name
|
||||
op.Addr = addrJSON
|
||||
op.Description = description
|
||||
op.Version = dbs.SQL("version+1")
|
||||
_, err := this.Save(op)
|
||||
return err
|
||||
}
|
||||
5
internal/db/models/origin_server_dao_test.go
Normal file
5
internal/db/models/origin_server_dao_test.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
60
internal/db/models/origin_server_model.go
Normal file
60
internal/db/models/origin_server_model.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package models
|
||||
|
||||
// 源站
|
||||
type OriginServer struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
Name string `field:"name"` // 名称
|
||||
Version uint32 `field:"version"` // 版本
|
||||
Addr string `field:"addr"` // 地址
|
||||
Description string `field:"description"` // 描述
|
||||
Code string `field:"code"` // 代号
|
||||
Weight uint32 `field:"weight"` // 权重
|
||||
ConnTimeout string `field:"connTimeout"` // 连接超时
|
||||
ReadTimeout string `field:"readTimeout"` // 读超时
|
||||
IdleTimeout string `field:"idleTimeout"` // 空闲连接超时
|
||||
MaxFails uint32 `field:"maxFails"` // 最多失败次数
|
||||
MaxConns uint32 `field:"maxConns"` // 最大并发连接数
|
||||
MaxIdleConns uint32 `field:"maxIdleConns"` // 最多空闲连接数
|
||||
HttpRequestURI string `field:"httpRequestURI"` // 转发后的请求URI
|
||||
HttpRequestHeaders string `field:"httpRequestHeaders"` // 请求Headers配置
|
||||
HttpResponseHeaders string `field:"httpResponseHeaders"` // 响应Headers配置
|
||||
Host string `field:"host"` // 自定义主机名
|
||||
HealthCheck string `field:"healthCheck"` // 健康检查设置
|
||||
IsDown uint8 `field:"isDown"` // 是否处于健康检查失败状态
|
||||
Cert string `field:"cert"` // 证书设置
|
||||
Ftp string `field:"ftp"` // FTP相关设置
|
||||
CreatedAt uint32 `field:"createdAt"` // 创建时间
|
||||
State uint8 `field:"state"` // 状态
|
||||
}
|
||||
|
||||
type OriginServerOperator struct {
|
||||
Id interface{} // ID
|
||||
IsOn interface{} // 是否启用
|
||||
Name interface{} // 名称
|
||||
Version interface{} // 版本
|
||||
Addr interface{} // 地址
|
||||
Description interface{} // 描述
|
||||
Code interface{} // 代号
|
||||
Weight interface{} // 权重
|
||||
ConnTimeout interface{} // 连接超时
|
||||
ReadTimeout interface{} // 读超时
|
||||
IdleTimeout interface{} // 空闲连接超时
|
||||
MaxFails interface{} // 最多失败次数
|
||||
MaxConns interface{} // 最大并发连接数
|
||||
MaxIdleConns interface{} // 最多空闲连接数
|
||||
HttpRequestURI interface{} // 转发后的请求URI
|
||||
HttpRequestHeaders interface{} // 请求Headers配置
|
||||
HttpResponseHeaders interface{} // 响应Headers配置
|
||||
Host interface{} // 自定义主机名
|
||||
HealthCheck interface{} // 健康检查设置
|
||||
IsDown interface{} // 是否处于健康检查失败状态
|
||||
Cert interface{} // 证书设置
|
||||
Ftp interface{} // FTP相关设置
|
||||
CreatedAt interface{} // 创建时间
|
||||
State interface{} // 状态
|
||||
}
|
||||
|
||||
func NewOriginServerOperator() *OriginServerOperator {
|
||||
return &OriginServerOperator{}
|
||||
}
|
||||
17
internal/db/models/origin_server_model_ext.go
Normal file
17
internal/db/models/origin_server_model_ext.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
)
|
||||
|
||||
// 解析地址
|
||||
func (this *OriginServer) DecodeAddr() (*serverconfigs.NetworkAddressConfig, error) {
|
||||
if len(this.Addr) == 0 || this.Addr == "null" {
|
||||
return nil, errors.New("addr is empty")
|
||||
}
|
||||
addr := &serverconfigs.NetworkAddressConfig{}
|
||||
err := json.Unmarshal([]byte(this.Addr), addr)
|
||||
return addr, err
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/iwind/TeaGo/Tea"
|
||||
"github.com/iwind/TeaGo/dbs"
|
||||
@@ -59,7 +60,7 @@ func (this *ServerDAO) FindEnabledServer(id int64) (*Server, error) {
|
||||
}
|
||||
|
||||
// 创建服务
|
||||
func (this *ServerDAO) CreateServer(adminId int64, userId int64, clusterId int64, configJSON string, includeNodesJSON string, excludeNodesJSON string) (serverId int64, err error) {
|
||||
func (this *ServerDAO) CreateServer(adminId int64, userId int64, serverType serverconfigs.ServerType, name string, description string, clusterId int64, configJSON string, includeNodesJSON string, excludeNodesJSON string) (serverId int64, err error) {
|
||||
uniqueId, err := this.genUniqueId()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -69,6 +70,9 @@ func (this *ServerDAO) CreateServer(adminId int64, userId int64, clusterId int64
|
||||
op.UniqueId = uniqueId
|
||||
op.UserId = userId
|
||||
op.AdminId = adminId
|
||||
op.Name = name
|
||||
op.Type = serverType
|
||||
op.Description = description
|
||||
op.ClusterId = clusterId
|
||||
if len(configJSON) > 0 {
|
||||
op.Config = configJSON
|
||||
@@ -87,28 +91,33 @@ func (this *ServerDAO) CreateServer(adminId int64, userId int64, clusterId int64
|
||||
return types.Int64(op.Id), err
|
||||
}
|
||||
|
||||
// 修改服务
|
||||
func (this *ServerDAO) UpdateServer(serverId int64, clusterId int64, configJSON string, includeNodesJSON string, excludeNodesJSON string) error {
|
||||
// 修改服务基本信息
|
||||
func (this *ServerDAO) UpdateServerBasic(serverId int64, name string, description string, clusterId int64) error {
|
||||
if serverId <= 0 {
|
||||
return errors.New("serverId should not be smaller than 0")
|
||||
}
|
||||
op := NewServerOperator()
|
||||
op.Id = serverId
|
||||
op.Name = name
|
||||
op.Description = description
|
||||
op.ClusterId = clusterId
|
||||
if len(configJSON) > 0 {
|
||||
op.Config = configJSON
|
||||
}
|
||||
if len(includeNodesJSON) > 0 {
|
||||
op.IncludeNodes = includeNodesJSON
|
||||
}
|
||||
if len(excludeNodesJSON) > 0 {
|
||||
op.ExcludeNodes = excludeNodesJSON
|
||||
}
|
||||
op.Version = dbs.SQL("version=version+1")
|
||||
_, err := this.Save(op)
|
||||
return err
|
||||
}
|
||||
|
||||
// 修改服务配置
|
||||
func (this *ServerDAO) UpdateServerConfig(serverId int64, config []byte) error {
|
||||
if serverId <= 0 {
|
||||
return errors.New("serverId should not be smaller than 0")
|
||||
}
|
||||
_, err := this.Query().
|
||||
Pk(serverId).
|
||||
Set("config", string(config)).
|
||||
Update()
|
||||
return err
|
||||
}
|
||||
|
||||
// 计算所有可用服务数量
|
||||
func (this *ServerDAO) CountAllEnabledServers() (int64, error) {
|
||||
return this.Query().
|
||||
@@ -148,6 +157,7 @@ func (this *ServerDAO) FindAllEnabledServersWithNode(nodeId int64) (result []*Se
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 生成唯一ID
|
||||
func (this *ServerDAO) genUniqueId() (string, error) {
|
||||
for {
|
||||
|
||||
@@ -3,10 +3,13 @@ package models
|
||||
// 服务
|
||||
type Server struct {
|
||||
Id uint32 `field:"id"` // ID
|
||||
UniqueId string `field:"uniqueId"` // 唯一ID
|
||||
IsOn uint8 `field:"isOn"` // 是否启用
|
||||
UniqueId string `field:"uniqueId"` // 唯一ID
|
||||
UserId uint32 `field:"userId"` // 用户ID
|
||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||
Type string `field:"type"` // 服务类型
|
||||
Name string `field:"name"` // 名称
|
||||
Description string `field:"description"` // 描述
|
||||
GroupIds string `field:"groupIds"` // 分组ID列表
|
||||
Config string `field:"config"` // 服务配置,自动生成
|
||||
ClusterId uint32 `field:"clusterId"` // 集群ID
|
||||
@@ -19,10 +22,13 @@ type Server struct {
|
||||
|
||||
type ServerOperator struct {
|
||||
Id interface{} // ID
|
||||
UniqueId interface{} // 唯一ID
|
||||
IsOn interface{} // 是否启用
|
||||
UniqueId interface{} // 唯一ID
|
||||
UserId interface{} // 用户ID
|
||||
AdminId interface{} // 管理员ID
|
||||
Type interface{} // 服务类型
|
||||
Name interface{} // 名称
|
||||
Description interface{} // 描述
|
||||
GroupIds interface{} // 分组ID列表
|
||||
Config interface{} // 服务配置,自动生成
|
||||
ClusterId interface{} // 集群ID
|
||||
|
||||
Reference in New Issue
Block a user