def copy_vm(self, folder_path, src, dst): cli = 'cd %s' % folder_path self._exec(cli, head='COPY_VM') cli = 'rm -fr %s' % dst self._exec(cli, head='COPY_VM') cli = 'cp -fr %s %s' % (src, dst) self._exec(cli, timeout=1200, head='COPY_VM') vmx_s = dst + '/' + src + '.vmx' vmx_d = dst + '/' + dst + '.vmx' cli = 'cp -f %s %s' % (vmx_s, vmx_d) self._exec(cli, head='COPY_VM') #sub display name #Cannot use cat v | ... >v, we should use cat v.bak | .. > v instead, else , we can get a null v, include nothing display_name_sub = '''displayName = "%s"''' % dst cli = '''cat %s | sed \ -e 's/displayName.*".*"/%s/' \ > %s''' % (vmx_s, display_name_sub, vmx_d) self._exec(cli, head='COPY_VM') cli = 'cat %s' % vmx_d self._exec(cli, head='COPY_VM') copy_attribute = self.connect.child.before is_c_a = re.search(r'answer.msg.uuid.altered', copy_attribute) if is_c_a: info('''[COPY_VM]The answer attribute has been already configured, do nothing''', self.connect.is_info) else: # add it info('''[COPY_VM]No answer attribute, add it''', self.connect.is_info) cli = '''echo 'answer.msg.uuid.altered = "I copied it"' >> %s''' % vmx_d self._exec(cli, head='COPY_VM')
def copy_vm(self, folder_path, src, dst): cli = 'cd %s' % folder_path self._exec(cli, head='COPY_VM') cli = 'rm -fr %s' % dst self._exec(cli, head='COPY_VM') cli = 'cp -fr %s %s' % (src, dst) self._exec(cli, timeout=1200, head='COPY_VM') vmx_s = dst + '/' + src + '.vmx' vmx_d = dst + '/' + dst + '.vmx' cli = 'cp -f %s %s' % (vmx_s, vmx_d) self._exec(cli, head='COPY_VM') #sub display name #Cannot use cat v | ... >v, we should use cat v.bak | .. > v instead, else , we can get a null v, include nothing display_name_sub = '''displayName = "%s"''' % dst cli = '''cat %s | sed \ -e 's/displayName.*".*"/%s/' \ > %s''' % (vmx_s, display_name_sub, vmx_d) self._exec(cli, head='COPY_VM') cli = 'cat %s' % vmx_d self._exec(cli, head='COPY_VM') copy_attribute = self.connect.child.before is_c_a = re.search(r'answer.msg.uuid.altered', copy_attribute) if is_c_a: info( '''[COPY_VM]The answer attribute has been already configured, do nothing''', self.connect.is_info) else: # add it info('''[COPY_VM]No answer attribute, add it''', self.connect.is_info) cli = '''echo 'answer.msg.uuid.altered = "I copied it"' >> %s''' % vmx_d self._exec(cli, head='COPY_VM')
def __init__(self): self.args = ExpectArgs() self.mode = self.args.mode self.ip = self.args.ip self.port = self.args.port self.user = self.args.user self.passwd = self.args.passwd self.prompt = self.args.prompt self.timeout = self.args.timeout self.log_file = self.args.log_file self.cli_list = self.args.cli_list self.cli_range_list = self.args.cli_range_list self.config_file = self.args.config_file self.wait = self.args.wait self.retry = self.args.retry self.sp = self.args.sp self.debug_level = self.args.debug_level self.child = None self._debug() self._tag() self._cli() self._port() self._logfile_init() #use str(self) to print __str__ value info('Expect Args\n' + str(self), self.is_info)
def power_off_vm_via_vmid(self, vmid): if self._is_vmid_exist: cli = 'vim-cmd vmsvc/power.off %s' % vmid self._exec(cli, head='POWER_OFF') else: info( '''[POWER_OFF]Not find the vmid %s in vmid_list, skip''' % vmid, self.connect.is_info)
def _data(self): cli1 = "vim-cmd vmsvc/getallvms" self._exec(cli1, head='DATA') f1 = self.connect.child.before ''' 94 Test_045 [datastore1] Test_045/Test_001.vmx otherGuest vmx-04 ''' self.id_list = re.findall(r'\n(\d+)\s+', f1) self.dis_list = re.findall(r'\n\d+\s+(\S+)\s+', f1) #self.reg_list = re.findall('\s+(\S+.vmx)\s+', f1) self.reg_list = re.findall('\n\d+\s+\S+\s+\S+\s+(.*.vmx)\s+', f1) self.disname_id_dict = {self.dis_list[i]:self.id_list[i] for i in range(len(self.id_list))} self.disname_regname_dict = {self.dis_list[i]:self.reg_list[i] for i in range(len(self.id_list))} self.disname_power_dict = {self.dis_list[i]:0 for i in range(len(self.id_list))} cli2 = "esxcli vm process list" self._exec(cli2, head='DATA') f2 = self.connect.child.before ''' NoRekey2_004 World ID: 101104 Process ID: 0 VMX Cartel ID: 101101 UUID: 56 4d 7c 63 47 84 18 3e-5b ac e3 30 58 e1 dd 1d Display Name: NoRekey2_004 Config File: /vmfs/volumes/52d3c413-092d8c72-5fc2-f01fafe5b986/NoRekey2_004/NoRekey2_001.vmx ''' self.poweron_list = re.findall(r'Display Name: (\S+)', f2) for i in self.poweron_list: self.disname_power_dict[i] = 1 info('''[DATA]Display name and VMID Dict is: %s''' % str(self.disname_id_dict), self.connect.is_info) info('''[DATA]Display name and Register Dict is: %s''' % str(self.disname_regname_dict), self.connect.is_info) info('''[DATA]Display name and Power Dict is: %s''' % str(self.disname_power_dict), self.connect.is_info)
def basic_logout(self): if self.mode == 'ssh': info('''[LOGOUT]SSH Logout Process''', self.is_info) self._retry_not_expect_list('d', 'sendcontrol', [pexpect.TIMEOUT, 'Connection to .* closed'], noexp_index_list=[0], retrymode='repeat') if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: info('''[LOGOUT]SSH Logout successfully''', self.is_info) elif self.mode == 'telnet': info('''[LOGOUT]TELNET Logout Process''', self.is_info) self._retry_not_expect_list(']', 'sendcontrol', [pexpect.TIMEOUT, 'telnet>.*'], noexp_index_list=[0]) if self.exec_index == 0: # send this cli again to confirm logout self._retry_not_expect_list(']', 'sendcontrol', [pexpect.TIMEOUT, 'telnet>.*'], noexp_index_list=[0]) if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: self._retry_not_expect_list('q', 'sendline', [pexpect.TIMEOUT, 'Connection closed.*'], noexp_index_list=[0]) if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: info('''[LOGOUT]TELNET Logout successfully''', self.is_info) info('''[LOGOUT]Connect Part Done''', self.is_info)
def __init__(self): self.args = ExpectArgs() self.mode = self.args.mode self.ip = self.args.ip self.port = self.args.port self.user = self.args.user self.passwd = self.args.passwd self.prompt = self.args.prompt self.timeout = self.args.timeout self.log_file = self.args.log_file self.cli_list = self.args.cli_list self.config_file = self.args.config_file self.wait = self.args.wait self.retry = self.args.retry self.para_dict = self.args.para_dict self.debug_level = self.args.debug_level self.child = None self._debug() self._tag() self._cli() self._port() self._logfile_init() # use str(self) to print __str__ value info('Expect Args\n' + str(self), self.is_info)
def _data(self): cli1 = "vim-cmd vmsvc/getallvms" self._exec(cli1, head='DATA') f1 = self.connect.child.before ''' 94 Test_045 [datastore1] Test_045/Test_001.vmx otherGuest vmx-04 ''' self.id_list = re.findall(r'\n(\d+)\s+', f1) self.dis_list = re.findall(r'\n\d+\s+(\S+)\s+', f1) #self.reg_list = re.findall('\s+(\S+.vmx)\s+', f1) self.reg_list = re.findall('\n\d+\s+\S+\s+\S+\s+(.*.vmx)\s+', f1) self.disname_id_dict = { self.dis_list[i]: self.id_list[i] for i in range(len(self.id_list)) } self.disname_regname_dict = { self.dis_list[i]: self.reg_list[i] for i in range(len(self.id_list)) } self.disname_power_dict = { self.dis_list[i]: 0 for i in range(len(self.id_list)) } cli2 = "esxcli vm process list" self._exec(cli2, head='DATA') f2 = self.connect.child.before ''' NoRekey2_004 World ID: 101104 Process ID: 0 VMX Cartel ID: 101101 UUID: 56 4d 7c 63 47 84 18 3e-5b ac e3 30 58 e1 dd 1d Display Name: NoRekey2_004 Config File: /vmfs/volumes/52d3c413-092d8c72-5fc2-f01fafe5b986/NoRekey2_004/NoRekey2_001.vmx ''' self.poweron_list = re.findall(r'Display Name: (\S+)', f2) for i in self.poweron_list: self.disname_power_dict[i] = 1 info( '''[DATA]Display name and VMID Dict is: %s''' % str(self.disname_id_dict), self.connect.is_info) info( '''[DATA]Display name and Register Dict is: %s''' % str(self.disname_regname_dict), self.connect.is_info) info( '''[DATA]Display name and Power Dict is: %s''' % str(self.disname_power_dict), self.connect.is_info)
def basic_logout(self): if self.mode == 'ssh': info('''[LOGOUT]SSH Logout Process''', self.is_info) self._retry_not_expect_list( 'd', 'sendcontrol', [pexpect.TIMEOUT, 'Connection to .* closed'], noexp_index_list=[0], retrymode='repeat') if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: info('''[LOGOUT]SSH Logout successfully''', self.is_info) elif self.mode == 'telnet': info('''[LOGOUT]TELNET Logout Process''', self.is_info) self._retry_not_expect_list(']', 'sendcontrol', [pexpect.TIMEOUT, 'telnet>.*'], noexp_index_list=[0]) if self.exec_index == 0: # send this cli again to confirm logout self._retry_not_expect_list(']', 'sendcontrol', [pexpect.TIMEOUT, 'telnet>.*'], noexp_index_list=[0]) if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: self._retry_not_expect_list( 'q', 'sendline', [pexpect.TIMEOUT, 'Connection closed.*'], noexp_index_list=[0]) if self.exec_index == 0: raise ValueError, '''Logout timeout Error''' elif self.exec_index == 1: info('''[LOGOUT]TELNET Logout successfully''', self.is_info)
def ssh_login(self): info('''[LOGIN-SSH]Send cli to login target''', self.is_info) self._retry_not_expect( 'ssh %s@%s -p %s' % (self.user, self.ip, self.port), 'sendline', [ pexpect.TIMEOUT, 'Connection timed out|No route to host.*', 'continue connecting .*\?', '[Pp]assword:', self.prompt ]) if self.log_file == 'stdout': self.child.logfile_read = sys.stdout else: self.child.logfile_read = self.f_o # maybe we can add retry in index 0 and 1 if self.exec_index == 0: self.is_error = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info( '''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Timeout/NoRoute''', self.is_info) elif self.exec_index == 2: info( '''[LOGIN-SSH]The target is not in known host list, need send yes to confirm login''', self.is_info) self._retry_not_expect( 'yes', 'sendline', [pexpect.TIMEOUT, '[Pp]assword:', self.prompt]) if self.exec_index == 0: self.is_error = True info( '''[LOGIN-SSH]From 'YES Confirm' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: info( '''[LOGIN-SSH]Send 'YES Confirm' successfully, meet passwd''', self.is_info) self.is_passwd = True info('''From 'YES Confirm' jump to is_passwd''', self.is_info) elif self.exec_index == 2: info( '''[LOGIN-SSH]Send 'YES Confirm' successfully, meet prompt''', self.is_info) self.is_prompt = True info('''From 'YES Confirm' jump to is_prompt''', self.is_info) elif self.exec_index == 3: self.is_passwd = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_passwd''', self.is_info) elif self.exec_index == 4: self.is_prompt = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_prompt''', self.is_info) else: info('''[LOGIN-SSH]Cannot match any option in expect list''', self.is_info) self.is_error = True info( '''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Unknow error''', self.is_info) self._basic_login()
def basic_exec(self): for cli, mode, expect, timeout, wait in self.c_m_e_t_w_list: exec_cli = '''self.child.%s(cli)''' % mode exec(exec_cli) exec_index = self.child.expect([pexpect.TIMEOUT, expect, '--More--', 'More:', '-- More --'], timeout) if exec_index == 0: info('''[CLI]Meet Timeout''', self.is_info) info('''[CLI]CLI = %s''' % cli, self.is_info) info('''[CLI]Expect = %s''' % expect, self.is_info) info('''[CLI]Before = %s''' % self.child.before, self.is_info) info('''[CLI]After = %s''' % self.child.after, self.is_info) elif exec_index == 1: info('''[CLI]Successfully Execute "%s"''' % cli, self.is_info) elif exec_index == 2 or exec_index == 3 or exec_index == 4: if exec_index == 2: info('''[CLI]Meet 'more', should send 'blank' to continue, Aerohive products''', self.is_info) if exec_index == 3: info('''[CLI]Meet 'more', should send 'blank' to continue, Dell products''', self.is_info) if exec_index == 4: info('''[CLI]Meet 'more', should send 'blank' to continue, H3C products''', self.is_info) # retry 9999 times, if not enough, we can add the value self._retry_not_expect_list(' ', 'send', [pexpect.TIMEOUT, expect, '--More--|More:|-- More --'], noexp_index_list=[0, 2], retrymode='repeat', retry=9999, interval=self.timeout) if self.exec_index == 1: # send enter to remove the blank self.child.sendline('') self.child.expect([pexpect.TIMEOUT, self.prompt], self.timeout) else: raise ValueError, '''Exec Error''' sleep(wait)
def _basic_login(self): # default is retry 5 times and the interval is 5s if self.is_user: info('[LOGIN-USER]Meet user,send user to confirm login', self.is_info) self._retry_not_expect(self.user, 'sendline', [pexpect.TIMEOUT, '[Pp]assword.*']) if self.exec_index == 0: self.is_error = True info('''[LOGIN-USER]Send username cannot get passwd, Timeout''', self.is_info) info('''[LOGIN-USER]From is_user jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_passwd = True info('''[LOGIN-USER]From is_user jump to is_passwd''', self.is_info) if self.is_passwd: info('[LOGIN-PASSWD]Meet passwd,send passwd to confirm login', self.is_info) self._retry_not_expect(self.passwd, 'sendline', [pexpect.TIMEOUT, '\nlogin.*', '[Pp]assword.*', 'yes\|no>:.*', self.prompt]) if self.exec_index == 0: self.is_error = True info('''[LOGIN-PASSWD]Send passwd cannot get expect, Timeout''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_error = True info('''[LOGIN-PASSWD]Send passwd, meet user again, may wrong user or passwd''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 2: self.is_error = True info('''[LOGIN-PASSWD]Send passwd, meet passwd again, may wrong user or passwd''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 3: self.is_no = True info('''[LOGIN-PASSWD]From is_passwd jump to is_no process ''', self.is_info) elif self.exec_index == 4: self.is_prompt = True info('''[LOGIN-PASSWD]From is_passwd jump to is_prompt process ''', self.is_info) if self.is_no: info('[LOGIN-NO]Meet yes or no,send no to not use default config', self.is_info) self._retry_not_expect('no', 'sendline', [pexpect.TIMEOUT, self.prompt]) if self.exec_index == 0: self.is_error = True info('''[LOGIN-NO]Send no cannot get prompt, Timeout''', self.is_info) info('''[LOGIN-NO]From is_no jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_prompt = True info('''[LOGIN-NO]From is_no jump to is_prompt''', self.is_info) if self.is_prompt: info('''[LOGIN-PROMPT]Meet prompt, can execute cli now''', self.is_info) if self.is_error: info('''[LOGIN-ERROR]Meet error, close the child''', self.is_info) info('''[LOGIN-ERROR]BEFORE is: %s''' % self.child.before, self.is_info) info('''[LOGIN-ERROR]AFTER is : %s''' % self.child.after, self.is_info) raise ValueError, '''Login Error'''
def telnet_login(self): info('''[LOGIN-TELNET]Send cli to login target''', self.is_info) self._retry_not_expect('telnet %s %s' % (self.ip, self.port) , 'sendline', [pexpect.TIMEOUT, 'No route to host.*', 'Unable .* Connection refused.*', 'Escape character is.*']) if self.log_file == 'stdout': self.child.logfile_read = sys.stdout else: self.child.logfile_read = self.f_o # maybe we can add retry in index 0 and 1 if self.exec_index == 0: self.is_error = True info('''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info('''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, NoRoute''', self.is_info) elif self.exec_index == 2: self.is_error = True info('''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, ConnectRefused''', self.is_info) elif self.exec_index == 3: info('''[LOGIN-TELNET]Send 'TELNET CMD' successfully, meet Escape''', self.is_info) self._retry_not_expect('' , 'sendline', [pexpect.TIMEOUT, pexpect.EOF, 'login.*', '[Pp]assword.*', 'yes\|no>:.*', self.prompt]) if self.exec_index == 0: self.is_error = True info('''[LOGIN-TELNET]From 'Enter' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info('''[LOGIN-TELNET]From 'Enter' jump to is_error, VMOSInActive''', self.is_info) elif self.exec_index == 2: self.is_user = True info('''[LOGIN-TELNET]From 'Enter' jump to is_user''', self.is_info) elif self.exec_index == 3: self.is_passwd = True info('''[LOGIN-TELNET]From 'Enter' jump to is_passwd''', self.is_info) elif self.exec_index == 4: self.is_no = True info('''[LOGIN-TELNET]From 'Enter' jump to is_no''', self.is_info) elif self.exec_index == 5: self.is_prompt = True info('''[LOGIN-TELNET]From 'Enter' jump to is_prompt''', self.is_info) else: info('''[LOGIN-TELNET]Cannot match any option in expect list''', self.is_info) self.is_error = True info('''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, Unknow error''', self.is_info) self._basic_login()
def telnet_login(self): info('''[LOGIN-TELNET]Send cli to login target''', self.is_info) self._retry_not_expect( 'telnet %s %s' % (self.ip, self.port), 'sendline', [ pexpect.TIMEOUT, 'No route to host.*', 'Unable .* Connection refused.*', 'Escape character is.*' ]) if self.log_file == 'stdout': self.child.logfile_read = sys.stdout else: self.child.logfile_read = self.f_o # maybe we can add retry in index 0 and 1 if self.exec_index == 0: self.is_error = True info( '''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info( '''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, NoRoute''', self.is_info) elif self.exec_index == 2: self.is_error = True info( '''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, ConnectRefused''', self.is_info) elif self.exec_index == 3: info( '''[LOGIN-TELNET]Send 'TELNET CMD' successfully, meet Escape''', self.is_info) self._retry_not_expect('', 'sendline', [ pexpect.TIMEOUT, pexpect.EOF, 'login.*', '[Pp]assword.*', 'yes\|no>:.*', self.prompt ]) if self.exec_index == 0: self.is_error = True info( '''[LOGIN-TELNET]From 'Enter' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info( '''[LOGIN-TELNET]From 'Enter' jump to is_error, VMOSInActive''', self.is_info) elif self.exec_index == 2: self.is_user = True info('''[LOGIN-TELNET]From 'Enter' jump to is_user''', self.is_info) elif self.exec_index == 3: self.is_passwd = True info('''[LOGIN-TELNET]From 'Enter' jump to is_passwd''', self.is_info) elif self.exec_index == 4: self.is_no = True info('''[LOGIN-TELNET]From 'Enter' jump to is_no''', self.is_info) elif self.exec_index == 5: self.is_prompt = True info('''[LOGIN-TELNET]From 'Enter' jump to is_prompt''', self.is_info) else: info('''[LOGIN-TELNET]Cannot match any option in expect list''', self.is_info) self.is_error = True info( '''[LOGIN-TELNET]From 'TELNET CMD' jump to is_error, Unknow error''', self.is_info) self._basic_login()
def _exec(self, cli, timeout=60, head=''): self.connect.child.sendline(cli) exp_list = [pexpect.TIMEOUT, pexpect.EOF, '[Ff]ail', self.connect.prompt] self.index = self.connect.child.expect(exp_list, timeout) if self.index == 0: info('''[%s]Meet Timeout''' % head, self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before) , self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after) , self.connect.is_info) elif self.index == 1: info('''[%s]Meet EOF''', self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before) , self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after) , self.connect.is_info) elif self.index == 2: info('''[%s]Meet Failed''', self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before) , self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after) , self.connect.is_info) #expect prompt to eat buf self.connect.child.expect(self.connect.prompt) elif self.index == 3: info('''[%s]Execute CLI "%s"''' % (head, cli), self.connect.is_info) else: info('''[%s]Meet Failed''' % head, self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before) , self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after) , self.connect.is_info)
def _exec(self, cli, timeout=60, head=''): self.connect.child.sendline(cli) exp_list = [ pexpect.TIMEOUT, pexpect.EOF, '[Ff]ail', self.connect.prompt ] self.index = self.connect.child.expect(exp_list, timeout) if self.index == 0: info('''[%s]Meet Timeout''' % head, self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before), self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after), self.connect.is_info) elif self.index == 1: info('''[%s]Meet EOF''', self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before), self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after), self.connect.is_info) elif self.index == 2: info('''[%s]Meet Failed''', self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before), self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after), self.connect.is_info) #expect prompt to eat buf self.connect.child.expect(self.connect.prompt) elif self.index == 3: info('''[%s]Execute CLI "%s"''' % (head, cli), self.connect.is_info) else: info('''[%s]Meet Failed''' % head, self.connect.is_info) info('''[%s]BEFORE = %s''' % (head, self.connect.child.before), self.connect.is_info) info('''[%s]AFTER = %s''' % (head, self.connect.child.after), self.connect.is_info)
def _retry_not_expect_list(self, cli, mode, exp_list, noexp_index_list=[0], retrymode='enter', retry=5, interval=5): if self.child: info('''[CLI]spawn child exist, send cli directly''', self.is_info) exec_cli = '''self.child.%s(cli)''' % mode else: info('''[CLI]spawn child not exist, create spawn firstly''', self.is_info) exec_cli = '''self.child=pexpect.spawn(cli)''' exec(exec_cli) self.exec_index = self.child.expect(list(exp_list), interval) if self.exec_index in noexp_index_list: info('''[RETRY]Trigger Retry Process''', self.is_info) info('''[RETRY]CLI = %s''' % cli, self.is_info) info('''[RETRY]MODE = %s''' % mode, self.is_info) info('''[RETRY]EXPECT_LIST = %s''' % str(exp_list), self.is_info) info('''[RETRY]RETRY_MODE = %s''' % retrymode, self.is_info) info('''[RETRY]RETRY = %s''' % retry, self.is_info) info('''[RETRY]INTERVAL = %s''' % interval, self.is_info) for i in xrange(int(retry)): info('''[RETRY]Retry %s time start''' % (i + 1), self.is_info) if retrymode == 'enter': self.child.sendline('') elif retrymode == 'repeat': exec(exec_cli) self.exec_index = self.child.expect(list(exp_list), interval) if self.exec_index not in noexp_index_list: info('''[RETRY]Match expect, end Retry Process''', self.is_info) return info('''[RETRY]Retry %s time end''' % (i + 1), self.is_info) info('''[RETRY]Retry %s times, still cannot get expect''' % retry, self.is_info) else: info('''[CLI]Match expect, no retry''', self.is_info) return raise ValueError, '''[RETRY]Retry %s times and still cannot match expect''' % retry
def basic_exec(self): for cli, mode, expect, timeout, wait in self.c_m_e_t_w_list: exec_cli = '''self.child.%s(cli)''' % mode exec(exec_cli) exec_index = self.child.expect( [pexpect.TIMEOUT, expect, '--More--', 'More:', '-- More --'], timeout) if exec_index == 0: info('''[CLI]Meet Timeout''', self.is_info) info('''[CLI]CLI = %s''' % cli, self.is_info) info('''[CLI]Expect = %s''' % expect, self.is_info) info('''[CLI]Before = %s''' % self.child.before, self.is_info) info('''[CLI]After = %s''' % self.child.after, self.is_info) elif exec_index == 1: info('''[CLI]Successfully Execute "%s"''' % cli, self.is_info) elif exec_index == 2 or exec_index == 3 or exec_index == 4: if exec_index == 2: info( '''[CLI]Meet 'more', should send 'blank' to continue, Aerohive products''', self.is_info) if exec_index == 3: info( '''[CLI]Meet 'more', should send 'blank' to continue, Dell products''', self.is_info) if exec_index == 4: info( '''[CLI]Meet 'more', should send 'blank' to continue, H3C products''', self.is_info) # retry 9999 times, if not enough, we can add the value self._retry_not_expect_list( ' ', 'send', [pexpect.TIMEOUT, expect, '--More--|More:|-- More --'], noexp_index_list=[0, 2], retrymode='repeat', retry=9999, interval=self.timeout) if self.exec_index == 1: # send enter to remove the blank self.child.sendline('') self.child.expect([pexpect.TIMEOUT, self.prompt], self.timeout) else: raise ValueError, '''Exec Error''' sleep(wait)
def _basic_login(self): # default is retry 5 times and the interval is 5s if self.is_user: info('[LOGIN-USER]Meet user,send user to confirm login', self.is_info) self._retry_not_expect(self.user, 'sendline', [pexpect.TIMEOUT, '[Pp]assword.*']) if self.exec_index == 0: self.is_error = True info( '''[LOGIN-USER]Send username cannot get passwd, Timeout''', self.is_info) info('''[LOGIN-USER]From is_user jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_passwd = True info('''[LOGIN-USER]From is_user jump to is_passwd''', self.is_info) if self.is_passwd: info('[LOGIN-PASSWD]Meet passwd,send passwd to confirm login', self.is_info) self._retry_not_expect(self.passwd, 'sendline', [ pexpect.TIMEOUT, '\nlogin.*', '[Pp]assword.*', 'yes\|no>:.*', self.prompt ]) if self.exec_index == 0: self.is_error = True info( '''[LOGIN-PASSWD]Send passwd cannot get expect, Timeout''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_error = True info( '''[LOGIN-PASSWD]Send passwd, meet user again, may wrong user or passwd''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 2: self.is_error = True info( '''[LOGIN-PASSWD]Send passwd, meet passwd again, may wrong user or passwd''', self.is_info) info('''[LOGIN-PASSWD]From is_passwd jump to is_error''', self.is_info) elif self.exec_index == 3: self.is_no = True info('''[LOGIN-PASSWD]From is_passwd jump to is_no process ''', self.is_info) elif self.exec_index == 4: self.is_prompt = True info( '''[LOGIN-PASSWD]From is_passwd jump to is_prompt process ''', self.is_info) if self.is_no: info('[LOGIN-NO]Meet yes or no,send no to not use default config', self.is_info) self._retry_not_expect('no', 'sendline', [pexpect.TIMEOUT, self.prompt]) if self.exec_index == 0: self.is_error = True info('''[LOGIN-NO]Send no cannot get prompt, Timeout''', self.is_info) info('''[LOGIN-NO]From is_no jump to is_error''', self.is_info) elif self.exec_index == 1: self.is_prompt = True info('''[LOGIN-NO]From is_no jump to is_prompt''', self.is_info) if self.is_prompt: info('''[LOGIN-PROMPT]Meet prompt, can execute cli now''', self.is_info) if self.is_error: info('''[LOGIN-ERROR]Meet error, close the child''', self.is_info) info('''[LOGIN-ERROR]BEFORE is: %s''' % self.child.before, self.is_info) info('''[LOGIN-ERROR]AFTER is : %s''' % self.child.after, self.is_info) raise ValueError, '''Login Error'''
def ssh_login(self): info('''[LOGIN-SSH]Send cli to login target''', self.is_info) os.system("rm -f /root/.ssh/known_hosts") self._retry_not_expect('ssh %s@%s -p %s' % (self.user, self.ip, self.port) , 'sendline', [pexpect.TIMEOUT, 'Connection timed out|No route to host.*', 'continue connecting .*\?', '[Pp]assword:', self.prompt]) if self.log_file == 'stdout': self.child.logfile_read = sys.stdout else: self.child.logfile_read = self.f_o # maybe we can add retry in index 0 and 1 if self.exec_index == 0: self.is_error = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: self.is_error = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Timeout/NoRoute''', self.is_info) elif self.exec_index == 2: info('''[LOGIN-SSH]The target is not in known host list, need send yes to confirm login''', self.is_info) self._retry_not_expect('yes', 'sendline', [pexpect.TIMEOUT, '[Pp]assword:', self.prompt]) if self.exec_index == 0: self.is_error = True info('''[LOGIN-SSH]From 'YES Confirm' jump to is_error, Timeout''', self.is_info) elif self.exec_index == 1: info('''[LOGIN-SSH]Send 'YES Confirm' successfully, meet passwd''', self.is_info) self.is_passwd = True info('''From 'YES Confirm' jump to is_passwd''', self.is_info) elif self.exec_index == 2: info('''[LOGIN-SSH]Send 'YES Confirm' successfully, meet prompt''', self.is_info) self.is_prompt = True info('''From 'YES Confirm' jump to is_prompt''', self.is_info) elif self.exec_index == 3: self.is_passwd = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_passwd''', self.is_info) elif self.exec_index == 4: self.is_prompt = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_prompt''', self.is_info) else: info('''[LOGIN-SSH]Cannot match any option in expect list''', self.is_info) self.is_error = True info('''[LOGIN-SSH]From 'SSH CMD' jump to is_error, Unknow error''', self.is_info) self._basic_login()
def power_off_vm_via_vmid(self, vmid): if self._is_vmid_exist: cli = 'vim-cmd vmsvc/power.off %s' % vmid self._exec(cli, head='POWER_OFF') else: info('''[POWER_OFF]Not find the vmid %s in vmid_list, skip''' % vmid, self.connect.is_info)