单个与批量交换机配置备份
本帖最后由 hoochanlon 于 2024-11-21 15:37 编辑# 单个与批量交换机配置备份
## 单个备份
设计思路(五个关键):
1. 连接 ssh 登录到交换机
2. 通过 `dis cu` (display current-configuration)显示交换机配置
3. 利用标识符“ops”、“return”作为读取的结尾。
4. 读取内容到指定文本文件。
5. 通过ftp导出vrpcfg.cfg文件进行对比,利用正则剔除`dis cu` 之前的以上所有信息,保留 `dis cu` 输出的以下所有信息。
其他(todo & think):写出这些,以后剩下的的配置之类的,也差不多。
* [ ] 打算写一份基于 ftp 导出的(所以命名有“导出”改成了“备份”)
* [ ] 有时间再写 display logbuffer 日志导出的
源码如下及地址:
* https://github.com/hoochanlon/scripts/tree/main/d-python-datacom
* 单个交换机配置备份模板.py
```
import paramiko
import time
import os
from datetime import datetime
import re
# 配置交换机的信息
hostname = "192.168.1.250"# 交换机的IP地址
username = "yonghuming"# SSH 登录用户名
password = "Mima12345@"# SSH 登录密码
# 动态生成备份文件名,包含日期时间
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")# 格式化时间
current_date = datetime.now().strftime("%Y%m%d")# 当天日期
backup_filename = f"switch_backup_{timestamp}.cfg"# 配置备份文件名
# 获取当前用户桌面路径
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
date_folder_path = os.path.join(desktop_path, current_date)# 当天日期的文件夹路径
backup_filepath = os.path.join(date_folder_path, backup_filename)# 文件完整路径
# 如果日期文件夹不存在,则创建
if not os.path.exists(date_folder_path):
os.makedirs(date_folder_path)
# 创建 SSH 客户端
client = paramiko.SSHClient()
# 自动接受未知的主机密钥
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
# 连接到交换机
client.connect(hostname, username=username, password=password)
# client.connect(hostname, username=username, password=password, port=2399)
# 打开交互式 shell
shell = client.invoke_shell()
# 禁用分页
shell.send("screen-length 0 temporary\n")
time.sleep(1)
# 执行备份命令
shell.send("display current-configuration\n")
time.sleep(2)# 等待命令执行
output = ""
found_ops = False# 初始化标志位,标记是否已找到 "ops"
while True:
# 增加接收缓冲区大小
part = shell.recv(8848).decode('utf-8')
# 将输出追加到结果中
output += part
# 判断是否遇到 "return"
if 'return' in part:
found_ops = True
# 如果找到了 "ops",继续读取直到出现 "return"
if found_ops and 'return' in part:
break# 找到 "return",停止读取
# 先将原始输出写入文件
with open(backup_filepath, "w") as backup_file:
backup_file.write(output)
# 重新读取文件内容,应用正则清理
with open(backup_filepath, "r") as backup_file:
raw_content = backup_file.read()
# 使用正则删除 dis cu 以上所有信息,保证格式与 vrpcfg.cfg 等同
cleaned_output = re.sub(
r"(?s).*?display current-configuration\n",
"",
raw_content
)
# 将清理后的内容写回文件
with open(backup_filepath, "w") as backup_file:
backup_file.write(cleaned_output)
print(f"备份已完成,配置已保存到 {backup_filepath}")
except Exception as e:
print(f"连接或备份过程中发生错误: {e}")
finally:
# 关闭 SSH 连接
client.close()
```
单个备份效果
![ ](https://cdn.sa.net/2024/11/21/hBryolkGcTUnmP9.png)
## 批量备份
设计思路:
* 在单个备份的基础上,通过读取 CSV,根据CSV的相关信息达到动态连接的目的。
* 这样还有个好处,也能统一批量修改文件名。(简单实验后想到)
* 由于文件较多,所以在桌面生成一个当天日期文件夹来存放,后来也把这思路放在了单个备份脚本上了。
SSH内容如下
![ ](https://cdn.sa.net/2024/11/21/DTNSgerkF6iZLHo.png)
附源码地址:
* https://github.com/hoochanlon/scripts/tree/main/d-python-datacom
* 批量交换机配置备份.py
```
import paramiko
import time
import os
import csv
from datetime import datetime
import re
# 获取当前用户桌面路径
desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
# 动态生成当天日期的文件夹
current_date = datetime.now().strftime("%Y%m%d")# 当天日期
date_folder_path = os.path.join(desktop_path, current_date)# 日期文件夹路径
# 如果日期文件夹不存在,则创建
if not os.path.exists(date_folder_path):
os.makedirs(date_folder_path)
# 读取 CSV 文件并逐行处理
csv_file_path = os.path.join(desktop_path, "SSH登记表.csv")# 假设 CSV 文件在桌面
try:
with open(csv_file_path, "r", encoding="utf-8") as csv_file:
csv_reader = csv.reader(csv_file)
for row in csv_reader:
# 解析每一行数据
if len(row) < 5:
print(f"跳过格式不正确的行: {row}")
continue
device_name, hostname, username, password, port = row
port = int(port)# 将端口号转换为整数
backup_filename = f"{device_name}.txt"# 备份文件名
backup_filepath = os.path.join(date_folder_path, backup_filename)# 文件完整路径
# 创建 SSH 客户端
client = paramiko.SSHClient()
# 自动接受未知的主机密钥
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
# 连接到交换机,使用动态端口
print(f"正在连接到 {hostname} ({device_name}),端口 {port}...")
client.connect(hostname, username=username, password=password, port=port)
# 打开交互式 shell
shell = client.invoke_shell()
# 禁用分页
shell.send("screen-length 0 temporary\n")
time.sleep(1)
# 执行备份命令
shell.send("display current-configuration\n")
time.sleep(2)# 等待命令执行
output = ""
found_ops = False# 初始化标志位,标记是否已找到 "ops"
while True:
# 增加接收缓冲区大小
part = shell.recv(8848).decode('utf-8')
# 将输出追加到结果中
output += part
# 判断是否遇到 "return"
if 'return' in part:
found_ops = True
# 如果找到了 "ops",继续读取直到出现 "return"
if found_ops and 'return' in part:
break# 找到 "return",停止读取
# 先将原始输出写入文件
with open(backup_filepath, "w", encoding="utf-8") as backup_file:
backup_file.write(output)
# 重新读取文件内容,应用正则清理
with open(backup_filepath, "r", encoding="utf-8") as backup_file:
raw_content = backup_file.read()
# 使用正则删除 dis cu 以上所有信息,保证格式与 vrpcfg.cfg 等同
cleaned_output = re.sub(
r"(?s).*?display current-configuration\n",
"",
raw_content
)
# 将清理后的内容写回文件
with open(backup_filepath, "w", encoding="utf-8") as backup_file:
backup_file.write(cleaned_output)
print(f"{device_name} ({hostname}) 备份完成,保存到 {backup_filepath}")
except Exception as e:
print(f"备份 {device_name} ({hostname}) 失败: {e}")
finally:
# 关闭 SSH 连接
client.close()
except FileNotFoundError:
print(f"CSV 文件未找到,请确认路径是否正确: {csv_file_path}")
except Exception as e:
print(f"处理 CSV 文件时发生错误: {e}")
```
单个备份与批量备份的效果一览
![ ](https://cdn.sa.net/2024/11/21/YiJRN24cZ56MLSq.png)
![ ](https://cdn.sa.net/2024/11/21/QsDngSjA1X48JEt.png) 感谢分享,很不错的脚本。 # 执行备份命令
shell.send("display current-configuration\n")
time.sleep(2)# 等待命令执行
这个地方建议修改成等待提示符,或者匹配设备名的方法判断命令是否执行完毕。 不错不错!收下了 cjy11235 发表于 2024-11-21 16:41
# 执行备份命令
shell.send("display current-configuration\n")
...
好主意,是可以这样 支持TSC卓越交换机吗? 谢谢楼主的分享,记号下载。 xiangzz 发表于 2024-11-21 20:30
支持TSC卓越交换机吗?
对应的,你看下你说的交换机品牌是否支持关闭分屏(必要),显示配置肯定可以的,无非命令不一样。然后你注意下结尾标记是否和华为的一样,华为交换机dis cu翻到最后就有“ops”、“return”,你可以依据这个思路改一下。 写得很好 感谢楼主的分享,先存着啦
页:
[1]
2