更新了备份交换机的脚本。先看效果。

备份网络设备的小脚本_第1张图片

备份网络设备的小脚本_第2张图片


config.ini 配置文件

备份网络设备的小脚本_第3张图片


iplist.txt配置文件

备份网络设备的小脚本_第4张图片


主代码

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
# @Author  :   Arcky.li

import getpass
import sys
import datetime
import os
import shutil
import re
import threading 
from enAPI import *
from netmiko import ConnectHandler
from netmiko.ssh_exception import NetMikoTimeoutException,NetMikoAuthenticationException


def auth(Conn):
    def wrapper(dtype,ip,username,password,tftpserverip):
        device = {
                 'device_type': dtype,
                 'ip': ip,
                 'username': username,
                 'password': password,
                  }
        try:          
            connect = ConnectHandler(**device)
            connect.enable()
        except (EOFError, NetMikoTimeoutException):            
            print(u" 网络设备%s: 无法连接!请确认该设备IPAddress是否可达!"%ip)  
            sys.exit(0)             
        except (EOFError, NetMikoAuthenticationException):
            print(u" 网络设备%s: 用户名与密码错误!请确认账号与密码!" %ip)
            sys.exit(0)
        res = Conn(dtype,ip,username,password,tftpserverip,connect)
        return res 
    return wrapper

@auth
def backupCiscoIOS(dtype,ip,username,password,tftpserverip,connect):
    date = datetime.datetime.now().strftime('%d-%H-%M')
    hostname = connect.find_prompt()
    hostname = hostname.replace("#","")
    bkfilename   = ''.join((('-'.join((hostname,date))),'.cfg'))
    backupcmd    =  'copy running-config tftp:'
    bkconf  = '\n'.join((backupcmd,tftpserverip,bkfilename))
    connect.send_command(bkconf)
    connect.disconnect()
    return hostname,bkfilename

@auth
def backupCiscoASA(dtype,ip,username,password,tftpserverip,connect):
    date = datetime.datetime.now().strftime('%d-%H-%M')
    hostname = connect.find_prompt()
    hostname = hostname.replace("#","")
    bkfilename   = ''.join((('-'.join((hostname,date))),'.cfg'))
    backupcmd    =  'copy running-config tftp:'
    backupcmd    = ''.join((backupcmd,'\n'))
    bkconf  = '\n'.join((backupcmd,tftpserverip,bkfilename,'\n'))
    connect.send_command(bkconf)
    connect.disconnect()
    return hostname,bkfilename

def backupDevice(dtype,ip,username,password,tftpserverip,backuppath):
    if dtype == 'cisco_ios':
        resbackup = backupCiscoIOS(dtype,ip,username,password,tftpserverip)
    if dtype =='cisco_asa':
        resbackup = backupCiscoASA(dtype,ip,username,password,tftpserverip)
    path = os.path.join(backuppath,resbackup[0])
    if not os.path.exists(path):
        os.makedirs(path)
    try:
        shutil.move((os.path.join(backuppath,resbackup[1])),path)
        print ("网络设备 %s 备份完成!!!" %ip)
        print ("-"*60)
    except Exception as e:
        print('备份文件%s不存在,请确认TFTServer是否可达!' %resbackup[1])

def begingbackup(username,password,tftpserverip,backuppath): 
    print("网络设备备份正式开始,请睁大眼睛检查。。。。") 
    print("  ")  
    with open('/data/autobackup/iplist.txt','r') as f:
        for ip in f.readlines():
            ip = ip.strip('\n').split(":")
            if ip[0]:   
                a = threading.Thread(target=backupDevice,args=(ip[0],ip[1],username,password,tftpserverip,backuppath))
                a.start()

def addConfigInfo():
    username = input("username: ")
    if len(username) == 0:
        sys.exit(0)
    password = getpass.getpass()
    tftpserverip    = input("tftpserverip: ")
    if len(tftpserverip) == 0:
        sys.exit(0)
    backuppath = input("backuppath: ")
    if len(backuppath) == 0:
        sys.exit(0)
    try:
        writeprofile('info','username',username)
        writeprofile('info','password',encrypt_and_decode().encrypted_text(password))
        writeprofile('info','tftpserverip',tftpserverip)
        writeprofile('info','backuppath',backuppath)
    except Exception as e:
        print('文件config.ini 写入失败!')
    begingbackup(username,password,tftpserverip,begingbackup)
    
       

def backupMain():
    os.system("clear")
    print ("                                                             ")               
    print ("   #                 网络设备自动备份工具              #")
    print ("   -----------------------------------------------------------")
    print ("   #  说明:                                                 #")
    print ("   #    1. 请在相应的文件夹增加config.ini与iplist.txt文件     #")
    print ("   #    2. config.ini配置登录交换用户名密码等信息,权限777    #")
    print ("   #    3. iplist.txt设定备网络设备基本信息,请按格式填写     #")
    print ("   #    4. 项次'1'为新增或修改备份信息,项次'2'为开始备份      #")
    print ("   #                                                          #")
    print ("   #                             ---- Author: Arcky.li        #")
    print ("   ###########################################################")
    print(" ")
    num = input("请选择项次'1'或'2':  " )
    if int(num) == 1 :
        addConfigInfo()    
    if int(num) == 2:
        username = readprofile('info','username')
        password = readprofile('info','password')
        password = encrypt_and_decode().decrypted_text(password)
        tftpserverip =  readprofile('info','tftpserverip')
        backuppath = readprofile('info','backuppath')
        if username != None and password != None and tftpserverip != None and backuppath != None:
            begingbackup(username,password,tftpserverip,backuppath)
    
if __name__ == '__main__':
    backupMain()


config.ini的文件配置以及加密、解码代码

import configparser
import os
import base64
from Crypto.Cipher import AES


inifilepath =  '/data/autobackup'
class encrypt_and_decode:
    #秘钥
    def __init__(self):
        self.key = '@0yKGh%AGzwG0P*dXxj9!3ed2RSXz11E'
       
        self.PADDING = '\0'

    def add_to_16(self,textvalue):
        while len(textvalue) % 16 != 0:
            textvalue += '\0'
        return str.encode(textvalue)  

    
    def encrypted_text(self,text):
        try:
            keyvalue = self.key
            aes = AES.new(self.add_to_16(keyvalue),AES.MODE_ECB)  
            encrypted_text = str(base64.encodebytes(aes.encrypt(self.add_to_16(text))), encoding='utf-8').replace('\n', '')  
            return encrypted_text
        except Exception  as e:
            return 'error value'

    
    def decrypted_text(self,text):
        try:
            keyvalue = self.key
            aes = AES.new(self.add_to_16(keyvalue),AES.MODE_ECB)  
            text_decrypted = str(
                aes.decrypt(base64.decodebytes(bytes(text, encoding='utf8'))).rstrip(b'\0').decode("utf8"))  
            return text_decrypted
        except Exception  as e:
            return 'error value'

def readprofile(title,key):
    try:
        conf = configparser.ConfigParser()
        conf.read(os.path.join(inifilepath,"config.ini"))
        returnvalue = conf.get(title, key)
        return returnvalue
    except Exception as e:
        return False

def writeprofile(title,key,value): 
    try:
        conf = configparser.ConfigParser()
        conf.read(os.path.join(inifilepath,"config.ini"))
        conf.set(title, key,value)
        conf.write(open(os.path.join(inifilepath,"config.ini"), "w"))
        return True
    except Exception as e:
        return False