| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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
- }
|