package device import ( "fmt" "network-topology-discovery/pkg/models" "regexp" "strings" ) // LinuxParser Linux服务器解析器 type LinuxParser struct { BaseParser } // GetCommands 获取Linux命令列表 func (p *LinuxParser) GetCommands() []string { return []string{ "hostname", "uname -a", "ip addr show", "ip link show", "uptime", } } // Parse 解析Linux输出 func (p *LinuxParser) Parse(device *models.Device, outputs []string) error { if len(outputs) < 5 { return fmt.Errorf("insufficient command outputs") } device.Hostname = strings.TrimSpace(outputs[0]) device.OSVersion = p.parseOSVersion(outputs[1]) device.Uptime = strings.TrimSpace(outputs[4]) device.Interfaces = p.parseInterfaces(outputs[2], outputs[3]) return nil } func (p *LinuxParser) parseOSVersion(output string) string { // 从uname提取内核版本 parts := strings.Fields(output) if len(parts) >= 3 { return fmt.Sprintf("Linux %s", parts[2]) } return output } func (p *LinuxParser) parseInterfaces(addrOutput, linkOutput string) []models.Interface { var interfaces []models.Interface // 解析ip addr show输出 interfaceMap := make(map[string]*models.Interface) var currentInterface *models.Interface lines := strings.Split(addrOutput, "\n") for _, line := range lines { // 匹配接口: 2: eth0: mtu 1500 if nameRegex := regexp.MustCompile(`^\d+:\s+(\S+):\s+<([^>]*)>`); nameRegex.MatchString(line) { matches := nameRegex.FindStringSubmatch(line) name := strings.TrimSuffix(matches[1], ":") flags := matches[2] currentInterface = &models.Interface{ Name: name, Status: "down", } if strings.Contains(flags, "UP") { currentInterface.Status = "up" } // 提取MTU if mtuRegex := regexp.MustCompile(`mtu\s+(\d+)`); mtuRegex.MatchString(line) { matches := mtuRegex.FindStringSubmatch(line) currentInterface.MTU = 0 fmt.Sscanf(matches[1], "%d", ¤tInterface.MTU) } interfaceMap[name] = currentInterface interfaces = append(interfaces, *currentInterface) } if currentInterface != nil { // 提取MAC地址 if macRegex := regexp.MustCompile(`link/ether\s+(\S+)`); macRegex.MatchString(line) { matches := macRegex.FindStringSubmatch(line) currentInterface.MAC = matches[1] } // 提取IP地址 if ipRegex := regexp.MustCompile(`inet\s+(\d+\.\d+\.\d+\.\d+)/(\d+)`); ipRegex.MatchString(line) { matches := ipRegex.FindStringSubmatch(line) currentInterface.IP = matches[1] currentInterface.Mask = matches[2] } } } // 更新接口列表 finalInterfaces := make([]models.Interface, 0, len(interfaceMap)) for _, iface := range interfaceMap { finalInterfaces = append(finalInterfaces, *iface) } return finalInterfaces }