def get_json_data(self, command_line, delay=None, data_struct=None, show_details=False): """ Sends command to cli and gets the json data formatted into dictionary :param data_struct: expected data format, almost like a schema check ;) Expected string type. Format: ['data']['corero-cms-system:system']['software']['installed'] :param command_line: Command is expected to contain '| nomore | display json' :param delay: wait after sending command :param show_details: Adds ' | details' to the command line, if missing :return: """ if show_details and SHOW_DETAILS not in command_line: command_line += SHOW_DETAILS if SHOW_JSON not in command_line: command_line += SHOW_JSON self.send_cmd(command_line, expected_value='json', delay=delay) json_data = PExpectWrapper.get_json_from_cli(self.cli) if data_struct: try: return eval(str(json_data) + data_struct) except (TypeError, KeyError): PExpectWrapper.display_before_n_after(self.cli) return None return json_data
def close_connection(self): """ This sends exit to the remote shell. If there are stopped jobs then this automatically sends exit twice. :return: """ try: self.sendline(Common.Utilities.Enums.ControlKeys.ctr_c) self.sendline("exit") index = self.expect( [pexpect.EOF, "(?i)there are stopped jobs", pexpect.TIMEOUT]) if index == 1: self.sendline("exit") self.expect(pexpect.EOF) elif index == 2: PExpectWrapper.display_before_n_after(self) except OSError: pass self.close() PrintMessage('Connection closed: {0}@{1}:{2}'.format( self.username, self.host, self.port))
def expect(self, expect_value): try: PrintMessage("Expect value: {0}".format(expect_value)) return self.cli.expect(expect_value) except: PExpectWrapper.display_before_n_after(self.cli) raise
def open_iptables_port(self, command, expected): PrintMessage('Attempt to modify ip tables on {0}'.format(self.host)) self.send_cmd('iptables -S') if self.cli.expect([expected, pexpect.TIMEOUT]) == 0: PrintMessage('IPTables already enabled - skipping') return if PExpectWrapper.execute_shell_command(self.cli, command) != 0: raise Exception('Failed opening ip tables!') if PExpectWrapper.execute_shell_command( self.cli, 'service iptables save', expected_value='[ OK ]') != 0: raise Exception('Failed opening ip tables!')
def _turn_on_config_mode(self): """ This is only applicable to CMS connection. :return: """ # previously executed test might have been stuck in conf mode # code belows attempts to fix the situation try: self.send_cmd(command_line=' ', expected_value=None) self.send_cmd(CONF_MODE) except: command_history_count = 15 show_history = SHOW_HISTORY.format(command_history_count) PrintMessage( 'Uncommitted changes found, quiting configuration mode.') PrintMessage( 'Print history of last {0}-commands in configuration mode'. format(command_history_count)) self.send_cmd(show_history, expected_value=show_history) self.send_cmd(EXIT_CONF) if PExpectWrapper.expect(self.cli, 'There are uncommitted changes.'): self.send_cmd(UsersChoice.yes) self.send_cmd(CONF_MODE) PrintMessage( 'Print history of last {0}-commands out of configuration mode'. format(command_history_count)) self.send_cmd(show_history, expected_value=show_history)
def setup_time(self, time_zone, enable_ntp='N', ntp_server=None): PrintMessage('Changing time zone to {0}, ntp server to {1} '.format( time_zone, ntp_server)) self.send_cmd('setup time') self.send_cmd(enable_ntp) if enable_ntp.lower() == 'y': self.send_cmd(ntp_server) self.send_cmd( 'none') # secondary server, none to finish server insertion self.send_cmd(time_zone) # expects [A]ccept, [C]hange if self.expect(['Enter \[A\]ccept', 'Enter \[C\]hange']) == 0: # save changes self.send_cmd('a', delay=60, expected_value='Applying changes...') else: # exit without saving as no modification was made self.send_cmd('e') # Added check to fish out any warnings SWALL-5007 index = self.expect([self.cli_prompt, 'WARNING']) if index == 0: return elif index == 1: self.expect(self.cli_prompt) PrintMessage(PExpectWrapper.display_before_n_after(self.cli)) assert False, "WARNING message is displayed: SWALL-5738"
def create_remote_temp_folder(cmd): cmd.send_cmd('mktemp -d', delay=1) temp_folder = '/tmp/tmp{0}/'.format( PExpectWrapper.get_text_after_value(cmd.cli, '/tmp/tmp')) cmd.send_cmd('cd {0}'.format(temp_folder), delay=1) return temp_folder
def log_with_ssh(self, username, password, host, port=None, expect=None): """ Helper method used to login with SSH method removes host from known_host list method creates a connection string :param expect: :param username: :param password: :param host: :param port: :return: """ PrintMessage("ssh-ing to {0}@{1}:{2}".format(username, host, port)) self.username = username self.host = host self.port = port self.remove_known_host_entry(host, port) connection_string = self.get_connection_string(username, host, port) pexpect.spawn._spawn(self, connection_string) expect_at_connection = [ "password", "Failed to connect to server", "Connection refused", "No route to host", pexpect.TIMEOUT, pexpect.EOF ] index = self.expect(expect_at_connection) if index == 0: if password: self.sendline(password) if expect: expect_ = [expect, pexpect.TIMEOUT, pexpect.EOF] index = self.expect(expect_) if index == 0: return True else: raise FailedLoginError else: PExpectWrapper.display_before_n_after(self) raise FailedLoginError
def wait_for_pending_commits(self): self.send_cmd('show debug devices pending-commits', 'pending-commits') pending_commits = PExpectWrapper.get_int_after_value( self.cli, 'pending-commits') if pending_commits > 0: PrintMessage('Pending commits found!', level=LoggingLevel.warning) raise CLINoResults('Pending commits in progress')
def get_current_load_levels(self, protection_profile): show_queue_depth = 'show configuration policy protection-profile {0} advanced-settings ingress-load-level ' \ '| details'.format(protection_profile) self.send_cmd(show_queue_depth, show_queue_depth) queue_depth = { '0': '0', '1': PExpectWrapper.get_text_after_value(self.cli, 'level-1').strip(';'), '2': PExpectWrapper.get_text_after_value(self.cli, 'level-2').strip(';'), '3': PExpectWrapper.get_text_after_value(self.cli, 'level-3').strip(';'), '4': PExpectWrapper.get_text_after_value(self.cli, 'level-4').strip(';'), '5': PExpectWrapper.get_text_after_value(self.cli, 'level-5').strip(';'), '6': PExpectWrapper.get_text_after_value(self.cli, 'level-6').strip(';'), '7': PExpectWrapper.get_text_after_value(self.cli, 'level-7').strip(';'), '8': '-1' } return queue_depth
def save_all_profile(self, destination_file): save_dump = SAVE_PROFILE.format('', destination_file) status_code = PExpectWrapper.execute_shell_command(self.cli, save_dump) if status_code == 0: PrintMessage('Defense profile saved') else: PrintMessage( 'Failed to save Defense profile, status code: {0}'.format( status_code))
def _get_current_version(self, device_ip): connection_details = ConfigLoader.get_general_config( 'DeviceConnectionDetails') user = UserWrapper(connection_details["User"], connection_details["Password"], None) with ActionsProvisionalCLI(user, device_ip) as device_pcli_action: device_pcli_action.send_cmd('show version') device_version = PExpectWrapper.get_text_after_value( device_pcli_action.cli, 'Application Version : ') return Version(device_version)
def send_cmd(self, command_line='', expected_value="[ok]", delay=None): """ Wrapper around PExpect sendline command :param command_line: :param expected_value: by default it expects an [ok] string, this is tuned towards CMS communication However, this can be used by any ssh type connection :param delay: wait after sending command :return: """ PrintMessage("cmd({0}): {1}".format(self.user.name, command_line)) self.cli.sendline(command_line) if delay is not None: time.sleep(delay) if expected_value is not None: try: if '[error]' in self.cli.before: PrintMessage('ERROR noted in cli', LoggingLevel.warning) PExpectWrapper.display_before_n_after(self.cli) index = self.cli.expect(expected_value) if '[error]' in self.cli.before: PrintMessage('ERROR noted in cli', LoggingLevel.warning) PExpectWrapper.display_before_n_after(self.cli) return index except: PExpectWrapper.display_before_n_after(self.cli) raise return self.cli.before
def send_cmd(self, command_line='', expected_value=None, delay=None): """ Wrapper around PExpect sendline command :param command_line: :param expected_value: Often used to reset position in pexpect buffer stream. :param delay: wait after sending command :return: """ PrintMessage("cmd({0}): {1}".format(self.user.name, command_line)) self.cli.sendline(command_line) if delay is not None: time.sleep(delay) if expected_value is not None: try: return self.cli.expect_exact(expected_value) except: PExpectWrapper.display_before_n_after(self.cli) raise return self.cli.before
def unzip_files(self, file_name): unzip_command = 'unzip -j {0}'.format(file_name) self.send_cmd(unzip_command, delay=10) show_files_command = 'ls -al' self.send_cmd(show_files_command) self.send_cmd('echo status_code:$?') output = PExpectWrapper.get_lines(self.cli, terminating_value='status_code:0') source_files_re = '([a-z-_0-9.]*\.qcow2)' source_files = [] for output_line in output: source_file = re_search(source_files_re, output_line) if source_file and source_file.group(1): if source_file.group(1) in source_files: continue source_files.append(source_file.group(1)) return source_files
def get_current_config_values(self, command_line, expected_value='xpath'): """ Since the json doesn't return default values (SWALL-5184) Assumes the key and value are separate with white space Assumes path in xpath is forward slash separated Last string (closest to vale) is used as key when returning data i.e. '/devices/cms-device-adv:advanced-settings/sflow/counter-record-interval 1000' as: {'counter-record-interval':1000} :return: """ command_line += SHOW_DEFAULT_XPATH self.send_cmd(command_line, expected_value=expected_value) all_data = PExpectWrapper.get_lines(self.cli, terminating_value='[ok]') result_data = {} for data in all_data: keys, value = data.split(' ') key = keys.split('/') key = key[len(key) - 1] result_data[key] = value return result_data
def update_sxos_version(self, new_version): assert type(new_version) is Version new_version.verify() new_version_as_string = new_version.get_as_string(fill_with_zeros=0) linux_command = "echo '{0}' > {1}".format(new_version_as_string, SXOS_FILE) PrintMessage('Updating sxos version to {0}, with command: {1}'.format( new_version_as_string, linux_command)) status_code = PExpectWrapper.execute_shell_command( self.cli, linux_command) if status_code == 0: PrintMessage('SXOS version was updated!') else: PrintMessage('Failed to update {0}, status code: {1}'.format( SXOS_FILE, status_code)) # verify file is updated self.send_cmd('cat ' + SXOS_FILE) self.cli.expect(SXOS_FILE) self.cli.expect(new_version_as_string)