|
@@ -2,7 +2,6 @@ package waf
|
|
|
|
|
|
import (
|
|
|
"context"
|
|
|
- "encoding/json"
|
|
|
"fmt"
|
|
|
v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
|
|
|
"github.com/go-nunu/nunu-layout-advanced/internal/model"
|
|
@@ -11,8 +10,6 @@ import (
|
|
|
"github.com/go-nunu/nunu-layout-advanced/internal/service"
|
|
|
"github.com/go-nunu/nunu-layout-advanced/internal/service/api/flexCdn"
|
|
|
"golang.org/x/sync/errgroup"
|
|
|
- "maps"
|
|
|
- "net"
|
|
|
"sort"
|
|
|
)
|
|
|
|
|
@@ -35,6 +32,7 @@ func NewUdpForWardingService(
|
|
|
wafformatter WafFormatterService,
|
|
|
cdn flexCdn.CdnService,
|
|
|
proxy flexCdn.ProxyService,
|
|
|
+ aidedUdp AidedUdpService,
|
|
|
) UdpForWardingService {
|
|
|
return &udpForWardingService{
|
|
|
Service: service,
|
|
@@ -47,6 +45,7 @@ func NewUdpForWardingService(
|
|
|
wafformatter: wafformatter,
|
|
|
cdn: cdn,
|
|
|
proxy: proxy,
|
|
|
+ aidedUdp: aidedUdp,
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -59,425 +58,244 @@ type udpForWardingService struct {
|
|
|
crawler service.CrawlerService
|
|
|
globalRep waf.GlobalLimitRepository
|
|
|
hostRep repository.HostRepository
|
|
|
- wafformatter WafFormatterService
|
|
|
- cdn flexCdn.CdnService
|
|
|
- proxy flexCdn.ProxyService
|
|
|
+ wafformatter WafFormatterService
|
|
|
+ cdn flexCdn.CdnService
|
|
|
+ proxy flexCdn.ProxyService
|
|
|
+ aidedUdp AidedUdpService
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-func (s *udpForWardingService) GetUdpForWarding(ctx context.Context,req v1.GetForwardingRequest) (v1.UdpForwardingDataRequest, error) {
|
|
|
+// GetUdpForWarding 获取单个UDP转发配置详情
|
|
|
+// 该函数根据ID同时查询主记录和规则记录,并合并返回完整的配置信息
|
|
|
+func (s *udpForWardingService) GetUdpForWarding(ctx context.Context, req v1.GetForwardingRequest) (v1.UdpForwardingDataRequest, error) {
|
|
|
+ // 参数验证
|
|
|
+ if req.Id <= 0 {
|
|
|
+ return v1.UdpForwardingDataRequest{}, fmt.Errorf("非法的ID参数: %d", req.Id)
|
|
|
+ }
|
|
|
+
|
|
|
var udpForWarding model.UdpForWarding
|
|
|
var backend model.UdpForwardingRule
|
|
|
var err error
|
|
|
+
|
|
|
+ // 并发查询主记录和规则记录以提高性能
|
|
|
g, gCtx := errgroup.WithContext(ctx)
|
|
|
g.Go(func() error {
|
|
|
res, e := s.udpForWardingRepository.GetUdpForWarding(gCtx, int64(req.Id))
|
|
|
if e != nil {
|
|
|
- return fmt.Errorf("GetUdpForWarding failed: %w", e)
|
|
|
+ return fmt.Errorf("查询UDP转发主记录失败 ID:%d, %w", req.Id, e)
|
|
|
}
|
|
|
if res != nil {
|
|
|
udpForWarding = *res
|
|
|
}
|
|
|
return nil
|
|
|
})
|
|
|
+
|
|
|
g.Go(func() error {
|
|
|
res, e := s.udpForWardingRepository.GetUdpForwardingIpsByID(gCtx, req.Id)
|
|
|
if e != nil {
|
|
|
- return fmt.Errorf("GetUdpForWardingByID failed: %w", e)
|
|
|
+ return fmt.Errorf("查询UDP转发规则记录失败 ID:%d, %w", req.Id, e)
|
|
|
}
|
|
|
if res != nil {
|
|
|
backend = *res
|
|
|
}
|
|
|
return nil
|
|
|
})
|
|
|
+
|
|
|
if err = g.Wait(); err != nil {
|
|
|
return v1.UdpForwardingDataRequest{}, err
|
|
|
}
|
|
|
|
|
|
- return v1.UdpForwardingDataRequest{
|
|
|
- Id: udpForWarding.Id,
|
|
|
- Port: udpForWarding.Port,
|
|
|
- BackendList: backend.BackendList,
|
|
|
- Comment: udpForWarding.Comment,
|
|
|
- Proxy: udpForWarding.Proxy,
|
|
|
- }, nil
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-func (s *udpForWardingService) buildUdpForwardingModel(req *v1.UdpForwardingDataRequest, ruleId int, require RequireResponse) *model.UdpForWarding {
|
|
|
- return &model.UdpForWarding{
|
|
|
- HostId: require.HostId,
|
|
|
- CdnWebId: ruleId,
|
|
|
- Port: req.Port,
|
|
|
- Comment: req.Comment,
|
|
|
- Proxy: req.Proxy,
|
|
|
+ // 检查是否找到主记录
|
|
|
+ if udpForWarding.Id == 0 {
|
|
|
+ return v1.UdpForwardingDataRequest{}, fmt.Errorf("UDP转发配置不存在 ID:%d", req.Id)
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-func (s *udpForWardingService) buildUdpRuleModel(reqData *v1.UdpForwardingDataRequest, require RequireResponse, localDbId int, cdnOriginIds map[string]int64) *model.UdpForwardingRule {
|
|
|
- return &model.UdpForwardingRule{
|
|
|
- Uid: require.Uid,
|
|
|
- HostId: require.HostId,
|
|
|
- UdpId: localDbId, // 关联到本地数据库的主记录 ID
|
|
|
- CdnOriginIds: cdnOriginIds,
|
|
|
- BackendList: reqData.BackendList,
|
|
|
- }
|
|
|
+ return v1.UdpForwardingDataRequest{
|
|
|
+ Id: udpForWarding.Id,
|
|
|
+ Port: udpForWarding.Port,
|
|
|
+ BackendList: backend.BackendList,
|
|
|
+ Comment: udpForWarding.Comment,
|
|
|
+ Proxy: udpForWarding.Proxy,
|
|
|
+ }, nil
|
|
|
}
|
|
|
|
|
|
-func (s *udpForWardingService) prepareWafData(ctx context.Context, req *v1.UdpForwardingRequest) (RequireResponse, v1.WebsiteSend, error) {
|
|
|
- require, err := s.wafformatter.Require(ctx, v1.GlobalRequire{
|
|
|
- HostId: req.HostId,
|
|
|
- Uid: req.Uid,
|
|
|
- Comment: req.UdpForwardingData.Comment,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return RequireResponse{}, v1.WebsiteSend{}, err
|
|
|
- }
|
|
|
- if require.Uid == 0 {
|
|
|
- return RequireResponse{}, v1.WebsiteSend{}, fmt.Errorf("请先配置实例")
|
|
|
- }
|
|
|
- var jsonData v1.TypeJSON
|
|
|
- jsonData.IsOn = true
|
|
|
- for _, v := range require.GatewayIps {
|
|
|
- jsonData.Listen = append(jsonData.Listen, v1.Listen{
|
|
|
- Protocol: "udp",
|
|
|
- Host: v,
|
|
|
- Port: req.UdpForwardingData.Port,
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- byteData, err := json.Marshal(jsonData)
|
|
|
- if err != nil {
|
|
|
- return RequireResponse{}, v1.WebsiteSend{}, err
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
|
|
|
- formData := v1.WebsiteSend{
|
|
|
- UserId: int64(require.CdnUid),
|
|
|
- Type: "udpProxy",
|
|
|
- Name: require.Tag,
|
|
|
- Description: req.UdpForwardingData.Comment,
|
|
|
- UdpJSON: byteData,
|
|
|
- ServerGroupIds: []int64{int64(require.GroupId)},
|
|
|
- NodeClusterId: 2,
|
|
|
- }
|
|
|
- return require, formData, nil
|
|
|
-}
|
|
|
-
|
|
|
+// AddUdpForwarding 添加 UDP 转发配置
|
|
|
+// 该函数完成 UDP 转发的完整创建流程:验证、创建 CDN、添加源站、配置代理、保存数据、处理异步任务
|
|
|
func (s *udpForWardingService) AddUdpForwarding(ctx context.Context, req *v1.UdpForwardingRequest) (int, error) {
|
|
|
- require, formData, err := s.prepareWafData(ctx, req)
|
|
|
+ // 1. 数据准备和验证
|
|
|
+ require, formData, err := s.aidedUdp.PrepareWafData(ctx, req)
|
|
|
if err != nil {
|
|
|
return 0, err
|
|
|
}
|
|
|
- err = s.wafformatter.validateWafPortCount(ctx, require.HostId)
|
|
|
- if err != nil {
|
|
|
+
|
|
|
+ if err := s.aidedUdp.ValidateAddRequest(ctx, req, require); err != nil {
|
|
|
return 0, err
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- // 验证端口重复
|
|
|
- err = s.wafformatter.VerifyPort(ctx, "udp", int64(req.UdpForwardingData.Id), req.UdpForwardingData.Port, int64(require.HostId), "")
|
|
|
+ // 2. 创建CDN网站
|
|
|
+ udpId, err := s.aidedUdp.CreateCdnWebsite(ctx, formData)
|
|
|
if err != nil {
|
|
|
return 0, err
|
|
|
}
|
|
|
|
|
|
- udpId, err := s.cdn.CreateWebsite(ctx, formData)
|
|
|
+ // 3. 添加源站
|
|
|
+ cdnOriginIds, err := s.aidedUdp.AddOriginsToWebsite(ctx, req, udpId)
|
|
|
if err != nil {
|
|
|
return 0, err
|
|
|
}
|
|
|
|
|
|
- // 添加源站
|
|
|
- cdnOriginIds := make(map[string]int64)
|
|
|
- for _, v := range req.UdpForwardingData.BackendList {
|
|
|
- id, err := s.wafformatter.AddOrigin(ctx, v1.WebJson{
|
|
|
- ApiType: "udp",
|
|
|
- BackendList: v,
|
|
|
- Comment: req.UdpForwardingData.Comment,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- cdnOriginIds[v] = id
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 添加源站到网站
|
|
|
- for _, v := range cdnOriginIds {
|
|
|
- err = s.cdn.AddServerOrigin(ctx, udpId, v)
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // 开启proxy
|
|
|
- if req.UdpForwardingData.Proxy {
|
|
|
- err = s.proxy.EditProxy(ctx,udpId, v1.ProxyProtocolJSON{
|
|
|
- IsOn: true,
|
|
|
- Version: 1,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
+ // 4. 配置代理协议
|
|
|
+ if err := s.aidedUdp.ConfigureProxyProtocol(ctx, req, udpId); err != nil {
|
|
|
+ return 0, err
|
|
|
}
|
|
|
|
|
|
- udpModel := s.buildUdpForwardingModel(&req.UdpForwardingData, int(udpId), require)
|
|
|
-
|
|
|
- id, err := s.udpForWardingRepository.AddUdpForwarding(ctx, udpModel)
|
|
|
+ // 5. 保存到数据库
|
|
|
+ id, err := s.aidedUdp.SaveToDatabase(ctx, req, require, udpId, cdnOriginIds)
|
|
|
if err != nil {
|
|
|
return 0, err
|
|
|
}
|
|
|
- udpRuleModel := s.buildUdpRuleModel(&req.UdpForwardingData, require, id, cdnOriginIds)
|
|
|
- if _, err = s.udpForWardingRepository.AddUdpForwardingIps(ctx, *udpRuleModel); err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
|
|
|
- // 异步任务:将IP添加到白名单
|
|
|
- var ips []string
|
|
|
- if req.UdpForwardingData.BackendList != nil {
|
|
|
- for _, v := range req.UdpForwardingData.BackendList {
|
|
|
- ip, _, err := net.SplitHostPort(v)
|
|
|
- if err != nil {
|
|
|
- return 0, err
|
|
|
- }
|
|
|
- ips = append(ips, ip)
|
|
|
- }
|
|
|
- go s.wafformatter.PublishIpWhitelistTask(ips, "add","","white")
|
|
|
- }
|
|
|
+ // 6. 处理异步任务
|
|
|
+ s.aidedUdp.ProcessAsyncTasks(req)
|
|
|
|
|
|
return id, nil
|
|
|
}
|
|
|
|
|
|
+// EditUdpForwarding 编辑 UDP 转发配置
|
|
|
+// 该函数完成 UDP 转发的完整编辑流程:验证、更新 CDN、处理IP白名单、更新源站、更新数据库
|
|
|
func (s *udpForWardingService) EditUdpForwarding(ctx context.Context, req *v1.UdpForwardingRequest) error {
|
|
|
- require, formData, err := s.prepareWafData(ctx, req)
|
|
|
+ // 1. 数据准备和验证
|
|
|
+ require, formData, err := s.aidedUdp.PrepareWafData(ctx, req)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
oldData, err := s.udpForWardingRepository.GetUdpForWarding(ctx, int64(req.UdpForwardingData.Id))
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return fmt.Errorf("获取原始数据失败: %w", err)
|
|
|
}
|
|
|
|
|
|
- // 验证端口重复
|
|
|
- if oldData.Port != req.UdpForwardingData.Port {
|
|
|
- err = s.wafformatter.VerifyPort(ctx, "udp", int64(req.UdpForwardingData.Id), req.UdpForwardingData.Port, int64(require.HostId), "")
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ if err := s.aidedUdp.ValidateEditRequest(ctx, req, require, oldData); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
- //修改网站端口
|
|
|
- if oldData.Port != req.UdpForwardingData.Port {
|
|
|
- err = s.cdn.EditServerType(ctx, v1.EditWebsite{
|
|
|
- Id: int64(oldData.CdnWebId),
|
|
|
- TypeJSON: formData.TcpJSON,
|
|
|
- }, "tcp")
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ // 2. 更新CDN配置
|
|
|
+ if err := s.aidedUdp.UpdateCdnConfiguration(ctx, req, oldData, require, formData); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
- //修改网站名字
|
|
|
- if oldData.Comment != req.UdpForwardingData.Comment {
|
|
|
- nodeId, err := s.globalRep.GetNodeId(ctx, oldData.CdnWebId)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- err = s.cdn.EditServerBasic(ctx, int64(oldData.CdnWebId), require.Tag, nodeId)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ // 3. 获取IP数据并处理白名单
|
|
|
+ ipData, err := s.udpForWardingRepository.GetUdpForwardingIpsByID(ctx, req.UdpForwardingData.Id)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("获取IP数据失败: %w", err)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- //修改Proxy
|
|
|
- if oldData.Proxy != req.UdpForwardingData.Proxy {
|
|
|
- err = s.proxy.EditProxy(ctx, int64(oldData.CdnWebId), v1.ProxyProtocolJSON{
|
|
|
- IsOn: req.UdpForwardingData.Proxy,
|
|
|
- Version: 1,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ if err := s.aidedUdp.ProcessIpWhitelistChanges(ctx, req, ipData); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
- // 异步任务:将IP添加到白名单
|
|
|
- ipData, err := s.udpForWardingRepository.GetUdpForwardingIpsByID(ctx, req.UdpForwardingData.Id)
|
|
|
- if err != nil {
|
|
|
+ // 4. 更新源站配置
|
|
|
+ if err := s.aidedUdp.UpdateOriginServers(ctx, req, oldData, ipData); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- addedIps, removedIps, err := s.wafformatter.WashEditWafIp(ctx,req.UdpForwardingData.BackendList,ipData.BackendList)
|
|
|
- if err != nil {
|
|
|
+
|
|
|
+ // 5. 更新数据库记录
|
|
|
+ if err := s.aidedUdp.UpdateDatabaseRecords(ctx, req, oldData, require, ipData); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if len(addedIps) > 0 {
|
|
|
- go s.wafformatter.PublishIpWhitelistTask(addedIps, "add","","white")
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
+ return nil
|
|
|
+}
|
|
|
|
|
|
- if len(removedIps) > 0 {
|
|
|
- ipsToDelist, err := s.wafformatter.WashDelIps(ctx, removedIps)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // 4. 如果有需要处理的IP,则批量发布一次任务
|
|
|
- if len(ipsToDelist) > 0 {
|
|
|
- go s.wafformatter.PublishIpWhitelistTask(ipsToDelist, "del", "0", "white")
|
|
|
+// DeleteUdpForwarding 批量删除 UDP 转发配置
|
|
|
+// 该函数支持批量删除多个 UDP 转发配置,对每个配置都执行完整的删除流程
|
|
|
+func (s *udpForWardingService) DeleteUdpForwarding(ctx context.Context, req v1.DeleteUdpForwardingRequest) error {
|
|
|
+ // 批量删除处理
|
|
|
+ for _, id := range req.Ids {
|
|
|
+ if err := s.deleteSingleUdpForwarding(ctx, id, req.HostId); err != nil {
|
|
|
+ return fmt.Errorf("删除UDP转发配置失败 ID:%d, %w", id, err)
|
|
|
}
|
|
|
}
|
|
|
+ return nil
|
|
|
+}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- //修改源站
|
|
|
- addOrigins, delOrigins := s.wafformatter.findIpDifferences(ipData.BackendList, req.UdpForwardingData.BackendList)
|
|
|
- addedIds := make(map[string]int64)
|
|
|
- for _, v := range addOrigins {
|
|
|
- id, err := s.wafformatter.AddOrigin(ctx,v1.WebJson{
|
|
|
- ApiType: "udp",
|
|
|
- BackendList: v,
|
|
|
- Comment: req.UdpForwardingData.Comment,
|
|
|
- })
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- addedIds[v] = id
|
|
|
+// deleteSingleUdpForwarding 删除单个 UDP 转发配置
|
|
|
+// 该函数完成单个配置的完整删除流程:权限验证、删除 CDN、清理IP白名单、清理数据库
|
|
|
+func (s *udpForWardingService) deleteSingleUdpForwarding(ctx context.Context, id int, hostId int) error {
|
|
|
+ // 1. 获取原始数据并验证权限
|
|
|
+ oldData, err := s.udpForWardingRepository.GetUdpForWarding(ctx, int64(id))
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("获取UDP转发数据失败: %w", err)
|
|
|
}
|
|
|
|
|
|
- for _, v := range addedIds {
|
|
|
- err = s.cdn.AddServerOrigin(ctx, int64(oldData.CdnWebId), v)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
+ if err := s.aidedUdp.ValidateDeletePermission(oldData, hostId); 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)
|
|
|
- }
|
|
|
- }
|
|
|
+ // 2. 删除CDN服务器
|
|
|
+ if err := s.aidedUdp.DeleteCdnServer(ctx, oldData.CdnWebId); err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- udpModel := s.buildUdpForwardingModel(&req.UdpForwardingData, oldData.CdnWebId, require)
|
|
|
- udpModel.Id = req.UdpForwardingData.Id
|
|
|
- if err = s.udpForWardingRepository.EditUdpForwarding(ctx, udpModel); err != nil {
|
|
|
+ // 3. 处理IP白名单清理
|
|
|
+ if err := s.aidedUdp.ProcessDeleteIpWhitelist(ctx, id); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- udpRuleModel := s.buildUdpRuleModel(&req.UdpForwardingData, require, req.UdpForwardingData.Id, ipData.CdnOriginIds)
|
|
|
- if err = s.udpForWardingRepository.EditUdpForwardingIps(ctx, *udpRuleModel); err != nil {
|
|
|
+
|
|
|
+ // 4. 清理数据库记录
|
|
|
+ if err := s.aidedUdp.CleanupDatabaseRecords(ctx, id); err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *udpForWardingService) DeleteUdpForwarding(ctx context.Context, req v1.DeleteUdpForwardingRequest) error {
|
|
|
- for _, id := range req.Ids {
|
|
|
- oldData, err := s.udpForWardingRepository.GetUdpForWarding(ctx, int64(id))
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- if oldData.HostId != req.HostId {
|
|
|
- return fmt.Errorf("用户权限不足")
|
|
|
- }
|
|
|
-
|
|
|
- err = s.cdn.DelServer(ctx, int64(oldData.CdnWebId))
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // 异步任务:将IP添加到白名单
|
|
|
- ipData, err := s.udpForWardingRepository.GetUdpForwardingIpsByID(ctx, id)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- var ips []string
|
|
|
-
|
|
|
- if ipData != nil && len(ipData.BackendList) > 0 {
|
|
|
- ips, err = s.wafformatter.WashDeleteWafIp(ctx, ipData.BackendList)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- if len(ips) > 0 {
|
|
|
- ipsToDelist, err := s.wafformatter.WashDelIps(ctx, ips)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // 4. 如果有需要处理的IP,则批量发布一次任务
|
|
|
- if len(ipsToDelist) > 0 {
|
|
|
- go s.wafformatter.PublishIpWhitelistTask(ipsToDelist, "del", "0", "white")
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- if err = s.udpForWardingRepository.DeleteUdpForwarding(ctx, int64(id)); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- if err = s.udpForWardingRepository.DeleteUdpForwardingIpsById(ctx, id); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+// GetUdpForwardingWafUdpAllIps 获取指定主机的所有 UDP 转发配置列表
|
|
|
+// 该函数使用并发查询优化性能,同时获取多个配置的详细信息并按ID降序排列
|
|
|
func (s *udpForWardingService) GetUdpForwardingWafUdpAllIps(ctx context.Context, req v1.GetForwardingRequest) ([]v1.UdpForwardingDataRequest, error) {
|
|
|
type CombinedResult struct {
|
|
|
Id int
|
|
|
Forwarding *model.UdpForWarding
|
|
|
BackendRule *model.UdpForwardingRule
|
|
|
- Err error // 如果此ID的处理出错,则携带错误
|
|
|
+ Err error
|
|
|
}
|
|
|
|
|
|
- g,gCtx := errgroup.WithContext(ctx)
|
|
|
+ g, gCtx := errgroup.WithContext(ctx)
|
|
|
ids, err := s.udpForWardingRepository.GetUdpForwardingWafUdpAllIds(gCtx, req.HostId)
|
|
|
if err != nil {
|
|
|
- return nil, fmt.Errorf("GetUdpForwardingWafUdpAllIds failed: %w", err)
|
|
|
+ return nil, fmt.Errorf("获取UDP转发ID列表失败: %w", err)
|
|
|
}
|
|
|
if len(ids) == 0 {
|
|
|
return nil, nil
|
|
|
}
|
|
|
resChan := make(chan CombinedResult, len(ids))
|
|
|
|
|
|
- for _, idVal := range ids {
|
|
|
- currentID := idVal
|
|
|
- g.Go(func() error {
|
|
|
- var wf *model.UdpForWarding
|
|
|
- var bk *model.UdpForwardingRule
|
|
|
- var localErr error
|
|
|
- wf, localErr = s.udpForWardingRepository.GetUdpForWarding(gCtx, int64(currentID))
|
|
|
- if localErr != nil {
|
|
|
- resChan <- CombinedResult{Id: currentID, Err: localErr}
|
|
|
- return localErr
|
|
|
- }
|
|
|
- bk, localErr = s.udpForWardingRepository.GetUdpForwardingIpsByID(gCtx, currentID)
|
|
|
- if localErr != nil {
|
|
|
- resChan <- CombinedResult{Id: currentID, Err: localErr}
|
|
|
- return localErr
|
|
|
- }
|
|
|
- resChan <- CombinedResult{Id: currentID, Forwarding: wf, BackendRule: bk}
|
|
|
- return nil
|
|
|
- })
|
|
|
- }
|
|
|
+ g.Go(func() error {
|
|
|
+ for _, idVal := range ids {
|
|
|
+ currentID := idVal
|
|
|
+ g.Go(func() error {
|
|
|
+ var wf *model.UdpForWarding
|
|
|
+ var bk *model.UdpForwardingRule
|
|
|
+ var localErr error
|
|
|
+ wf, localErr = s.udpForWardingRepository.GetUdpForWarding(gCtx, int64(currentID))
|
|
|
+ if localErr != nil {
|
|
|
+ resChan <- CombinedResult{Id: currentID, Err: localErr}
|
|
|
+ return localErr
|
|
|
+ }
|
|
|
+ bk, localErr = s.udpForWardingRepository.GetUdpForwardingIpsByID(gCtx, currentID)
|
|
|
+ if localErr != nil {
|
|
|
+ resChan <- CombinedResult{Id: currentID, Err: localErr}
|
|
|
+ return localErr
|
|
|
+ }
|
|
|
+ resChan <- CombinedResult{Id: currentID, Forwarding: wf, BackendRule: bk}
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+ })
|
|
|
groupErr := g.Wait()
|
|
|
close(resChan)
|
|
|
if groupErr != nil {
|
|
@@ -486,17 +304,17 @@ func (s *udpForWardingService) GetUdpForwardingWafUdpAllIps(ctx context.Context,
|
|
|
res := make([]v1.UdpForwardingDataRequest, 0, len(ids))
|
|
|
for r := range resChan {
|
|
|
if r.Err != nil {
|
|
|
- return nil, fmt.Errorf("received error from goroutine for ID %d: %w", r.Id, r.Err)
|
|
|
+ return nil, fmt.Errorf("处理ID %d 时出错: %w", r.Id, r.Err)
|
|
|
}
|
|
|
- if r.Forwarding == nil {
|
|
|
- return nil, fmt.Errorf("received nil forwarding from goroutine for ID %d", r.Id)
|
|
|
+ if r.Forwarding == nil {
|
|
|
+ return nil, fmt.Errorf("ID %d 对应的转发配置为空", r.Id)
|
|
|
}
|
|
|
|
|
|
dataReq := v1.UdpForwardingDataRequest{
|
|
|
- Id: r.Forwarding.Id,
|
|
|
- Port: r.Forwarding.Port,
|
|
|
- Comment: r.Forwarding.Comment,
|
|
|
- Proxy: r.Forwarding.Proxy,
|
|
|
+ Id: r.Forwarding.Id,
|
|
|
+ Port: r.Forwarding.Port,
|
|
|
+ Comment: r.Forwarding.Comment,
|
|
|
+ Proxy: r.Forwarding.Proxy,
|
|
|
}
|
|
|
|
|
|
if r.BackendRule != nil {
|