前置条件
- python3.10
- 需要在配置文件输入的主机上起一个tftp服务
- 交换这里是锐捷交换机
- 这里的认证协议是telnet
- 需要准备一个交换机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中的参数
由于使用了多线程,所以打印的信息不会按顺序