瀏覽代碼

feat(cdn): 优化 TCP转发功能

- 新增 CDN 相关接口和实现,包括编辑源站、修改网站基本信息等
- 重构 TCP转发服务,支持添加和删除源站
- 优化 TCP转发规则的创建和更新逻辑
- 修复了一些与 CDN 集成相关的问题
fusu 1 月之前
父節點
當前提交
f750e63ced
共有 3 個文件被更改,包括 160 次插入16 次删除
  1. 1 1
      internal/repository/tcpforwarding.go
  2. 99 1
      internal/service/cdn.go
  3. 60 14
      internal/service/tcpforwarding.go

+ 1 - 1
internal/repository/tcpforwarding.go

@@ -134,7 +134,7 @@ func (r *tcpforwardingRepository) EditTcpforwardingIps(ctx context.Context, req
 
 
 	updateData["deny_ip_list"] = req.DenyIpList
 	updateData["deny_ip_list"] = req.DenyIpList
 
 
-
+	updateData["cdn_origin_ids"] = req.CdnOriginIds
 	// 始终更新更新时间
 	// 始终更新更新时间
 	updateData["updated_at"] = time.Now()
 	updateData["updated_at"] = time.Now()
 
 

+ 99 - 1
internal/service/cdn.go

@@ -11,7 +11,9 @@ import (
 )
 )
 
 
 type CdnService interface {
 type CdnService interface {
+	// GetToken 获取token
 	GetToken(ctx context.Context) (string, error)
 	GetToken(ctx context.Context) (string, error)
+	// AddUser 注册用户
 	AddUser(ctx context.Context, req v1.User) (int64, error)
 	AddUser(ctx context.Context, req v1.User) (int64, error)
 	CreateGroup(ctx context.Context, req v1.Group) (int64, error)
 	CreateGroup(ctx context.Context, req v1.Group) (int64, error)
 	BindPlan(ctx context.Context, req v1.Plan) (int64, error)
 	BindPlan(ctx context.Context, req v1.Plan) (int64, error)
@@ -22,6 +24,13 @@ type CdnService interface {
 	CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
 	CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
 	EditOrigin(ctx context.Context, req v1.Origin) error
 	EditOrigin(ctx context.Context, req v1.Origin) error
 	AddServerOrigin(ctx context.Context, serverId int64, originId int64) error
 	AddServerOrigin(ctx context.Context, serverId int64, originId int64) error
+	EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error
+	// 修改网站基本信息
+	EditServerBasic (ctx context.Context, serverId int64,name string) error
+	// 从网站中删除某个源站
+	DelServerOrigin (ctx context.Context,serverId int64, originId int64) error
+	// 删除网站
+	DelServer(ctx context.Context, serverId int64) error
 }
 }
 
 
 func NewCdnService(
 func NewCdnService(
@@ -398,6 +407,7 @@ func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, er
 	return res.Data.OriginId, nil
 	return res.Data.OriginId, nil
 }
 }
 
 
+
 func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiType string) error {
 func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiType string) error {
 	typeName := apiType + "JSON"
 	typeName := apiType + "JSON"
 	formData := map[string]interface{}{
 	formData := map[string]interface{}{
@@ -420,6 +430,8 @@ func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiT
 
 
 }
 }
 
 
+// EditOrigin 编辑源站
+
 func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 	formData := map[string]interface{}{
 	formData := map[string]interface{}{
 		"originId":                req.OriginId,
 		"originId":                req.OriginId,
@@ -451,6 +463,8 @@ func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 	return nil
 	return nil
 }
 }
 
 
+
+// AddServerOrigin 网站绑定源站
 func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error  {
 func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error  {
 	formData := map[string]interface{}{
 	formData := map[string]interface{}{
 		"serverId": serverId,
 		"serverId": serverId,
@@ -458,7 +472,91 @@ func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, origin
 		"isPrimary": true,
 		"isPrimary": true,
 	}
 	}
 	apiUrl := s.Url + "ServerService/addServerOrigin"
 	apiUrl := s.Url + "ServerService/addServerOrigin"
-	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl) // 使用封装后的方法
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return err
+	}
+	var res v1.GeneralResponse[any]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return nil
+}
+
+// EditOriginIsOn 编辑源站是否开启
+func (s *cdnService) EditOriginIsOn(ctx context.Context, originId int64, isOn bool) error  {
+	formData := map[string]interface{}{
+		"originId": originId,
+		"isOn": isOn,
+	}
+	apiUrl := s.Url + "OriginService/updateOriginIsOn"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return err
+	}
+	var res v1.GeneralResponse[any]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return nil
+}
+
+// EditServerBasic 修改网站基本信息
+func (s *cdnService) EditServerBasic (ctx context.Context, serverId int64,name string) error  {
+	formData := map[string]interface{}{
+		"serverId": serverId,
+		"name": name,
+		"nodeClusterId" : 1,
+		"isOn": true,
+	}
+	apiUrl := s.Url + "ServerService/updateServerBasic"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return err
+	}
+	var res v1.GeneralResponse[any]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return nil
+}
+
+// DelServerOrigin 从网站中删除某个源站
+func (s *cdnService) DelServerOrigin (ctx context.Context,serverId int64, originId int64) error  {
+	formData := map[string]interface{}{
+		"serverId": serverId,
+		"originId": originId,
+	}
+	apiUrl := s.Url + "ServerService/deleteServerOrigin"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
+	if err != nil {
+		return err
+	}
+	var res v1.GeneralResponse[any]
+	if err := json.Unmarshal(resBody, &res); err != nil {
+		return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
+	}
+	if res.Code != 200 {
+		return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
+	}
+	return nil
+}
+
+func (s *cdnService) DelServer(ctx context.Context, serverId int64) error  {
+	formData := map[string]interface{}{
+		"serverId": serverId,
+	}
+	apiUrl := s.Url + "ServerService/deleteServer"
+	resBody, err := s.sendDataWithTokenRetry(ctx, formData, apiUrl)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 60 - 14
internal/service/tcpforwarding.go

@@ -8,9 +8,9 @@ import (
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 	"github.com/go-nunu/nunu-layout-advanced/internal/model"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"github.com/go-nunu/nunu-layout-advanced/internal/repository"
 	"golang.org/x/sync/errgroup"
 	"golang.org/x/sync/errgroup"
+	"maps"
 	"net"
 	"net"
 	"sort"
 	"sort"
-	"strconv"
 )
 )
 
 
 type TcpforwardingService interface {
 type TcpforwardingService interface {
@@ -166,10 +166,12 @@ func (s *tcpforwardingService) prepareWafData(ctx context.Context, req *v1.TcpFo
 
 
 func (s *tcpforwardingService) AddOrigin(ctx context.Context, req v1.TcpForwardingRequest) (map[string]int64, error) {
 func (s *tcpforwardingService) AddOrigin(ctx context.Context, req v1.TcpForwardingRequest) (map[string]int64, error) {
 	res := make(map[string]int64)
 	res := make(map[string]int64)
+
 	for _, v := range req.TcpForwardingData.BackendList {
 	for _, v := range req.TcpForwardingData.BackendList {
+
 		ip, port, err := net.SplitHostPort(v)
 		ip, port, err := net.SplitHostPort(v)
 		if err != nil {
 		if err != nil {
-			return nil, err
+			return nil, fmt.Errorf("无效的后端地址: %s", err)
 		}
 		}
 		addr := v1.Addr{
 		addr := v1.Addr{
 			Protocol: "tcp",
 			Protocol: "tcp",
@@ -264,19 +266,29 @@ func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.Tc
 	if err != nil {
 	if err != nil {
 		return  err
 		return  err
 	}
 	}
+
 	oldData, err := s.tcpforwardingRepository.GetTcpforwarding(ctx, int64(req.TcpForwardingData.Id))
 	oldData, err := s.tcpforwardingRepository.GetTcpforwarding(ctx, int64(req.TcpForwardingData.Id))
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	//修改网站
-	editData := v1.EditWebsite{
-		Id: int64(oldData.CdnWebId),
-		TypeJSON: formData.TcpJSON,
+	//修改网站端口
+	if oldData.Port != req.TcpForwardingData.Port {
+		err = s.cdn.EditServerType(ctx, v1.EditWebsite{
+			Id:       int64(oldData.CdnWebId),
+			TypeJSON: formData.TcpJSON,
+		}, "tcp")
+		if err != nil {
+			return err
+		}
 	}
 	}
-	err = s.cdn.EditServerType(ctx, editData,"tcp")
-	if err != nil {
-		return err
+
+	//修改网站名字
+	if oldData.Comment != req.TcpForwardingData.Comment {
+		err = s.cdn.EditServerBasic(ctx, int64(oldData.CdnWebId), require.Tag)
+		if err != nil {
+			return err
+		}
 	}
 	}
 
 
 	// 异步任务:将IP添加到白名单
 	// 异步任务:将IP添加到白名单
@@ -306,12 +318,46 @@ func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.Tc
 		}
 		}
 	}
 	}
 
 
-	tcpModel := s.buildTcpForwardingModel(&req.TcpForwardingData, req.TcpForwardingData.WafTcpId, require)
+	addOrigins, delOrigins := s.wafformatter.findIpDifferences(ipData.BackendList, req.TcpForwardingData.BackendList)
+	addedIds, err := s.AddOrigin(ctx,v1.TcpForwardingRequest{
+		HostId:            req.HostId,
+		Uid:               req.Uid,
+		TcpForwardingData: v1.TcpForwardingDataRequest{
+			Id: req.TcpForwardingData.Id,
+			BackendList: addOrigins,
+			Comment: req.TcpForwardingData.Comment,
+		},
+	})
+
+	for _, v := range addedIds {
+		err = s.cdn.AddServerOrigin(ctx, int64(oldData.CdnWebId), v)
+		if err != nil {
+			return err
+		}
+	}
+
+	if err != nil {
+		return err
+	}
+	maps.Copy(ipData.CdnOriginIds, addedIds)
+	for k, v := range ipData.CdnOriginIds {
+		for _, ip := range delOrigins {
+			if k == ip {
+				err = s.cdn.DelServerOrigin(ctx, int64(oldData.CdnWebId), v)
+				if err != nil {
+					return err
+				}
+				delete(ipData.CdnOriginIds, k)
+			}
+		}
+	}
+
+	tcpModel := s.buildTcpForwardingModel(&req.TcpForwardingData,oldData.CdnWebId, require)
 	tcpModel.Id = req.TcpForwardingData.Id
 	tcpModel.Id = req.TcpForwardingData.Id
 		if err = s.tcpforwardingRepository.EditTcpforwarding(ctx, tcpModel); err != nil {
 		if err = s.tcpforwardingRepository.EditTcpforwarding(ctx, tcpModel); err != nil {
 		return  err
 		return  err
 	}
 	}
-	TcpRuleModel := s.buildTcpRuleModel(&req.TcpForwardingData, require, req.TcpForwardingData.Id)
+	TcpRuleModel := s.buildTcpRuleModel(&req.TcpForwardingData, require, req.TcpForwardingData.Id, ipData.CdnOriginIds)
 	if err = s.tcpforwardingRepository.EditTcpforwardingIps(ctx, *TcpRuleModel); err != nil {
 	if err = s.tcpforwardingRepository.EditTcpforwardingIps(ctx, *TcpRuleModel); err != nil {
 		return err
 		return err
 	}
 	}
@@ -320,12 +366,12 @@ func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.Tc
 
 
 func (s *tcpforwardingService) DeleteTcpForwarding(ctx context.Context, req v1.DeleteTcpForwardingRequest)  error {
 func (s *tcpforwardingService) DeleteTcpForwarding(ctx context.Context, req v1.DeleteTcpForwardingRequest)  error {
 	for _, Id := range req.Ids {
 	for _, Id := range req.Ids {
-		wafTcpId, err := s.tcpforwardingRepository.GetTcpforwardingWafTcpIdById(ctx, Id)
+		oldData, err := s.tcpforwardingRepository.GetTcpforwarding(ctx, int64(Id))
 		if err != nil {
 		if err != nil {
-			return  err
+			return err
 		}
 		}
 
 
-		_, err = s.crawler.DeleteRule(ctx, wafTcpId, "admin/delete/waf_tcp?page=1&__pageSize=1000000&__sort=waf_tcp_id&__sort_type=desc")
+		err = s.cdn.DelServer(ctx, int64(oldData.CdnWebId))
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}