huawei.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package device
  2. import (
  3. "bufio"
  4. "fmt"
  5. "network-topology-discovery/pkg/models"
  6. "regexp"
  7. "strings"
  8. )
  9. // HuaweiParser 华为设备解析器
  10. type HuaweiParser struct {
  11. BaseParser
  12. }
  13. // GetCommands 获取华为设备命令列表
  14. func (p *HuaweiParser) GetCommands() []string {
  15. return []string{
  16. "display version",
  17. "display interface",
  18. "display ip interface brief",
  19. "display lldp neighbor",
  20. }
  21. }
  22. // Parse 解析华为设备输出
  23. func (p *HuaweiParser) Parse(device *models.Device, outputs []string) error {
  24. if len(outputs) < 4 {
  25. return fmt.Errorf("insufficient command outputs")
  26. }
  27. p.parseVersion(device, outputs[0])
  28. device.Interfaces = p.parseInterfaces(outputs[1], outputs[2])
  29. device.Neighbors = p.parseNeighbors(outputs[3])
  30. return nil
  31. }
  32. func (p *HuaweiParser) parseVersion(device *models.Device, output string) {
  33. // 提取主机名
  34. hostnameRegex := regexp.MustCompile(`<(\S+)>`)
  35. if matches := hostnameRegex.FindStringSubmatch(output); len(matches) > 1 {
  36. device.Hostname = matches[1]
  37. }
  38. // 提取版本信息
  39. if strings.Contains(output, "VRP") {
  40. lines := strings.Split(output, "\n")
  41. for _, line := range lines {
  42. if strings.Contains(line, "VRP") {
  43. device.OSVersion = strings.TrimSpace(line)
  44. break
  45. }
  46. }
  47. }
  48. // 提取运行时间
  49. uptimeRegex := regexp.MustCompile(`uptime is\s+(\d+\s+\S+)`)
  50. if matches := uptimeRegex.FindStringSubmatch(output); len(matches) > 1 {
  51. device.Uptime = matches[1]
  52. }
  53. }
  54. func (p *HuaweiParser) parseInterfaces(interfaceOutput, briefOutput string) []models.Interface {
  55. var interfaces []models.Interface
  56. briefMap := p.parseInterfaceBrief(briefOutput)
  57. scanner := bufio.NewScanner(strings.NewReader(interfaceOutput))
  58. var currentInterface *models.Interface
  59. for scanner.Scan() {
  60. line := scanner.Text()
  61. // 匹配接口名称
  62. if nameRegex := regexp.MustCompile(`^(\S+)\s+current state\s+(UP|DOWN)`); nameRegex.MatchString(line) {
  63. if currentInterface != nil {
  64. interfaces = append(interfaces, *currentInterface)
  65. }
  66. matches := nameRegex.FindStringSubmatch(line)
  67. currentInterface = &models.Interface{
  68. Name: matches[1],
  69. Status: strings.ToLower(matches[2]),
  70. }
  71. if brief, ok := briefMap[currentInterface.Name]; ok {
  72. currentInterface.IP = brief.IP
  73. }
  74. }
  75. if currentInterface != nil {
  76. // 描述
  77. if descRegex := regexp.MustCompile(`Description:\s+(.+)`); descRegex.MatchString(line) {
  78. currentInterface.Description = descRegex.FindStringSubmatch(line)[1]
  79. }
  80. // MAC地址
  81. if macRegex := regexp.MustCompile(`Hardware address is\s+(\S+)`); macRegex.MatchString(line) {
  82. currentInterface.MAC = macRegex.FindStringSubmatch(line)[1]
  83. }
  84. // IP地址
  85. if ipRegex := regexp.MustCompile(`Internet Address is\s+(\d+\.\d+\.\d+\.\d+),\s+Subnet mask is\s+(\d+\.\d+\.\d+\.\d+)`); ipRegex.MatchString(line) {
  86. matches := ipRegex.FindStringSubmatch(line)
  87. currentInterface.IP = matches[1]
  88. currentInterface.Mask = matches[2]
  89. }
  90. // 带宽
  91. if speedRegex := regexp.MustCompile(`(\d+)\s+(Kbps|Mbps|Gbps)`); speedRegex.MatchString(line) {
  92. matches := speedRegex.FindStringSubmatch(line)
  93. currentInterface.Speed = matches[1] + " " + matches[2]
  94. }
  95. }
  96. }
  97. if currentInterface != nil {
  98. interfaces = append(interfaces, *currentInterface)
  99. }
  100. return interfaces
  101. }
  102. func (p *HuaweiParser) parseInterfaceBrief(output string) map[string]models.Interface {
  103. interfaces := make(map[string]models.Interface)
  104. lines := strings.Split(output, "\n")
  105. for _, line := range lines {
  106. fields := strings.Fields(line)
  107. if len(fields) >= 4 {
  108. iface := models.Interface{
  109. Name: fields[0],
  110. IP: fields[1],
  111. Status: strings.ToLower(fields[3]),
  112. }
  113. interfaces[iface.Name] = iface
  114. }
  115. }
  116. return interfaces
  117. }
  118. func (p *HuaweiParser) parseNeighbors(output string) []models.Neighbor {
  119. var neighbors []models.Neighbor
  120. scanner := bufio.NewScanner(strings.NewReader(output))
  121. var currentNeighbor *models.Neighbor
  122. for scanner.Scan() {
  123. line := scanner.Text()
  124. // 跳过标题行
  125. if strings.Contains(line, "Local Interface") || strings.Contains(line, "-----") {
  126. continue
  127. }
  128. fields := strings.Fields(line)
  129. if len(fields) >= 5 {
  130. currentNeighbor = &models.Neighbor{
  131. LocalInterface: fields[0],
  132. RemoteDevice: fields[2],
  133. RemoteInterface: fields[4],
  134. Protocol: "LLDP",
  135. }
  136. neighbors = append(neighbors, *currentNeighbor)
  137. }
  138. }
  139. return neighbors
  140. }