侧边栏壁纸
博主头像
荒山无可觅博主等级

一半聪明一半憨😕

  • 累计撰写 18 篇文章
  • 累计创建 1 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Python网络交换机批量备份

nice
2024-07-31 / 0 评论 / 0 点赞 / 48 阅读 / 7503 字 / 正在检测是否收录...

使用paramiko模块ssh连接实现交换机配置自动备份

将devices_list.txt和network_backup.py文件放在同一目录内

编辑内容如下

172.16.0.1 1F01 startup.cfg
172.16.0.2 2F01 vrpcfg.zip
172.16.0.3 3F01 vrpcfg.zip
172.16.0.4 4F01 startup.cfg
172.16.0.5 5F01 startup.cfg

直接运行network_backup.py,利用FTP上传配置文件,即可完成自动批量备份交换机

Python 代码:

import paramiko
import time
import os
import logging

# 配置日志,指定日志文件路径
log_file_path = 'log.txt'

# 创建文件处理器,记录所有级别的日志
file_handler = logging.FileHandler(log_file_path, mode='w')
file_handler.setLevel(logging.DEBUG)

# 创建终端处理器,仅显示INFO及以上级别的日志
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 配置日志格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 获取根日志记录器,并添加处理器
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 从环境变量获取用户名和密码
username = os.getenv('SSH_USERNAME', '用户名')
password = os.getenv('SSH_PASSWORD', '密码')

# FTP 服务器信息
ftp_server = 'FTP服务器'
ftp_user = 'FTP账号'
ftp_password = 'FTP密码'

# 打开设备列表文件
with open('devices_list.txt', 'r') as f:
    devices = f.readlines()
    total_devices = len(devices)
    success_count = 0  # 上传成功计数
    failure_count = 0  # 上传失败计数
    success_devices = []  # 记录上传成功的设备信息
    failure_devices = []  # 记录上传失败的设备信息

    for index, line in enumerate(devices):
        line_s = line.strip().split()

        # 检查行是否为空或是否有足够的列
        if not line_s or len(line_s) < 2:
            logging.warning(f"行格式不正确或为空,跳过: {line.strip()}")
            continue

        device_ip = line_s[0]
        device_name = line_s[1]

        # 判断备份文件类型
        if len(line_s) > 2:
            backup_file = line_s[2]  # 第三列为备份文件名
        else:
            backup_file = 'startup.cfg'  # 默认文件名

        try:
            # 创建 SSH 客户端并设置策略
            with paramiko.SSHClient() as ssh_client:
                ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh_client.connect(hostname=device_ip, username=username, password=password)

                # 仅在终端显示 SSH 连接成功
                print(f'成功连接上 {device_ip}')
                logging.info(f'成功连接上 {device_ip}')

                # 通过 SSH 会话发送命令
                command = ssh_client.invoke_shell()


                # 发送命令并接收输出的函数
                def send_and_receive(command_str, expected_output=None, sleep_time=2):
                    command.send(command_str + '\n')
                    time.sleep(sleep_time)  # 增加等待时间
                    output = ''
                    while True:
                        if command.recv_ready():
                            output += command.recv(1024).decode('utf-8')
                        else:
                            break
                    logging.debug(f'发送命令: {command_str}, 接收响应: {output}')
                    if expected_output is not None:
                        if expected_output in output:
                            logging.info(f'收到预期输出: {expected_output}')
                        else:
                            logging.warning(f'未收到预期输出: {expected_output}')
                    return output


                # 执行 FTP 命令
                output = send_and_receive(f'ftp {ftp_server}', sleep_time=8)

                # 输出FTP命令的初始响应
                logging.debug(f'FTP命令初始响应: {output}')

                # 确认设备是否要求用户名
                if "User" in output or "Name" in output or "Login:" in output:
                    output = send_and_receive(ftp_user, sleep_time=2)
                else:
                    print(f'FTP连接失败: {device_ip}')
                    logging.warning(f'未收到FTP用户名提示,可能未能正确连接到FTP服务器: {device_ip}')
                    failure_count += 1
                    failure_devices.append(f"{device_ip} ({device_name})")  # 记录失败设备
                    continue

                # 发送密码并确认登录成功
                if "Password" in output or "Password:" in output:
                    output = send_and_receive(ftp_password, sleep_time=2)
                    if "230" in output or "Login successful" in output:
                        # 仅在终端显示 FTP 连接成功
                        print(f'FTP 登录成功: {device_ip}')
                        logging.info(f'FTP 登录成功: {device_ip}')
                    else:
                        print(f'FTP 登录失败: {device_ip}')
                        logging.warning(f'FTP 登录失败: {device_ip}')
                        failure_count += 1
                        failure_devices.append(f"{device_ip} ({device_name})")  # 记录失败设备
                        continue
                else:
                    print(f'FTP登录失败: {device_ip}')
                    logging.warning(f'未收到FTP密码提示,可能未能正确登录: {device_ip}')
                    failure_count += 1
                    failure_devices.append(f"{device_ip} ({device_name})")  # 记录失败设备
                    continue

                # 上传文件并检查是否成功
                output = send_and_receive(f'put {backup_file} {device_name}_{backup_file}', '226 Transfer complete',
                                          sleep_time=2)
                logging.debug(f'FTP 上传响应: {output}')  # 记录完整的 FTP 上传响应

                send_and_receive('quit', sleep_time=1)  # 退出 FTP

                # 检查输出是否包含 "226 Transfer complete"
                if "226 Transfer complete" in output:
                    # 仅在终端显示上传成功的信息
                    print(f'文件上传成功: {device_ip}')
                    logging.info(f'文件上传成功: {device_ip}')
                    success_count += 1
                    success_devices.append(f"{device_ip} ({device_name})")
                else:
                    print(f'文件上传失败: {device_ip}')
                    logging.warning(f'文件上传失败: {device_ip}')
                    failure_count += 1
                    failure_devices.append(f"{device_ip} ({device_name})")  # 记录失败设备

        except Exception as e:
            print(f'连接 {device_ip} 失败')
            logging.error(f'连接 {device_ip} 失败: {e}')
            failure_count += 1
            failure_devices.append(f"{device_ip} ({device_name})")  # 记录失败设备

# 统计上传结果
print(f'总共设备数量: {success_count + failure_count}')
logging.info(f'总共设备数量: {success_count + failure_count}')
print(f'文件上传成功的设备数量: {success_count}')
logging.info(f'文件上传成功的设备数量: {success_count}')
print(f'文件上传失败的设备数量: {failure_count}')
logging.info(f'文件上传失败的设备数量: {failure_count}')

# 将统计信息和成功、失败设备信息写入 备份结果.txt 文件
with open('备份结果.txt', 'w') as report_file:
    report_file.write(f'总共设备数量: {success_count + failure_count}\n')
    report_file.write(f'文件上传成功的设备数量: {success_count}\n')
    report_file.write(f'文件上传失败的设备数量: {failure_count}\n\n')

    report_file.write('成功上传的设备列表:\n')
    for device in success_devices:
        report_file.write(f'{device}\n')

    report_file.write('\n上传失败的设备列表:\n')
    for device in failure_devices:
        report_file.write(f'{device}\n')

# 等待一段时间再结束脚本
time.sleep(3)
input("按任意键退出...")

0

评论区