feat(copilot): add Netmiko device list generator and simplify Huawei driver

- Add script to generate Markdown documentation of all Netmiko supported
     devices (SSH and Telnet), grouped by platform with source attribution
   - Highlight custom GNS3-Copilot devices with "Custom " marker
   - Auto-generate device list to docs/gns3-copilot/netmiko_devices.md
   - Simplify HuaweiTelnetCE driver: remove redundant aliases
     (huawei_ce, huawei_telnet_ce_telnet), keep only huawei_telnet_ce
   - Update tests to match simplified device registration
This commit is contained in:
YueGuobin 2026-03-12 23:03:19 +08:00
parent 50fa4f6e2a
commit effea3fb26
4 changed files with 640 additions and 12 deletions

View File

@ -0,0 +1,234 @@
# Netmiko Supported Devices
**Netmiko Version:** 4.6.0
**Generated:** 2026-03-12 23:00:41
---
## Summary
- **Total Device Types:** 364
- **SSH Devices:** 154
- **Telnet Devices:** 53
- **Custom Devices:** 1
## SSH Supported Devices
| Platform | Device Type | Source |
|----------|-------------|--------|
| A10 | `a10_ssh` | Netmiko |
| Accedian | `accedian_ssh` | Netmiko |
| Adtran | `adtran_os_ssh` | Netmiko |
| Adva | `adva_fsp150f2_ssh` | Netmiko |
| Adva | `adva_fsp150f3_ssh` | Netmiko |
| Alaxala | `alaxala_ax26s_ssh` | Netmiko |
| Alaxala | `alaxala_ax36s_ssh` | Netmiko |
| Alcatel | `alcatel_aos_ssh` | Netmiko |
| Alcatel | `alcatel_sros_ssh` | Netmiko |
| Allied | `allied_telesis_awplus_ssh` | Netmiko |
| Apresia | `apresia_aeos_ssh` | Netmiko |
| Arista | `arista_eos_ssh` | Netmiko |
| Arris | `arris_cer_ssh` | Netmiko |
| Aruba | `aruba_aoscx_ssh` | Netmiko |
| Aruba | `aruba_os_ssh` | Netmiko |
| Aruba | `aruba_osswitch_ssh` | Netmiko |
| Aruba | `aruba_procurve_ssh` | Netmiko |
| Asterfusion | `asterfusion_asternos_ssh` | Netmiko |
| Audiocode | `audiocode_66_ssh` | Netmiko |
| Audiocode | `audiocode_72_ssh` | Netmiko |
| Audiocode | `audiocode_shell_ssh` | Netmiko |
| Avaya | `avaya_ers_ssh` | Netmiko |
| Avaya | `avaya_vsp_ssh` | Netmiko |
| Bintec | `bintec_boss_ssh` | Netmiko |
| Broadcom | `broadcom_icos_ssh` | Netmiko |
| Brocade | `brocade_fastiron_ssh` | Netmiko |
| Brocade | `brocade_fos_ssh` | Netmiko |
| Brocade | `brocade_netiron_ssh` | Netmiko |
| Brocade | `brocade_nos_ssh` | Netmiko |
| Brocade | `brocade_vdx_ssh` | Netmiko |
| Brocade | `brocade_vyos_ssh` | Netmiko |
| Calix | `calix_b6_ssh` | Netmiko |
| Casa | `casa_cmts_ssh` | Netmiko |
| Cdot | `cdot_cros_ssh` | Netmiko |
| Centec | `centec_os_ssh` | Netmiko |
| Check Point | `checkpoint_gaia_ssh` | Netmiko |
| Ciena | `ciena_saos10_ssh` | Netmiko |
| Ciena | `ciena_saos_ssh` | Netmiko |
| Ciena | `ciena_waveserver_ssh` | Netmiko |
| Cisco | `cisco_apic_ssh` | Netmiko |
| Cisco | `cisco_asa_ssh` | Netmiko |
| Cisco | `cisco_ftd_ssh` | Netmiko |
| Cisco | `cisco_ios_ssh` | Netmiko |
| Cisco | `cisco_nxos_ssh` | Netmiko |
| Cisco | `cisco_s200_ssh` | Netmiko |
| Cisco | `cisco_s300_ssh` | Netmiko |
| Cisco | `cisco_tp_ssh` | Netmiko |
| Cisco | `cisco_viptela_ssh` | Netmiko |
| Cisco | `cisco_wlc_ssh` | Netmiko |
| Cisco | `cisco_xe_ssh` | Netmiko |
| Cisco | `cisco_xr_ssh` | Netmiko |
| Cloudgenix | `cloudgenix_ion_ssh` | Netmiko |
| Corelight | `corelight_linux_ssh` | Netmiko |
| Coriant | `coriant_ssh` | Netmiko |
| Cumulus | `cumulus_linux_ssh` | Netmiko |
| Dell | `dell_dnos9_ssh` | Netmiko |
| Dell | `dell_force10_ssh` | Netmiko |
| Dell | `dell_isilon_ssh` | Netmiko |
| Dell | `dell_os10_ssh` | Netmiko |
| Dell | `dell_os6_ssh` | Netmiko |
| Dell | `dell_os9_ssh` | Netmiko |
| Dell | `dell_powerconnect_ssh` | Netmiko |
| Dell | `dell_sonic_ssh` | Netmiko |
| Digi | `digi_transport_ssh` | Netmiko |
| Dlink | `dlink_ds_ssh` | Netmiko |
| Edgecore | `edgecore_sonic_ssh` | Netmiko |
| Ekinops | `ekinops_ek360_ssh` | Netmiko |
| Eltex | `eltex_esr_ssh` | Netmiko |
| Eltex | `eltex_ssh` | Netmiko |
| Endace | `endace_ssh` | Netmiko |
| Enterasys | `enterasys_ssh` | Netmiko |
| Ericsson | `ericsson_ipos_ssh` | Netmiko |
| Ericsson | `ericsson_mltn63_ssh` | Netmiko |
| Ericsson | `ericsson_mltn66_ssh` | Netmiko |
| Extreme | `extreme_ers_ssh` | Netmiko |
| Extreme | `extreme_exos_ssh` | Netmiko |
| Extreme | `extreme_netiron_ssh` | Netmiko |
| Extreme | `extreme_nos_ssh` | Netmiko |
| Extreme | `extreme_slx_ssh` | Netmiko |
| Extreme | `extreme_ssh` | Netmiko |
| Extreme | `extreme_tierra_ssh` | Netmiko |
| Extreme | `extreme_vdx_ssh` | Netmiko |
| Extreme | `extreme_vsp_ssh` | Netmiko |
| Extreme | `extreme_wing_ssh` | Netmiko |
| F5 | `f5_linux_ssh` | Netmiko |
| F5 | `f5_ltm_ssh` | Netmiko |
| F5 | `f5_tmsh_ssh` | Netmiko |
| Fiberstore | `fiberstore_fsos_ssh` | Netmiko |
| Fiberstore | `fiberstore_fsosv2_ssh` | Netmiko |
| Fiberstore | `fiberstore_networkos_ssh` | Netmiko |
| Flexvnf | `flexvnf_ssh` | Netmiko |
| Fortinet | `fortinet_ssh` | Netmiko |
| Garderos | `garderos_grs_ssh` | Netmiko |
| Generic | `generic_ssh` | Netmiko |
| Generic | `generic_termserver_ssh` | Netmiko |
| H3C (华三) | `h3c_comware_ssh` | Netmiko |
| HP | `hp_comware_ssh` | Netmiko |
| HP | `hp_procurve_ssh` | Netmiko |
| Hillstone | `hillstone_stoneos_ssh` | Netmiko |
| Huawei | `huawei_olt_ssh` | Netmiko |
| Huawei | `huawei_smartax_ssh` | Netmiko |
| Huawei | `huawei_smartaxmmi_ssh` | Netmiko |
| Huawei | `huawei_ssh` | Netmiko |
| Huawei | `huawei_vrp_ssh` | Netmiko |
| Huawei | `huawei_vrpv8_ssh` | Netmiko |
| Infinera | `infinera_packet_ssh` | Netmiko |
| Ipinfusion | `ipinfusion_ocnos_ssh` | Netmiko |
| Juniper | `juniper_junos_ssh` | Netmiko |
| Juniper | `juniper_screenos_ssh` | Netmiko |
| Juniper | `juniper_ssh` | Netmiko |
| Keymile | `keymile_nos_ssh` | Netmiko |
| Keymile | `keymile_ssh` | Netmiko |
| Lancom | `lancom_lcossx4_ssh` | Netmiko |
| Linux | `linux_ssh` | Netmiko |
| Maipu (迈普) | `maipu_ssh` | Netmiko |
| Mellanox | `mellanox_mlnxos_ssh` | Netmiko |
| Mellanox | `mellanox_ssh` | Netmiko |
| Mikrotik | `mikrotik_routeros_ssh` | Netmiko |
| Mikrotik | `mikrotik_switchos_ssh` | Netmiko |
| Mrv | `mrv_lx_ssh` | Netmiko |
| Mrv | `mrv_optiswitch_ssh` | Netmiko |
| Nec | `nec_ix_ssh` | Netmiko |
| Netapp | `netapp_cdot_ssh` | Netmiko |
| Netgear | `netgear_prosafe_ssh` | Netmiko |
| Netscaler | `netscaler_ssh` | Netmiko |
| Nokia | `nokia_srl_ssh` | Netmiko |
| Nokia | `nokia_sros_ssh` | Netmiko |
| Oneaccess | `oneaccess_oneos_ssh` | Netmiko |
| Ovs | `ovs_linux_ssh` | Netmiko |
| Palo Alto | `paloalto_panos_ssh` | Netmiko |
| Pluribus | `pluribus_ssh` | Netmiko |
| Quanta | `quanta_mesh_ssh` | Netmiko |
| Rad | `rad_etx_ssh` | Netmiko |
| Raisecom | `raisecom_roap_ssh` | Netmiko |
| Ruckus | `ruckus_fastiron_ssh` | Netmiko |
| Ruijie (锐捷) | `ruijie_os_ssh` | Netmiko |
| Silverpeak | `silverpeak_vxoa_ssh` | Netmiko |
| Sixwind | `sixwind_os_ssh` | Netmiko |
| Sophos | `sophos_sfos_ssh` | Netmiko |
| Supermicro | `supermicro_smis_ssh` | Netmiko |
| Telcosystems | `telcosystems_binos_ssh` | Netmiko |
| Teldat | `teldat_cit_ssh` | Netmiko |
| Tplink | `tplink_jetstream_ssh` | Netmiko |
| Ubiquiti | `ubiquiti_edge_ssh` | Netmiko |
| Ubiquiti | `ubiquiti_edgerouter_ssh` | Netmiko |
| Ubiquiti | `ubiquiti_edgeswitch_ssh` | Netmiko |
| Ubiquiti | `ubiquiti_unifiswitch_ssh` | Netmiko |
| Vertiv | `vertiv_mph_ssh` | Netmiko |
| Vyatta | `vyatta_vyos_ssh` | Netmiko |
| Vyos | `vyos_ssh` | Netmiko |
| Watchguard | `watchguard_fireware_ssh` | Netmiko |
| Yamaha | `yamaha_ssh` | Netmiko |
| ZTE (中兴) | `zte_zxros_ssh` | Netmiko |
| Zyxel | `zyxel_os_ssh` | Netmiko |
## Telnet Supported Devices
| Platform | Device Type | Source |
|----------|-------------|--------|
| Adtran | `adtran_os_telnet` | Netmiko |
| Apresia | `apresia_aeos_telnet` | Netmiko |
| Arista | `arista_eos_telnet` | Netmiko |
| Aruba | `aruba_procurve_telnet` | Netmiko |
| Audiocode | `audiocode_66_telnet` | Netmiko |
| Audiocode | `audiocode_72_telnet` | Netmiko |
| Audiocode | `audiocode_shell_telnet` | Netmiko |
| Bintec | `bintec_boss_telnet` | Netmiko |
| Brocade | `brocade_fastiron_telnet` | Netmiko |
| Brocade | `brocade_netiron_telnet` | Netmiko |
| Calix | `calix_b6_telnet` | Netmiko |
| Centec | `centec_os_telnet` | Netmiko |
| Ciena | `ciena_saos_telnet` | Netmiko |
| Cisco | `cisco_ios_telnet` | Netmiko |
| Cisco | `cisco_nxos_telnet` | Netmiko |
| Cisco | `cisco_s200_telnet` | Netmiko |
| Cisco | `cisco_s300_telnet` | Netmiko |
| Cisco | `cisco_xr_telnet` | Netmiko |
| Dell | `dell_dnos6_telnet` | Netmiko |
| Dell | `dell_powerconnect_telnet` | Netmiko |
| Dlink | `dlink_ds_telnet` | Netmiko |
| Extreme | `extreme_exos_telnet` | Netmiko |
| Extreme | `extreme_netiron_telnet` | Netmiko |
| Extreme | `extreme_telnet` | Netmiko |
| Fiberstore | `fiberstore_fsosv2_telnet` | Netmiko |
| Generic | `generic_telnet` | Netmiko |
| Generic | `generic_termserver_telnet` | Netmiko |
| Genexis | `genexis_solt33_telnet` | Netmiko |
| HP | `hp_comware_telnet` | Netmiko |
| HP | `hp_procurve_telnet` | Netmiko |
| Huawei | `huawei_olt_telnet` | Netmiko |
| Huawei | `huawei_telnet` | Netmiko |
| Huawei | `huawei_telnet_ce` | Custom ✨ |
| Infinera | `infinera_packet_telnet` | Netmiko |
| Ipinfusion | `ipinfusion_ocnos_telnet` | Netmiko |
| Juniper | `juniper_junos_telnet` | Netmiko |
| Maipu (迈普) | `maipu_telnet` | Netmiko |
| Nec | `nec_ix_telnet` | Netmiko |
| Nokia | `nokia_sros_telnet` | Netmiko |
| Oneaccess | `oneaccess_oneos_telnet` | Netmiko |
| Optilink | `optilink_eolt11444_telnet` | Netmiko |
| Optilink | `optilink_eolt9702_telnet` | Netmiko |
| Palo Alto | `paloalto_panos_telnet` | Netmiko |
| Rad | `rad_etx_telnet` | Netmiko |
| Raisecom | `raisecom_telnet` | Netmiko |
| Ruckus | `ruckus_fastiron_telnet` | Netmiko |
| Ruijie (锐捷) | `ruijie_os_telnet` | Netmiko |
| Supermicro | `supermicro_smis_telnet` | Netmiko |
| Telcosystems | `telcosystems_binos_telnet` | Netmiko |
| Teldat | `teldat_cit_telnet` | Netmiko |
| Tplink | `tplink_jetstream_telnet` | Netmiko |
| Yamaha | `yamaha_telnet` | Netmiko |
| ZTE (中兴) | `zte_zxros_telnet` | Netmiko |
---
*This document was generated automatically by the Netmiko device list script.*

