mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-10-14 09:49:19 +00:00
1
This commit is contained in:
parent
8f5ac21be1
commit
f80fc9fc56
@ -1,5 +1,4 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import telnetlib3
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional
|
||||
@ -41,8 +40,6 @@ class SwitchConfigurator:
|
||||
password: str = None,
|
||||
timeout: int = None,
|
||||
max_workers: int = 5,
|
||||
ensp_mode: bool = False,
|
||||
ensp_port: int = 2000,
|
||||
ensp_command_delay: float = 0.5,
|
||||
**ssh_options
|
||||
):
|
||||
@ -52,34 +49,45 @@ class SwitchConfigurator:
|
||||
self.semaphore = asyncio.Semaphore(max_workers)
|
||||
self.backup_dir = Path("config_backups")
|
||||
self.backup_dir.mkdir(exist_ok=True)
|
||||
self.ensp_mode = ensp_mode
|
||||
self.ensp_port = ensp_port
|
||||
self.ensp_delay = ensp_command_delay
|
||||
self.ssh_options = ssh_options
|
||||
|
||||
async def _get_or_create_connection(self, ip: str):
|
||||
"""
|
||||
从连接池获取连接,如果没有则新建 Telnet 连接
|
||||
"""
|
||||
if ip in self.connection_pool:
|
||||
logger.debug(f"复用已有连接: {ip}")
|
||||
return self.connection_pool[ip]
|
||||
|
||||
logger.info(f"建立新连接: {ip}")
|
||||
reader, writer = await telnetlib3.open_connection(host=ip, port=23)
|
||||
reader, writer = await telnetlib3.open_connection(
|
||||
host=ip,
|
||||
port=23,
|
||||
encoding=None,
|
||||
shell=None
|
||||
)
|
||||
|
||||
try:
|
||||
if self.username != 'NONE' :
|
||||
if self.username and self.username.upper() != "NONE":
|
||||
try:
|
||||
logger.debug("等待用户名提示...")
|
||||
await asyncio.wait_for(reader.readuntil(b"Username:"), timeout=self.timeout)
|
||||
writer.write(f"{self.username}\n")
|
||||
writer.write(self.username.encode() + b"\n")
|
||||
await writer.drain()
|
||||
logger.info("用户名发送完成")
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning("未收到用户名提示,可能交换机不要求用户名")
|
||||
|
||||
await asyncio.wait_for(reader.readuntil(b"Password:"), timeout=self.timeout)
|
||||
writer.write(f"{self.password}\n")
|
||||
|
||||
await asyncio.sleep(1)
|
||||
try:
|
||||
logger.debug("等待密码提示...")
|
||||
await asyncio.wait_for(reader.readuntil(b"assword:"), timeout=self.timeout)
|
||||
writer.write(self.password.encode() + b"\n")
|
||||
await writer.drain()
|
||||
logger.info("密码发送完成")
|
||||
except asyncio.TimeoutError:
|
||||
writer.close()
|
||||
raise EnspConnectionException("登录超时,未收到用户名或密码提示")
|
||||
raise EnspConnectionException("未收到密码提示,登录失败")
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
except Exception as e:
|
||||
writer.close()
|
||||
raise EnspConnectionException(f"登录异常: {e}")
|
||||
@ -88,9 +96,6 @@ class SwitchConfigurator:
|
||||
return reader, writer
|
||||
|
||||
async def _send_ensp_commands(self, ip: str, commands: List[str]) -> bool:
|
||||
"""
|
||||
通过 Telnet 协议发送命令
|
||||
"""
|
||||
try:
|
||||
reader, writer = await self._get_or_create_connection(ip)
|
||||
|
||||
@ -98,10 +103,24 @@ class SwitchConfigurator:
|
||||
if cmd.startswith("!"):
|
||||
logger.debug(f"跳过特殊命令: {cmd}")
|
||||
continue
|
||||
|
||||
logger.info(f"[{ip}] 发送命令: {cmd}")
|
||||
writer.write(f"{cmd}\n")
|
||||
writer.write(cmd.encode() + b"\n")
|
||||
await writer.drain()
|
||||
await asyncio.sleep(self.ensp_delay)
|
||||
try:
|
||||
output = b""
|
||||
while True:
|
||||
chunk = await asyncio.wait_for(reader.read(1024), timeout=1)
|
||||
if not chunk:
|
||||
break
|
||||
output += chunk
|
||||
if output:
|
||||
logger.info(f"[{ip}] 返回结果:\n{output.decode(errors='ignore').strip()}")
|
||||
else:
|
||||
logger.warning(f"[{ip}] 返回为空")
|
||||
except asyncio.TimeoutError:
|
||||
logger.warning(f"[{ip}] 读取返回超时 (命令: {cmd})")
|
||||
|
||||
logger.info(f"[{ip}] 所有命令发送完成")
|
||||
return True
|
||||
@ -114,9 +133,5 @@ class SwitchConfigurator:
|
||||
return False
|
||||
|
||||
async def execute_raw_commands(self, ip: str, commands: List[str]) -> bool:
|
||||
"""
|
||||
对外接口:单台交换机执行命令
|
||||
"""
|
||||
async with self.semaphore:
|
||||
success = await self._send_ensp_commands(ip, commands)
|
||||
return success
|
||||
return await self._send_ensp_commands(ip, commands)
|
||||
|
Loading…
x
Reference in New Issue
Block a user