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 }