| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- package device
- import (
- "fmt"
- "time"
- "network-topology-discovery/pkg/models"
- sshclient "network-topology-discovery/internal/ssh"
- )
- // Parser 设备解析器接口
- type Parser interface {
- // GetCommands 获取需要执行的命令列表
- GetCommands() []string
-
- // Parse 解析命令输出,填充设备信息
- Parse(device *models.Device, outputs []string) error
-
- // GetType 获取设备类型
- GetType() models.DeviceType
- }
- // BaseParser 基础解析器
- type BaseParser struct {
- DeviceType models.DeviceType
- }
- // GetType 获取设备类型
- func (b *BaseParser) GetType() models.DeviceType {
- return b.DeviceType
- }
- // DiscoverDevice 发现并采集设备信息
- func DiscoverDevice(ip string, deviceType models.DeviceType, username, password string) (*models.Device, error) {
- device := &models.Device{
- IP: ip,
- Type: deviceType,
- }
- // 创建SSH客户端 - 默认启用不安全加密算法以兼容老旧设备,增加超时时间
- client := sshclient.NewClient(sshclient.Config{
- Host: ip,
- Username: username,
- Password: password,
- Timeout: 30 * time.Second, // 增加到30秒,防止大输出超时
- InsecureCiphers: true, // 启用旧版加密算法支持
- })
- // 连接
- if err := client.Connect(); err != nil {
- device.ScanStatus = "failed"
- device.ErrorMessage = err.Error()
- return device, err
- }
- defer client.Close()
- // 获取对应的解析器
- var parser Parser
- switch deviceType {
- case models.DeviceTypeCisco:
- parser = &CiscoParser{}
- case models.DeviceTypeHuawei:
- parser = &HuaweiParser{}
- case models.DeviceTypeH3C:
- parser = &H3CParser{}
- case models.DeviceTypeASA:
- parser = &ASAParser{}
- case models.DeviceTypeLinux:
- parser = &LinuxParser{}
- case models.DeviceTypeWindows:
- parser = &WindowsParser{}
- default:
- device.ScanStatus = "failed"
- device.ErrorMessage = "unsupported device type"
- return device, nil
- }
- // 获取命令列表
- commands := parser.GetCommands()
- // 执行所有命令(使用Shell模式,在同一个会话中顺序执行)
- outputs, err := client.ExecuteCommands(commands)
- if err != nil {
- device.ScanStatus = "failed"
- device.ErrorMessage = err.Error()
- return device, err
- }
- // 打印调试信息
- for i, output := range outputs {
- fmt.Printf("[PARSER] Command %d/%d returned %d bytes\n", i+1, len(commands), len(output))
- }
- // 解析输出
- if err := parser.Parse(device, outputs); err != nil {
- device.ScanStatus = "failed"
- device.ErrorMessage = err.Error()
- return device, err
- }
- device.ScanStatus = "success"
- return device, nil
- }
|