0
点赞
收藏
分享

微信扫一扫

华三交换机自动备份

以下是一个基于Python的周期性自动备份华三(H3C)交换机日志和配置的脚本。这个脚本使用SSH连接到交换机,执行相关命令获取配置和日志,并将其保存到本地文件中,同时支持通过定时任务实现周期性备份。

使用说明

这个脚本提供了以下功能:

  1. 通过SSH连接到华三交换机
  2. 自动获取交换机的配置信息和日志
  3. 将备份文件按交换机IP和时间戳分类保存
  4. 支持设置定时任务,实现周期性自动备份
  5. 详细的日志记录,方便排查问题

前置条件

使用前需要安装必要的依赖库:

pip install paramiko python-crontab

配置方法

  1. 创建switches.conf文件,按照以下格式添加交换机信息:

# 格式: IP地址,用户名,密码,端口(可选)
192.168.1.1,admin,admin123,22
192.168.1.2,admin,admin456

  1. 直接运行脚本进行手动备份:

python h3c_backup.py

  1. 设置定时任务(可选):

# 每天自动备份
python h3c_backup.py --setup-cron daily

# 每周自动备份
python h3c_backup.py --setup-cron weekly

# 每小时自动备份
python h3c_backup.py --setup-cron hourly

备份文件存储

备份文件会保存在backups/交换机IP/目录下,文件名格式为:

  • 配置文件:交换机IP_config_时间戳.txt
  • 日志文件:交换机IP_logs_时间戳.txt

注意事项

  1. 确保执行脚本的机器能够通过SSH连接到目标交换机
  2. 交换机用户需要有足够的权限执行display current-configurationdisplay logbuffer命令
  3. 定期检查备份日志h3c_backup.log,确保备份正常执行
  4. 可以根据需要调整脚本中的命令等待时间,以适应不同性能的交换机

这个脚本可以根据实际需求进行扩展,例如添加邮件通知功能、备份文件压缩、旧文件自动清理等。

import paramiko
import time
import os
import logging
from datetime import datetime
from crontab import CronTab
import getpass

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='h3c_backup.log'
)

class H3CBackup:
    def __init__(self, host, username, password, port=22, timeout=30):
        self.host = host
        self.username = username
        self.password = password
        self.port = port
        self.timeout = timeout
        self.ssh = None
        self.channel = None
        
    def connect(self):
        """建立SSH连接"""
        try:
            self.ssh = paramiko.SSHClient()
            self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.ssh.connect(
                self.host,
                port=self.port,
                username=self.username,
                password=self.password,
                timeout=self.timeout
            )
            self.channel = self.ssh.invoke_shell()
            time.sleep(1)
            # 清除欢迎信息
            self.channel.recv(65535)
            logging.info(f"成功连接到交换机 {self.host}")
            return True
        except Exception as e:
            logging.error(f"连接交换机 {self.host} 失败: {str(e)}")
            return False
    
    def send_command(self, command, wait_time=2):
        """发送命令到交换机并返回结果"""
        try:
            self.channel.send(command + '\n')
            time.sleep(wait_time)
            result = self.channel.recv(65535).decode('utf-8', errors='ignore')
            # 去除命令回显
            return result.replace(command, '', 1).strip()
        except Exception as e:
            logging.error(f"发送命令 {command} 失败: {str(e)}")
            return None
    
    def get_config(self):
        """获取交换机配置"""
        return self.send_command('display current-configuration', wait_time=5)
    
    def get_logs(self):
        """获取交换机日志"""
        return self.send_command('display logbuffer', wait_time=3)
    
    def save_to_file(self, content, file_type):
        """保存配置或日志到文件"""
        if not content:
            logging.warning(f"没有获取到 {file_type} 内容,不保存文件")
            return False
            
        # 创建备份目录
        backup_dir = os.path.join('backups', self.host)
        os.makedirs(backup_dir, exist_ok=True)
        
        # 生成文件名
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
        filename = f"{self.host}_{file_type}_{timestamp}.txt"
        file_path = os.path.join(backup_dir, filename)
        
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write(content)
            logging.info(f"{file_type} 已保存到 {file_path}")
            return True
        except Exception as e:
            logging.error(f"保存 {file_type} 失败: {str(e)}")
            return False
    
    def backup(self):
        """执行备份操作"""
        if not self.connect():
            return False
            
        try:
            # 获取并保存配置
            config = self.get_config()
            self.save_to_file(config, 'config')
            
            # 获取并保存日志
            logs = self.get_logs()
            self.save_to_file(logs, 'logs')
            
            return True
        finally:
            self.disconnect()
    
    def disconnect(self):
        """关闭SSH连接"""
        if self.ssh:
            self.ssh.close()
            logging.info(f"已断开与交换机 {self.host} 的连接")

