def expect(self, blob_list=None, timeout=None, fail_ok=False, rm_date=False, searchwindowsize=None): if timeout is None: timeout = self.timeout if not blob_list: blob_list = self.prompt if isinstance(blob_list, (str, bytes)): blob_list = [blob_list] blobs = [] for blob in blob_list: if isinstance(blob, str): blob = blob.encode() blobs.append(blob) try: # index, re_obj, matched_text = super(TelnetClient, self).expect( # list=blobs, timeout=timeout) index, re_obj, matched_text = super(TelnetClient, self).expect(blobs, timeout=timeout) # Reformat the output output = self._process_output(output=matched_text, rm_date=rm_date) if index >= 0: # Match found self.logger.debug("Found: {}".format(output)) return index # Error handling self.logger.debug( "No match found for: {}. Actual output: {}".format( blob_list, output)) if self.eof: err_msg = 'EOF encountered before {} appear. '.format( blob_list) index = -1 else: err_msg = "Timed out waiting for {} to appear. ".format( blob_list) index = -2 except EOFError: err_msg = 'EOF encountered and before receiving anything. ' index = -1 if fail_ok: self.logger.warning(err_msg) return index if index == -1: raise exceptions.TelnetEOF(err_msg) elif index == -2: raise exceptions.TelnetTimeout(err_msg) else: raise exceptions.TelnetError( "Unknown error! Please update telnet expect method")
def login(self, expect_prompt_timeout=10, fail_ok=False, handle_init_login=False): self.write(b'\r\n') index = self.expect(blob_list=[TELNET_LOGIN_PROMPT, self.prompt], timeout=expect_prompt_timeout, fail_ok=fail_ok, searchwindowsize=50) self.flush() code = 0 if index == 0: self.send(self.user) self.expect(PASSWORD_PROMPT, searchwindowsize=50, timeout=expect_prompt_timeout) self.send(self.password) index = self.expect([self.prompt, TELNET_LOGIN_PROMPT], searchwindowsize=50, timeout=expect_prompt_timeout) if index == 1: if not handle_init_login: raise exceptions.TelnetError( 'Unable to login to {} with credential {}/{}'.format( self.hostname, self.user, self.password)) self.send(self.user) self.expect(PASSWORD_PROMPT, searchwindowsize=50, timeout=expect_prompt_timeout) self.send( self.user) # in initial login, assume password=username self.expect(PASSWORD_PROMPT, searchwindowsize=50, timeout=expect_prompt_timeout) self.send(self.user) # enter original password self.expect(PASSWORD_PROMPT, searchwindowsize=50, timeout=expect_prompt_timeout) self.send(self.password) # enter new password self.expect(PASSWORD_PROMPT, searchwindowsize=50, timeout=expect_prompt_timeout) self.send(self.password) # confirm new password self.expect(searchwindowsize=50, timeout=expect_prompt_timeout) elif index < 0: self.logger.warning( "System is not in login page and default prompt is not found either" ) code = 1 return code
def exec_sudo_cmd(self, cmd, expect_timeout=60, rm_date=True, fail_ok=True, get_exit_code=True, searchwindowsize=None, strict_passwd_prompt=False, extra_prompt=None, prefix_space=False): """ Execute a command with sudo. Args: cmd (str): command to execute. such as 'ifconfig' expect_timeout (int): timeout waiting for command to return rm_date (bool): whether to remove date info at the end of the output fail_ok (bool): whether to raise exception when non-zero exit code is returned get_exit_code searchwindowsize (int): max chars to look for match from the end of the output. Usage: when expecting a prompt, set this to slightly larger than the number of chars of the prompt, to speed up the search, and to avoid matching in the middle of the output. strict_passwd_prompt (bool): whether to search output with strict password prompt (Not recommended. Use searchwindowsize instead) extra_prompt (str|None) prefix_space (bool): prefix ' ' to cmd, so that it will not go into bash history if HISTCONTROL=ignorespace Returns (tuple): (exit code (int), command output (str)) """ cmd = 'sudo ' + cmd if prefix_space: cmd = ' {}'.format(cmd) LOG.debug("Executing sudo command...") self.send(cmd) pw_prompt = Prompt.PASSWORD_PROMPT if not strict_passwd_prompt else Prompt.SUDO_PASSWORD_PROMPT prompts = [self.prompt] if extra_prompt is not None: prompts.append(extra_prompt) prompts.append(pw_prompt) index = self.expect(prompts, timeout=expect_timeout, searchwindowsize=searchwindowsize, fail_ok=fail_ok) if index == prompts.index(pw_prompt): self.send(self.password) prompts.remove(pw_prompt) self.expect(prompts, timeout=expect_timeout, searchwindowsize=searchwindowsize, fail_ok=fail_ok) code, output = self._process_exec_result(rm_date, get_exit_code=get_exit_code) if code != 0 and not fail_ok: raise exceptions.TelnetError( "Non-zero return code for sudo cmd: {}. Output: {}".format( cmd, output)) return code, output