|
@@ -21,8 +21,7 @@ import (
|
|
|
|
|
|
// ApiDescriptionMap API描述映射
|
|
|
var ApiDescriptionMap = map[string]string{
|
|
|
- "/webForward/get": "获取web详情",
|
|
|
- "/webForward/getList": "获取web列表",
|
|
|
+
|
|
|
"/webForward/add": "添加web",
|
|
|
"/webForward/edit": "修改web",
|
|
|
"/webForward/delete": "删除web",
|
|
@@ -30,29 +29,26 @@ var ApiDescriptionMap = map[string]string{
|
|
|
"/tcpForward/add": "添加tcp",
|
|
|
"/tcpForward/edit": "修改tcp",
|
|
|
"/tcpForward/delete": "删除tcp",
|
|
|
- "/tcpForward/getList": "获取tcp列表",
|
|
|
- "/tcpForward/get": "获取tcp详情",
|
|
|
+
|
|
|
|
|
|
"/udpForward/add": "添加udp",
|
|
|
"/udpForward/edit": "修改udp",
|
|
|
"/udpForward/delete": "删除udp",
|
|
|
- "/udpForward/getList": "获取udp列表",
|
|
|
- "/udpForward/get": "获取udp详情",
|
|
|
+
|
|
|
|
|
|
"/globalLimit/add": "添加实例",
|
|
|
"/globalLimit/edit": "修改实例",
|
|
|
"/globalLimit/delete": "删除实例",
|
|
|
|
|
|
- "/allowAndDeny/get": "获取黑白名单详情",
|
|
|
- "/allowAndDeny/getList": "获取黑白名单列表",
|
|
|
+
|
|
|
"/allowAndDeny/add": "添加黑白名单",
|
|
|
"/allowAndDeny/edit": "修改黑白名单",
|
|
|
"/allowAndDeny/delete": "删除黑白名单",
|
|
|
|
|
|
- "/cc/getList": "获取CC列表",
|
|
|
+
|
|
|
"/cc/editState": "删除CC黑名单",
|
|
|
|
|
|
- "/ccIpList/getList": "获取CC白名单列表",
|
|
|
+
|
|
|
"/ccIpList/add": "添加CC白名单",
|
|
|
"/ccIpList/edit": "修改CC白名单",
|
|
|
"/ccIpList/delete": "删除CC白名单",
|
|
@@ -74,12 +70,14 @@ func NewWafLogService(
|
|
|
wafLogRepository adminRep.WafLogRepository,
|
|
|
globalLimitRepository waf.GlobalLimitRepository,
|
|
|
mq *rabbitmq.RabbitMQ,
|
|
|
+ wafLogDataCleanService WafLogDataCleanService,
|
|
|
) WafLogService {
|
|
|
return &wafLogService{
|
|
|
Service: service,
|
|
|
wafLogRepository: wafLogRepository,
|
|
|
globalLimitRepository: globalLimitRepository,
|
|
|
mq : mq,
|
|
|
+ wafLogDataCleanService: wafLogDataCleanService,
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -88,6 +86,7 @@ type wafLogService struct {
|
|
|
wafLogRepository adminRep.WafLogRepository
|
|
|
globalLimitRepository waf.GlobalLimitRepository
|
|
|
mq *rabbitmq.RabbitMQ
|
|
|
+ wafLogDataCleanService WafLogDataCleanService
|
|
|
}
|
|
|
func (s *wafLogService) getFirstPathSegment(path string) (segment []string, ok bool) {
|
|
|
// 1. 为了统一处理,先去掉路径最前面的 "/"
|
|
@@ -274,11 +273,12 @@ func (s *wafLogService) SmartExportWafLog(ctx context.Context, req adminApi.Expo
|
|
|
exportType := excel.SmartExport(count, 200)
|
|
|
|
|
|
// 3. 设置Excel表头映射
|
|
|
- headers := []string{"name", "request_ip", "host_id", "api_name", "addr_backend_list", "domain", "comment", "custom_host", "expose_addr", "created_at"}
|
|
|
+ headers := []string{"name", "request_ip", "host_id", "rule_id", "api_name", "addr_backend_list", "domain", "comment", "custom_host", "expose_addr", "created_at"}
|
|
|
headerMap := map[string]string{
|
|
|
"name": "用户名",
|
|
|
"request_ip": "请求IP",
|
|
|
- "host_id": "主机ID",
|
|
|
+ "host_id": "主机ID",
|
|
|
+ "rule_id": "规则ID",
|
|
|
"api_name": "API名称",
|
|
|
"addr_backend_list": "后端地址",
|
|
|
"domain": "域名",
|
|
@@ -322,11 +322,12 @@ func (s *wafLogService) normalExportWafLog(ctx context.Context, req adminApi.Exp
|
|
|
"name": item.Name,
|
|
|
"request_ip": item.RequestIp,
|
|
|
"host_id": item.HostId,
|
|
|
+ "rule_id": item.RuleId,
|
|
|
"api_name": item.ApiName,
|
|
|
"addr_backend_list": s.formatBackendList(item.AddrBackendList),
|
|
|
"domain": item.Domain,
|
|
|
"comment": item.Comment,
|
|
|
- "custom_host": item.CustomHost,
|
|
|
+ "custom_host": s.formatExposeAddr(item.CustomHost),
|
|
|
"expose_addr": s.formatExposeAddr(item.ExposeAddr),
|
|
|
"created_at": item.CreatedAt,
|
|
|
}
|
|
@@ -386,7 +387,7 @@ func (s *wafLogService) streamExportWafLog(ctx context.Context, req adminApi.Exp
|
|
|
"addr_backend_list": s.formatBackendList(item.AddrBackendList),
|
|
|
"domain": item.Domain,
|
|
|
"comment": item.Comment,
|
|
|
- "custom_host": item.CustomHost,
|
|
|
+ "custom_host": s.formatExposeAddr(item.CustomHost),
|
|
|
"expose_addr": s.formatExposeAddr(item.ExposeAddr),
|
|
|
"created_at": item.CreatedAt,
|
|
|
}
|
|
@@ -459,17 +460,20 @@ func (s *wafLogService) formatExposeAddr(exposeAddr []string) string {
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
// convertRawDataToExportResults 将原始数据转换为导出结果(复用原有的ExPortWafLog逻辑)
|
|
|
func (s *wafLogService) convertRawDataToExportResults(ctx context.Context, rawData []model.WafLog) ([]adminApi.ExportWafLogRes, error) {
|
|
|
if len(rawData) == 0 {
|
|
|
return []adminApi.ExportWafLogRes{}, nil
|
|
|
}
|
|
|
|
|
|
- // 收集所有需要查询的hostId和uid,用于批量获取网关组
|
|
|
+ // 批量准备逻辑保持不变...
|
|
|
hostIds := make([]int64, 0, len(rawData))
|
|
|
uids := make([]int64, 0, len(rawData))
|
|
|
maxCreatedAt := time.Time{}
|
|
|
-
|
|
|
for _, v := range rawData {
|
|
|
hostIds = append(hostIds, int64(v.HostId))
|
|
|
uids = append(uids, int64(v.Uid))
|
|
@@ -477,132 +481,51 @@ func (s *wafLogService) convertRawDataToExportResults(ctx context.Context, rawDa
|
|
|
maxCreatedAt = v.CreatedAt
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 批量获取网关组数据
|
|
|
gatewayMap, err := s.wafLogRepository.BatchGetWafLogGateWayIps(ctx, hostIds, uids, maxCreatedAt)
|
|
|
if err != nil {
|
|
|
s.Logger.Warn("批量获取网关组失败,降级为单个查询", zap.Error(err))
|
|
|
- gatewayMap = make(map[string]model.WafLog) // 空map,后续会降级处理
|
|
|
+ gatewayMap = make(map[string]model.WafLog)
|
|
|
}
|
|
|
|
|
|
var res []adminApi.ExportWafLogRes
|
|
|
for _, v := range rawData {
|
|
|
- var AddrBackendList interface{}
|
|
|
- var customHost string
|
|
|
- var port string
|
|
|
- var domain string
|
|
|
- var comment string
|
|
|
-
|
|
|
- var mapData map[string]interface{}
|
|
|
- err := json.Unmarshal(v.ExtraData, &mapData)
|
|
|
- if err != nil {
|
|
|
- // 尝试解析为数组格式
|
|
|
- var arrayData []interface{}
|
|
|
- if arrayErr := json.Unmarshal(v.ExtraData, &arrayData); arrayErr != nil {
|
|
|
- // 如果不是符合的JSON格式,直接把原始值作为字符串处理
|
|
|
- s.Logger.Warn("额外数据不是有效JSON格式,使用原始值", zap.Error(err), zap.Int("id", v.Id),
|
|
|
- zap.String("extra_data", string(v.ExtraData)))
|
|
|
- mapData = map[string]interface{}{
|
|
|
- "raw_data": string(v.ExtraData),
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 如果是数组格式,将数组作为值存储
|
|
|
- s.Logger.Warn("额外数据为数组格式,保存为数组值", zap.Int("id", v.Id))
|
|
|
- mapData = map[string]interface{}{
|
|
|
- "array_data": arrayData,
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // --- 核心改动:一行代码完成所有数据清洗 ---
|
|
|
+ cleanedData := s.wafLogDataCleanService.ParseWafLogExtraData(v.ExtraData, v.ApiName)
|
|
|
|
|
|
- if strings.Contains(v.ApiName, "tcp") || strings.Contains(v.ApiName, "udp") || strings.Contains(v.ApiName, "web") {
|
|
|
- // 安全地获取extraData
|
|
|
- var extraData map[string]interface{}
|
|
|
- if mapData["data"] != nil {
|
|
|
- if data, ok := mapData["data"].(map[string]interface{}); ok {
|
|
|
- extraData = data
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if extraData != nil {
|
|
|
- if extraData["port"] != nil {
|
|
|
- if portStr, ok := extraData["port"].(string); ok {
|
|
|
- port = portStr
|
|
|
- }
|
|
|
- }
|
|
|
- if extraData["domain"] != nil {
|
|
|
- if domainStr, ok := extraData["domain"].(string); ok {
|
|
|
- domain = domainStr
|
|
|
- }
|
|
|
- }
|
|
|
- if extraData["backendList"] != nil {
|
|
|
- if strings.Contains(v.ApiName, "web") {
|
|
|
- if backendListStr, ok := extraData["backendList"].(string); ok {
|
|
|
- var backendList []map[string]interface{}
|
|
|
- err := json.Unmarshal([]byte(backendListStr), &backendList)
|
|
|
- if err != nil {
|
|
|
- s.Logger.Error("解析后端列表失败", zap.Error(err))
|
|
|
- continue
|
|
|
- }
|
|
|
- for _, backend := range backendList {
|
|
|
- if backend["addr"] != nil {
|
|
|
- AddrBackendList = backend["addr"]
|
|
|
- }
|
|
|
- if backend["customHost"] != nil {
|
|
|
- if customHostStr, ok := backend["customHost"].(string); ok {
|
|
|
- customHost = customHostStr
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- AddrBackendList = extraData["backendList"]
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if mapData["comment"] != nil {
|
|
|
- if commentStr, ok := mapData["comment"].(string); ok {
|
|
|
- comment = commentStr
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 优化:从批量获取的网关组数据中查找
|
|
|
+ // 网关 IP 获取逻辑保持不变,但使用清洗后的 port
|
|
|
var exposeAddr []string
|
|
|
key := fmt.Sprintf("%d_%d", v.HostId, v.Uid)
|
|
|
if gatewayModel, exists := gatewayMap[key]; exists {
|
|
|
var gateWayIps []string
|
|
|
- if err := json.Unmarshal(gatewayModel.ExtraData, &gateWayIps); err == nil {
|
|
|
- if len(gateWayIps) > 0 && port != "" {
|
|
|
- for _, ip := range gateWayIps {
|
|
|
- exposeAddr = append(exposeAddr, ip+":"+port)
|
|
|
- }
|
|
|
+ if err := json.Unmarshal(gatewayModel.ExtraData, &gateWayIps); err == nil && len(gateWayIps) > 0 && cleanedData.Port != "" {
|
|
|
+ for _, ip := range gateWayIps {
|
|
|
+ exposeAddr = append(exposeAddr, ip+":"+cleanedData.Port)
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- // 降级:单个查询
|
|
|
+ // 降级查询逻辑...
|
|
|
gateWayIpModel, err := s.wafLogRepository.GetWafLogGateWayIp(ctx, int64(v.HostId), int64(v.Uid), v.CreatedAt)
|
|
|
if err == nil {
|
|
|
var gateWayIps []string
|
|
|
- if err := json.Unmarshal(gateWayIpModel.ExtraData, &gateWayIps); err == nil {
|
|
|
- if len(gateWayIps) > 0 && port != "" {
|
|
|
- for _, ip := range gateWayIps {
|
|
|
- exposeAddr = append(exposeAddr, ip+":"+port)
|
|
|
- }
|
|
|
+ if err := json.Unmarshal(gateWayIpModel.ExtraData, &gateWayIps); err == nil && len(gateWayIps) > 0 && cleanedData.Port != "" {
|
|
|
+ for _, ip := range gateWayIps {
|
|
|
+ exposeAddr = append(exposeAddr, ip+":"+cleanedData.Port)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 构造结果,代码更清晰
|
|
|
res = append(res, adminApi.ExportWafLogRes{
|
|
|
Name: v.Name,
|
|
|
RequestIp: v.RequestIp,
|
|
|
HostId: v.HostId,
|
|
|
+ RuleId: v.RuleId,
|
|
|
ApiName: v.ApiName,
|
|
|
- AddrBackendList: AddrBackendList,
|
|
|
- Domain: domain,
|
|
|
- Comment: comment,
|
|
|
- CustomHost: customHost,
|
|
|
+ AddrBackendList: cleanedData.AddrBackendList,
|
|
|
+ Domain: cleanedData.Domain,
|
|
|
+ Comment: cleanedData.Comment,
|
|
|
+ CustomHost: cleanedData.CustomHost,
|
|
|
ExposeAddr: exposeAddr,
|
|
|
CreatedAt: v.CreatedAt,
|
|
|
})
|