【Python】批量保存并备份思科交换机配置

Netmiko是一个用于连接网络设备的Python库,该库提供了标准化的接口,使得连接诸如路由器、交换机、防火墙等各种类型的网络设备成为可能。这个库可以与Telnet、SSH等协议进行通信,并支持超过30种不同的网络厂商和设备型号。用于路由、交换、配置、监控和管理网络设备的Python脚本可以使用Netmiko实现,可用于自动化配置、端口映射、路由配置、设备查询和监控等任务。Netmiko库的主要功能包括与设备的连接、发送命令和获取输出、执行配置、收集设备信息等。Netmiko不仅大大简化了配置和管理网络设备的操作,而且提高了网络管理的效率和可靠性。

Netmiko库的优势:

  • 支持多种协议:Netmiko库支持SSH、Telnet和Serial(串口)等多种协议,可以轻松访问各种品牌的网络设备,如博科、思科、华为等,免去了使用不同命令和语法的繁琐手动配置过程。
  • 高度的可定制性:Netmiko支持高度可定制的配置文件,以与不同的网络设备相适应。用户可以自定义设备类型、协议、设备信息,以及处理特殊情况的脚本,提高通用性和灵活性。
  • 简单易学:Netmiko使用Python编程语言,语法简单易懂,使用方便,可单独使用或与其他Python库集成使用。与传统的CLI相比,Netmiko使用命令行或脚本都可以轻松管理设备。
  • 活跃的社区支持:Netmiko有一个活跃的用户社区和开发者社区,可以在GitHub上找到各种示例和脚本。这些示例和脚本可以帮助开发人员更快地上手和定制。

ref: https://pypi.org/project/netmiko/

以下脚本使用Netmiko模块以及zipfile模块,并结合具体方案,实现了备份和压缩Cisco设备配置文件,并上传到TFTP服务器的功能。脚本定义了每个设备的参数列表,并连接每个设备,保存运行配置到NVRAM和TFTP服务器。在备份过程中,脚本会输出更好的日志信息,以便于故障诊断。脚本还会压缩前一天的所有备份文件,并删除90天以前的备份文件。本脚本使用Python编写,可根据需要进行修改以适应不同的环境。

import os, zipfile, re, logging
from netmiko import ConnectHandler
from datetime import datetime, timedelta, date

# 配置日志文件
logging.basicConfig(filename='running.log', level=logging.INFO,format='%(asctime)s:%(levelname)s:%(message)s', filemode='w')

# 定义所有设备的参数列表
devices = [
    {
        'device_type': 'cisco_ios',
        'ip': '192.168.0.26',
        'username': 'cisco',
        'password': '*******',
        'secret': '******'
    },
    {
        'device_type': 'cisco_ios',
        'ip': '192.168.0.26',
        'username': 'cisco',
        'password': '*******',
        'secret': '******'
    }
]

# 连接和备份每个设备
for device in devices:
    # 连接到设备
    net_connect = ConnectHandler(**device)

    # 如果有secret,则激活特权模式
    if device['secret'] == 'cisco':
        net_connect.enable()
    # 保存设备配置至 NVRAM
    logging.info(f"Start save running-config...")
    backup_output = net_connect.send_command_expect('write memory', expect_string=']')

    # 打印保存配置结果
    if '[OK]' in backup_output:
        print(f'{device["ip"]}: Configuration backup saved successfully.')
        logging.info(f'{device["ip"]}: Configuration backup saved successfully.')
    else:
        print(f'{device["ip"]}: Failed to save configuration backup.')
        logging.info(f'{device["ip"]}: Failed to save configuration backup.')
    logging.info(f"End save running-config...")

    logging.info(f"Start save running-config to TFTP...")
    # 备份设备配置到 TFTP 服务器
    tftp_address = '192.168.1.9' # TFTP 服务器的 IP 地址
    filename = datetime.now().strftime("%Y%m%d%H%M%S") + '-' + device["ip"] + "-config" # 文件名
    tftp_output = net_connect.send_command_timing(f'copy running-config tftp://{tftp_address}/{filename}', delay_factor=1)

    while '?' in tftp_output:
        net_connect.clear_buffer()
        tftp_output = net_connect.send_command_timing('\n', delay_factor=20)

    tftp_output += net_connect.send_command_timing('\n', delay_factor=1)

    # 打印输出结果
    if 'bytes copied in' in tftp_output:
        for line in tftp_output.split('\n'):
            if 'bytes copied in' in line:
                result = line
                break
        if 'bytes/sec' not in result:
            # 使用正则表达式从字符串中匹配数字
            bytes_copied = int(re.search(r'\b(\d+)\b\s+bytes', result).group(1))
            seconds = float(re.search(r'in\s+([\d.]+)\s+secs', result).group(1))
            rounded_rate = round(bytes_copied / seconds)
            result = f"{result} ({rounded_rate} bytes/sec)"

        print(f'{device["ip"]}: Configuration successfully copied to TFTP server. {result}')
        logging.info(f'{device["ip"]}: Configuration successfully copied to TFTP server. {result}')
    else:
        print(f'{device["ip"]}: Failed to copy configuration to TFTP server.')
        logging.info(f'{device["ip"]}: Failed to copy configuration to TFTP server.')

    logging.info(f"End save running-config to TFTP...")
    # 断开网络连接
    net_connect.disconnect()

##压缩前一日备份文件

# 备份文件夹路径
dirpath = '/tftp_folder/'
# 昨天日期
yesterday = (date.today() - timedelta(days=1)).strftime("%Y%m%d")
# 90天前日期
b90day = (date.today() - timedelta(days=90)).strftime("%Y%m%d")

# 压缩文件路径
zip_file_path = os.path.join(dirpath, f"{yesterday}.zip")

# 判断zip文件是否存在,存在则追加数据,否则创建新的zip文件
mode = 'a' if os.path.exists(zip_file_path) else 'w'

# 使用with语句打开Zip文件,自动关闭文件对象
with zipfile.ZipFile(zip_file_path, mode) as Zip:
    # 获取备份文件列表
    backup_files = os.listdir(dirpath)
    for name in backup_files:
        if name.startswith(yesterday) and not name.endswith('.zip'):
            # 如果是昨天的备份文件,且不是zip文件,则添加到压缩文件中
            Zip.write(os.path.join(dirpath, name), name, zipfile.ZIP_DEFLATED)
            os.remove(os.path.join(dirpath, name))
        elif name.endswith('.zip') and int(name[:8]) < int(b90day):
            # 如果是zip文件且创建时间早于90天前,则删除文件
            os.remove(os.path.join(dirpath, name))

当然以上只是一个实现需求的办法,还有很多其他的方法可以实现相同的功能。在实际的开发过程中,我们需要根据具体的需求和场景选择最合适的实现方式。不同的需求和场景需要选择最合适的实现方式,而Python作为一种简单易学、灵活性高、库丰富、跨平台性好、社区活跃的编程语言,逐渐成为了网络管理员等开发者的首选语言之一。

文末冷笑话

为什么网络管理员喜欢Python?因为他们从来都不想再通过命令行输入两个相同的命令!
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值