python多執行緒併發
阿新 • • 發佈:2018-12-26
# coding=utf8 # 使用前需安裝net-snmp-utils或net-snmp包 from _utils.patrol2 import run_cmd import sys import os from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor from zipfile import ZipFile import stat import time import datetime now_time = datetime.datetime.now().strftime('%Y-%m-%d_%H:%M:%S') # def get_host_ip(): # try: # s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # s.connect(('8.8.8.8', 80)) # ip = s.getsockname()[0] # finally: # s.close() # return ip # # ftp_ips = get_host_ip() # if ftp_ips in (None,'') or ftp_ips.startswith('127.'): # # print 'ftp_ip:',ftp_ip def get_type(host): cmd = 'snmpwalk -v {} -c {} {}|head -1'.format(snmp_version, community, host) # print cmd code, result = run_cmd(cmd) if code: print '查詢型別失敗' sys.exit(1) # print result if 'H3C' in result: return 'H3C' else: return 'Cisco' def snmp_set(host, oid): cmd = 'snmpset -r 0 -v {} -c {} {} {}'.format(snmp_version, community, host, oid) # print cmd code, result = run_cmd(cmd) return code, result def snmp_test(pre_oid, host, flag): cmd = 'snmpwalk -r 0 -v {} -c {} {} {}.{}'.format(snmp_version, community, host, pre_oid, flag) # print cmd code, result = run_cmd(cmd) return code, result def do_snmp(host, filename, ftp_ip): if connect_type != 'tftp' and (not username or not password): print '檔案伺服器的登入使用者名稱或密碼缺失,請重新輸入後嘗試' sys.exit(1) device_type = get_type(host) print device_type if device_type == 'H3C': pre_oid = '1.3.6.1.4.1.25506.2.4.1.2.4.1.9' elif device_type == 'Cisco': pre_oid = '.1.3.6.1.4.1.9.9.96.1.1.1.1.3' flag_num = 1 while 1: code, res = snmp_test(pre_oid, host, flag_num) if (code and res) or 'No Such Instance currently exists at this OID' in res: break flag_num += 1 if device_type == 'H3C': action_type = '1.3.6.1.4.1.25506.2.4.1.2.4.1.2.{} i 3'.format( flag_num) # 指定配置檔案操作型別,3為當前系統執行的配置 filename = '1.3.6.1.4.1.25506.2.4.1.2.4.1.4.{} s {}'.format(flag_num, filename) # 指定檔名,目的檔名 ftp_ip = '1.3.6.1.4.1.25506.2.4.1.2.4.1.5.{} a {}'.format(flag_num, ftp_ip) # 指定伺服器地址 if connect_type == 'tftp': protocol_type = '1.3.6.1.4.1.25506.2.4.1.2.4.1.3.{} i 2'.format(flag_num) # 2 #使用TFTP協議 elif connect_type == 'ftp': # 1 #使用FTP協議 login_info = '1.3.6.1.4.1.25506.2.4.1.2.4.1.6.{flag_num} s {username} 1.3.6.1.4.1.25506.2.4.1.2.4.1.7.{flag_num} s {password} '.format( username=username, password=password, flag_num=flag_num) ftp_ip = ftp_ip + ' ' + login_info protocol_type = '1.3.6.1.4.1.25506.2.4.1.2.4.1.3.{} i 1'.format(flag_num) # 1 #使用FTP協議 save_log = '1.3.6.1.4.1.25506.2.4.1.2.4.1.9.{} i 4'.format(flag_num) oid = '{action_type} {protocol_type} {filename} {ftp_ip} {save_log}'.format( action_type=action_type, filename=filename, protocol_type=protocol_type, ftp_ip=ftp_ip, save_log=save_log) elif device_type == 'Cisco': action_type = '.1.3.6.1.4.1.9.9.96.1.1.1.1.3.{} i 4'.format( flag_num) # 指定配置檔案操作型別,3為當前系統執行的配置 filename = '.1.3.6.1.4.1.9.9.96.1.1.1.1.6.{} s "{}"'.format(flag_num, filename) # 指定檔名 ftp_ip = '.1.3.6.1.4.1.9.9.96.1.1.1.1.5.{} a {}'.format(flag_num, ftp_ip) # 指定伺服器地址 if connect_type == 'tftp': protocol_type = '.1.3.6.1.4.1.9.9.96.1.1.1.1.4.{} i 1'.format(flag_num) # 2 #使用TFTP協議 elif connect_type == 'ftp': # 1 #使用FTP協議 protocol_type == '' save_log = '.1.3.6.1.4.1.9.9.96.1.1.1.1.14.{} i 4'.format(flag_num) oid = '{action_type} {protocol_type} {ftp_ip} {filename} {save_log}'.format( action_type=action_type, filename=filename, protocol_type=protocol_type, ftp_ip=ftp_ip, save_log=save_log) print oid code, res = snmp_set(host, oid) if code: print '{}配置備份失敗'.format(host) print res return False,filename,ftp_ip else: print '{}配置備份成功'.format(host) time.sleep(2) # print res return True,filename,ftp_ip def zip_file(filenames): has_file = False dest_path = os.path.join(ftp_directory, '{}.zip'.format(now_time)) for path in filenames: if not os.path.exists(path): print '{}檔案不存在'.format(path) filename = path.split(os.sep)[-1] failhosts.append(filename.split('_')[0]) continue run_cmd('chmod 777 {}'.format(path)) dest_path = '{}/{}.zip'.format(ftp_directory, now_time) code, res = run_cmd('tar -rvf {} {}'.format(dest_path, path)) if not code: has_file = True os.remove(path) else: failhosts.append(path.split('_')[0]) print res # filename = path.split(os.sep)[-1] # print path, filename # with ZipFile(dest_path, mode='a') as fp: # fp.write(path, filename) if has_file: return dest_path else: return 'no back files' def get_result(status): status,name,host_member = status.result() if status: filenames.append(os.path.join(ftp_directory, name)) else: failhosts.append(host_member) if __name__ == '__main__': try: filenames = [] failhosts = [] if host_file not in ([], [''], '', None): with open(host_file[0], 'r') as f: hosts = f.readlines() else: hosts = host.split(',') p = ProcessPoolExecutor() for host_member in hosts: host_member = host_member.strip() if filename: name = '{}_{}_{}'.format(host_member, now_time, filename) else: name = '{}_{}.cfg'.format(host_member, now_time) res = p.submit(do_snmp, host_member, name, ftp_ip).add_done_callback(get_result) p.shutdown() if filenames: backup_file = zip_file(filenames) print '備份完成,備份檔案路徑:', backup_file if not filenames: backup_file = 'no back files' print '備份失敗' if failhosts: print '裝置備份失敗:', ','.join(failhosts) failhosts = ','.join(failhosts) if not failhosts: failhosts='null' except Exception as e: print '裝置備份失敗:', e