# -*-encoding:utf-8 -*- import logging import pexpect.popen_spawn class PSSH: def __init__(self): self.handle = None def ssh_ap(self, host, username, password, port=22, timeout=5, retry_times=3): """ windows ssh AP 服务器; :param host: AP信息,如hostname 或IP; :param username: 登录AP使用的用户名; :param password: 登录AP使用的密码; :param port: ssh 使用的端口,默认为22; :param timeout: 登录设置的超时时间,输入用户名密码等待指定信息的时间,默认值为5; :param retry_times: 登录失败后,重试登录次数,默认值为3次; :return:登录成功返回True,否则False; """ return self.__ssh_connect_ap(host, username, password, port=port, timeout=timeout, retry_times=retry_times, flag='this is ap shell') def ssh_ac(self, host, username, password, port=22, timeout=5, retry_times=3): """ windows ssh AP 服务器; param host: AP信息,如hostname 或IP; :param username: 登录AP使用的用户名; :param password: 登录AP使用的密码; :param port: ssh 使用的端口,默认为22; :param timeout: 登录设置的超时时间,输入用户名密码等待指定信息的时间,默认值为5; :param retry_times: 登录失败后,重试登录次数,默认值为3次; :return:登录成功返回True,否则False; """ return self.__ssh_connect_ap(host, username, password, port=port, timeout=timeout, retry_times=retry_times, flag='Current license state .*') def __ssh_connect_ap(self, host, username, password, port=22, timeout=5, retry_times=3, flag=None): """ windows ssh 服务器; :param host: 服务器信息,如hostname 或IP; :param username: 登录使用的用户名; :param password: 登录使用的密码; :param port: ssh 使用的端口,默认为22; :param timeout: 登录设置的超时时间,输入用户名密码等待指定信息的时间,默认值为5; :param retry_times: 登录失败后,重试登录次数,默认值为3次; :param flag: 判断登录成功的标志; :return:登录成功返回True,否则False; """ cmd = 'plink.exe -ssh -P {} {}'.format(port, host) login_status = False if host is None or host == '': logging.error('Host is invalid,please check') if username is None or host.strip() == '': logging.error('username is invalid,please check') else: logging.debug('ssh execute command:{}'.format(cmd)) ssh_handle = pexpect.popen_spawn.PopenSpawn(cmd, timeout=timeout) self.handle = ssh_handle exp = self.handle.expect(['login as:', pexpect.EOF, pexpect.TIMEOUT], timeout=5) if exp == 0: logging.info('input username:{}'.format(username)) self.handle.sendline(username) exp1 = self.handle.expect(['password:', pexpect.EOF, pexpect.TIMEOUT], timeout=timeout) if exp1 == 0: logging.info(self.handle.before + self.handle.after) self.handle.sendline(password) logging.info('input password:{}'.format(password)) exp11 = ssh_handle.expect([flag, 'Access denied', pexpect.EOF, pexpect.TIMEOUT], timeout=timeout) if exp11 == 0: login_status = True logging.info('buffer value:{}'.format(ssh_handle.before + ssh_handle.after)) logging.info('login success') elif exp11 == 1: logging.error('login failed,username or password error') for i in range(1, retry_times + 1): logging.info('retry login,retry times:{}'.format(i)) self.handle.sendline(password) exp12 = self.handle.expect(['this is ap shell', pexpect.EOF, pexpect.TIMEOUT], timeout=timeout) if exp12 == 0: logging.info('buffer value:{}'.format(ssh_handle.before + ssh_handle.after)) logging.info('Login success') login_status = True break elif exp12 == 1: self.__log_eof() else: self.__log_timeout() elif exp11 == 2: self.__log_eof() else: self.__log_timeout() elif exp == 1: self.__log_eof() else: self.__log_timeout() elif exp == 1: self.__log_eof() else: self.__log_timeout() return login_status def __buf_get(self): return str(self.handle.before) + str(self.handle.after) def __log_eof(self): logging.error('Received EOF signal,buf value:{}'.format(self.__buf_get())) def __log_timeout(self): logging.error('Received TIMEOUT,buf value:{}'.format(self.__buf_get())) def execute_cmd_by_ssh(self, cmd, timeout=5, prompt='>'): """ ssh 命令执行,AC 与AP均可使用此方法,并将结果进行返回; :param cmd: 执行的命令; :param timeout:设置等待某信息的超时时间,默认为5s; :param prompt: 等待的提示符,默认为:>; :return: 返回执行消息的返回值,如果执行出现异常,超时等返回None; """ self.handle.sendline(cmd) exp = self.handle.expect([prompt, pexpect.EOF, pexpect.TIMEOUT], timeout=timeout) res = None if exp == 0: res = self.handle.before + self.handle.after elif exp == 1: self.__log_eof() else: self.__log_timeout() return res