Python导入CSV实现SSH批量路由器配置:IP与位置变量匹配问题
解决IP与Facility一一对应批量配置路由器的问题
看起来你现在的核心问题是CSV里的IP和Facility没有建立正确的一一映射关系,导致脚本会把所有Facility变量都用到每个IP上。其实根本不需要额外构建表格,只要调整CSV结构和对应的处理代码,就能实现每个IP对应专属的Facility配置。
第一步:修正CSV的结构(关键!)
你的CSV必须是每行一条记录,每行包含一个路由器IP和它对应的位置Facility,格式如下:
ipaddress,facility 192.168.10.1,NorthBuilding 192.168.10.2,SouthBuilding 192.168.10.3,EastCampus ...
如果你的CSV目前是把所有IP放在一个单元格、所有Facility放在另一个单元格的格式,先把它转换成上面的行式结构——这是实现一一对应的基础。
第二步:用Python实现批量SSH配置(示例代码)
用Python的paramiko(SSH客户端库)和csv模块可以轻松搞定这个需求,代码会逐行读取CSV,每个IP只使用对应的Facility生成配置命令:
import csv import paramiko from paramiko.ssh_exception import SSHException, NoValidConnectionsError def configure_router(router_ip, facility, username, password): # 根据Facility动态生成配置命令,这里替换成你的实际配置 config_cmds = [ f"hostname RT-{facility}", "interface GigabitEthernet0/0", f"description Uplink to {facility} Core", "ip address 10.0.0.1 255.255.255.0", "no shutdown", "exit", "write memory" ] try: # 初始化SSH客户端 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect( hostname=router_ip, username=username, password=password, timeout=10 ) # 进入配置模式并发送命令 shell = ssh.invoke_shell() shell.send("enable\n") shell.send("configure terminal\n") for cmd in config_cmds: shell.send(f"{cmd}\n") # 等待命令执行(可以根据设备响应调整等待时间) shell.recv(1024) print(f"✅ Successfully configured {router_ip} (Facility: {facility})") ssh.close() except NoValidConnectionsError: print(f"❌ Failed to connect to {router_ip}: Invalid IP or unreachable") except SSHException as e: print(f"❌ SSH error on {router_ip}: {str(e)}") except Exception as e: print(f"❌ Unexpected error on {router_ip}: {str(e)}") if __name__ == "__main__": # 读取映射后的CSV文件 with open("router_facilities.csv", "r") as csv_file: csv_reader = csv.DictReader(csv_file) # 替换成你的SSH账号密码 ssh_username = "admin" ssh_password = "your_secure_password" for row in csv_reader: ip = row["ipaddress"].strip() fac = row["facility"].strip() configure_router(ip, fac, ssh_username, ssh_password)
额外:如果你的CSV是“列表式”结构,先转换为映射格式
如果你的原始CSV是把所有IP和Facility分别放在两个列的单元格里(比如ipaddresses列是192.168.1.1,192.168.1.2,facilities列是BuildingA,BuildingB),可以用下面的脚本转换成正确的行式结构:
import csv # 读取原始列表式CSV with open("original_routers.csv", "r") as infile: reader = csv.reader(infile) headers = next(reader) # 拆分IP和Facility列表 ip_list = [ip.strip() for ip in headers[0].split(",")] facility_list = [fac.strip() for fac in headers[1].split(",")] # 写入映射后的CSV with open("mapped_routers.csv", "w", newline="") as outfile: writer = csv.writer(outfile) writer.writerow(["ipaddress", "facility"]) # 一一对应写入行 for ip, fac in zip(ip_list, facility_list): writer.writerow([ip, fac])
核心逻辑总结
- 让CSV成为IP与Facility的一对一映射表(每行对应一组),这是最直观且易维护的方式;
- 脚本逐行读取CSV,为每个IP生成专属的配置命令,不会混用其他Facility变量;
- 加入异常处理,避免单台设备故障导致整个批量任务中断。
内容的提问来源于stack exchange,提问作者ROSSMAN
相关产品推荐
相关产品推荐

