1+ #!/usr/bin/python3
2+
3+ import paramiko
4+ from paramiko_expect import SSHClientInteraction
5+ import serial
6+ import os
7+ import time
8+ import argparse
9+ import sys
10+
11+ def main ():
12+
13+ parser = argparse .ArgumentParser (description = "description: Used to verify if CIN ports are up. No checks if in correct location." )
14+
15+ #parser.add_argument(dest='c', help='TB ports that need to be checked on CIN. Format of \'tb3\' or \'tb4\'.')
16+ parser .add_argument ('-c' , dest = 'chassisSelection' , help = 'Used to pick which chassis to check.' )
17+ parser .add_argument ('-l' , dest = 'cards' , help = 'List LC to check. Seperate list with a comma, no spaces.' )
18+ parser .add_argument ('-s' , dest = 'show' , help = "Show console output." , action = 'store_true' , default = False )
19+ parser .add_argument ('-a' , dest = 'skipConfig' , help = "Skip chassis config and just do checks. Default option is to apply config." , action = 'store_true' , default = False )
20+
21+ args = parser .parse_args ()
22+ chassisSelection = args .chassisSelection #what testbed's ports to check on cin.
23+ show = args .show
24+ cards = args .cards
25+ chassis = str (chassisSelection [- 1 ])
26+ skip = args .skipConfig
27+
28+ if len (chassisSelection ) > 1 :
29+ sys .exit ("Too many char for tb name. Exiting..." )
30+
31+ if chassis != '3' and chassis != '4' :
32+ sys .exit ("Chassis selection invalid. Exiting..." )
33+
34+ if cards is None :
35+ #cards to test should be all?
36+ cards = '1,2,3,6,7,8,9'
37+
38+ if chassis == '3' :
39+ serialPort = '/dev/USB3'
40+
41+ if chassis == '4' :
42+ serialPort = '/dev/USB5'
43+
44+ console = console_in (serialPort )
45+ cinIP = copy_network_config (chassis , console , skip )
46+ sys .exit ("\r \r \t CIN config done. Please ping addresses to check connectivity. Exiting script.\r " )
47+
48+ ssh , client = ssh_connect (cinIP ) #this needs to be from the cin
49+
50+ if len (cards ) == 1 :
51+ cards = list (cards )
52+ if len (cards ) != 1 :
53+ cards = cards .split (',' )
54+
55+ cards .insert (0 , '0' ) #add to the 0 position card '0'
56+ print ()
57+ print ('Checking below cards:\r ' )
58+ print ('\t ' + str (cards ))
59+
60+ lssueCards = check_cards (ssh , client , chassis , cards ) #ssh to CIN, and cards to test
61+
62+ if len (issueCards ) != 0 :
63+ the_issues (issueCards )
64+
65+ else :
66+ print ('\r \r \t After looking at requested cards, chassis is ready to test.' )
67+
68+ sys .exit ("Exiting" )
69+
70+ return
71+
72+
73+ def copy_network_config (chassis , console , skip ):
74+
75+ primaryIP = '10.23' + chassis + '.' + chassis + '0.5' #format of '10.23x.x0.5 /24 -> 10.233.30.5 for tb3
76+
77+ if not skip :
78+
79+ vlan = chassis + "0"
80+ hostApply = "hostname chassis" + chassis
81+ atpAdd = primaryIP [:- 1 ]+ '1'
82+ cfgFile = '23' + chassis + '_ip'
83+ priAddCMD = "ip addr " + str (primaryIP ) + " 255.255.255.0"
84+
85+ cfgFile = '23' + chassis + '_ip'
86+
87+ configAddresses = ['clear logging' , '\r \n \r \n ' ,"conf t" , 'int hun4/1/0' ,
88+ 'no shut' , "int hun4/1/0." + vlan , "encapsulation dot1Q " + vlan , "vrf forwarding Mgmt-intf" ,
89+ priAddCMD , "no shut" , "exit" , "ip route 0.0.0.0 0.0.0.0 hun4/1/0" , "end" , "\r \n " ]
90+
91+ print ("\r \t Getting to the correct location.\r " )
92+
93+ right_spot (console )
94+
95+ print ("\r \t Starting basic configuration for network access.\r " )
96+
97+ print ("\r Sending Console Commands\r \r " )
98+ consoleOutput = []
99+ for command in configAddresses :
100+ console .flushInput () #flush input buffer
101+ console .flushOutput ()#flush output buffer
102+ time .sleep (1 )
103+ console .write (bytes (command + '\r \n ' , "utf-8" ))
104+ output = console .readlines ()
105+ for item in output :
106+ decodedOut = item .decode ('utf-8' )
107+ consoleOutput .append (decodedOut )
108+ print (decodedOut )
109+
110+ print ("\r \t Basic network application completed. Attempting to ping chassis from TFTP server." )
111+ time .sleep (5 )
112+ response = os .system ("ping -c 3 " + primaryIP ) #ping chassis 3 times
113+ if response == 0 : #Checks for the number of failures?
114+ print ("\r \t CBR is able to ping test server. SSHing to chassis..." )
115+
116+
117+ if response != 0 :
118+ sys .exit ("\r \t Unable to ping chassis. Verify connectivity and try again." )
119+
120+ copyCfgCMD = 'copy tftp://' + atpAdd + '/cbr_cfg_files/' + cfgFile + ' running-config\r \r \r '
121+ console .write (bytes (copyCfgCMD , 'utf-8' ))
122+ output = ''
123+ output = console .readlines ()
124+
125+ for returned in output :
126+ print (returned .decode ('utf-8' ))
127+
128+ cinIP = primaryIP [:- 1 ]+ '3' #CIN IP for this tb's vlan
129+ return cinIP
130+
131+ def right_spot (console ):
132+
133+ i = 0
134+ while i < 3 :
135+ print ("\r \n Attempt number " + str (i ) + "\r \r " )
136+ console .write (b'\r \n ' )
137+ output = console .readlines ()
138+
139+ for line in output :
140+ line = line .decode ('utf-8' )
141+ i += 1
142+ for item in output :
143+ item = item .decode ('utf-8' )
144+ print (item )
145+ if "#" in item : #if in priv exec mode
146+ if "(confi" in item : #exit config mode, check in priv exec, leave to global
147+ console .write (b'end\r \n ' )
148+ leaveConfig = console .readlines ()
149+ for item in leaveConfig :
150+ item = item .decode ('utf-8' )
151+ if "#" in item :
152+ console .write (b"exit\r \n " )
153+ print (console .readlines ()) #TODO: output what's being sent to console. Comment out of final
154+ console .write (b"\r \n \r \n " )
155+ print (console .readlines ())
156+ time .sleep (1 )
157+ console .write (b"en\r \n " )
158+ print (console .readlines ())
159+ break
160+ else : #if only in priv exec mode, break 3 times to skip checks
161+ i = 3
162+ break
163+
164+ if ">" in item :
165+ console .write (b"en\r \n " )
166+ enableCheck = console .readlines ()
167+ for item in enableCheck :
168+ item = item .decode ('utf-8' ) #!todo - untested
169+ if "password" in item .lower ():
170+ console .write (b"cisco\r \n " )
171+ print (console .readlines ())
172+
173+ break
174+
175+ if "ress RETURN to" in item :
176+ console .write (b"\r \n \r \n " )
177+ print (console .readlines ())
178+ time .sleep (1 )
179+ console .write (b"en\r \n " )
180+ print (console .readlines ())
181+ break
182+
183+ console .write (b'\r \n ' ) #used to get it to just kick out a line
184+ output = console .readlines ()
185+ found = False
186+ for item in output :
187+ item = item .decode ('utf-8' )
188+ if "#" in item :
189+ found = True
190+ break
191+ if found == False :
192+ print ("Failed to get to correct prompt. Re-run ONCE to see if corrected. Exiting Script" )
193+ sys .exit ("\r \t Failed to get to correct prompt. Re-run ONCE to see if corrected." )
194+
195+ def console_in (serialPort ): #returns console connection information
196+
197+ baud = 9600
198+ console = serial .Serial (serialPort , baud , timeout = 1 )
199+ print ()
200+ print ("\r \r \t Chassis connected to console at" + serialPort ) #print("here")
201+ print ()
202+
203+ return console
204+
205+ def ssh_connect (primaryIP ):
206+ user = 'admin'
207+ passwd = 'WWTwwt1!'
208+ #prompt = 'WWT-ATP-CIN#'
209+ prompt = ".*# "
210+ primaryIP = '10.233.30.3'
211+
212+ client = paramiko .SSHClient ()
213+ client .set_missing_host_key_policy (paramiko .AutoAddPolicy ())#
214+ print ( "\r \t Attempting to SSH into chassis at " + primaryIP + "...\r \r " )
215+
216+ i = 0
217+ for i in range (10 ):
218+
219+ try :
220+ client .connect (hostname = '10.233.30.3' , username = user , password = passwd , allow_agent = False ,look_for_keys = False )
221+ print ( "\n \t Connection established to " + str (primaryIP ))
222+ break
223+
224+ except :
225+ i += 1
226+ if i == 9 :
227+ print ( "SSH FAILED. Verify connection to Supervisor port NME0. Exiting Script" )
228+ sys .exit ('\n \t SSH failed. Exiting' )
229+ time .sleep (10 )
230+ print ( "\n \t SSH attempt " + str (i ) + " failed. waiting 10sec.\r " )
231+
232+
233+ ssh = SSHClientInteraction (client , timeout = 10 , display = True ) #!todo- change true
234+ ssh .send ('\r \n ' )
235+ time .sleep (1 )
236+ ssh .expect (prompt )
237+ ssh .current_output_clean
238+ return ssh , client
239+
240+ def send_command (ssh , client , text ):
241+
242+ prompt = '.*CIN.*'
243+
244+ ssh .send (text + '\r ' )
245+ #time.sleep(6)
246+ ssh .expect (prompt )
247+
248+
249+ output = ssh .current_output_clean
250+ output = output .splitlines ()
251+
252+ return output
253+
254+ def check_cards (ssh , client , chassis , cards ):
255+
256+ issueCards = {}
257+ issues = []
258+ shelfGroups = ['1' ,'2' ,'6' ,'7' ] #groupings for each rpd/vlan group TODO: THis is wrong
259+ ipGroup = ['8' ,'9' ]
260+
261+ for lc in cards :
262+ print ('Looking at card ' + lc )
263+ for shelfIP in shelfGroups : #the 1,2,6,7
264+ passed = 2
265+
266+ for port in ipGroup : #the .x8 and .x9
267+
268+ address = '10.23' + chassis + '.' + lc + '.' + str (shelfIP ) + str (port ) #10.23C.S.LP
269+ pingCmd = 'ping ' + address
270+ output = send_command (ssh , client , pingCmd )
271+
272+ for item in output :
273+ print (item )
274+ #input('hold')
275+ if " 100.00% packet loss" in item :
276+ print ()
277+ print ("\r \r \t Ip " + address + " not reachable...\r \r " )
278+ passed -= 1
279+ break
280+
281+ if passed < 1 :
282+ issueCards .update ({lc :shelfIP })
283+
284+
285+ print ()
286+ print (str (len (issueCards ))+ " found on card " + lc + "..." )
287+ input ()
288+
289+
290+ return lssueCards
291+
292+ def the_issues (issueCards ):
293+
294+ pass
295+
296+ main ()
0 commit comments