python基于telnet验证的交换机配置导出打包脚本

前置条件

  1. python3.10
  2. 需要在配置文件输入的主机上起一个tftp服务
  3. 交换这里是锐捷交换机
  4. 这里的认证协议是telnet
  5. 需要准备一个交换机IP地址的文件供脚本读取

代码部分

import datetime
import telnetlib
import time
import concurrent.futures as fu
import queue
from pathlib import Path
import zipfile, os, shutil


class ruijie_get_cu:
    def __init__(self, ip_list_path, serv_ip, serv_path, username, passwd, threads=None):
        self.ip_list_path = ip_list_path
        self.serv_ip = serv_ip
        self.serv_path = serv_path
        self.username = username
        self.passwd = passwd
        self.threads = threads
        self.ip_list = list()
        self.q = queue.Queue()
        self.dir_name = datetime.datetime.now().strftime("%Y%m%d")

    def put_ip(self):
        with open(self.ip_list_path, 'r') as f:
            for i in f.readlines():
                self.ip_list.append(i.strip())

    def get_cu(self, ip):
        try:
            con = telnetlib.Telnet(host=ip, timeout=3)
        except TimeoutError as e:
            print(e,ip,'=======')
            self.q.put(f'{ip}无法连接!!')
            con.close()
            return False
            # print(type(con), con)
        con.read_until(b'Username:')
        con.write(f'{self.username}\r\n'.encode())
        # print(con.read_until(b'Password:'),'====')
        con.read_until(b'Password:')
        con.write(f'{self.passwd}\r\n'.encode())
        time.sleep(1)
        end = con.read_some()
        if end.decode().endswith('>'):
            con.write('en\r\n'.encode())
            con.read_until(b'Password:')
            # print(con.read_until(b'Password:'),'有>')
            con.write(f'{self.passwd}\r\n'.encode())
        con.write('\r\n'.encode())
        # print(con.read_until(b'#'),'~~~~')
        con.read_until(b'#')
        con.write(f'copy flash:config.text tftp://{self.serv_ip}/{self.dir_name}/{ip}config.text\r\n'.encode())
        if con.read_until(b'Copy success.', timeout=3).endswith(b'Copy success.'):
            print(f'{ip}-->导出成功!')
        else:
            print(f'{ip}导出失败!\n可能ftp服务器未打开!')
        con.close()

    # 可以打印或者写文件
    def write_txt(self):
        with open('log.txt', 'w', encoding='utf8') as file:
            while not self.q.empty():
                # file.write(self.q.get().strip() + '\n')
                print(self.q.get())

    # 打包数据
    def zip_dir(self):
        source_dir = self.serv_path + '/' + self.dir_name
        with zipfile.ZipFile(self.serv_path + '/' + self.dir_name + '.zip', 'w') as zipf:
            pre_len = len(os.path.dirname(source_dir))
            for parent, dirnames, filenames in os.walk(source_dir):
                for filename in filenames:
                    pathfile = os.path.join(parent, filename)
                    arcname = pathfile[pre_len:].strip(os.path.sep)  # 相对路径
                    zipf.write(pathfile, arcname)
        # 删除原文件
        shutil.rmtree(self.serv_path + '/' + self.dir_name, ignore_errors=True)

    def run(self):
        stat = datetime.datetime.now()
        print('开始创建文件夹'.center(60, '='))
        (Path(self.serv_path) / self.dir_name).mkdir(exist_ok=True)
        print('开始导配置'.center(60, '='))
        self.put_ip()
        if not self.threads:
            count = len(self.ip_list)
        else:
            count = self.threads
        with fu.ThreadPoolExecutor(count) as pool:
            fs = []
            for ip in self.ip_list:
                fut = pool.submit(self.get_cu, ip)
                fs.append(fut)
            fu.as_completed(fs)
        print('开始打包'.center(60, '='))
        self.zip_dir()
        self.write_txt()
        print(('结束,全程共耗时:%.2fs' % ((datetime.datetime.now() - stat).total_seconds())).center(60, '='))


if __name__ == '__main__':
    # 锐捷tftp服务器地址
    serv_path = r'/xx/xx/xx/xx'
    # ip地址存储文件地址
    ip_list_path = 'ip'
    # 运行tftp服务器的主机ip地址
    serv_ip = "xx.xx.xx.xx"
    # 必须保证所有的用户名和密码一致
    # 交换机登录用户名
    username = 'admin'
    # 交换机登录密码
    passwd = 'xxxxx'
    ruijie_get_cu(ip_list_path, serv_ip, serv_path, username, passwd).run()

注意: 这里只是脚本,并没有做工程化处理,使用时直接用python运行脚本文件就好了,记得修改下面main中的参数
由于使用了多线程,所以打印的信息不会按顺序

posted @ 2023-02-20 09:26  厚礼蝎  阅读(116)  评论(0编辑  收藏  举报