def setup_cron_job(interval='daily', script_path=None):
    """设置定时任务"""
    if not script_path:
        script_path = os.path.abspath(__file__)
    
    # 确保脚本有执行权限
    os.chmod(script_path, 0o755)
    
    try:
        # 创建当前用户的crontab
        cron = CronTab(user=getpass.getuser())
        
        # 移除已存在的相同任务
        for job in cron.find_comment('H3C交换机自动备份'):
            cron.remove(job)
        
        # 根据间隔设置定时任务
        if interval == 'hourly':
            job = cron.new(command=f'python3 {script_path} --auto', comment='H3C交换机自动备份')
            job.hour.every(1)
        elif interval == 'daily':
            job = cron.new(command=f'python3 {script_path} --auto', comment='H3C交换机自动备份')
            job.hour.on(2)  # 每天凌晨2点执行
        elif interval == 'weekly':
            job = cron.new(command=f'python3 {script_path} --auto', comment='H3C交换机自动备份')
            job.hour.on(2)
            job.dow.on(0)  # 每周日执行
        else:
            logging.error(f"不支持的备份间隔: {interval}")
            return False
        
        # 写入定时任务
        cron.write()
        logging.info(f"已设置{interval}定时备份任务")
        return True
    except Exception as e:
        logging.error(f"设置定时任务失败: {str(e)}")
        return False

def load_switch_configs(config_file='switches.conf'):
    """从配置文件加载交换机信息"""
    switches = []
    
    if not os.path.exists(config_file):
        logging.warning(f"配置文件 {config_file} 不存在")
        return switches
        
    try:
        with open(config_file, 'r') as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith('#'):
                    continue
                    
                parts = line.split(',')
                if len(parts) >= 3:
                    host, username, password = parts[0], parts[1], parts[2]
                    port = int(parts[3]) if len(parts) > 3 else 22
                    switches.append({
                        'host': host,
                        'username': username,
                        'password': password,
                        'port': port
                    })
        
        logging.info(f"从配置文件加载了 {len(switches)} 台交换机信息")
        return switches
    except Exception as e:
        logging.error(f"加载交换机配置失败: {str(e)}")
        return []

def main():
    import argparse
    
    parser = argparse.ArgumentParser(description='华三交换机配置和日志自动备份工具')
    parser.add_argument('--auto', action='store_true', help='自动执行备份(用于定时任务)')
    parser.add_argument('--setup-cron', choices=['hourly', 'daily', 'weekly'], 
                      help='设置定时备份任务')
    args = parser.parse_args()
    
    # 加载交换机配置
    switches = load_switch_configs()
    
    # 如果没有配置交换机,提示用户
    if not switches and not args.setup_cron:
        print("未找到交换机配置信息,请在switches.conf文件中配置交换机信息")
        print("格式: IP地址,用户名,密码,端口(可选)")
        return
    
    # 执行自动备份
    if args.auto or not args.setup_cron:
        print(f"开始备份 {len(switches)} 台交换机...")
        for switch_info in switches:
            print(f"正在备份 {switch_info['host']}...")
            backup = H3CBackup(
                host=switch_info['host'],
                username=switch_info['username'],
                password=switch_info['password'],
                port=switch_info.get('port', 22)
            )
            backup.backup()
        print("备份完成,详情请查看h3c_backup.log")
    
    # 设置定时任务
    if args.setup_cron:
        print(f"正在设置{args.setup_cron}定时备份任务...")
        if setup_cron_job(args.setup_cron):
            print(f"{args.setup_cron}定时备份任务设置成功")
        else:
            print("定时备份任务设置失败")

if __name__ == "__main__":
    main()

举报

相关推荐

0 条评论