Initial commit: 网络拓扑发现系统
- 支持Cisco、华为、H3C、ASA、Linux、Windows设备 - SSH远程采集设备信息 - 自动发现网络拓扑(LLDP/CDP) - Web可视化界面 - 支持旧版SSH加密算法兼容
这个提交包含在:
@@ -0,0 +1,94 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"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,
|
||||
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()
|
||||
|
||||
// 执行命令
|
||||
outputs, err := client.ExecuteCommands(commands)
|
||||
if err != nil {
|
||||
device.ScanStatus = "failed"
|
||||
device.ErrorMessage = err.Error()
|
||||
return device, err
|
||||
}
|
||||
|
||||
// 解析输出
|
||||
if err := parser.Parse(device, outputs); err != nil {
|
||||
device.ScanStatus = "failed"
|
||||
device.ErrorMessage = err.Error()
|
||||
return device, err
|
||||
}
|
||||
|
||||
device.ScanStatus = "success"
|
||||
return device, nil
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户