这是群里大佬Lindh08分享的实用脚本,支持多厂商的设备配置文件备份,也支持自定义配置,修改密码模块有点完善,感兴趣的小伙伴可以运行测试,也可以在此基础进行完善。

    代码如下:

    1. import os
    2. import time
    3. from datetime import datetime
    4. import getpass
    5. import re
    6. import sys
    7. from netmiko import ConnectHandler
    8. from netmiko.ssh_exception import NetMikoTimeoutException
    9. from netmiko.ssh_exception import AuthenticationException
    10. from paramiko.ssh_exception import SSHException
    11. import gevent
    12. from gevent import spawn
    13. from gevent import monkey;monkey.patch_all()
    14. from gevent.pool import Pool
    15. from openpyxl import Workbook
    16. from openpyxl import load_workbook
    17. #####################################################################################################
    18. # v1.2.0 2021.4.29 新增进度条显示功能
    19. # v1.3.0 2021.4.30 新增华为设备模块
    20. # v1.4.0 2021.5.6 新增锐捷AC模块
    21. # v1.5.0 2021.5.7 1.新增"点击回车键"退出程序功能
    22. # 2.打包封装程序并增加图标
    23. # v2.0.0 2021.6.2 重构代码框架,后续可模块化添加设备和任务类型
    24. # v2.0.1 2021.6.3 细微调整结构框架
    25. # v3.0.0 2021.6.5 1.将原先多线程方式运行改为用gevent协程方式运行
    26. # 2.修改flag信息
    27. # 3.任务99名称修改为"自定义操作"
    28. # 4.取消进度条显示,改为实时任务进度显示
    29. # v3.1.0 2021.6.6 1.重构函数,增加报错输出。
    30. # 2.修复get_config中锐捷的output变量bug
    31. # v3.2.0 2021.6.8 1.读取文件形式由txt改成excel
    32. # v3.2.1 2021.6.16 增加特权密码
    33. # v3.2.2 2021.6.17 1.修复进入特权bug
    34. # 2.增加ASA设备
    35. # 3.修复ASA有failover创建文件bug
    36. # v3.2.3 2021.6.18 修改H3C登录bug
    37. #####################################################################################################
    38. print('****************************************************')
    39. print('*Welcome!This program designed by Lindh08. *')
    40. print('*Please contact me by E-mail.Add:511768312@qq.com. *')
    41. print('****************************************************')
    42. dev_type = input("请选择设备类型:\n\
    43. 1.Cisco\n\
    44. 2.Ruijie\n\
    45. 3.Ruijie_AC\n\
    46. 4.H3C\n\
    47. 5.Huawei\n\
    48. 6.Cisco-ASA\n\
    49. 请输入序号: ")
    50. print('******************************************')
    51. task = input("请选择想要运行的脚本类型:\n\
    52. 1.备份配置\n\
    53. 2.修改密码\n\
    54. 99.自定义操作\n\
    55. 请输入序号: ")
    56. print('******************************************')
    57. username = input('Username: ')
    58. password = getpass.getpass('Password: ')
    59. secret = getpass.getpass('Secret: ')
    60. #####################################################################################################
    61. # 1.1判断模块
    62. #####################################################################################################
    63. # 1.1.1判断设备类型
    64. #####################################################################################################
    65. if int(dev_type)==1: # Cisco设备
    66. dev_type_brand = "cisco"
    67. dev_type_str = "cisco_ios"
    68. elif int(dev_type)==2: #锐捷路由器或者交换机设备
    69. dev_type_brand = "ruijie"
    70. dev_type_str = "ruijie_os"
    71. elif int(dev_type)==3: #锐捷AC
    72. dev_type_brand = "ruijie_AC"
    73. dev_type_str = "ruijie_os"
    74. elif int(dev_type)==4: #H3C设备
    75. dev_type_brand = "H3C"
    76. dev_type_str = "hp_comware"
    77. elif int(dev_type)==5: #华为设备
    78. dev_type_brand = "Huawei"
    79. dev_type_str = "huawei"
    80. elif int(dev_type)==6: #Cisco-ASA
    81. dev_type_brand = "ASA"
    82. dev_type_str = "cisco_asa_ssh"
    83. #elif int(dev_type)==x: #后续添加设备
    84. # dev_type_brand = "xxxx"
    85. # dev_type_str = "xxxx"
    86. #####################################################################################################
    87. # 1.1.2判断任务类型
    88. #####################################################################################################
    89. if int(task)==1: #备份配置
    90. task_type = "bak"
    91. elif int(task)!=1:
    92. if int(task)==2: #修改密码
    93. task_type = "pwd"
    94. #elif int(task)==x: #后续可添加模块
    95. elif int(task)==99: #其他操作
    96. task_type = "other"
    97. #####################################################################################################
    98. # 1.2函数模块
    99. #####################################################################################################
    100. # 1.2.1会话连接
    101. #####################################################################################################
    102. def get_config(ip):
    103. dev = {'device_type':dev_type_str,
    104. 'host':ip,
    105. 'username':username,
    106. 'password':password,
    107. 'secret':secret,
    108. }
    109. ssh_session = ConnectHandler(**dev)
    110. get_hostname = ssh_session.find_prompt().replace("#","").replace("<","").replace(">","").replace("/","-")
    111. print(f"---- 正在连接: {get_hostname}({ip.strip()}).")
    112. # 判断任务类型输入命令
    113. if int(task)==1: #备份配置
    114. if int(dev_type)==1 or int(dev_type)==2 or int(dev_type)==3 or int(dev_type)==6: # Cisco设备
    115. ssh_session.enable()
    116. command = ("sh run")
    117. output = ssh_session.send_command(command)
    118. elif int(dev_type)==4 or int(dev_type)==5 : # 华为设备
    119. command = ("dis cur")
    120. output = ssh_session.send_command(command)
    121. elif int(task)!=1:
    122. cmdlist = open(f'cmd\\{int(task)}.{task_type}\\{task_type}_cmd_{dev_type_brand}.txt','r')
    123. cmdlist.seek(0)
    124. output = ssh_session.send_config_set(cmdlist.readlines())
    125. output += ssh_session.save_config()
    126. return output,get_hostname
    127. #####################################################################################################
    128. # 1.2.2输出配置信息
    129. #####################################################################################################
    130. def output_log(output,get_hostname):
    131. now = datetime.now()
    132. date= "%s-%s-%s"%(now.year,now.month,now.day)
    133. config_path = f'log\\{int(task)}.{task_type}\\{task_type}'+date
    134. verify_path = os.path.exists(config_path)
    135. if not verify_path:
    136. os.makedirs(config_path)
    137. config_filename = f'{config_path}\\{get_hostname}_{date}.txt'
    138. print ('---- 正在写入输出文件: ', config_filename)
    139. with open( config_filename, "w",encoding='utf-8' ) as config_out:
    140. config_out.write(output)
    141. #####################################################################################################
    142. # 1.2.3检查问题设备
    143. #####################################################################################################
    144. def output_issue_device(issue_device):
    145. now = datetime.now()
    146. date= "%s-%s-%s"%(now.year,now.month,now.day)
    147. time_now = "%s-%s"%(now.hour,now.minute)
    148. config_path = 'log\\issue_device\\'+'issue_'+date
    149. verify_path = os.path.exists(config_path)
    150. if not verify_path:
    151. os.makedirs(config_path)
    152. config_filename = f'{config_path}\\issue_{date}_{time_now}.txt'
    153. print ('---- 正在写入问题设备: ', config_filename)
    154. with open (config_filename, "a", encoding='utf-8') as issue_facts:
    155. issue_facts.write('\n'.join(issue_device)+'\n')
    156. #####################################################################################################
    157. # 1.2.4运行读取ip
    158. #####################################################################################################
    159. def read_device():
    160. ip_list = []
    161. wb = load_workbook(f'lists\\ip_list.xlsx')
    162. ws = wb[dev_type_brand]
    163. for cow_num in range(2,ws.max_row+1):
    164. ip = ws["a"+str(cow_num)].value
    165. ip_list.append(ip)
    166. return ip_list
    167. #####################################################################################################
    168. # 1.2.5运行gevent
    169. #####################################################################################################
    170. def run_gevent(ip):
    171. issue_device = []
    172. try:
    173. device_config = get_config(ip)
    174. output = device_config[0]
    175. get_hostname = device_config[1]
    176. output_log(output,get_hostname)
    177. except (AuthenticationException):
    178. issue_message = (ip + ': 认证错误 ')
    179. issue_device.append(issue_message)
    180. output_issue_device(issue_device)
    181. except NetMikoTimeoutException:
    182. issue_message = (ip + ': 网络不可达 ')
    183. issue_device.append(issue_message)
    184. output_issue_device(issue_device)
    185. except (SSHException):
    186. issue_message = (ip +': SSH端口异常 ')
    187. issue_device.append(issue_message)
    188. output_issue_device(issue_device)
    189. except Exception as unknown_error:
    190. issue_message = (ip +': 发生未知错误: ')
    191. output_issue_device(issue_device)
    192. issue_device.append(issue_message+str(unknown_error))
    193. #####################################################################################################
    194. # 1.2.6主函数
    195. #####################################################################################################
    196. def main():
    197. start_time = time.time()
    198. print(f"******************************************")
    199. print(f"程序于{time.strftime('%X')}开始执行\n")
    200. ip_list = read_device()
    201. pool = Pool(100)
    202. pool.map(run_gevent,ip_list)
    203. pool.join()
    204. print(f"\n程序于{time.strftime('%X')}执行结束")
    205. print(f"******************************************")
    206. quit_program = input("请按回车键退出: ")
    207. #####################################################################################################
    208. # 1.3运行程序
    209. #####################################################################################################
    210. if __name__ == '__main__':
    211. main()
    212. #####################################################################################################

    演示如下:

    这里小编把py脚本打包成exe可执行文件来操作,在此以思科设备为例。
    image.png
    image.png
    https://mp.weixin.qq.com/s/AwVf_wmCFoQZsiNl1k501g (公众号文章中有视频演示)
    ,时长05:34

    脚本文件获取:公众号后台回复“ py网络工具
    5、python网络运维工具包 - 图3