123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package waf
- import (
- "context"
- "fmt"
- v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
- wafRep "github.com/go-nunu/nunu-layout-advanced/internal/repository/api/waf"
- "github.com/go-nunu/nunu-layout-advanced/internal/service"
- "strconv"
- "strings"
- "sync"
- )
- type ZzybgpService interface {
- SetDefense(ctx context.Context, hostId int64,defense int) error
- }
- func NewZzybgpService(
- service *service.Service,
- gatewayIpRep wafRep.GatewayipRepository,
- host service.HostService,
- aoDun service.AoDunService,
- ) ZzybgpService {
- return &zzybgpService{
- Service: service,
- gatewayIpRep: gatewayIpRep,
- host: host,
- aoDun: aoDun,
- }
- }
- type zzybgpService struct {
- *service.Service
- gatewayIpRep wafRep.GatewayipRepository
- host service.HostService
- aoDun service.AoDunService
- }
- func (s *zzybgpService) SetDefense(ctx context.Context, hostId int64, defense int) error {
- ips, err := s.gatewayIpRep.GetGatewayipOnlyIpByHostIdAll(ctx, hostId)
- if err != nil {
- return fmt.Errorf("通过hostId获取IP列表失败: %w", err)
- }
- if len(ips) == 0 {
- return nil
- }
- // 2.【修复BUG】使用一个明确的变量来存储最终生效的防御值
- effectiveDefense := defense
- // 如果传入的防御值为0,则从全局配置中获取
- if effectiveDefense == 0 {
- config, err := s.host.GetGlobalLimitConfig(ctx, int(hostId))
- if err != nil {
- return fmt.Errorf("获取全局限制配置失败: %w", err)
- }
- // 从配置中解析防御值
- defenseStr := strings.TrimSuffix(config.ConfigMaxProtection, "G")
- defenseInt, err := strconv.Atoi(defenseStr)
- if err != nil {
- // 如果解析失败,返回包含原始值的错误信息,便于排查
- return fmt.Errorf("解析防御配置 '%s' 失败: %w", config.ConfigMaxProtection, err)
- }
- // 如果配置的防御值也为0,则无需操作
- if defenseInt == 0 {
- return nil
- }
- // 将从配置中获取的值赋给 effectiveDefense
- effectiveDefense = defenseInt
- }
- var wg sync.WaitGroup
- // 创建一个足够大的 channel 来收集所有可能发生的错误
- errChan := make(chan error, len(ips))
- wg.Add(len(ips))
- for _, ip := range ips {
- go func(ipAddr string) {
- defer wg.Done()
- e := s.aoDun.SetDefense(ctx, v1.SetDefense{
- IpAddr: ipAddr,
- Defense: effectiveDefense,
- })
- if e != nil {
- // 3.【优化】为错误添加IP地址信息,便于定位问题
- errChan <- fmt.Errorf("IP [%s] 设置防御带宽失败: %w", ipAddr, e)
- }
- }(ip)
- }
- wg.Wait()
- close(errChan)
- var allErrors []error
- for e := range errChan {
- allErrors = append(allErrors, e)
- }
- if len(allErrors) > 0 {
- // 将多个错误信息拼接成一个字符串
- var errStrings []string
- for _, singleErr := range allErrors {
- errStrings = append(errStrings, singleErr.Error())
- }
- return fmt.Errorf("设置防御时发生多个错误: %s", strings.Join(errStrings, "; "))
- }
- return nil
- }
|