View File

@ -396,19 +396,12 @@ def register_custom_device_type() -> None:
# not a function
sd = importlib.import_module("netmiko.ssh_dispatcher")
# Add to both mappers
# Register the device type in both mappers
# CLASS_MAPPER_BASE is used for base class definitions
sd.CLASS_MAPPER_BASE["huawei_telnet_ce"] = HuaweiTelnetCE
sd.CLASS_MAPPER_BASE["huawei_ce"] = HuaweiTelnetCE
# CLASS_MAPPER is used by ConnectHandler for device type validation
sd.CLASS_MAPPER["huawei_telnet_ce"] = HuaweiTelnetCE
sd.CLASS_MAPPER["huawei_ce"] = HuaweiTelnetCE
# CRITICAL: Netmiko may also look for types with _telnet suffix
# Add this variant to ensure compatibility
sd.CLASS_MAPPER["huawei_telnet_ce_telnet"] = HuaweiTelnetCE
sd.CLASS_MAPPER_BASE["huawei_telnet_ce_telnet"] = HuaweiTelnetCE
# CRITICAL: Update the static platforms lists
# These lists are computed at module import time and won't

View File

@ -0,0 +1,403 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-3.0-or-later
#
# GNS3-Copilot - AI-powered Network Lab Assistant for GNS3
#
# Script to list all Netmiko supported devices (SSH and Telnet)
#
# This script queries the Netmiko library to extract all device types
# that support SSH and Telnet connections, grouped by vendor/brand.
# Includes custom device drivers from the GNS3-Copilot project.
# Outputs a Markdown document with the complete device list.
#
# Usage: python list_netmiko_devices.py
# Output: netmiko_devices.md (in current directory)
#
"""
Netmiko Device List Generator
This script extracts and displays all SSH and Telnet-supported device
types from the Netmiko library, organized by vendor/brand.
Features:
- Automatically detects Netmiko version
- Loads custom GNS3-Copilot device drivers
- Extracts all SSH and Telnet device types from CLASS_MAPPER
- Groups devices by vendor/brand
- Generates Markdown documentation
- Provides statistics and summary
"""
import os
import sys
from typing import Dict, List, Tuple
from datetime import datetime
def get_netmiko_version() -> str:
"""Get Netmiko library version."""
try:
import netmiko
return netmiko.__version__
except Exception:
return "Unknown"
def register_custom_drivers() -> set:
"""
Register custom GNS3-Copilot device drivers.
This function imports and executes the registration functions for
custom device drivers, adding them to Netmiko's CLASS_MAPPER.
Returns:
Set of custom device type names that were registered
"""
# Get the directory where this script is located
script_dir = os.path.dirname(os.path.abspath(__file__))
# Find the custom drivers directory
custom_drivers_dir = os.path.dirname(script_dir)
# Add to sys.path if not already there
if custom_drivers_dir not in sys.path:
sys.path.insert(0, custom_drivers_dir)
custom_devices = set()
try:
# Import and register Huawei CE driver
from gns3server.agent.gns3_copilot.utils.custom_netmiko \
import huawei_ce
# Store custom device types before registration
custom_devices.add("huawei_telnet_ce")
# The driver auto-registers on import, but we can call it
# explicitly
if hasattr(huawei_ce, 'register_custom_device_type'):
huawei_ce.register_custom_device_type()
except ImportError:
# Silently skip if custom drivers are not available
pass
except Exception as e:
# Log but don't fail
print(
f"Warning: Failed to register custom drivers: {e}",
file=sys.stderr
)
return custom_devices
def extract_brand_name(device_type: str) -> str:
"""
Extract brand name from device type.
Args:
device_type: Device type string (e.g., 'cisco_ios_telnet')
Returns:
Brand name in a standardized format
"""
# Remove common suffixes
name = device_type.replace('_telnet', '').replace('_ssh', '')
name = name.replace('_serial', '')
# Map to standard brand names
brand_mapping = {
'cisco': 'Cisco',
'huawei': 'Huawei',
'juniper': 'Juniper',
'arista': 'Arista',
'hp': 'HP',
'aruba': 'Aruba',
'dell': 'Dell',
'brocade': 'Brocade',
'extreme': 'Extreme',
'ruckus': 'Ruckus',
'ruijie': 'Ruijie (锐捷)',
'zte': 'ZTE (中兴)',
'maipu': 'Maipu (迈普)',
'h3c': 'H3C (华三)',
'nokia': 'Nokia',
'paloalto': 'Palo Alto',
'f5': 'F5',
'checkpoint': 'Check Point',
'generic': 'Generic',
'huaweiyt': 'HuaweiYT',
'vsz': 'Ruckus',
}
# Check for exact matches first
for key, value in brand_mapping.items():
if name == key:
return value
# Check for partial matches
for key, value in brand_mapping.items():
if key in name:
return value
# Return capitalized version of the first part
return name.split('_')[0].capitalize()
def group_devices_by_brand(device_types: List[str]) -> Dict[str, List[str]]:
"""
Group device types by brand.
Args:
device_types: List of device type strings
Returns:
Dictionary mapping brand names to device type lists
"""
brands = {}
for device_type in device_types:
brand = extract_brand_name(device_type)
if brand not in brands:
brands[brand] = []
brands[brand].append(device_type)
return brands
def get_devices_by_protocol() -> Tuple[List[str], List[str]]:
"""
Get all SSH and Telnet device types from Netmiko.
Returns:
Tuple of (ssh_devices, telnet_devices) as sorted lists
"""
try:
from netmiko.ssh_dispatcher import CLASS_MAPPER
ssh_devices = []
telnet_devices = []
both_protocols = []
for device_type in CLASS_MAPPER.keys():
device_lower = device_type.lower()
has_telnet = 'telnet' in device_lower
has_ssh = 'ssh' in device_lower
if has_telnet and has_ssh:
both_protocols.append(device_type)
elif has_telnet:
telnet_devices.append(device_type)
elif has_ssh:
ssh_devices.append(device_type)
# Devices with both protocols go to both lists
ssh_devices.extend(both_protocols)
telnet_devices.extend(both_protocols)
return sorted(ssh_devices), sorted(telnet_devices)
except ImportError as e:
print(f"Error: Failed to import Netmiko: {e}", file=sys.stderr)
sys.exit(1)
def get_total_device_count() -> int:
"""Get total number of device types in Netmiko."""
try:
from netmiko.ssh_dispatcher import CLASS_MAPPER
return len(CLASS_MAPPER)
except ImportError:
return 0
def generate_markdown(
version: str,
ssh_devices: List[str],
telnet_devices: List[str],
total_count: int,
custom_devices: set
) -> str:
"""
Generate Markdown documentation with table format.
Args:
version: Netmiko version string
ssh_devices: List of SSH device types
telnet_devices: List of Telnet device types
total_count: Total number of device types
custom_devices: Set of custom device type names
Returns:
Markdown formatted string
"""
md_lines = []
# Header
md_lines.append("# Netmiko Supported Devices")
md_lines.append("")
md_lines.append(f"**Netmiko Version:** {version}")
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
md_lines.append(f"**Generated:** {timestamp}")
md_lines.append("")
md_lines.append("---")
md_lines.append("")
# Summary
md_lines.append("## Summary")
md_lines.append("")
md_lines.append(f"- **Total Device Types:** {total_count}")
md_lines.append(f"- **SSH Devices:** {len(ssh_devices)}")
md_lines.append(f"- **Telnet Devices:** {len(telnet_devices)}")
md_lines.append(f"- **Custom Devices:** {len(custom_devices)}")
md_lines.append("")
# SSH Devices Section
md_lines.append("## SSH Supported Devices")
md_lines.append("")
md_lines.append("| Platform | Device Type | Source |")
md_lines.append("|----------|-------------|--------|")
ssh_brands = group_devices_by_brand(ssh_devices)
for brand in sorted(ssh_brands.keys()):
devices = sorted(ssh_brands[brand])
for device in devices:
if device in custom_devices:
source = "Custom ✨"
else:
source = "Netmiko"
md_lines.append(f"| {brand} | `{device}` | {source} |")
md_lines.append("")
# Telnet Devices Section
md_lines.append("## Telnet Supported Devices")
md_lines.append("")
md_lines.append("| Platform | Device Type | Source |")
md_lines.append("|----------|-------------|--------|")
telnet_brands = group_devices_by_brand(telnet_devices)
for brand in sorted(telnet_brands.keys()):
devices = sorted(telnet_brands[brand])
for device in devices:
if device in custom_devices:
source = "Custom ✨"
else:
source = "Netmiko"
md_lines.append(f"| {brand} | `{device}` | {source} |")
md_lines.append("")
# Footer
md_lines.append("---")
md_lines.append("")
md_lines.append("*This document was generated automatically by the "
"Netmiko device list script.*")
return "\n".join(md_lines)
def save_markdown(content: str, filename: str = "netmiko_devices.md") -> None:
"""
Save Markdown content to file in docs/gns3-copilot directory.
Args:
content: Markdown content to save
filename: Output filename (default: netmiko_devices.md)
"""
# Get the project root directory
script_dir = os.path.dirname(os.path.abspath(__file__))
# Go up from: .../gns3server/agent/gns3_copilot/utils/
# custom_netmiko/scripts to project root
# That's 6 levels up
project_root = os.path.dirname(os.path.dirname(
os.path.dirname(os.path.dirname(
os.path.dirname(os.path.dirname(script_dir))))
)
)
# Target directory: docs/gns3-copilot
target_dir = os.path.join(project_root, "docs", "gns3-copilot")
# Create directory if it doesn't exist
os.makedirs(target_dir, exist_ok=True)
# Full file path
output_path = os.path.join(target_dir, filename)
try:
with open(output_path, 'w', encoding='utf-8') as f:
f.write(content)
print(f"Markdown document saved to: {output_path}")
except IOError as e:
print(f"Error: Failed to save Markdown file: {e}",
file=sys.stderr)
sys.exit(1)
def print_summary(version: str, ssh_count: int, telnet_count: int,
total_count: int, output_file: str) -> None:
"""Print summary to console."""
print("=" * 80)
print("Netmiko Device List Generator")
print(f"Netmiko Version: {version}")
print("=" * 80)
print()
print(f"Total SSH devices: {ssh_count}")
print(f"Total Telnet devices: {telnet_count}")
print(f"Total device types: {total_count}")
print()
print(f"Output file: {output_file}")
print("=" * 80)
def main() -> int:
"""
Main function to execute the script.
Returns:
Exit code (0 for success, 1 for error)
"""
# Register custom GNS3-Copilot drivers
custom_devices = register_custom_drivers()
# Get Netmiko version
version = get_netmiko_version()
# Get SSH and Telnet devices
ssh_devices, telnet_devices = get_devices_by_protocol()
if not ssh_devices and not telnet_devices:
print("Error: No devices found!", file=sys.stderr)
return 1
# Get total device count
total_count = get_total_device_count()
# Generate Markdown
markdown_content = generate_markdown(
version=version,
ssh_devices=ssh_devices,
telnet_devices=telnet_devices,
total_count=total_count,
custom_devices=custom_devices
)
# Save to file
output_file = "netmiko_devices.md"
save_markdown(markdown_content, output_file)
# Print summary
print_summary(
version=version,
ssh_count=len(ssh_devices),
telnet_count=len(telnet_devices),
total_count=total_count,
output_file=output_file
)
return 0
if __name__ == "__main__":
sys.exit(main())

View File

@ -51,10 +51,8 @@ class TestHuaweiTelnetCEDriver(unittest.TestCase):
# Check CLASS_MAPPER_BASE
self.assertIn("huawei_telnet_ce", CLASS_MAPPER_BASE)
self.assertEqual(CLASS_MAPPER_BASE["huawei_telnet_ce"], self.HuaweiTelnetCE)
# Check alias
self.assertIn("huawei_ce", CLASS_MAPPER)
self.assertEqual(CLASS_MAPPER_BASE["huawei_telnet_ce"],
self.HuaweiTelnetCE)
def test_inheritance_from_huawei_base(self):
"""Test that HuaweiTelnetCE inherits from HuaweiBase."""