mirror of
https://github.com/TeaOSLab/EdgeAPI.git
synced 2025-11-05 00:31:54 +08:00
增加服务之间拷贝配置的API(开源版本只有定义,没有完全实现)
This commit is contained in:
@@ -96,6 +96,27 @@ func (this *HTTPAuthPolicyDAO) UpdateHTTPAuthPolicy(tx *dbs.Tx, policyId int64,
|
|||||||
return this.NotifyUpdate(tx, policyId)
|
return this.NotifyUpdate(tx, policyId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneAuthPolicy 复制策略
|
||||||
|
func (this *HTTPAuthPolicyDAO) CloneAuthPolicy(tx *dbs.Tx, fromPolicyId int64) (int64, error) {
|
||||||
|
policyOne, err := this.Query(tx).
|
||||||
|
Pk(fromPolicyId).
|
||||||
|
Find()
|
||||||
|
if err != nil || policyOne == nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var policy = policyOne.(*HTTPAuthPolicy)
|
||||||
|
|
||||||
|
var op = NewHTTPAuthPolicyOperator()
|
||||||
|
op.IsOn = policy.IsOn
|
||||||
|
op.Name = policy.Name
|
||||||
|
op.Type = policy.Type
|
||||||
|
if len(policy.Params) > 0 {
|
||||||
|
op.Params = policy.Params
|
||||||
|
}
|
||||||
|
op.State = policy.State
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
// ComposePolicyConfig 组合配置
|
// ComposePolicyConfig 组合配置
|
||||||
func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPAuthPolicy, error) {
|
func (this *HTTPAuthPolicyDAO) ComposePolicyConfig(tx *dbs.Tx, policyId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPAuthPolicy, error) {
|
||||||
if cacheMap == nil {
|
if cacheMap == nil {
|
||||||
|
|||||||
@@ -133,6 +133,32 @@ func (this *HTTPPageDAO) UpdatePage(tx *dbs.Tx, pageId int64, statusList []strin
|
|||||||
return this.NotifyUpdate(tx, pageId)
|
return this.NotifyUpdate(tx, pageId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClonePage 克隆页面
|
||||||
|
func (this *HTTPPageDAO) ClonePage(tx *dbs.Tx, fromPageId int64) (newPageId int64, err error) {
|
||||||
|
if fromPageId <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageOne, err := this.Query(tx).
|
||||||
|
Pk(fromPageId).
|
||||||
|
Find()
|
||||||
|
if err != nil || pageOne == nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var page = pageOne.(*HTTPPage)
|
||||||
|
|
||||||
|
var op = NewHTTPPageOperator()
|
||||||
|
op.IsOn = page.IsOn
|
||||||
|
if len(page.StatusList) > 0 {
|
||||||
|
op.StatusList = page.StatusList
|
||||||
|
}
|
||||||
|
op.Url = page.Url
|
||||||
|
op.NewStatus = page.NewStatus
|
||||||
|
op.Body = page.Body
|
||||||
|
op.BodyType = page.BodyType
|
||||||
|
op.State = page.State
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
// ComposePageConfig 组合配置
|
// ComposePageConfig 组合配置
|
||||||
func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPPageConfig, error) {
|
func (this *HTTPPageDAO) ComposePageConfig(tx *dbs.Tx, pageId int64, cacheMap *utils.CacheMap) (*serverconfigs.HTTPPageConfig, error) {
|
||||||
if cacheMap == nil {
|
if cacheMap == nil {
|
||||||
|
|||||||
@@ -732,32 +732,6 @@ func (this *HTTPWebDAO) UpdateWebStat(tx *dbs.Tx, webId int64, statJSON []byte)
|
|||||||
return this.NotifyUpdate(tx, webId)
|
return this.NotifyUpdate(tx, webId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyWebStats 拷贝统计配置
|
|
||||||
func (this *HTTPWebDAO) CopyWebStats(tx *dbs.Tx, fromWebId int64, toWebIds []int64) error {
|
|
||||||
if fromWebId <= 0 || len(toWebIds) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
statJSON, err := this.Query(tx).
|
|
||||||
Pk(fromWebId).
|
|
||||||
Result("stat").
|
|
||||||
FindJSONCol()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 暂时不处理
|
|
||||||
if len(statJSON) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.Query(tx).
|
|
||||||
Pk(toWebIds).
|
|
||||||
Reuse(false).
|
|
||||||
Set("stat", statJSON).
|
|
||||||
UpdateQuickly()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateWebCache 更改缓存配置
|
// UpdateWebCache 更改缓存配置
|
||||||
func (this *HTTPWebDAO) UpdateWebCache(tx *dbs.Tx, webId int64, cacheJSON []byte) error {
|
func (this *HTTPWebDAO) UpdateWebCache(tx *dbs.Tx, webId int64, cacheJSON []byte) error {
|
||||||
if webId <= 0 {
|
if webId <= 0 {
|
||||||
@@ -1182,8 +1156,6 @@ func (this *HTTPWebDAO) UpdateWebHostRedirects(tx *dbs.Tx, webId int64, hostRedi
|
|||||||
return this.NotifyUpdate(tx, webId)
|
return this.NotifyUpdate(tx, webId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通用设置
|
|
||||||
|
|
||||||
// FindWebHostRedirects 查找主机跳转
|
// FindWebHostRedirects 查找主机跳转
|
||||||
func (this *HTTPWebDAO) FindWebHostRedirects(tx *dbs.Tx, webId int64) ([]byte, error) {
|
func (this *HTTPWebDAO) FindWebHostRedirects(tx *dbs.Tx, webId int64) ([]byte, error) {
|
||||||
col, err := this.Query(tx).
|
col, err := this.Query(tx).
|
||||||
|
|||||||
@@ -159,6 +159,31 @@ func (this *HTTPWebsocketDAO) UpdateWebsocket(tx *dbs.Tx, websocketId int64, han
|
|||||||
return this.NotifyUpdate(tx, websocketId)
|
return this.NotifyUpdate(tx, websocketId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneWebsocket 复制配置
|
||||||
|
func (this *HTTPWebsocketDAO) CloneWebsocket(tx *dbs.Tx, fromWebsocketId int64) (newWebsocketId int64, err error) {
|
||||||
|
websocketOne, err := this.Query(tx).
|
||||||
|
Pk(fromWebsocketId).
|
||||||
|
Find()
|
||||||
|
if err != nil || websocketOne == nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var websocket = websocketOne.(*HTTPWebsocket)
|
||||||
|
|
||||||
|
var op = NewHTTPWebsocketOperator()
|
||||||
|
op.State = websocket.State
|
||||||
|
op.IsOn = websocket.IsOn
|
||||||
|
if len(websocket.HandshakeTimeout) > 0 {
|
||||||
|
op.HandshakeTimeout = websocket.HandshakeTimeout
|
||||||
|
}
|
||||||
|
op.AllowAllOrigins = websocket.AllowAllOrigins
|
||||||
|
if len(websocket.AllowedOrigins) > 0 {
|
||||||
|
op.AllowedOrigins = websocket.AllowedOrigins
|
||||||
|
}
|
||||||
|
op.RequestSameOrigin = websocket.RequestSameOrigin
|
||||||
|
op.RequestOrigin = websocket.RequestOrigin
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *HTTPWebsocketDAO) NotifyUpdate(tx *dbs.Tx, websocketId int64) error {
|
func (this *HTTPWebsocketDAO) NotifyUpdate(tx *dbs.Tx, websocketId int64) error {
|
||||||
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithWebsocketId(tx, websocketId)
|
webId, err := SharedHTTPWebDAO.FindEnabledWebIdWithWebsocketId(tx, websocketId)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package models
|
|||||||
|
|
||||||
import "github.com/iwind/TeaGo/dbs"
|
import "github.com/iwind/TeaGo/dbs"
|
||||||
|
|
||||||
// Websocket设置
|
// HTTPWebsocket Websocket设置
|
||||||
type HTTPWebsocket struct {
|
type HTTPWebsocket struct {
|
||||||
Id uint32 `field:"id"` // ID
|
Id uint32 `field:"id"` // ID
|
||||||
AdminId uint32 `field:"adminId"` // 管理员ID
|
AdminId uint32 `field:"adminId"` // 管理员ID
|
||||||
@@ -15,20 +15,22 @@ type HTTPWebsocket struct {
|
|||||||
AllowedOrigins dbs.JSON `field:"allowedOrigins"` // 支持的源域名列表
|
AllowedOrigins dbs.JSON `field:"allowedOrigins"` // 支持的源域名列表
|
||||||
RequestSameOrigin uint8 `field:"requestSameOrigin"` // 是否请求一样的Origin
|
RequestSameOrigin uint8 `field:"requestSameOrigin"` // 是否请求一样的Origin
|
||||||
RequestOrigin string `field:"requestOrigin"` // 请求Origin
|
RequestOrigin string `field:"requestOrigin"` // 请求Origin
|
||||||
|
WebId uint64 `field:"webId"` // Web
|
||||||
}
|
}
|
||||||
|
|
||||||
type HTTPWebsocketOperator struct {
|
type HTTPWebsocketOperator struct {
|
||||||
Id interface{} // ID
|
Id any // ID
|
||||||
AdminId interface{} // 管理员ID
|
AdminId any // 管理员ID
|
||||||
UserId interface{} // 用户ID
|
UserId any // 用户ID
|
||||||
CreatedAt interface{} // 创建时间
|
CreatedAt any // 创建时间
|
||||||
State interface{} // 状态
|
State any // 状态
|
||||||
IsOn interface{} // 是否启用
|
IsOn any // 是否启用
|
||||||
HandshakeTimeout interface{} // 握手超时时间
|
HandshakeTimeout any // 握手超时时间
|
||||||
AllowAllOrigins interface{} // 是否支持所有源
|
AllowAllOrigins any // 是否支持所有源
|
||||||
AllowedOrigins interface{} // 支持的源域名列表
|
AllowedOrigins any // 支持的源域名列表
|
||||||
RequestSameOrigin interface{} // 是否请求一样的Origin
|
RequestSameOrigin any // 是否请求一样的Origin
|
||||||
RequestOrigin interface{} // 请求Origin
|
RequestOrigin any // 请求Origin
|
||||||
|
WebId any // Web
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHTTPWebsocketOperator() *HTTPWebsocketOperator {
|
func NewHTTPWebsocketOperator() *HTTPWebsocketOperator {
|
||||||
|
|||||||
@@ -275,6 +275,64 @@ func (this *OriginDAO) UpdateOrigin(tx *dbs.Tx,
|
|||||||
return this.NotifyUpdate(tx, originId)
|
return this.NotifyUpdate(tx, originId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneOrigin 复制源站
|
||||||
|
func (this *OriginDAO) CloneOrigin(tx *dbs.Tx, fromOriginId int64) (newOriginId int64, err error) {
|
||||||
|
if fromOriginId <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
originOne, err := this.Find(tx, fromOriginId)
|
||||||
|
if err != nil || originOne == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var origin = originOne.(*Origin)
|
||||||
|
var op = NewOriginOperator()
|
||||||
|
op.IsOn = origin.IsOn
|
||||||
|
op.Name = origin.Name
|
||||||
|
op.Version = origin.Version
|
||||||
|
if IsNotNull(origin.Addr) {
|
||||||
|
op.Addr = origin.Addr
|
||||||
|
}
|
||||||
|
op.Description = origin.Description
|
||||||
|
op.Code = origin.Code
|
||||||
|
op.Weight = origin.Weight
|
||||||
|
if IsNotNull(origin.ConnTimeout) {
|
||||||
|
op.ConnTimeout = origin.ConnTimeout
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.ReadTimeout) {
|
||||||
|
op.ReadTimeout = origin.ReadTimeout
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.IdleTimeout) {
|
||||||
|
op.IdleTimeout = origin.IdleTimeout
|
||||||
|
}
|
||||||
|
op.MaxFails = origin.MaxFails
|
||||||
|
op.MaxConns = origin.MaxConns
|
||||||
|
op.MaxIdleConns = origin.MaxIdleConns
|
||||||
|
op.HttpRequestURI = origin.HttpRequestURI
|
||||||
|
if IsNotNull(origin.HttpRequestHeader) {
|
||||||
|
op.HttpRequestHeader = origin.HttpRequestHeader
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.HttpResponseHeader) {
|
||||||
|
op.HttpResponseHeader = origin.HttpResponseHeader
|
||||||
|
}
|
||||||
|
op.Host = origin.Host
|
||||||
|
if IsNotNull(origin.HealthCheck) {
|
||||||
|
op.HealthCheck = origin.HealthCheck
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.Cert) {
|
||||||
|
// TODO 需要Clone证书
|
||||||
|
op.Cert = origin.Cert
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.Ftp) {
|
||||||
|
op.Ftp = origin.Ftp
|
||||||
|
}
|
||||||
|
if IsNotNull(origin.Domains) {
|
||||||
|
op.Domains = origin.Domains
|
||||||
|
}
|
||||||
|
op.FollowPort = origin.FollowPort
|
||||||
|
op.State = origin.State
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
// ComposeOriginConfig 将源站信息转换为配置
|
// ComposeOriginConfig 将源站信息转换为配置
|
||||||
func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.OriginConfig, error) {
|
func (this *OriginDAO) ComposeOriginConfig(tx *dbs.Tx, originId int64, dataMap *shared.DataMap, cacheMap *utils.CacheMap) (*serverconfigs.OriginConfig, error) {
|
||||||
if cacheMap == nil {
|
if cacheMap == nil {
|
||||||
|
|||||||
@@ -243,6 +243,115 @@ func (this *ReverseProxyDAO) CreateReverseProxy(tx *dbs.Tx, adminId int64, userI
|
|||||||
return types.Int64(op.Id), nil
|
return types.Int64(op.Id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloneReverseProxy 复制反向代理
|
||||||
|
func (this *ReverseProxyDAO) CloneReverseProxy(tx *dbs.Tx, fromReverseProxyId int64) (newReverseProxyId int64, err error) {
|
||||||
|
if fromReverseProxyId <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reverseProxyOne, err := this.Query(tx).
|
||||||
|
Pk(fromReverseProxyId).
|
||||||
|
State(ReverseProxyStateEnabled).
|
||||||
|
Find()
|
||||||
|
if err != nil || reverseProxyOne == nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var reverseProxy = reverseProxyOne.(*ReverseProxy)
|
||||||
|
var op = NewReverseProxyOperator()
|
||||||
|
op.TemplateId = reverseProxy.TemplateId
|
||||||
|
op.IsOn = reverseProxy.IsOn
|
||||||
|
if IsNotNull(reverseProxy.Scheduling) {
|
||||||
|
op.Scheduling = reverseProxy.Scheduling
|
||||||
|
}
|
||||||
|
if IsNotNull(reverseProxy.PrimaryOrigins) {
|
||||||
|
var originRefs = []*serverconfigs.OriginRef{}
|
||||||
|
err = json.Unmarshal(reverseProxy.PrimaryOrigins, &originRefs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRefs = []*serverconfigs.OriginRef{}
|
||||||
|
for _, originRef := range originRefs {
|
||||||
|
if originRef.OriginId > 0 {
|
||||||
|
newOriginId, err := SharedOriginDAO.CloneOrigin(tx, originRef.OriginId)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if newOriginId > 0 {
|
||||||
|
newRef, err := utils.JSONClone[*serverconfigs.OriginRef](originRef)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
newRef.OriginId = newOriginId
|
||||||
|
newRefs = append(newRefs, newRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newRefsJSON, err := json.Marshal(newRefs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.PrimaryOrigins = newRefsJSON
|
||||||
|
}
|
||||||
|
if IsNotNull(reverseProxy.BackupOrigins) {
|
||||||
|
var originRefs = []*serverconfigs.OriginRef{}
|
||||||
|
err = json.Unmarshal(reverseProxy.BackupOrigins, &originRefs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var newRefs = []*serverconfigs.OriginRef{}
|
||||||
|
for _, originRef := range originRefs {
|
||||||
|
if originRef.OriginId > 0 {
|
||||||
|
newOriginId, err := SharedOriginDAO.CloneOrigin(tx, originRef.OriginId)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if newOriginId > 0 {
|
||||||
|
newRef, err := utils.JSONClone[*serverconfigs.OriginRef](originRef)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
newRef.OriginId = newOriginId
|
||||||
|
newRefs = append(newRefs, newRef)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newRefsJSON, err := json.Marshal(newRefs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
op.BackupOrigins = newRefsJSON
|
||||||
|
}
|
||||||
|
op.StripPrefix = reverseProxy.StripPrefix
|
||||||
|
op.RequestHostType = reverseProxy.RequestHostType
|
||||||
|
op.RequestHost = reverseProxy.RequestHost
|
||||||
|
op.RequestHostExcludingPort = reverseProxy.RequestHostExcludingPort
|
||||||
|
op.RequestURI = reverseProxy.RequestURI
|
||||||
|
op.AutoFlush = reverseProxy.AutoFlush
|
||||||
|
if IsNotNull(reverseProxy.AddHeaders) {
|
||||||
|
// TODO 复制Header
|
||||||
|
op.AddHeaders = reverseProxy.AddHeaders
|
||||||
|
}
|
||||||
|
op.State = reverseProxy.State
|
||||||
|
if IsNotNull(reverseProxy.ConnTimeout) {
|
||||||
|
op.ConnTimeout = reverseProxy.ConnTimeout
|
||||||
|
}
|
||||||
|
if IsNotNull(reverseProxy.ReadTimeout) {
|
||||||
|
op.ReadTimeout = reverseProxy.ReadTimeout
|
||||||
|
}
|
||||||
|
if IsNotNull(reverseProxy.IdleTimeout) {
|
||||||
|
op.IdleTimeout = reverseProxy.IdleTimeout
|
||||||
|
}
|
||||||
|
op.MaxConns = reverseProxy.MaxConns
|
||||||
|
op.MaxIdleConns = reverseProxy.MaxIdleConns
|
||||||
|
if IsNotNull(reverseProxy.ProxyProtocol) {
|
||||||
|
op.ProxyProtocol = reverseProxy.ProxyProtocol
|
||||||
|
}
|
||||||
|
op.FollowRedirects = reverseProxy.FollowRedirects
|
||||||
|
|
||||||
|
return this.SaveInt64(tx, op)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateReverseProxyScheduling 修改反向代理调度算法
|
// UpdateReverseProxyScheduling 修改反向代理调度算法
|
||||||
func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error {
|
func (this *ReverseProxyDAO) UpdateReverseProxyScheduling(tx *dbs.Tx, reverseProxyId int64, schedulingJSON []byte) error {
|
||||||
if reverseProxyId <= 0 {
|
if reverseProxyId <= 0 {
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ func (this *ServerDAO) FindEnabledServerBasic(tx *dbs.Tx, serverId int64) (*Serv
|
|||||||
result, err := this.Query(tx).
|
result, err := this.Query(tx).
|
||||||
Pk(serverId).
|
Pk(serverId).
|
||||||
State(ServerStateEnabled).
|
State(ServerStateEnabled).
|
||||||
Result("id", "name", "description", "isOn", "type", "clusterId", "userId").
|
Result("id", "name", "description", "isOn", "type", "clusterId", "userId", "groupIds").
|
||||||
Find()
|
Find()
|
||||||
if result == nil {
|
if result == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -1,173 +0,0 @@
|
|||||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
||||||
|
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 服务基本信息
|
|
||||||
type clusterServerList struct {
|
|
||||||
clusterId int64
|
|
||||||
serverIds []int64
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyServerConfigToServers 拷贝服务配置到一组服务
|
|
||||||
func (this *ServerDAO) CopyServerConfigToServers(tx *dbs.Tx, fromServerId int64, toServerIds []int64, configCode serverconfigs.ConfigCode) error {
|
|
||||||
if fromServerId <= 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if len(toServerIds) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
webId, err := SharedServerDAO.FindServerWebId(tx, fromServerId)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
clusterServers, toWebIds, err := this.findServerClusterIdsAndWebIds(tx, toServerIds)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(clusterServers) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch configCode {
|
|
||||||
case serverconfigs.ConfigCodeStat: // 统计
|
|
||||||
if webId <= 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = SharedHTTPWebDAO.CopyWebStats(tx, webId, toWebIds)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 通知更新
|
|
||||||
for _, serverList := range clusterServers {
|
|
||||||
err = SharedUpdatingServerListDAO.CreateList(tx, serverList.clusterId, serverList.serverIds)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = SharedNodeTaskDAO.CreateClusterTask(tx, nodeconfigs.NodeRoleNode, serverList.clusterId, 0, 0, NodeTaskTypeUpdatingServers)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找一组服务的集群和WebId信息
|
|
||||||
func (this *ServerDAO) findServerClusterIdsAndWebIds(tx *dbs.Tx, serverIds []int64) (clusterServers []*clusterServerList, webIds []int64, err error) {
|
|
||||||
if len(serverIds) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ones, err := this.Query(tx).
|
|
||||||
Result("id", "webId", "clusterId").
|
|
||||||
Pk(serverIds).
|
|
||||||
Reuse(false).
|
|
||||||
FindAll()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var clusterMap = map[int64]*clusterServerList{} // clusterId => servers
|
|
||||||
|
|
||||||
for _, one := range ones {
|
|
||||||
var server = one.(*Server)
|
|
||||||
var clusterId = int64(server.ClusterId)
|
|
||||||
if clusterId <= 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
serverList, ok := clusterMap[clusterId]
|
|
||||||
if ok {
|
|
||||||
serverList.serverIds = append(serverList.serverIds, int64(server.Id))
|
|
||||||
} else {
|
|
||||||
clusterMap[clusterId] = &clusterServerList{
|
|
||||||
clusterId: clusterId,
|
|
||||||
serverIds: []int64{int64(server.Id)},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var webId = int64(server.WebId)
|
|
||||||
if webId > 0 {
|
|
||||||
webIds = append(webIds, webId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, serverList := range clusterMap {
|
|
||||||
clusterServers = append(clusterServers, serverList)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyServerConfigToGroups 拷贝服务配置到分组
|
|
||||||
func (this *ServerDAO) CopyServerConfigToGroups(tx *dbs.Tx, fromServerId int64, groupIds []int64, configCode string) error {
|
|
||||||
if len(groupIds) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var serverIds = []int64{}
|
|
||||||
for _, groupId := range groupIds {
|
|
||||||
ones, err := this.Query(tx).
|
|
||||||
ResultPk().
|
|
||||||
State(ServerStateEnabled).
|
|
||||||
Where("JSON_CONTAINS(groupIds, :groupId)").
|
|
||||||
Param("groupId", groupId).
|
|
||||||
FindAll()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, one := range ones {
|
|
||||||
serverIds = append(serverIds, int64(one.(*Server).Id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.CopyServerConfigToServers(tx, fromServerId, serverIds, configCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyServerConfigToCluster 拷贝服务配置到集群
|
|
||||||
func (this *ServerDAO) CopyServerConfigToCluster(tx *dbs.Tx, fromServerId int64, clusterId int64, configCode string) error {
|
|
||||||
ones, err := this.Query(tx).
|
|
||||||
ResultPk().
|
|
||||||
State(ServerStateEnabled).
|
|
||||||
Attr("clusterId", clusterId).
|
|
||||||
UseIndex("clusterId").
|
|
||||||
FindAll()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var serverIds = []int64{}
|
|
||||||
for _, one := range ones {
|
|
||||||
serverIds = append(serverIds, int64(one.(*Server).Id))
|
|
||||||
}
|
|
||||||
return this.CopyServerConfigToServers(tx, fromServerId, serverIds, configCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyServerConfigToUser 拷贝服务配置到用户
|
|
||||||
func (this *ServerDAO) CopyServerConfigToUser(tx *dbs.Tx, fromServerId int64, userId int64, configCode string) error {
|
|
||||||
ones, err := this.Query(tx).
|
|
||||||
ResultPk().
|
|
||||||
State(ServerStateEnabled).
|
|
||||||
Attr("userId", userId).
|
|
||||||
UseIndex("userId").
|
|
||||||
FindAll()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var serverIds = []int64{}
|
|
||||||
for _, one := range ones {
|
|
||||||
serverIds = append(serverIds, int64(one.(*Server).Id))
|
|
||||||
}
|
|
||||||
return this.CopyServerConfigToServers(tx, fromServerId, serverIds, configCode)
|
|
||||||
}
|
|
||||||
35
internal/db/models/server_dao_copy_ext.go
Normal file
35
internal/db/models/server_dao_copy_ext.go
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
//go:build !plus
|
||||||
|
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
||||||
|
"github.com/iwind/TeaGo/dbs"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CopyServerConfigToServers 拷贝服务配置到一组服务
|
||||||
|
func (this *ServerDAO) CopyServerConfigToServers(tx *dbs.Tx, fromServerId int64, toServerIds []int64, configCode serverconfigs.ConfigCode) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyServerConfigToGroups 拷贝服务配置到分组
|
||||||
|
func (this *ServerDAO) CopyServerConfigToGroups(tx *dbs.Tx, fromServerId int64, groupIds []int64, configCode string) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyServerConfigToCluster 拷贝服务配置到集群
|
||||||
|
func (this *ServerDAO) CopyServerConfigToCluster(tx *dbs.Tx, fromServerId int64, clusterId int64, configCode string) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyServerConfigToUser 拷贝服务配置到用户
|
||||||
|
func (this *ServerDAO) CopyServerConfigToUser(tx *dbs.Tx, fromServerId int64, userId int64, configCode string) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyServerUAMConfigs 复制UAM设置
|
||||||
|
func (this *ServerDAO) CopyServerUAMConfigs(tx *dbs.Tx, fromServerId int64, toServerIds []int64) error {
|
||||||
|
return errors.New("not implemented")
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
|
||||||
|
|
||||||
package models_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
|
||||||
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
|
|
||||||
"github.com/iwind/TeaGo/dbs"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestServerDAO_CopyServerConfigToServers(t *testing.T) {
|
|
||||||
dbs.NotifyReady()
|
|
||||||
|
|
||||||
var tx *dbs.Tx
|
|
||||||
var dao = models.NewServerDAO()
|
|
||||||
|
|
||||||
err := dao.CopyServerConfigToServers(tx, 10170, []int64{23, 10171}, serverconfigs.ConfigCodeStat)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -424,6 +424,18 @@ func (this *ServerGroupDAO) ExistsGroup(tx *dbs.Tx, groupId int64) (bool, error)
|
|||||||
Exist()
|
Exist()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FindGroupUserId 读取分组所属用户
|
||||||
|
func (this *ServerGroupDAO) FindGroupUserId(tx *dbs.Tx, groupId int64) (userId int64, err error) {
|
||||||
|
if groupId <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return this.Query(tx).
|
||||||
|
Pk(groupId).
|
||||||
|
State(ServerGroupStateEnabled).
|
||||||
|
Result("userId").
|
||||||
|
FindInt64Col(0)
|
||||||
|
}
|
||||||
|
|
||||||
// NotifyUpdate 通知更新
|
// NotifyUpdate 通知更新
|
||||||
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
|
func (this *ServerGroupDAO) NotifyUpdate(tx *dbs.Tx, groupId int64) error {
|
||||||
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)
|
serverIds, err := SharedServerDAO.FindAllEnabledServerIdsWithGroupId(tx, groupId)
|
||||||
|
|||||||
@@ -1299,6 +1299,16 @@ func (this *ServerService) CountAllEnabledServersWithServerGroupId(ctx context.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
if userId <= 0 {
|
||||||
|
// 指定用户ID可以加快查询速度
|
||||||
|
groupUserId, err := models.SharedServerGroupDAO.FindGroupUserId(tx, req.ServerGroupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if groupUserId > 0 {
|
||||||
|
userId = groupUserId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
count, err := models.SharedServerDAO.CountAllEnabledServersWithGroupId(tx, req.ServerGroupId, userId)
|
count, err := models.SharedServerDAO.CountAllEnabledServersWithGroupId(tx, req.ServerGroupId, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1562,11 +1572,29 @@ func (this *ServerService) FindEnabledUserServerBasic(ctx context.Context, req *
|
|||||||
return &pb.FindEnabledUserServerBasicResponse{Server: nil}, nil
|
return &pb.FindEnabledUserServerBasicResponse{Server: nil}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 集群
|
||||||
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
|
clusterName, err := models.SharedNodeClusterDAO.FindNodeClusterName(tx, int64(server.ClusterId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分组
|
||||||
|
var pbGroups = []*pb.ServerGroup{}
|
||||||
|
for _, groupId := range server.DecodeGroupIds() {
|
||||||
|
group, err := models.SharedServerGroupDAO.FindEnabledServerGroup(tx, groupId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if group == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pbGroups = append(pbGroups, &pb.ServerGroup{
|
||||||
|
Id: groupId,
|
||||||
|
Name: group.Name,
|
||||||
|
UserId: int64(group.UserId),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return &pb.FindEnabledUserServerBasicResponse{Server: &pb.Server{
|
return &pb.FindEnabledUserServerBasicResponse{Server: &pb.Server{
|
||||||
Id: int64(server.Id),
|
Id: int64(server.Id),
|
||||||
Name: server.Name,
|
Name: server.Name,
|
||||||
@@ -1578,6 +1606,7 @@ func (this *ServerService) FindEnabledUserServerBasic(ctx context.Context, req *
|
|||||||
Id: int64(server.ClusterId),
|
Id: int64(server.ClusterId),
|
||||||
Name: clusterName,
|
Name: clusterName,
|
||||||
},
|
},
|
||||||
|
ServerGroups: pbGroups,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,21 +85,26 @@ func (this *ServerGroupService) DeleteServerGroup(ctx context.Context, req *pb.D
|
|||||||
// FindAllEnabledServerGroups 查询所有分组
|
// FindAllEnabledServerGroups 查询所有分组
|
||||||
func (this *ServerGroupService) FindAllEnabledServerGroups(ctx context.Context, req *pb.FindAllEnabledServerGroupsRequest) (*pb.FindAllEnabledServerGroupsResponse, error) {
|
func (this *ServerGroupService) FindAllEnabledServerGroups(ctx context.Context, req *pb.FindAllEnabledServerGroupsRequest) (*pb.FindAllEnabledServerGroupsResponse, error) {
|
||||||
// 校验请求
|
// 校验请求
|
||||||
_, userId, err := this.ValidateAdminAndUser(ctx, true)
|
adminId, userId, err := this.ValidateAdminAndUser(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if adminId > 0 {
|
||||||
|
userId = req.UserId
|
||||||
|
}
|
||||||
|
|
||||||
var tx = this.NullTx()
|
var tx = this.NullTx()
|
||||||
|
|
||||||
groups, err := models.SharedServerGroupDAO.FindAllEnabledGroups(tx, userId)
|
groups, err := models.SharedServerGroupDAO.FindAllEnabledGroups(tx, userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := []*pb.ServerGroup{}
|
var result = []*pb.ServerGroup{}
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
result = append(result, &pb.ServerGroup{
|
result = append(result, &pb.ServerGroup{
|
||||||
Id: int64(group.Id),
|
Id: int64(group.Id),
|
||||||
|
IsOn: group.IsOn,
|
||||||
Name: group.Name,
|
Name: group.Name,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -153,6 +158,7 @@ func (this *ServerGroupService) FindEnabledServerGroup(ctx context.Context, req
|
|||||||
return &pb.FindEnabledServerGroupResponse{
|
return &pb.FindEnabledServerGroupResponse{
|
||||||
ServerGroup: &pb.ServerGroup{
|
ServerGroup: &pb.ServerGroup{
|
||||||
Id: int64(group.Id),
|
Id: int64(group.Id),
|
||||||
|
IsOn: group.IsOn,
|
||||||
Name: group.Name,
|
Name: group.Name,
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
45
internal/utils/json.go
Normal file
45
internal/utils/json.go
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JSONClone 使用JSON协议克隆对象
|
||||||
|
func JSONClone[T any](ptr T) (newPtr T, err error) {
|
||||||
|
var ptrType = reflect.TypeOf(ptr)
|
||||||
|
var kind = ptrType.Kind()
|
||||||
|
if kind != reflect.Ptr && kind != reflect.Slice {
|
||||||
|
err = errors.New("JSONClone: input must be a ptr or slice")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var jsonData []byte
|
||||||
|
jsonData, err = json.Marshal(ptr)
|
||||||
|
if err != nil {
|
||||||
|
return ptr, errors.New("JSONClone: marshal failed: " + err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValue any
|
||||||
|
switch kind {
|
||||||
|
case reflect.Ptr:
|
||||||
|
newValue = reflect.New(ptrType.Elem()).Interface()
|
||||||
|
case reflect.Slice:
|
||||||
|
newValue = reflect.New(reflect.SliceOf(ptrType.Elem())).Interface()
|
||||||
|
default:
|
||||||
|
return ptr, errors.New("JSONClone: unknown data type")
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(jsonData, newValue)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.New("JSONClone: unmarshal failed: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind == reflect.Slice {
|
||||||
|
newValue = reflect.Indirect(reflect.ValueOf(newValue)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue.(T), nil
|
||||||
|
}
|
||||||
51
internal/utils/json_test.go
Normal file
51
internal/utils/json_test.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||||
|
|
||||||
|
package utils_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/TeaOSLab/EdgeAPI/internal/utils"
|
||||||
|
"github.com/iwind/TeaGo/logs"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestJSONClone(t *testing.T) {
|
||||||
|
type user struct {
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
|
||||||
|
var u = &user{
|
||||||
|
Name: "Jack",
|
||||||
|
Age: 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
newU, err := utils.JSONClone[*user](u)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Logf("%#v", newU)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONClone_Slice(t *testing.T) {
|
||||||
|
type user struct {
|
||||||
|
Name string
|
||||||
|
Age int
|
||||||
|
}
|
||||||
|
|
||||||
|
var u = []*user{
|
||||||
|
{
|
||||||
|
Name: "Jack",
|
||||||
|
Age: 20,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Lily",
|
||||||
|
Age: 18,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
newU, err := utils.JSONClone[[]*user](u)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
logs.PrintAsJSON(newU, t)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user