def ldap_get_user(self, uid=None): ''' 获取ldap用户详情,失败返None ''' obj = self.ldapconn obj.protocal_version = ldap.VERSION3 searchScope = ldap.SCOPE_SUBTREE retrieveAttributes = None searchFilter = "cn=" + uid try: ldap_result_id = obj.search(self.base_dn, searchScope, searchFilter, retrieveAttributes) result_type, result_data = obj.result(ldap_result_id, 0) if result_type == ldap.RES_SEARCH_ENTRY: username = result_data[0][1]['cn'][0] mail = result_data[0][1]['mail'][0] displayName = result_data[0][1]['displayName'][0] sn = result_data[0][1]['sn'][0] result = { 'username': username, 'mail': mail, 'displayName': displayName, 'sn': sn } return result else: return None except ldap.LDAPError, e: log().error(str(e))
def rollback(creds, nodes): #, img, hostname): ''' Rollbacks to old image version on the device. @args: - img: old image from the config files we save. - hostname: hostname. ''' # print(f'old images under rollback {img}') try: for node in nodes: connection, cisco = common.find_type(node, creds) session = netmiko.ConnectHandler(**connection) model = common.get_interface_by_model(session, cisco=cisco) # image = config[model]['image'] print(f'Hostname i have {node}') image = config[model]['image'] regex = image.split('-')[0] lines = session.send_command(f'dir | inc {regex}').split('\n') for line in lines: ## retrieving old image if image not in line: img = re.findall(r'' + regex + '.*', line)[0] print(f'Rollback to {img} for {hostname}') ##TODO: umcomment when ready to set_boot(session, img, hostname) if 'cs' in node: bootvar = session.send_command('show boot') else: bootvar = session.send_command('show bootvar') print(bootvar) reload_3 = input( "\n\nSuccess! - proceed with reload ? (y/n) ... ") if reload_3 == 'y': try: ##TODO: umcomment when ready to reload # reload(session) print("Reloading ... ") except: print("NOT Reloading ... ") # with open(f"/home/few7/device-ios-upgrade/run_conf/{node}-running-config.txt") as fo: # for line in fo: # # print(f'Im inside the while {line}') # if img in line: # ##UNCOMMENT ONES READY # common.set_boot(session ,img, hostname) # common.reload(session) # ##COMMENT OUT LATER # print(f' The line which has the image :{img} is {line}') except Exception as e: common.log(f'{node} - rollback() Error -> {str(e)}') print(f'{node} - Exception in rollback {e}')
def __init__(self, ldap_host=None, base_dn=None, user=None, password=None): self.base_dn = base_dn self.ldap_host = ldap_host self.user = user self.password = password try: self.ldapconn = ldap.initialize(ldap_host) self.ldapconn.simple_bind(user, password) except ldap.LDAPError, e: log().error(str(e)) print e
def ldap_get(self, uid=None, passwd=None): ''' 验证ldap账号密码,成功返True,失败返False ''' target_cn = self._ldap_search_dn(uid) if not target_cn: return False try: client = ldap.initialize(self.ldap_host) client.simple_bind_s(target_cn, passwd) client.unbind_s() return True except ldap.LDAPError, e: log().error(str(e)) return False
def status(self): ''' 验证初始化ldap账号密码,以及ldap地址是否正确 ''' ldap_client = ldap.initialize(self.ldap_host) try: ldap_client.simple_bind_s(self.user, self.password) ldap_client.unbind_s() return {"status": True} except Exception as e: log().error(str(e)) return { "status": False, "msg": "ldap初始化管理员账号密码或ldap地址有误,详情:{0}".format(str(e)) }
def _ldap_search_dn(self, uid=None): obj = self.ldapconn obj.protocal_version = ldap.VERSION3 searchScope = ldap.SCOPE_SUBTREE retrieveAttributes = None searchFilter = "cn=" + uid try: ldap_result_id = obj.search(self.base_dn, searchScope, searchFilter, retrieveAttributes) result_type, result_data = obj.result(ldap_result_id, 0) if result_type == ldap.RES_SEARCH_ENTRY: return result_data[0][0] else: return None except ldap.LDAPError, e: log().error(str(e))
def handle_file_reception(a_socket, an_address, filename, total_length, storage_dir, verbose): path = storage_dir + '/' + filename file = open(path, 'wb') a_socket.settimeout(TIMEOUT_SECONDS) first_ack = ack_message(filename, 0) a_socket.sendto(first_ack.encode(), an_address) total_received = 0 while total_received < total_length: print("Porcentaje recibido: {}%".format(total_received / total_length * 100)) timeouts = 0 sender_address = None while sender_address != an_address and timeouts < MAX_TIMEOUTS: try: raw_received, sender_address = a_socket.\ recvfrom(MAX_PACKET_SIZE) except timeout: log("Timeout {}".format(timeouts), verbose) a_socket.sendto( ack_message(filename, total_received).encode(), an_address) timeouts += 1 headers_and_data = raw_received.split( bytes('DATA' + HEADER_SEP, encoding='utf-8'), 1) headers = headers_and_data[0].decode().split(HEADER_SEP) data = headers_and_data[1] offset = int(headers[2]) if offset != total_received: a_socket.sendto( ack_message(filename, total_received).encode(), an_address) continue file.write(data) total_received += len(data) log("Se envia ACK con offset {}".format(total_received), verbose) a_socket.sendto( ack_message(filename, total_received).encode(), an_address) handle_fin_receptor(a_socket, an_address, filename, total_length, verbose) print("Fin de recepción")
def list_model(creds, nodes): ''' Lists models of the device or at a particular site. @args: - creds: username and password - nodes: a list of devices ''' try: print('Hostname \t Model') connection, cisco = common.find_type(nodes) node = connection['ip'] if connection: ssh_session = netmiko.ConnectHandler(**connection) model = common.get_interface_by_model(ssh_session, cisco=cisco) print(f'{node} \t {model}') ssh_session.disconnect() except Exception as e: common.log(f'{node} - exception in list_model: {e}') print(f'{node} - exception in list_model : {e}')
def upload_file(server_address, src, name, verbose): print('UDP: upload_file({}, {}, {})'.format(server_address, src, name)) if not os.path.isfile(src): print("Error: el archivo no existe") return global client_socket client_socket = socket(AF_INET, SOCK_DGRAM) client_socket.settimeout(TIMEOUT_SECONDS) total_length = os.path.getsize(src) total_uploaded = 0 f = open(src, 'rb') first_acked = False total_uploaded = 0 while total_uploaded < total_length: print("Subidos: {} de {} [{}%]".format( total_uploaded, total_length, total_uploaded / total_length * 100)) if not first_acked: to_send = initial_message(name, total_length).encode() data_length = 0 else: to_send, data_length = upload_message(name, total_uploaded, f) total_uploaded += data_length acked = False send_message = True timeouts = 0 while not acked and timeouts < MAX_TIMEOUTS: if send_message: log( "Enviado paquete con offset {} y {} bytes de datos".format( total_uploaded - data_length, data_length), verbose) client_socket.sendto(to_send, server_address) sender_address = None while sender_address != server_address: try: raw_data, sender_address = client_socket.\ recvfrom(MAX_PACKET_SIZE) except timeout: timeouts += 1 send_message = True log("Timeout nro {}".format(timeouts), verbose) break if sender_address != server_address: continue headers = raw_data.decode().split(HEADER_SEP) if headers[0] == 'ACK' and headers[1] == name: send_message = False log("Recibido ACK con offset {}".format(headers[2]), verbose) if int(headers[2]) == total_uploaded: first_acked = True acked = True handle_fin_emisor(client_socket, server_address, name, total_length, verbose) print("Fin de transmisión") f.close()
def cnupdatepass(self, cn, passwd): ''' 更改ldap密码,成功返True,失败返error ''' dn = 'cn={0},{1}'.format(cn, self.base_dn) try: result = self.ldapconn.search_s(dn, ldap.SCOPE_SUBTREE, 'cn=%s' % cn) oldpass = result[0][1]['userPassword'] oldwifipass = result[0][1]['sambaNTPassword'] newpass = '******' + b64encode(hashlib.md5(passwd).digest()) wifipass = binascii.hexlify( hashlib.new('md4', passwd.encode('utf-16le')).digest()) old = {'userPassword': oldpass, 'sambaNTPassword': oldwifipass} new = {"sambaNTPassword": [wifipass], "userPassword": [newpass]} mlist = modlist.modifyModlist(old, new) self.ldapconn.modify_s(dn, mlist) return {"status": True} except ldap.LDAPError as e: log().error(str(e)) return { "status": False, "msg": "ldap更改密码错误,详情: {0}".format(str(e)) }
def upload(creds, nodes, config, running_configs): ''' Uploads IOS file(s) to the device or a particular site. @args: - creds: username and password - nodes: a list of devices - config: file with devices' models and images ''' try: # print(f'Nodes i get {nodes}') for node in nodes: connection, cisco = common.find_type(node, creds) ##SAVE RUNING CONFIG print(f'node is : {node}') run_file = connection['ip'] + "-running-config.txt" print( f'\nSaving running config into file: {running_configs}/{run_file} \n' ) common.archive_run(connection, f'{running_configs}/{run_file}') common.log( f'{node} - Saving running config into file: {running_configs}/{run_file}' ) session = netmiko.ConnectHandler(**connection) if cisco == False: model = common.get_interface_by_model(session, cisco=cisco) else: model = common.get_interface_by_model(session, cisco=cisco) threads = [] print(f'node just before the if condition {node}') if node != None: # print('the if Condition is failing') # ssh_session = netmiko.ConnectHandler(**connection) print(f'config under the upload {model}') if model in config: th = Thread(target=common.upload_ios_file, args=(connection, config, model)) threads.append(th) else: common.log( f'{node} - Please add {model} model to config.json ') print(f'{node} - Please add {model} model to config.json') for th in threads: th.start() for th in threads: th.join() except Exception as e: common.log(f'{node} - exception : {e}') print(f'{node} - exception in upload under actions : {e}')
def handle_file_sending(a_socket, an_address, filename, storage_dir, verbose): a_socket.settimeout(TIMEOUT_SECONDS) path = storage_dir + '/' + filename if not os.path.isfile(path): a_socket.sendto(ERROR_MESSAGE.encode(), an_address) return total_length = os.path.getsize(path) f = open(path, 'rb') total_sent = 0 while total_sent < total_length: print("Porcentaje enviado: {}%".format(total_sent / total_length * 100)) to_send, data_length = download_message(f, filename, total_sent, total_length, DATA_LENGTH) total_sent += data_length acked = False timeouts = 0 send_message = True while (not acked and timeouts < MAX_TIMEOUTS): if send_message: log( "Se envia paquete con offset {} y {} bytes de datos". format(total_sent - data_length, data_length), verbose) a_socket.sendto(to_send, an_address) sender_address = None while sender_address != an_address: try: raw_data, sender_address = a_socket.\ recvfrom(MAX_PACKET_SIZE) except timeout: send_message = True timeouts += 1 log("Timeout nro {}".format(timeouts), verbose) break if sender_address != an_address: continue message = raw_data.decode().split(HEADER_SEP) if message[0] == 'ACK' and message[1] == filename: send_message = False log("Recibido ACK con offset {}".format(message[2]), verbose) if int(message[2]) == total_sent: acked = True if not acked: break handle_fin_emisor(a_socket, an_address, filename, total_length, verbose) print("Fin de transmisión") f.close()
def download_file(server_address, name, dst, verbose): print('UDP: download_file({}, {}, {})'.format(server_address, name, dst)) global client_socket client_socket = socket(AF_INET, SOCK_DGRAM) f = open(dst, 'wb') total_length = int(1e10) # Muy alto client_socket.sendto(initial_message(name).encode(), server_address) total_received = 0 client_socket.settimeout(3) while total_received < total_length: try: raw_received, sender_address = client_socket\ .recvfrom(MAX_PACKET_SIZE) except timeout: if verbose: log("Timeout", verbose) if total_received == 0: client_socket.sendto( initial_message(name).encode(), server_address) continue if sender_address != server_address: continue headers_and_data = raw_received.\ split(bytes('DATA' + SEP, encoding='utf-8'), 1) headers = headers_and_data[0].decode().split(SEP) if headers[0] != 'DOWNLOAD' and headers[1] != name: print("Ha ocurrido un error, fin de la descarga") break data = headers_and_data[1] offset = int(headers[2]) if total_received == 0: total_length = int(headers[3]) if offset != total_received: log("Envío ACK con offset {}".format(total_received), verbose) client_socket.sendto( ack_message(name, total_received).encode(), server_address) continue f.write(data) total_received += len(data) log( "Recibido paquete con offset {} y {} bytes de datos".format( offset, len(data)), verbose) client_socket.sendto( ack_message(name, total_received).encode(), server_address) log("Envío ACK con offset {}".format(total_received), verbose) print("Porcentaje recibido: {}%".format(total_received / total_length * 100)) if total_received == total_length: handle_fin_receptor(client_socket, server_address, name, total_length, verbose) print("Fin de recepción") f.close()
def upgrade_ios(creds, nodes, config): ''' upgrade_ios IOS file(s) to the device or a particular site. @args: - creds: username and password - nodes: a list of devices - config: file with devices' models and images ''' try: print(nodes) for node in nodes: connection, cisco = common.find_type(node, creds) # node = connection['ip'] # print(connection) session = netmiko.ConnectHandler(**connection) model = common.get_interface_by_model(session, cisco=cisco) image = config[model]['image'] md5 = config[model]['md5'] # print(md5) # is_device_up = common.waiting_for_device(node, creds) common.log(f'{node} - is upgrading to IOS : {image}') print(f'{node} - is upgrading to IOS : {image}') verify_md5 = common.verify_md5(session, image, md5, node) if verify_md5 == True: ##TODO: umcomment when ready to boot common.log(f'{node} - md5 validated Successfull..!') print(f'{node} - md5 validated Successfull..!') boot = input( f"\n{node} - proceed with changing boot ? (y/n): ") common.log(boot) # response = subprocess.check_output([f"{mute}, f'{node}']) # print(response) if boot == 'y': common.set_boot(session, image, node) if 'cs' in node: bootvar = session.send_command('show boot') else: bootvar = session.send_command('show bootvar') # print(bootvar) print(f'{node} - Preforming pre checks ') common.pre_post_reload_check(node, creds) common.log(f'\n{node} - {bootvar}') accept_reload = input( "\n\nSuccess! - proceed with reload ? (y/n): ") common.log(f'\n{node} - {accept_reload}') if accept_reload == 'y': try: ##TODO: umcomment when ready to reload print('Im reloading now\n ') common.reload(session, node) # is_device_up = common.waiting_for_device(node, creds) # sleep(10) common.waiting_for_device(node, creds) print('reloading completed') except Exception as e: common.log(f'{node} - unable to reload {e} ...') print(f'{node} - unable to reload {e} ... ') else: common.log(f'{node} - Aborting reload') print(f'\n{node} - Aborting reload !!!\n\n') else: common.log( f'{node} - Error veryfiing md5 checksum on device, quitting !!!' ) print( f'\n\n{node} - Error veryfiing md5 checksum on device, quitting !!!\n\n' ) session.disconnect() except Exception as e: common.log(f'{node} - upgrade_ios() Error -> {str(e)}') print(f'{node} - exception in upgrade_ios : {e}')