package device import ( "bufio" "fmt" "network-topology-discovery/pkg/models" "regexp" "strings" ) // HuaweiParser 华为设备解析器 type HuaweiParser struct { BaseParser } // GetCommands 获取华为设备命令列表 func (p *HuaweiParser) GetCommands() []string { return []string{ "display version", "display interface", "display ip interface brief", "display lldp neighbor", } } // Parse 解析华为设备输出 func (p *HuaweiParser) Parse(device *models.Device, outputs []string) error { if len(outputs) < 4 { return fmt.Errorf("insufficient command outputs") } p.parseVersion(device, outputs[0]) device.Interfaces = p.parseInterfaces(outputs[1], outputs[2]) device.Neighbors = p.parseNeighbors(outputs[3]) return nil } func (p *HuaweiParser) parseVersion(device *models.Device, output string) { // 提取主机名 hostnameRegex := regexp.MustCompile(`<(\S+)>`) if matches := hostnameRegex.FindStringSubmatch(output); len(matches) > 1 { device.Hostname = matches[1] } // 提取版本信息 if strings.Contains(output, "VRP") { lines := strings.Split(output, "\n") for _, line := range lines { if strings.Contains(line, "VRP") { device.OSVersion = strings.TrimSpace(line) break } } } // 提取运行时间 uptimeRegex := regexp.MustCompile(`uptime is\s+(\d+\s+\S+)`) if matches := uptimeRegex.FindStringSubmatch(output); len(matches) > 1 { device.Uptime = matches[1] } } func (p *HuaweiParser) parseInterfaces(interfaceOutput, briefOutput string) []models.Interface { var interfaces []models.Interface briefMap := p.parseInterfaceBrief(briefOutput) scanner := bufio.NewScanner(strings.NewReader(interfaceOutput)) var currentInterface *models.Interface for scanner.Scan() { line := scanner.Text() // 匹配接口名称 if nameRegex := regexp.MustCompile(`^(\S+)\s+current state\s+(UP|DOWN)`); nameRegex.MatchString(line) { if currentInterface != nil { interfaces = append(interfaces, *currentInterface) } matches := nameRegex.FindStringSubmatch(line) currentInterface = &models.Interface{ Name: matches[1], Status: strings.ToLower(matches[2]), } if brief, ok := briefMap[currentInterface.Name]; ok { currentInterface.IP = brief.IP } } if currentInterface != nil { // 描述 if descRegex := regexp.MustCompile(`Description:\s+(.+)`); descRegex.MatchString(line) { currentInterface.Description = descRegex.FindStringSubmatch(line)[1] } // MAC地址 if macRegex := regexp.MustCompile(`Hardware address is\s+(\S+)`); macRegex.MatchString(line) { currentInterface.MAC = macRegex.FindStringSubmatch(line)[1] } // IP地址 if ipRegex := regexp.MustCompile(`Internet Address is\s+(\d+\.\d+\.\d+\.\d+),\s+Subnet mask is\s+(\d+\.\d+\.\d+\.\d+)`); ipRegex.MatchString(line) { matches := ipRegex.FindStringSubmatch(line) currentInterface.IP = matches[1] currentInterface.Mask = matches[2] } // 带宽 if speedRegex := regexp.MustCompile(`(\d+)\s+(Kbps|Mbps|Gbps)`); speedRegex.MatchString(line) { matches := speedRegex.FindStringSubmatch(line) currentInterface.Speed = matches[1] + " " + matches[2] } } } if currentInterface != nil { interfaces = append(interfaces, *currentInterface) } return interfaces } func (p *HuaweiParser) parseInterfaceBrief(output string) map[string]models.Interface { interfaces := make(map[string]models.Interface) lines := strings.Split(output, "\n") for _, line := range lines { fields := strings.Fields(line) if len(fields) >= 4 { iface := models.Interface{ Name: fields[0], IP: fields[1], Status: strings.ToLower(fields[3]), } interfaces[iface.Name] = iface } } return interfaces } func (p *HuaweiParser) parseNeighbors(output string) []models.Neighbor { var neighbors []models.Neighbor scanner := bufio.NewScanner(strings.NewReader(output)) var currentNeighbor *models.Neighbor for scanner.Scan() { line := scanner.Text() // 跳过标题行 if strings.Contains(line, "Local Interface") || strings.Contains(line, "-----") { continue } fields := strings.Fields(line) if len(fields) >= 5 { currentNeighbor = &models.Neighbor{ LocalInterface: fields[0], RemoteDevice: fields[2], RemoteInterface: fields[4], Protocol: "LLDP", } neighbors = append(neighbors, *currentNeighbor) } } return neighbors }