Selaa lähdekoodia

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

- 新增 CDN 相关接口和实现,包括编辑源站、修改网站基本信息等
- 重构 TCP转发服务,支持添加和删除源站
- 优化 TCP转发规则的创建和更新逻辑
- 修复了一些与 CDN 集成相关的问题
fusu 1 kuukausi sitten
vanhempi
sitoutus
f750e63ced
3 muutettua tiedostoa jossa 160 lisäystä ja 16 poistoa
  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["cdn_origin_ids"] = req.CdnOriginIds
 	// 始终更新更新时间
 	updateData["updated_at"] = time.Now()
 

+ 99 - 1
internal/service/cdn.go

@@ -11,7 +11,9 @@ import (
 )
 
 type CdnService interface {
+	// GetToken 获取token
 	GetToken(ctx context.Context) (string, error)
+	// AddUser 注册用户
 	AddUser(ctx context.Context, req v1.User) (int64, error)
 	CreateGroup(ctx context.Context, req v1.Group) (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)
 	EditOrigin(ctx context.Context, req v1.Origin) 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(
@@ -398,6 +407,7 @@ func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, er
 	return res.Data.OriginId, nil
 }
 
+
 func (s *cdnService) EditServerType(ctx context.Context, req v1.EditWebsite,apiType string) error {
 	typeName := apiType + "JSON"
 	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 {
 	formData := map[string]interface{}{
 		"originId":                req.OriginId,
@@ -451,6 +463,8 @@ func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
 	return nil
 }
 
+
+// AddServerOrigin 网站绑定源站
 func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, originId int64) error  {
 	formData := map[string]interface{}{
 		"serverId": serverId,
@@ -458,7 +472,91 @@ func (s *cdnService) AddServerOrigin(ctx context.Context, serverId int64, origin
 		"isPrimary": true,
 	}
 	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 {
 		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/repository"
 	"golang.org/x/sync/errgroup"
+	"maps"
 	"net"
 	"sort"
-	"strconv"
 )
 
 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) {
 	res := make(map[string]int64)
+
 	for _, v := range req.TcpForwardingData.BackendList {
+
 		ip, port, err := net.SplitHostPort(v)
 		if err != nil {
-			return nil, err
+			return nil, fmt.Errorf("无效的后端地址: %s", err)
 		}
 		addr := v1.Addr{
 			Protocol: "tcp",
@@ -264,19 +266,29 @@ func (s *tcpforwardingService) EditTcpForwarding(ctx context.Context, req *v1.Tc
 	if err != nil {
 		return  err
 	}
+
 	oldData, err := s.tcpforwardingRepository.GetTcpforwarding(ctx, int64(req.TcpForwardingData.Id))
 	if err != nil {
 		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添加到白名单
@@ -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
 		if err = s.tcpforwardingRepository.EditTcpforwarding(ctx, tcpModel); err != nil {
 		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 {
 		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 {
 	for _, Id := range req.Ids {
-		wafTcpId, err := s.tcpforwardingRepository.GetTcpforwardingWafTcpIdById(ctx, Id)
+		oldData, err := s.tcpforwardingRepository.GetTcpforwarding(ctx, int64(Id))
 		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 {
 			return err
 		}