def reload_device(self, timeout, action_map=None, error_map=None): """Reload device. :param timeout: session reconnect timeout :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ try: redundancy_reload = CommandTemplateExecutor( self._cli_service, configuration.REDUNDANCY_PEER_SHELF, action_map=action_map, error_map=error_map, ).execute_command() if re.search(r"[Ii]nvalid\s*([Ii]nput|[Cc]ommand)", redundancy_reload, re.IGNORECASE): CommandTemplateExecutor( self._cli_service, configuration.RELOAD, action_map=action_map, error_map=error_map, ).execute_command() time.sleep(60) except Exception: self._logger.info("Device rebooted, starting reconnect") self._cli_service.reconnect(timeout)
def map_bidi_multi_node(self, src_node, dst_node, src_port, dst_port, src_tunnel, dst_tunnel, vlan_id, vle_name): # self._validate_port_is_not_a_member(src_node, src_port) # self._validate_port_is_not_a_member(dst_node, dst_port) self._validate_port(src_node, src_port) self._validate_port(dst_node, dst_port) self._create_vlan(src_node, src_port, vlan_id) out = CommandTemplateExecutor( self._cli_service, command_template.ADD_VXLAN_TO_TUNNEL).execute_command( node_name=src_node, tunnel_name=src_tunnel, vxlan_id=vlan_id) self._validate_vxlan_add(src_node, vlan_id, src_tunnel) self._create_vlan(dst_node, dst_port, vlan_id) out += CommandTemplateExecutor( self._cli_service, command_template.ADD_VXLAN_TO_TUNNEL).execute_command( node_name=dst_node, tunnel_name=dst_tunnel, vxlan_id=vlan_id) self._validate_vxlan_add(dst_node, vlan_id, dst_tunnel) out += CommandTemplateExecutor( self._cli_service, command_template.VLE_CREATE).execute_command(vle_name=vle_name, node_1=src_node, node_1_port=src_port, node_2=dst_node, node_2_port=dst_port) self._validate_vle_creation(vle_name)
def create_vlan(self, vlan_range, action_map=None, error_map=None): """Create vlan entity on the device. :param vlan_range: range of vlans to be created :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ result = CommandTemplateExecutor( self._cli_service, add_remove_vlan.CONFIGURE_VLAN, action_map=action_map, error_map=error_map, ).execute_command(vlan_id=vlan_range) if self.CREATE_VLAN_VALIDATION_PATTERN.search(result): self._logger.info("Unable to create vlan, proceeding") return elif self.CREATE_VLAN_ERROR_PATTERN.search(result): raise Exception("Failed to configure vlan: Unable to create vlan") CommandTemplateExecutor( self._cli_service, iface.STATE_ACTIVE, action_map=action_map, error_map=error_map, ).execute_command() CommandTemplateExecutor( self._cli_service, iface.NO_SHUTDOWN, action_map=action_map, error_map=error_map, ).execute_command()
def default_trex_config(self): """ """ CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command( path="{}/{}".format(TREX_ROOT_PATH, TREX_FOLDER)) CommandTemplateExecutor( self._cli_service, trex_install.TREX_DAEMON_STATE).execute_command( daemon_state="stop") output = CommandTemplateExecutor( cli_service=self._cli_service, command_template=trex_install.CREATE_TREX_CONFIG, expected_string= r"{prompt}|Enter list of interfaces separated by space".format( prompt=self._cli_service.command_mode.prompt)).execute_command( ) match = re.finditer( r"\|\s+(?P<id>\d+)\s+\|.*?\|.*?\|.*\|.*?\|.*?\|.*?\|(?P<state>.*)\s+\|", output, re.IGNORECASE | re.MULTILINE) vinc_ids = [ int(item.groupdict().get("id")) for item in match if "active" not in item.groupdict().get("state").lower() ] if len(vinc_ids) % 2 == 1: vinc_ids = sorted(vinc_ids)[:-1] self._cli_service.send_command( command=" ".join(map(str, vinc_ids)), action_map=trex_install.CONFIG_ACTION_MAP, check_action_loop_detector=False)
def ports_table(self): """ :rtype: dict """ port_table = {} port_logic_output = CommandTemplateExecutor( self._cli_service, command_template.PORT_SHOW_LOGIC_TABLE).execute_command() for record in CommandActionsHelper.parse_table( port_logic_output.strip(), r'^\w+\s+\d+\s+\w+\s+e\d+\s+w\d+$'): port_table[record[1]] = {'blade': record[2]} port_output = CommandTemplateExecutor( self._cli_service, command_template.PORT_SHOW).execute_command() for record in CommandActionsHelper.parse_table( port_output.strip(), r'^e\d+\s+\d+\s+\d+\s+\d+\s+w\d+\s+.*$'): record_id = re.sub(r'\D', '', record[0]) if record_id in port_table: port_table[record_id]['locked'] = record[1] if len(record) > 7: port_table[record_id]['connected'] = re.sub( r'\D', '', record[5]) else: port_table[record_id]['connected'] = None return port_table
def download_file(self, test_config_url): """ Download file from FTP/TFTP Server """ try: test_files_location = self._trex_client.get_trex_files_path() except Exception as e: self._logger.exception(e) raise Exception( "Error happened during determination TRex files location") output = CommandTemplateExecutor( self._cli_service, FILE_INFO).execute_command(file_path=test_files_location) if "no such file or directory" in output.lower(): CommandTemplateExecutor( self._cli_service, MAKE_DIRECTORY).execute_command(path=test_files_location) file_name = os.path.basename(test_config_url) output = CommandTemplateExecutor( self._cli_service, DOWNLOAD_FILE_TO_TREX).execute_command( file_path=os.path.join(test_files_location, file_name), url=test_config_url) if not re.search(r"saved\s*\[\d+\]", output, re.IGNORECASE): self._logger.error( "Downloading TRex test configuration file failed: {}".format( output)) raise Exception("Downloading TRex test configuration file failed.")
def get_trex_ports(self): """ """ CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command( path="{}/{}".format(TREX_ROOT_PATH, TREX_FOLDER)) output = CommandTemplateExecutor( self._cli_service, trex_autoload.GET_AVAILABLE_PORTS).execute_command() if re.search(r"error|fail", output, re.IGNORECASE | re.DOTALL): raise Exception( self.__class__.__name__, "Determining TRex ports count failed with error: {}".format( output)) ports_list = re.finditer( r"^[0-9A-F]+:(?P<port_uid>[0-9A-F]+:[0-9A-F]+.[0-9A-F]+).*?(\*(?P<state>\w+)\*)*$", output, re.IGNORECASE | re.MULTILINE) test_ports = [ port.groupdict().get("port_uid", None) for port in ports_list if not port.groupdict().get("state", None) ] # return len(re.findall(r"[0-9A-F]+:[0-9A-F]+:[0-9A-F]+.[0-9A-F]+", output, re.IGNORECASE | re.DOTALL)) return test_ports
def remove_snmp_user(self, snmp_user, snmp_group=None, action_map=None, error_map=None): """Disable SNMP user on the device :param snmp_user: snmp v3 user name :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ if snmp_group: result = CommandTemplateExecutor( cli_service=self._cli_service, command_template=enable_disable_snmp. DISABLE_SNMP_USER_WITH_GROUP, action_map=action_map, error_map=error_map).execute_command(snmp_user=snmp_user, snmp_group=snmp_group) else: result = CommandTemplateExecutor( cli_service=self._cli_service, command_template=enable_disable_snmp.DISABLE_SNMP_USER, action_map=action_map, error_map=error_map).execute_command(snmp_user=snmp_user) return result
def create_vlan(self, vlan_range, action_map=None, error_map=None): """Create vlan entity on the device. :param vlan_range: range of vlans to be created :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ CommandTemplateExecutor( self._cli_service, vlan_command_template.CONFIGURE_VLAN, action_map=action_map, error_map=error_map, ).execute_command(vlan_id=vlan_range) CommandTemplateExecutor( self._cli_service, iface_command_template.STATE_ACTIVE, action_map=action_map, error_map=error_map, ).execute_command() CommandTemplateExecutor( self._cli_service, iface_command_template.NO_SHUTDOWN, action_map=action_map, error_map=error_map, ).execute_command()
def set_auto_negotiation(self, phys_port, value): logical_port_id = self._get_logical(phys_port) if value.lower() == 'true': out = CommandTemplateExecutor(self._cli_service, command_template.SET_AUTO_NEG_ON).execute_command( port_id=logical_port_id) else: out = CommandTemplateExecutor(self._cli_service, command_template.SET_AUTO_NEG_OFF).execute_command( port_id=logical_port_id)
def add_snmp_user( self, snmp_user, snmp_password, snmp_priv_key, snmp_auth_proto, snmp_priv_proto, action_map=None, error_map=None, ): """Add snmp user. :param snmp_user: :param snmp_password: :param snmp_priv_key: :param snmp_auth_proto: :param snmp_priv_proto: :param action_map: :param error_map: :return: """ try: auth_command_template = self.AUTH_COMMAND_MAP[snmp_auth_proto] except KeyError: raise Exception( "Authentication protocol {} is not supported".format( snmp_auth_proto)) try: priv_command_template = self.PRIV_COMMAND_MAP[snmp_priv_proto] except KeyError: raise Exception( "Privacy Protocol {} is not supported".format(snmp_priv_proto)) if not priv_command_template: return CommandTemplateExecutor( cli_service=self._cli_service, command_template=enable_disable_snmp.SET_V3_SNMP_USER_NO_PRIV, action_map=action_map, error_map=error_map, ).execute_command( user=snmp_user, password=snmp_password, auth_protocol=auth_command_template, ) return CommandTemplateExecutor( cli_service=self._cli_service, command_template=enable_disable_snmp.SET_V3_SNMP_USER_PRIV, action_map=action_map, error_map=error_map, ).execute_command( user=snmp_user, password=snmp_password, auth_protocol=auth_command_template, private_key=snmp_priv_key, priv_encrypt_protocol=priv_command_template, )
def add_snmp_user_auth_and_priv( self, snmp_password, snmp_priv_key, snmp_auth_proto, snmp_priv_proto, action_map=None, error_map=None, ): """Add SNMPv3 user Auth and Priv. :param snmp_password: :param snmp_priv_key: :param snmp_auth_proto: :param snmp_priv_proto: :param action_map: :param error_map: :return: """ try: auth_command_template = self.AUTH_COMMAND_MAP[snmp_auth_proto] except KeyError: raise Exception( "Authentication protocol {} is not supported".format( snmp_auth_proto)) try: priv_command_template = self.PRIV_COMMAND_MAP[snmp_priv_proto] except KeyError: raise Exception( "Privacy Protocol {} is not supported".format(snmp_priv_proto)) output = CommandTemplateExecutor( cli_service=self._cli_service, command_template=snmpv3.SET_DEFAULT_AUTH_AND_PRIV, action_map=action_map, error_map=error_map, ).execute_command() if snmp_auth_proto != SNMPV3Parameters.AUTH_NO_AUTH: output += CommandTemplateExecutor( cli_service=self._cli_service, command_template=snmpv3.ADD_SNMP_USER_AUTH, action_map=action_map, error_map=error_map, ).execute_command(snmp_auth_proto=auth_command_template, snmp_password=snmp_password) if snmp_priv_proto != SNMPV3Parameters.PRIV_NO_PRIV: output += CommandTemplateExecutor( cli_service=self._cli_service, command_template=snmpv3.ADD_SNMP_USER_PRIV, action_map=action_map, error_map=error_map, ).execute_command(snmp_priv_proto=priv_command_template, snmp_priv_key=snmp_priv_key) return output
def delete_single_node_vle(self, node, vle_name, vlan_id): out = CommandTemplateExecutor( self._cli_service, command_template.DELETE_VLE).execute_command(vle_name=vle_name) self._validate_vle_deletion(vle_name) out += CommandTemplateExecutor( self._cli_service, command_template.DELETE_VLAN).execute_command(node=node, vlan_id=vlan_id) self._validate_vlan_id_deletion(node, vlan_id)
def start_trex_daemon(self): """ """ CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command( path="{}/{}".format(TREX_ROOT_PATH, TREX_FOLDER)) CommandTemplateExecutor( self._cli_service, trex_install.TREX_DAEMON_STATE).execute_command( daemon_state="start")
def custom_trex_config(self, server_config_path): """ """ CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command(path="/etc") CommandTemplateExecutor(self._cli_service, trex_common.DOWNLOAD_FILE).execute_command( file_name=TREX_SERVER_CONFIG, url=server_config_path)
def _on_session_start(self, session, logger): """ :param session: :param logging.Logger logger: :return: """ cli_service = CliServiceImpl(session, self.config_mode, logger) CommandTemplateExecutor(cli_service, DISABLE_PAGINATION).execute_command() CommandTemplateExecutor(cli_service, COMMIT).execute_command()
def install_firmware(self, firmware_file_name): """Set boot firmware file. :param firmware_file_name: firmware file name """ CommandTemplateExecutor(self._cli_service, firmware.BOOT_SYSTEM_FILE).execute_command( firmware_file_name=firmware_file_name) CommandTemplateExecutor(self._cli_service, firmware.CONFIG_REG).execute_command()
def download_trex_package(self, trex_url): """ """ CommandTemplateExecutor( self._cli_service, trex_common.MAKE_DIRECTORY).execute_command(path=TREX_ROOT_PATH) CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command(path=TREX_ROOT_PATH) CommandTemplateExecutor(self._cli_service, trex_common.DOWNLOAD_FILE).execute_command( file_name=TREX_PACK_NAME, url=trex_url)
def set_vlan_to_sub_interface( self, vlan_range, port_mode, port_name, qnq, c_tag, l2_transport=None, is_untagged=None, action_map=None, error_map=None, ): """Assign vlan to a certain interface. :param vlan_range: range of vlans to be assigned :param port_mode: switchport mode :param port_name: interface name :param qnq: qinq settings (dot1q tunnel) :param c_tag: selective qnq :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ untagged = None if is_untagged: untagged = "" CommandTemplateExecutor( self._cli_service, iface.NO_SHUTDOWN, action_map=action_map, error_map=error_map, ).execute_command() if qnq: CommandTemplateExecutor( self._cli_service, add_remove_vlan.VLAN_SUB_IFACE, action_map=action_map, error_map=error_map, ).execute_command(vlan_id=vlan_range, qnq="") else: CommandTemplateExecutor( self._cli_service, add_remove_vlan.VLAN_SUB_IFACE, action_map=action_map, error_map=error_map, ).execute_command(vlan_id=vlan_range, untagged=untagged)
def enable_snmp(self): """Enable snmp on the device""" CommandTemplateExecutor( self._cli_service, enable_disable_snmp.SNMP_V2_CREATE_REMOVE_USER, ).execute_command(user=self.USER) CommandTemplateExecutor( self._cli_service, enable_disable_snmp.SNMP_V2_CREATE_COMMUNITY, ).execute_command(community=self.community) CommandTemplateExecutor( self._cli_service, enable_disable_snmp.EXIT_MODE).execute_command()
def restore(self, config, protocol, host, file_path, overwrite=False, action_map=None, error_map=None): """ Restore device configuration :param config: device configuration type. running-config or startup-config :param protocol: file transfer protocol. Example: tftp, ftp, scp ... :param host: remote server address :param file_path: full path to file on remote server :param overwrite: determines that device configuration can be reloaded without reboot :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors :return: """ if overwrite: output = CommandTemplateExecutor( self._cli_service, save_restore.RESTORE, action_map=action_map, error_map=error_map).execute_command(config=config, protocol=protocol, host=host, file_path=file_path, overwrite="") else: output = CommandTemplateExecutor( self._cli_service, save_restore.RESTORE, action_map=action_map, error_map=error_map).execute_command(config=config, protocol=protocol, host=host, file_path=file_path) if not re.search(r"TFTP.*done", output): matched = re.match(r"TFTP:.*", output) if matched: error = matched.group() else: error = "Restore device configuration failed" raise Exception( self.__class__.__name__, "Restore configuration failed with error: {}".format(error))
def delete_multi_node_vle(self, src_node, dst_node, vle_name, vlan_id): out = CommandTemplateExecutor( self._cli_service, command_template.DELETE_VLE).execute_command(vle_name=vle_name) self._validate_vle_deletion(vle_name) out += CommandTemplateExecutor( self._cli_service, command_template.DELETE_VLAN).execute_command(node=src_node, vlan_id=vlan_id) self._validate_vlan_id_deletion(src_node, vlan_id) out += CommandTemplateExecutor( self._cli_service, command_template.DELETE_VLAN).execute_command(node=dst_node, vlan_id=vlan_id) self._validate_vlan_id_deletion(dst_node, vlan_id)
def unarchive_trex(self): """ """ CommandTemplateExecutor( self._cli_service, trex_common.CHANGE_PATH).execute_command(path=TREX_ROOT_PATH) output = CommandTemplateExecutor( self._cli_service, trex_common.FILE_INFO).execute_command(file_path=TREX_PACK_NAME) if "gzip" in output.lower(): command = trex_common.UNTAR_GZ_PACKAGE._command.format( trex_package=TREX_PACK_NAME) elif "tar" in output.lower(): command = trex_common.UNTAR_PACKAGE._command.format( trex_package=TREX_PACK_NAME) # elif "Zip" in output: # pass else: raise Exception(self.__class__.__name__, "Can't determine TRex Package format") output = self._cli_service.send_command( command=command, action_map=trex_common.UNTAR_PACKAGE._action_map, error_map=trex_common.UNTAR_PACKAGE._error_map, remove_command_from_output=False) if re.search(r"error|fail", output, re.IGNORECASE | re.DOTALL): raise Exception(self.__class__.__name__, "Un-tar TRex package failed : {}".format(output)) trex_folder = "" for line in output.split("\n"): line = line.strip() if line and line != command: trex_folder = line break if not trex_folder: raise Exception(self.__class__.__name__, "Can't determine root TRex package folder") CommandTemplateExecutor(self._cli_service, trex_common.CREATE_SIM_LINK).execute_command( source_path=trex_folder, link_name=TREX_FOLDER)
def show_install_request(self, operation_id, action_map=None, error_map=None): retry = 0 result = "" while re.search(r"operation {} is \d+% complete".format(operation_id), result, re.IGNORECASE) or retry < self.SHOW_REQUEST_MAX_RETRY: try: result = CommandTemplateExecutor( self._cli_service, ios_xr_cmd_templates.SHOW_INSTALL_REQUEST, action_map=action_map, error_map=error_map).execute_command() if re.search(r"No install operation in progress", result, re.IGNORECASE): return True except: self._cli_service.reconnect(self.RESTART_TIMEOUT) if not re.search( r"operation {} is \d+% complete".format(operation_id), result, re.IGNORECASE): retry += 1 time.sleep(self.SHOW_REQUEST_TIMEOUT)
def load(self, source_file, vrf=None, action_map=None, error_map=None): load_cmd = CommandTemplateExecutor(self._cli_service, ios_xr_cmd_templates.LOAD, action_map=action_map, error_map=error_map) if vrf: load_result = load_cmd.execute_command(source_file=source_file, vrf=vrf) else: load_result = load_cmd.execute_command(source_file=source_file) match_success = re.search( r"[\[\(][1-9][0-9]*[\)\]].*bytes|^([1-9][0-9]*)+\s*bytes\s*(parsed|process+ed)", load_result, re.IGNORECASE | re.MULTILINE) if not match_success: error_str = "Failed to restore configuration, please check logs" match_error = re.search( r" Can't assign requested address|[Ee]rror:.*\n|%.*$", load_result, re.IGNORECASE | re.MULTILINE) if match_error: error_str = 'load error: ' + match_error.group() raise Exception('validate_load_success', error_str) return load_result
def disable_snmp(self): """Disable snmp on the device""" CommandTemplateExecutor( self._cli_service, enable_disable_snmp.SNMP_V2_CREATE_REMOVE_USER, ).execute_command(user=self.USER, remove='')
def _get_l2_protocol_tunnel_cmd(self, action_map=None, error_map=None): return CommandTemplateExecutor( self._cli_service, add_remove_vlan.L2_TUNNEL, action_map=action_map, error_map=error_map, )
def get_config(self): """Get SNMP config""" return CommandTemplateExecutor( self._cli_service, enable_disable_snmp.SNMP_GET_CONFIG, ).execute_command()
def remove_vlan_from_interface(self, tag_type, port_name, vlan, action_map=None, error_map=None): """ Assign vlan to a certain interface :param vlan: VLAN number :param tag_type: port mode. tagged or untagged :param port_name: interface name :param action_map: actions will be taken during executing commands, i.e. handles yes/no prompts :param error_map: errors will be raised during executing commands, i.e. handles Invalid Commands errors """ output = CommandTemplateExecutor( cli_service=self._cli_service, command_template=vlan_command_template.REMOVE_VLAN_FROM_IFACE, action_map=action_map, error_map=error_map, expected_string=r"vlan\s*{0}|VLAN\s*{0}".format( vlan)).execute_command(tag_type=tag_type, port_name=port_name) if re.search(r"error", output, re.IGNORECASE | re.DOTALL): raise Exception( self.__class__.__name__, "Error during vlan configuration. See logs for details") self._cli_service.send_command(command="")
def enable_snmp_server(self): """Enable SNMP server""" CommandTemplateExecutor( self._cli_service, enable_disable_snmp.ENABLE_SNMP_SERVER, ).execute_command()