zzybgp.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package waf
  2. import (
  3. "context"
  4. "fmt"
  5. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  6. wafRep "github.com/go-nunu/nunu-layout-advanced/internal/repository/api/waf"
  7. "github.com/go-nunu/nunu-layout-advanced/internal/service"
  8. "strconv"
  9. "strings"
  10. "sync"
  11. )
  12. type ZzybgpService interface {
  13. SetDefense(ctx context.Context, hostId int64,defense int) error
  14. }
  15. func NewZzybgpService(
  16. service *service.Service,
  17. gatewayIpRep wafRep.GatewayipRepository,
  18. host service.HostService,
  19. aoDun service.AoDunService,
  20. ) ZzybgpService {
  21. return &zzybgpService{
  22. Service: service,
  23. gatewayIpRep: gatewayIpRep,
  24. host: host,
  25. aoDun: aoDun,
  26. }
  27. }
  28. type zzybgpService struct {
  29. *service.Service
  30. gatewayIpRep wafRep.GatewayipRepository
  31. host service.HostService
  32. aoDun service.AoDunService
  33. }
  34. func (s *zzybgpService) SetDefense(ctx context.Context, hostId int64, defense int) error {
  35. ips, err := s.gatewayIpRep.GetGatewayipOnlyIpByHostIdAll(ctx, hostId)
  36. if err != nil {
  37. return fmt.Errorf("通过hostId获取IP列表失败: %w", err)
  38. }
  39. if len(ips) == 0 {
  40. return nil
  41. }
  42. // 2.【修复BUG】使用一个明确的变量来存储最终生效的防御值
  43. effectiveDefense := defense
  44. // 如果传入的防御值为0,则从全局配置中获取
  45. if effectiveDefense == 0 {
  46. config, err := s.host.GetGlobalLimitConfig(ctx, int(hostId))
  47. if err != nil {
  48. return fmt.Errorf("获取全局限制配置失败: %w", err)
  49. }
  50. // 从配置中解析防御值
  51. defenseStr := strings.TrimSuffix(config.ConfigMaxProtection, "G")
  52. defenseInt, err := strconv.Atoi(defenseStr)
  53. if err != nil {
  54. // 如果解析失败,返回包含原始值的错误信息,便于排查
  55. return fmt.Errorf("解析防御配置 '%s' 失败: %w", config.ConfigMaxProtection, err)
  56. }
  57. // 如果配置的防御值也为0,则无需操作
  58. if defenseInt == 0 {
  59. return nil
  60. }
  61. // 将从配置中获取的值赋给 effectiveDefense
  62. effectiveDefense = defenseInt
  63. }
  64. var wg sync.WaitGroup
  65. // 创建一个足够大的 channel 来收集所有可能发生的错误
  66. errChan := make(chan error, len(ips))
  67. wg.Add(len(ips))
  68. for _, ip := range ips {
  69. go func(ipAddr string) {
  70. defer wg.Done()
  71. e := s.aoDun.SetDefense(ctx, v1.SetDefense{
  72. IpAddr: ipAddr,
  73. Defense: effectiveDefense,
  74. })
  75. if e != nil {
  76. // 3.【优化】为错误添加IP地址信息,便于定位问题
  77. errChan <- fmt.Errorf("IP [%s] 设置防御带宽失败: %w", ipAddr, e)
  78. }
  79. }(ip)
  80. }
  81. wg.Wait()
  82. close(errChan)
  83. var allErrors []error
  84. for e := range errChan {
  85. allErrors = append(allErrors, e)
  86. }
  87. if len(allErrors) > 0 {
  88. // 将多个错误信息拼接成一个字符串
  89. var errStrings []string
  90. for _, singleErr := range allErrors {
  91. errStrings = append(errStrings, singleErr.Error())
  92. }
  93. return fmt.Errorf("设置防御时发生多个错误: %s", strings.Join(errStrings, "; "))
  94. }
  95. return nil
  96. }