87d233659c
- 实现ExecuteCommands使用Shell模式,在同一个会话中顺序执行 - 解决H3C设备session.Run后EOF断开问题 - 增加cleanCommandOutput清理命令回显和版权信息 - display interface等待5秒,其他命令等待2秒
103 baris
2.5 KiB
Go
103 baris
2.5 KiB
Go
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
|
|
}
|