blob: 6d7fb2acd1598dbdb7b741c987f6a8ba96afd12a [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
kelvin8ec71442015-01-15 16:57:00 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 24-Oct-2012
kelvin8ec71442015-01-15 16:57:00 -08004
5author:s: Anil Kumar ( anilkumar.s@paxterrasolutions.com ),
6 Raghav Kashyap( raghavkashyap@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07007
8
9 TestON is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 2 of the License, or
kelvin8ec71442015-01-15 16:57:00 -080012 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070013
14 TestON is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
kelvin8ec71442015-01-15 16:57:00 -080020 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070021
22
kelvin8ec71442015-01-15 16:57:00 -080023
24"""
adminbae64d82013-08-01 10:50:15 -070025import pexpect
kelvin8ec71442015-01-15 16:57:00 -080026import struct
27import fcntl
28import os
29import sys
30import signal
31import sys
32import re
33sys.path.append( "../" )
adminbae64d82013-08-01 10:50:15 -070034
35from drivers.component import Component
kelvin8ec71442015-01-15 16:57:00 -080036
37
38class CLI( Component ):
39
40 """
adminbae64d82013-08-01 10:50:15 -070041 This will define common functions for CLI included.
kelvin8ec71442015-01-15 16:57:00 -080042 """
43 def __init__( self ):
44 super( Component, self ).__init__()
45
46 def connect( self, **connectargs ):
47 """
adminbae64d82013-08-01 10:50:15 -070048 Connection will establish to the remote host using ssh.
49 It will take user_name ,ip_address and password as arguments<br>
kelvin8ec71442015-01-15 16:57:00 -080050 and will return the handle.
51 """
adminbae64d82013-08-01 10:50:15 -070052 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080053 vars( self )[ key ] = connectargs[ key ]
adminbae64d82013-08-01 10:50:15 -070054
kelvin8ec71442015-01-15 16:57:00 -080055 connect_result = super( CLI, self ).connect()
adminbae64d82013-08-01 10:50:15 -070056 ssh_newkey = 'Are you sure you want to continue connecting'
kelvin8ec71442015-01-15 16:57:00 -080057 refused = "ssh: connect to host " + \
58 self.ip_address + " port 22: Connection refused"
adminbae64d82013-08-01 10:50:15 -070059 if self.port:
kelvin8ec71442015-01-15 16:57:00 -080060 self.handle = pexpect.spawn(
61 'ssh -p ' +
62 self.port +
63 ' ' +
64 self.user_name +
65 '@' +
66 self.ip_address,
Jon Hall9aaba882015-01-19 15:05:15 -080067 env={ "TERM": "xterm-mono" },
kelvin8ec71442015-01-15 16:57:00 -080068 maxread=50000 )
69 else:
70 self.handle = pexpect.spawn(
71 'ssh -X ' +
72 self.user_name +
73 '@' +
74 self.ip_address,
Jon Hall9aaba882015-01-19 15:05:15 -080075 env={ "TERM": "xterm-mono" },
kelvin8ec71442015-01-15 16:57:00 -080076 maxread=1000000,
77 timeout=60 )
adminbae64d82013-08-01 10:50:15 -070078
79 self.handle.logfile = self.logfile_handler
kelvin8ec71442015-01-15 16:57:00 -080080 i = 5
81 while i == 5:
82 i = self.handle.expect( [
83 ssh_newkey,
Jon Hall21270ac2015-02-16 17:59:55 -080084 'password:',
kelvin8ec71442015-01-15 16:57:00 -080085 pexpect.EOF,
86 pexpect.TIMEOUT,
87 refused,
88 'teston>',
89 '>|#|\$' ],
90 120 )
91 if i == 0:
92 main.log.info( "ssh key confirmation received, send yes" )
93 self.handle.sendline( 'yes' )
94 i = self.handle.expect(
95 [ ssh_newkey, 'password:', pexpect.EOF ] )
96 if i == 1:
97 main.log.info(
98 "ssh connection asked for password, gave password" )
99 self.handle.sendline( self.pwd )
100 self.handle.expect( '>|#|\$' )
101 elif i == 2:
102 main.log.error( "Connection timeout" )
103 return main.FALSE
104 elif i == 3: # timeout
105 main.log.error(
106 "No route to the Host " +
107 self.user_name +
108 "@" +
109 self.ip_address )
110 return main.FALSE
111 elif i == 4:
112 main.log.error(
113 "ssh: connect to host " +
114 self.ip_address +
115 " port 22: Connection refused" )
116 return main.FALSE
117 elif i == 6:
118 main.log.info( "Password not required logged in" )
adminbae64d82013-08-01 10:50:15 -0700119
kelvin8ec71442015-01-15 16:57:00 -0800120 self.handle.sendline( "" )
121 self.handle.expect( '>|#|\$' )
adminbae64d82013-08-01 10:50:15 -0700122 return self.handle
123
kelvin8ec71442015-01-15 16:57:00 -0800124 def disconnect( self ):
125 result = super( CLI, self ).disconnect( self )
adminbae64d82013-08-01 10:50:15 -0700126 result = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800127 # self.execute( cmd="exit",timeout=120,prompt="(.*)" )
128
129 def execute( self, **execparams ):
130 """
adminbae64d82013-08-01 10:50:15 -0700131 It facilitates the command line execution of a given command. It has arguments as :
132 cmd => represents command to be executed,
133 prompt => represents expect command prompt or output,
134 timeout => timeout for command execution,
135 more => to provide a key press if it is on.
136
137 It will return output of command exection.
kelvin8ec71442015-01-15 16:57:00 -0800138 """
139 result = super( CLI, self ).execute( self )
adminaef00552014-05-08 09:18:36 -0700140 defaultPrompt = '.*[$>\#]'
kelvin8ec71442015-01-15 16:57:00 -0800141 args = utilities.parse_args( [
142 "CMD",
143 "TIMEOUT",
144 "PROMPT",
145 "MORE" ],
146 **execparams )
147
148 expectPrompt = args[ "PROMPT" ] if args[ "PROMPT" ] else defaultPrompt
adminbae64d82013-08-01 10:50:15 -0700149 self.LASTRSP = ""
kelvin8ec71442015-01-15 16:57:00 -0800150 timeoutVar = args[ "TIMEOUT" ] if args[ "TIMEOUT" ] else 10
adminbae64d82013-08-01 10:50:15 -0700151 cmd = ''
kelvin8ec71442015-01-15 16:57:00 -0800152 if args[ "CMD" ]:
153 cmd = args[ "CMD" ]
154 else:
adminbae64d82013-08-01 10:50:15 -0700155 return 0
kelvin8ec71442015-01-15 16:57:00 -0800156 if args[ "MORE" ] is None:
157 args[ "MORE" ] = " "
158 self.handle.sendline( cmd )
adminbae64d82013-08-01 10:50:15 -0700159 self.lastCommand = cmd
kelvin8ec71442015-01-15 16:57:00 -0800160 index = self.handle.expect( [
161 expectPrompt,
162 "--More--",
163 'Command not found.',
164 pexpect.TIMEOUT,
165 "^:$" ],
166 timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700167 if index == 0:
kelvin8ec71442015-01-15 16:57:00 -0800168 self.LASTRSP = self.LASTRSP + \
169 self.handle.before + self.handle.after
170 main.log.info(
171 "Executed :" + str(
172 cmd ) + " \t\t Expected Prompt '" + str(
173 expectPrompt) + "' Found" )
adminbae64d82013-08-01 10:50:15 -0700174 elif index == 1:
175 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800176 self.handle.send( args[ "MORE" ] )
177 main.log.info(
178 "Found More screen to go , Sending a key to proceed" )
179 indexMore = self.handle.expect(
180 [ "--More--", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700181 while indexMore == 0:
kelvin8ec71442015-01-15 16:57:00 -0800182 main.log.info(
183 "Found anoother More screen to go , Sending a key to proceed" )
184 self.handle.send( args[ "MORE" ] )
185 indexMore = self.handle.expect(
186 [ "--More--", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700187 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800188 elif index == 2:
189 main.log.error( "Command not found" )
adminbae64d82013-08-01 10:50:15 -0700190 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800191 elif index == 3:
192 main.log.error( "Expected Prompt not found , Time Out!!" )
193 main.log.error( expectPrompt )
adminbae64d82013-08-01 10:50:15 -0700194 return "Expected Prompt not found , Time Out!!"
kelvin8ec71442015-01-15 16:57:00 -0800195
adminbae64d82013-08-01 10:50:15 -0700196 elif index == 4:
197 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800198 # self.handle.send( args[ "MORE" ] )
199 self.handle.sendcontrol( "D" )
200 main.log.info(
201 "Found More screen to go , Sending a key to proceed" )
202 indexMore = self.handle.expect(
203 [ "^:$", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700204 while indexMore == 0:
kelvin8ec71442015-01-15 16:57:00 -0800205 main.log.info(
206 "Found another More screen to go , Sending a key to proceed" )
207 self.handle.sendcontrol( "D" )
208 indexMore = self.handle.expect(
209 [ "^:$", expectPrompt ], timeout=timeoutVar )
adminbae64d82013-08-01 10:50:15 -0700210 self.LASTRSP = self.LASTRSP + self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800211
212 main.last_response = self.remove_contol_chars( self.LASTRSP )
adminbae64d82013-08-01 10:50:15 -0700213 return self.LASTRSP
kelvin8ec71442015-01-15 16:57:00 -0800214
215 def remove_contol_chars( self, response ):
216 # RE_XML_ILLEGAL = '([\u0000-\u0008\u000b-\u000c\u000e-\u001f\ufffe-\uffff])|([%s-%s][^%s-%s])|([^%s-%s][%s-%s])|([%s-%s]$)|(^[%s-%s])'%( unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ),unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ),unichr( 0xd800 ),unichr( 0xdbff ),unichr( 0xdc00 ),unichr( 0xdfff ) )
217 # response = re.sub( RE_XML_ILLEGAL, "\n", response )
218 response = re.sub( r"[\x01-\x1F\x7F]", "", response )
219 # response = re.sub( r"\[\d+\;1H", "\n", response )
220 response = re.sub( r"\[\d+\;\d+H", "", response )
adminbae64d82013-08-01 10:50:15 -0700221 return response
adminbae64d82013-08-01 10:50:15 -0700222
kelvin8ec71442015-01-15 16:57:00 -0800223 def runAsSudoUser( self, handle, pwd, default ):
224
225 i = handle.expect( [ ".ssword:*", default, pexpect.EOF ] )
226 if i == 0:
227 handle.sendline( pwd )
228 handle.sendline( "\r" )
229
230 if i == 1:
231 handle.expect( default )
232
233 if i == 2:
234 main.log.error( "Unable to run as Sudo user" )
235
adminbae64d82013-08-01 10:50:15 -0700236 return handle
adminbae64d82013-08-01 10:50:15 -0700237
kelvin8ec71442015-01-15 16:57:00 -0800238 def onfail( self ):
239 if 'onfail' in main.componentDictionary[ self.name ]:
240 commandList = main.componentDictionary[
241 self.name ][ 'onfail' ].split( "," )
242 for command in commandList:
243 response = self.execute(
244 cmd=command,
245 prompt="(.*)",
246 timeout=120 )
adminbae64d82013-08-01 10:50:15 -0700247
kelvin8ec71442015-01-15 16:57:00 -0800248 def secureCopy( self, user_name, ip_address, filepath, pwd, dst_path ):
249
250 # scp openflow@192.168.56.101:/home/openflow/sample
251 # /home/paxterra/Desktop/
252 """
adminbae64d82013-08-01 10:50:15 -0700253 Connection will establish to the remote host using ssh.
254 It will take user_name ,ip_address and password as arguments<br>
kelvin8ec71442015-01-15 16:57:00 -0800255 and will return the handle.
256 """
adminbae64d82013-08-01 10:50:15 -0700257 ssh_newkey = 'Are you sure you want to continue connecting'
kelvin8ec71442015-01-15 16:57:00 -0800258 refused = "ssh: connect to host " + \
259 ip_address + " port 22: Connection refused"
adminbae64d82013-08-01 10:50:15 -0700260
kelvin8ec71442015-01-15 16:57:00 -0800261 cmd = 'scp ' + str( user_name ) + '@' + str( ip_address ) + ':' + \
262 str( filepath ) + ' ' + str(dst_path )
263
264 main.log.info( "Sending: " + cmd )
265 self.handle = pexpect.spawn( cmd )
266 i = self.handle.expect( [
267 ssh_newkey,
268 'password:',
269 pexpect.EOF,
270 pexpect.TIMEOUT,
271 refused ],
272 120 )
273
274 if i == 0:
275 main.log.info( "ssh key confirmation received, send yes" )
276 self.handle.sendline( 'yes' )
277 i = self.handle.expect( [ ssh_newkey, 'password:', pexpect.EOF ] )
278 if i == 1:
279 main.log.info( "ssh connection asked for password, gave password" )
280 self.handle.sendline( pwd )
281 # self.handle.expect( user_name )
282
283 elif i == 2:
284 main.log.error( "Connection timeout" )
adminbae64d82013-08-01 10:50:15 -0700285 pass
kelvin8ec71442015-01-15 16:57:00 -0800286 elif i == 3: # timeout
287 main.log.error(
288 "No route to the Host " +
289 user_name +
290 "@" +
291 ip_address )
adminbae64d82013-08-01 10:50:15 -0700292 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800293 elif i == 4:
294 main.log.error(
295 "ssh: connect to host " +
296 ip_address +
297 " port 22: Connection refused" )
adminbae64d82013-08-01 10:50:15 -0700298 return main.FALSE
299
kelvin8ec71442015-01-15 16:57:00 -0800300 self.handle.sendline( "" )
301 self.handle.expect( "$" )
Jon Hall94fd0472014-12-08 11:52:42 -0800302 print self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800303
adminbae64d82013-08-01 10:50:15 -0700304 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800305