blob: dd54d45cf140792e6dfa67808ef91756777d9bda [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
3'''
4This driver enters the onos> prompt to issue commands.
5
6Please follow the coding style demonstrated by existing
7functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
18'''
19
20import sys
21import time
22import pexpect
23import re
24import traceback
25import os.path
26import pydoc
Jon Halla001c392014-10-17 18:50:59 -040027import re
andrewonlab95ce8322014-10-13 14:12:04 -040028sys.path.append("../")
29from drivers.common.clidriver import CLI
30
31class OnosCliDriver(CLI):
32
33 def __init__(self):
34 '''
35 Initialize client
36 '''
37 super(CLI, self).__init__()
38
39 def connect(self,**connectargs):
40 '''
41 Creates ssh handle for ONOS cli.
42 '''
43 try:
44 for key in connectargs:
45 vars(self)[key] = connectargs[key]
46 self.home = "~/ONOS"
47 for key in self.options:
48 if key == "home":
49 self.home = self.options['home']
50 break
51
52
53 self.name = self.options['name']
54 self.handle = super(OnosCliDriver,self).connect(
55 user_name = self.user_name,
56 ip_address = self.ip_address,
57 port = self.port,
58 pwd = self.pwd,
59 home = self.home)
60
61 self.handle.sendline("cd "+ self.home)
62 self.handle.expect("\$")
63 if self.handle:
64 return self.handle
65 else :
66 main.log.info("NO ONOS HANDLE")
67 return main.FALSE
68 except pexpect.EOF:
69 main.log.error(self.name + ": EOF exception found")
70 main.log.error(self.name + ": " + self.handle.before)
71 main.cleanup()
72 main.exit()
73 except:
andrewonlab9627f432014-11-14 12:45:10 -050074 main.log.info(self.name + ":::::::::::::::::::::::")
andrewonlab95ce8322014-10-13 14:12:04 -040075 main.log.error( traceback.print_exc() )
andrewonlab9627f432014-11-14 12:45:10 -050076 main.log.info(":::::::::::::::::::::::")
andrewonlab95ce8322014-10-13 14:12:04 -040077 main.cleanup()
78 main.exit()
79
80 def disconnect(self):
81 '''
82 Called when Test is complete to disconnect the ONOS handle.
83 '''
84 response = ''
85 try:
andrewonlab2a6c9342014-10-16 13:40:15 -040086 self.handle.sendline("")
Jon Hall7e5b9172014-10-22 12:32:47 -040087 i = self.handle.expect(["onos>","\$"])
88 if i == 0:
89 self.handle.sendline("system:shutdown")
90 self.handle.expect("Confirm")
91 self.handle.sendline("yes")
92 self.handle.expect("\$")
93 self.handle.sendline("\n")
andrewonlabc2d05aa2014-10-13 16:51:10 -040094 self.handle.expect("\$")
Jon Hall7e5b9172014-10-22 12:32:47 -040095 self.handle.sendline("exit")
96 self.handle.expect("closed")
andrewonlabc2d05aa2014-10-13 16:51:10 -040097
andrewonlab95ce8322014-10-13 14:12:04 -040098 except pexpect.EOF:
99 main.log.error(self.name + ": EOF exception found")
100 main.log.error(self.name + ": " + self.handle.before)
101 except:
102 main.log.error(self.name + ": Connection failed to the host")
103 response = main.FALSE
104 return response
105
andrewonlab38d2b4a2014-11-13 16:28:47 -0500106 def logout(self):
107 '''
108 Sends 'logout' command to ONOS cli
109 '''
110 try:
andrewonlab9627f432014-11-14 12:45:10 -0500111 self.handle.sendline("")
112 i = self.handle.expect([
113 "onos>",
114 "\$"], timeout=10)
115 if i == 0:
116 self.handle.sendline("logout")
117 self.handle.expect("\$")
118 elif i == 1:
119 return main.TRUE
120
andrewonlab38d2b4a2014-11-13 16:28:47 -0500121 except pexpect.EOF:
122 main.log.error(self.name + ": eof exception found")
andrewonlab9627f432014-11-14 12:45:10 -0500123 main.log.error(self.name + ": " +
124 self.handle.before)
andrewonlab38d2b4a2014-11-13 16:28:47 -0500125 main.cleanup()
126 main.exit()
127 except:
128 main.log.info(self.name+" ::::::")
129 main.log.error( traceback.print_exc())
130 main.log.info(self.name+" ::::::")
131 main.cleanup()
132 main.exit()
133
andrewonlab95ce8322014-10-13 14:12:04 -0400134 def set_cell(self, cellname):
135 '''
136 Calls 'cell <name>' to set the environment variables on ONOSbench
137
138 Before issuing any cli commands, set the environment variable first.
139 '''
140 try:
141 if not cellname:
142 main.log.error("Must define cellname")
143 main.cleanup()
144 main.exit()
145 else:
146 self.handle.sendline("cell "+str(cellname))
147 #Expect the cellname in the ONOS_CELL variable.
148 #Note that this variable name is subject to change
149 # and that this driver will have to change accordingly
150 self.handle.expect("ONOS_CELL="+str(cellname))
151 handle_before = self.handle.before
152 handle_after = self.handle.after
153 #Get the rest of the handle
154 self.handle.sendline("")
155 self.handle.expect("\$")
156 handle_more = self.handle.before
157
158 main.log.info("Cell call returned: "+handle_before+
159 handle_after + handle_more)
160
161 return main.TRUE
162
163 except pexpect.EOF:
andrewonlab38d2b4a2014-11-13 16:28:47 -0500164 main.log.error(self.name + ": eof exception found")
andrewonlab95ce8322014-10-13 14:12:04 -0400165 main.log.error(self.name + ": " + self.handle.before)
166 main.cleanup()
167 main.exit()
168 except:
169 main.log.info(self.name+" ::::::")
170 main.log.error( traceback.print_exc())
171 main.log.info(self.name+" ::::::")
172 main.cleanup()
173 main.exit()
174
andrewonlabc2d05aa2014-10-13 16:51:10 -0400175 def start_onos_cli(self, ONOS_ip):
andrewonlab95ce8322014-10-13 14:12:04 -0400176 try:
177 self.handle.sendline("")
andrewonlab48829f62014-11-17 13:49:01 -0500178 x = self.handle.expect([
179 "\$", "onos>"], timeout=10)
180
181 if x == 1:
182 main.log.info("ONOS cli is already running")
183 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400184
185 #Wait for onos start (-w) and enter onos cli
andrewonlabc2d05aa2014-10-13 16:51:10 -0400186 self.handle.sendline("onos -w "+str(ONOS_ip))
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400187 i = self.handle.expect([
188 "onos>",
189 pexpect.TIMEOUT],timeout=60)
190
191 if i == 0:
192 main.log.info(str(ONOS_ip)+" CLI Started successfully")
193 return main.TRUE
194 else:
andrewonlab3a7c3c72014-10-24 17:21:03 -0400195 #If failed, send ctrl+c to process and try again
andrewonlabf47993a2014-10-24 17:56:01 -0400196 main.log.info("Starting CLI failed. Retrying...")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400197 self.handle.sendline("\x03")
andrewonlab367b5132014-11-20 14:20:16 -0500198 i = self.handle.expect(["onos>",pexpect.TIMEOUT],
199 timeout=30)
200 #Send ctrl+d to exit the onos> prompt that was
201 #not successful
202 self.handle.sendline("\x04")
203 self.handle.expect("\$")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400204 self.handle.sendline("onos -w "+str(ONOS_ip))
205 i = self.handle.expect(["onos>",pexpect.TIMEOUT],
206 timeout=30)
207 if i == 0:
andrewonlab28ca4b22014-11-20 13:15:59 -0500208 main.log.info(str(ONOS_ip)+" CLI Started "+
209 "successfully after retry attempt")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400210 return main.TRUE
211 else:
212 main.log.error("Connection to CLI "+\
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400213 str(ONOS_ip)+" timeout")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400214 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400215
216 except pexpect.EOF:
217 main.log.error(self.name + ": EOF exception found")
218 main.log.error(self.name + ": " + self.handle.before)
219 main.cleanup()
220 main.exit()
221 except:
222 main.log.info(self.name+" ::::::")
223 main.log.error( traceback.print_exc())
224 main.log.info(self.name+" ::::::")
225 main.cleanup()
226 main.exit()
227
andrewonlaba18f6bf2014-10-13 19:31:54 -0400228 def sendline(self, cmd_str):
229 '''
230 Send a completely user specified string to
231 the onos> prompt. Use this function if you have
232 a very specific command to send.
233
234 Warning: There are no sanity checking to commands
235 sent using this method.
236 '''
237 try:
238 self.handle.sendline("")
239 self.handle.expect("onos>")
240
241 self.handle.sendline(cmd_str)
242 self.handle.expect("onos>")
243
244 handle = self.handle.before
245
246 self.handle.sendline("")
247 self.handle.expect("onos>")
248
249 handle += self.handle.before
250 handle += self.handle.after
251
252 main.log.info("Command sent.")
Jon Hall42db6dc2014-10-24 19:03:48 -0400253 ansi_escape = re.compile(r'\x1b[^m]*m')
254 handle = ansi_escape.sub('', handle)
andrewonlaba18f6bf2014-10-13 19:31:54 -0400255
256 return handle
257 except pexpect.EOF:
258 main.log.error(self.name + ": EOF exception found")
259 main.log.error(self.name + ": " + self.handle.before)
260 main.cleanup()
261 main.exit()
262 except:
263 main.log.info(self.name+" ::::::")
264 main.log.error( traceback.print_exc())
265 main.log.info(self.name+" ::::::")
266 main.cleanup()
267 main.exit()
268
andrewonlab95ce8322014-10-13 14:12:04 -0400269 #IMPORTANT NOTE:
270 #For all cli commands, naming convention should match
271 #the cli command replacing ':' with '_'.
272 #Ex) onos:topology > onos_topology
273 # onos:links > onos_links
274 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400275
276 def add_node(self, node_id, ONOS_ip, tcp_port=""):
277 '''
278 Adds a new cluster node by ID and address information.
279 Required:
280 * node_id
281 * ONOS_ip
282 Optional:
283 * tcp_port
284 '''
285 try:
286 self.handle.sendline("")
287 self.handle.expect("onos>")
288
289 self.handle.sendline("add-node "+
290 str(node_id)+" "+
291 str(ONOS_ip)+" "+
292 str(tcp_port))
293
294 i = self.handle.expect([
295 "Error",
296 "onos>" ])
297
298 #Clear handle to get previous output
299 self.handle.sendline("")
300 self.handle.expect("onos>")
301
302 handle = self.handle.before
303
304 if i == 0:
305 main.log.error("Error in adding node")
306 main.log.error(handle)
307 return main.FALSE
308 else:
309 main.log.info("Node "+str(ONOS_ip)+" added")
310 return main.TRUE
311
312 except pexpect.EOF:
313 main.log.error(self.name + ": EOF exception found")
314 main.log.error(self.name + ": " + self.handle.before)
315 main.cleanup()
316 main.exit()
317 except:
318 main.log.info(self.name+" ::::::")
319 main.log.error( traceback.print_exc())
320 main.log.info(self.name+" ::::::")
321 main.cleanup()
322 main.exit()
323
andrewonlab86dc3082014-10-13 18:18:38 -0400324 def remove_node(self, node_id):
325 '''
326 Removes a cluster by ID
327 Issues command: 'remove-node [<node-id>]'
328 Required:
329 * node_id
330 '''
331 try:
332 self.handle.sendline("")
333 self.handle.expect("onos>")
334
335 self.handle.sendline("remove-node "+str(node_id))
336 self.handle.expect("onos>")
337
338 return main.TRUE
339
340 except pexpect.EOF:
341 main.log.error(self.name + ": EOF exception found")
342 main.log.error(self.name + ": " + self.handle.before)
343 main.cleanup()
344 main.exit()
345 except:
346 main.log.info(self.name+" ::::::")
347 main.log.error( traceback.print_exc())
348 main.log.info(self.name+" ::::::")
349 main.cleanup()
350 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400351
andrewonlab7c211572014-10-15 16:45:20 -0400352 def nodes(self):
353 '''
354 List the nodes currently visible
355 Issues command: 'nodes'
356 Returns: entire handle of list of nodes
357 '''
358 try:
359 self.handle.sendline("")
360 self.handle.expect("onos>")
361
362 self.handle.sendline("nodes")
363 self.handle.expect("onos>")
364
365 self.handle.sendline("")
366 self.handle.expect("onos>")
367
368 handle = self.handle.before
369
370 return handle
371
372 except pexpect.EOF:
373 main.log.error(self.name + ": EOF exception found")
374 main.log.error(self.name + ": " + self.handle.before)
375 main.cleanup()
376 main.exit()
377 except:
378 main.log.info(self.name+" ::::::")
379 main.log.error( traceback.print_exc())
380 main.log.info(self.name+" ::::::")
381 main.cleanup()
382 main.exit()
383
andrewonlab38d6ae22014-10-15 14:23:45 -0400384 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400385 '''
386 Shows the current state of the topology
387 by issusing command: 'onos> onos:topology'
388 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400389 try:
390 self.handle.sendline("")
391 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400392 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400393 self.handle.sendline("onos:topology")
394 self.handle.expect("onos>")
395
396 handle = self.handle.before
397
398 main.log.info("onos:topology returned: " +
399 str(handle))
400
401 return handle
402
403 except pexpect.EOF:
404 main.log.error(self.name + ": EOF exception found")
405 main.log.error(self.name + ": " + self.handle.before)
406 main.cleanup()
407 main.exit()
408 except:
409 main.log.info(self.name+" ::::::")
410 main.log.error( traceback.print_exc())
411 main.log.info(self.name+" ::::::")
412 main.cleanup()
413 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400414
415 def feature_install(self, feature_str):
416 '''
417 Installs a specified feature
418 by issuing command: 'onos> feature:install <feature_str>'
419 '''
420 try:
421 self.handle.sendline("")
422 self.handle.expect("onos>")
423
424 self.handle.sendline("feature:install "+str(feature_str))
425 self.handle.expect("onos>")
426
427 return main.TRUE
428
429 except pexpect.EOF:
430 main.log.error(self.name + ": EOF exception found")
431 main.log.error(self.name + ": " + self.handle.before)
andrewonlabbf225b02014-11-12 12:14:05 -0500432 main.log.report("Failed to install feature")
433 main.log.report("Exiting test")
andrewonlabc2d05aa2014-10-13 16:51:10 -0400434 main.cleanup()
435 main.exit()
436 except:
437 main.log.info(self.name+" ::::::")
438 main.log.error( traceback.print_exc())
andrewonlabbf225b02014-11-12 12:14:05 -0500439 main.log.report("Failed to install feature")
440 main.log.report("Exiting test")
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 main.log.info(self.name+" ::::::")
442 main.cleanup()
443 main.exit()
444
445 def feature_uninstall(self, feature_str):
446 '''
447 Uninstalls a specified feature
448 by issuing command: 'onos> feature:uninstall <feature_str>'
449 '''
450 try:
451 self.handle.sendline("")
452 self.handle.expect("onos>")
453
454 self.handle.sendline("feature:uninstall "+str(feature_str))
455 self.handle.expect("onos>")
456
457 return main.TRUE
458
459 except pexpect.EOF:
460 main.log.error(self.name + ": EOF exception found")
461 main.log.error(self.name + ": " + self.handle.before)
462 main.cleanup()
463 main.exit()
464 except:
465 main.log.info(self.name+" ::::::")
466 main.log.error( traceback.print_exc())
467 main.log.info(self.name+" ::::::")
468 main.cleanup()
469 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400470
Jon Halle8217482014-10-17 13:49:14 -0400471 def devices(self, json_format=True, grep_str=""):
andrewonlab86dc3082014-10-13 18:18:38 -0400472 '''
Jon Hall7b02d952014-10-17 20:14:54 -0400473 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400474 Optional argument:
475 * grep_str - pass in a string to grep
476 '''
477 try:
478 self.handle.sendline("")
479 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400480
481 if json_format:
482 if not grep_str:
483 self.handle.sendline("devices -j")
484 self.handle.expect("devices -j")
485 self.handle.expect("onos>")
486 else:
487 self.handle.sendline("devices -j | grep '"+
andrewonlab86dc3082014-10-13 18:18:38 -0400488 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400489 self.handle.expect("devices -j | grep '"+str(grep_str)+"'")
490 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400491 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400492 '''
493 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
494 To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
Jon Hall5227ce82014-10-17 20:09:51 -0400495 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Hall983a1702014-10-28 18:44:22 -0400496 So we take off that escape sequence using
Jon Halld815ce42014-10-17 19:52:30 -0400497 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hall983a1702014-10-28 18:44:22 -0400498 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400499 '''
500 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400501 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
502 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400503 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400504 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400505 else:
506 if not grep_str:
507 self.handle.sendline("devices")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400508 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400509 else:
510 self.handle.sendline("devices | grep '"+
511 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400512 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400513 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400514 #print "handle =",handle
Jon Hallcd707292014-10-17 19:06:17 -0400515 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400516 except pexpect.EOF:
517 main.log.error(self.name + ": EOF exception found")
518 main.log.error(self.name + ": " + self.handle.before)
519 main.cleanup()
520 main.exit()
521 except:
522 main.log.info(self.name+" ::::::")
523 main.log.error( traceback.print_exc())
524 main.log.info(self.name+" ::::::")
525 main.cleanup()
526 main.exit()
527
Jon Halle8217482014-10-17 13:49:14 -0400528 def links(self, json_format=True, grep_str=""):
529 '''
530 Lists all core links
531 Optional argument:
532 * grep_str - pass in a string to grep
533 '''
534 try:
535 self.handle.sendline("")
536 self.handle.expect("onos>")
537
538 if json_format:
539 if not grep_str:
540 self.handle.sendline("links -j")
541 self.handle.expect("links -j")
542 self.handle.expect("onos>")
543 else:
544 self.handle.sendline("links -j | grep '"+
545 str(grep_str)+"'")
546 self.handle.expect("links -j | grep '"+str(grep_str)+"'")
547 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400548 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400549 '''
550 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
551 To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
Jon Hall5227ce82014-10-17 20:09:51 -0400552 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Halld815ce42014-10-17 19:52:30 -0400553 So we take off that escape sequence using
554 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
555 handle1 = ansi_escape.sub('', handle)
556 '''
557 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400558 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
559 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400560 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400561 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400562 else:
563 if not grep_str:
564 self.handle.sendline("links")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400565 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400566 else:
567 self.handle.sendline("links | grep '"+
568 str(grep_str)+"'")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400569 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400570 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400571 #print "handle =",handle
Jon Halla001c392014-10-17 18:50:59 -0400572 return handle
Jon Halle8217482014-10-17 13:49:14 -0400573 except pexpect.EOF:
574 main.log.error(self.name + ": EOF exception found")
575 main.log.error(self.name + ": " + self.handle.before)
576 main.cleanup()
577 main.exit()
578 except:
579 main.log.info(self.name+" ::::::")
580 main.log.error( traceback.print_exc())
581 main.log.info(self.name+" ::::::")
582 main.cleanup()
583 main.exit()
584
585
586 def ports(self, json_format=True, grep_str=""):
587 '''
588 Lists all ports
589 Optional argument:
590 * grep_str - pass in a string to grep
591 '''
592 try:
593 self.handle.sendline("")
594 self.handle.expect("onos>")
595
596 if json_format:
597 if not grep_str:
598 self.handle.sendline("ports -j")
599 self.handle.expect("ports -j")
600 self.handle.expect("onos>")
601 else:
602 self.handle.sendline("ports -j | grep '"+
603 str(grep_str)+"'")
604 self.handle.expect("ports -j | grep '"+str(grep_str)+"'")
605 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400606 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400607 '''
608 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
609 To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
Jon Hall5227ce82014-10-17 20:09:51 -0400610 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Shreya Shah0c525cc2014-10-17 20:20:24 -0400611 So we take off that escape sequence using the following commads:
Jon Halld815ce42014-10-17 19:52:30 -0400612 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
613 handle1 = ansi_escape.sub('', handle)
614 '''
615 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400616 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
617 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400618 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400619 return handle1
620
Jon Halle8217482014-10-17 13:49:14 -0400621 else:
622 if not grep_str:
623 self.handle.sendline("ports")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400624 self.handle.expect("onos>")
625 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400626 self.handle.expect("onos>")
627 else:
628 self.handle.sendline("ports | grep '"+
629 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400630 self.handle.expect("onos>")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400631 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400632 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400633 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400634 #print "handle =",handle
Jon Hallcd707292014-10-17 19:06:17 -0400635 return handle
Jon Halle8217482014-10-17 13:49:14 -0400636 except pexpect.EOF:
637 main.log.error(self.name + ": EOF exception found")
638 main.log.error(self.name + ": " + self.handle.before)
639 main.cleanup()
640 main.exit()
641 except:
642 main.log.info(self.name+" ::::::")
643 main.log.error( traceback.print_exc())
644 main.log.info(self.name+" ::::::")
645 main.cleanup()
646 main.exit()
647
648
Jon Hall983a1702014-10-28 18:44:22 -0400649 def roles(self, json_format=True, grep_str=""):
andrewonlab7c211572014-10-15 16:45:20 -0400650 '''
Jon Hall983a1702014-10-28 18:44:22 -0400651 Lists all devices and the controllers with roles assigned to them
652 Optional argument:
653 * grep_str - pass in a string to grep
andrewonlab7c211572014-10-15 16:45:20 -0400654 '''
655 try:
656 self.handle.sendline("")
657 self.handle.expect("onos>")
Jon Hallb1290e82014-11-18 16:17:48 -0500658
Jon Hall983a1702014-10-28 18:44:22 -0400659 if json_format:
Jon Hallb1290e82014-11-18 16:17:48 -0500660 self.handle.sendline("roles -j")
661 self.handle.expect("roles -j")
662 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -0400663 handle = self.handle.before
664 '''
Jon Hallb1290e82014-11-18 16:17:48 -0500665 handle variable here contains some ANSI escape color code sequences at the
666 end which are invisible in the print command output. To make that escape
667 sequence visible, use repr() function. The repr(handle) output when printed
668 shows the ANSI escape sequences. In json.loads(somestring), this somestring
669 variable is actually repr(somestring) and json.loads would fail with the escape
670 sequence.
671
672 So we take off that escape sequence using the following commads:
Jon Hall983a1702014-10-28 18:44:22 -0400673 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hallb1290e82014-11-18 16:17:48 -0500674 handle1 = ansi_escape.sub('', handle)
Jon Hall983a1702014-10-28 18:44:22 -0400675 '''
676 #print "repr(handle) =", repr(handle)
677 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
678 handle1 = ansi_escape.sub('', handle)
679 #print "repr(handle1) = ", repr(handle1)
680 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400681
andrewonlab7c211572014-10-15 16:45:20 -0400682 else:
Jon Hallb1290e82014-11-18 16:17:48 -0500683 self.handle.sendline("roles")
684 self.handle.expect("onos>")
685 self.handle.sendline("")
686 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -0400687 handle = self.handle.before
688 #print "handle =",handle
689 return handle
690 except pexpect.EOF:
691 main.log.error(self.name + ": EOF exception found")
692 main.log.error(self.name + ": " + self.handle.before)
693 main.cleanup()
694 main.exit()
695 except:
696 main.log.info(self.name+" ::::::")
697 main.log.error( traceback.print_exc())
698 main.log.info(self.name+" ::::::")
699 main.cleanup()
700 main.exit()
701
702 def get_role(self, device_id):
703 '''
704 Given the a string containing the json representation of the "roles" cli command and a
705 partial or whole device id, returns a json object containing the
706 roles output for the first device whose id contains "device_id"
707
708 Returns:
709 Dict of the role assignments for the given device or
710 None if not match
711 '''
712 try:
713 import json
714 if device_id == None:
715 return None
716 else:
717 raw_roles = self.roles()
718 roles_json = json.loads(raw_roles)
719 #search json for the device with id then return the device
720 for device in roles_json:
Jon Hall720653a2014-10-28 19:02:37 -0400721 #print device
Jon Hall983a1702014-10-28 18:44:22 -0400722 if str(device_id) in device['id']:
723 return device
724 return None
andrewonlab7c211572014-10-15 16:45:20 -0400725
andrewonlab86dc3082014-10-13 18:18:38 -0400726 except pexpect.EOF:
727 main.log.error(self.name + ": EOF exception found")
728 main.log.error(self.name + ": " + self.handle.before)
729 main.cleanup()
730 main.exit()
731 except:
732 main.log.info(self.name+" ::::::")
733 main.log.error( traceback.print_exc())
734 main.log.info(self.name+" ::::::")
735 main.cleanup()
736 main.exit()
andrewonlab2a6c9342014-10-16 13:40:15 -0400737
andrewonlab3e15ead2014-10-15 14:21:34 -0400738 def paths(self, src_id, dst_id):
739 '''
740 Returns string of paths, and the cost.
741 Issues command: onos:paths <src> <dst>
742 '''
743 try:
744 self.handle.sendline("")
745 self.handle.expect("onos>")
746
747 self.handle.sendline("onos:paths "+
748 str(src_id) + " " + str(dst_id))
749 i = self.handle.expect([
750 "Error",
751 "onos>"])
752
753 self.handle.sendline("")
754 self.handle.expect("onos>")
755
756 handle = self.handle.before
757
758 if i == 0:
759 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400760 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400761 else:
762 path = handle.split(";")[0]
763 cost = handle.split(";")[1]
764 return (path, cost)
765
766 except pexpect.EOF:
767 main.log.error(self.name + ": EOF exception found")
768 main.log.error(self.name + ": " + self.handle.before)
769 main.cleanup()
770 main.exit()
771 except:
772 main.log.info(self.name+" ::::::")
773 main.log.error( traceback.print_exc())
774 main.log.info(self.name+" ::::::")
775 main.cleanup()
776 main.exit()
andrewonlab3f0a4af2014-10-17 12:25:14 -0400777
Jon Hall42db6dc2014-10-24 19:03:48 -0400778 def hosts(self, json_format=True, grep_str=""):
779 '''
780 Lists all discovered hosts
781 Optional argument:
782 * grep_str - pass in a string to grep
783 '''
784 try:
785 self.handle.sendline("")
786 self.handle.expect("onos>")
787
788 if json_format:
789 if not grep_str:
790 self.handle.sendline("hosts -j")
791 self.handle.expect("hosts -j")
792 self.handle.expect("onos>")
793 else:
794 self.handle.sendline("hosts -j | grep '"+
795 str(grep_str)+"'")
796 self.handle.expect("hosts -j | grep '"+str(grep_str)+"'")
797 self.handle.expect("onos>")
798 handle = self.handle.before
799 '''
800 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
801 To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
802 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
803 So we take off that escape sequence using
804 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
805 handle1 = ansi_escape.sub('', handle)
806 '''
807 #print "repr(handle) =", repr(handle)
808 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
809 handle1 = ansi_escape.sub('', handle)
810 #print "repr(handle1) = ", repr(handle1)
811 return handle1
812 else:
813 if not grep_str:
814 self.handle.sendline("hosts")
815 self.handle.expect("onos>")
816 else:
817 self.handle.sendline("hosts | grep '"+
818 str(grep_str)+"'")
819 self.handle.expect("onos>")
820 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400821 #print "handle =",handle
Jon Hall42db6dc2014-10-24 19:03:48 -0400822 return handle
823 except pexpect.EOF:
824 main.log.error(self.name + ": EOF exception found")
825 main.log.error(self.name + ": " + self.handle.before)
826 main.cleanup()
827 main.exit()
828 except:
829 main.log.info(self.name+" ::::::")
830 main.log.error( traceback.print_exc())
831 main.log.info(self.name+" ::::::")
832 main.cleanup()
833 main.exit()
834
835 def get_host(self, mac):
836 '''
837 Return the first host from the hosts api whose 'id' contains 'mac'
838 Note: mac must be a colon seperated mac address, but could be a partial mac address
839 Return None if there is no match
840 '''
841 import json
842 try:
843 if mac == None:
844 return None
845 else:
846 mac = mac
847 raw_hosts = self.hosts()
848 hosts_json = json.loads(raw_hosts)
849 #search json for the host with mac then return the device
850 for host in hosts_json:
Jon Hall983a1702014-10-28 18:44:22 -0400851 #print "%s in %s?" % (mac, host['id'])
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 if mac in host['id']:
853 return host
854 return None
855 except pexpect.EOF:
856 main.log.error(self.name + ": EOF exception found")
857 main.log.error(self.name + ": " + self.handle.before)
858 main.cleanup()
859 main.exit()
860 except:
861 main.log.info(self.name+" ::::::")
862 main.log.error( traceback.print_exc())
863 main.log.info(self.name+" ::::::")
864 main.cleanup()
865 main.exit()
866
andrewonlab3f0a4af2014-10-17 12:25:14 -0400867
868 def get_hosts_id(self, host_list):
869 '''
870 Obtain list of hosts
871 Issues command: 'onos> hosts'
872
873 Required:
874 * host_list: List of hosts obtained by Mininet
875 IMPORTANT:
876 This function assumes that you started your
877 topology with the option '--mac'.
878 Furthermore, it assumes that value of VLAN is '-1'
879 Description:
880 Converts mininet hosts (h1, h2, h3...) into
881 ONOS format (00:00:00:00:00:01/-1 , ...)
882 '''
883
884 try:
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 onos_host_list = []
886
887 for host in host_list:
888 host = host.replace("h", "")
889 host_hex = hex(int(host)).zfill(12)
890 host_hex = str(host_hex).replace('x','0')
891 i = iter(str(host_hex))
892 host_hex = ":".join(a+b for a,b in zip(i,i))
893 host_hex = host_hex + "/-1"
894 onos_host_list.append(host_hex)
895
896 return onos_host_list
897
898 except pexpect.EOF:
899 main.log.error(self.name + ": EOF exception found")
900 main.log.error(self.name + ": " + self.handle.before)
901 main.cleanup()
902 main.exit()
903 except:
904 main.log.info(self.name+" ::::::")
905 main.log.error( traceback.print_exc())
906 main.log.info(self.name+" ::::::")
907 main.cleanup()
908 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400909
andrewonlabe6745342014-10-17 14:29:13 -0400910 def add_host_intent(self, host_id_one, host_id_two):
911 '''
912 Required:
913 * host_id_one: ONOS host id for host1
914 * host_id_two: ONOS host id for host2
915 Description:
916 Adds a host-to-host intent (bidrectional) by
Jon Hallb1290e82014-11-18 16:17:48 -0500917 specifying the two hosts.
andrewonlabe6745342014-10-17 14:29:13 -0400918 '''
919 try:
920 self.handle.sendline("")
921 self.handle.expect("onos>")
Jon Hallb1290e82014-11-18 16:17:48 -0500922
andrewonlabe6745342014-10-17 14:29:13 -0400923 self.handle.sendline("add-host-intent "+
924 str(host_id_one) + " " + str(host_id_two))
925 self.handle.expect("onos>")
926
andrewonlabe6745342014-10-17 14:29:13 -0400927 handle = self.handle.before
Shreya Shah4f25fdf2014-10-29 19:55:35 -0400928 print "handle =", handle
andrewonlabe6745342014-10-17 14:29:13 -0400929
930 main.log.info("Intent installed between "+
931 str(host_id_one) + " and " + str(host_id_two))
932
933 return handle
Jon Hallb1290e82014-11-18 16:17:48 -0500934
andrewonlabe6745342014-10-17 14:29:13 -0400935 except pexpect.EOF:
936 main.log.error(self.name + ": EOF exception found")
937 main.log.error(self.name + ": " + self.handle.before)
938 main.cleanup()
939 main.exit()
940 except:
941 main.log.info(self.name+" ::::::")
942 main.log.error( traceback.print_exc())
943 main.log.info(self.name+" ::::::")
944 main.cleanup()
945 main.exit()
946
andrewonlab7b31d232014-10-24 13:31:47 -0400947 def add_optical_intent(self, ingress_device, egress_device):
948 '''
949 Required:
950 * ingress_device: device id of ingress device
951 * egress_device: device id of egress device
952 Optional:
953 TODO: Still needs to be implemented via dev side
954 '''
955 try:
956 self.handle.sendline("add-optical-intent "+
957 str(ingress_device) + " " + str(egress_device))
958 self.handle.expect("add-optical-intent")
959 i = self.handle.expect([
960 "Error",
961 "onos>"])
962
963 handle = self.handle.before
964
965 #If error, return error message
966 if i == 0:
967 return handle
968 else:
969 return main.TRUE
970
971 except pexpect.EOF:
972 main.log.error(self.name + ": EOF exception found")
973 main.log.error(self.name + ": " + self.handle.before)
974 main.cleanup()
975 main.exit()
976 except:
977 main.log.info(self.name+" ::::::")
978 main.log.error( traceback.print_exc())
979 main.log.info(self.name+" ::::::")
980 main.cleanup()
981 main.exit()
982
andrewonlab36af3822014-11-18 17:48:18 -0500983 def add_point_intent(self, ingress_device, egress_device,
984 port_ingress="", port_egress="", ethType="", ethSrc="",
andrewonlabfa4ff502014-11-11 16:41:30 -0500985 ethDst="", bandwidth="", lambda_alloc=False,
986 ipProto="", ipSrc="", ipDst="", tcpSrc="", tcpDst=""):
andrewonlab4dbb4d82014-10-17 18:22:31 -0400987 '''
988 Required:
989 * ingress_device: device id of ingress device
990 * egress_device: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -0400991 Optional:
992 * ethType: specify ethType
993 * ethSrc: specify ethSrc (i.e. src mac addr)
994 * ethDst: specify ethDst (i.e. dst mac addr)
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500995 * bandwidth: specify bandwidth capacity of link
andrewonlab40ccd8b2014-11-06 16:23:34 -0500996 * lambda_alloc: if True, intent will allocate lambda
997 for the specified intent
andrewonlabf77e0cb2014-11-11 17:17:59 -0500998 * ipProto: specify ip protocol
999 * ipSrc: specify ip source address
1000 * ipDst: specify ip destination address
1001 * tcpSrc: specify tcp source port
1002 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001003 Description:
1004 Adds a point-to-point intent (uni-directional) by
andrewonlab289e4b72014-10-21 21:24:18 -04001005 specifying device id's and optional fields
1006
andrewonlab4dbb4d82014-10-17 18:22:31 -04001007 NOTE: This function may change depending on the
1008 options developers provide for point-to-point
1009 intent via cli
1010 '''
1011 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001012 cmd = ""
1013
1014 #If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001015 if not ethType and not ethSrc and not ethDst\
andrewonlabfa4ff502014-11-11 16:41:30 -05001016 and not bandwidth and not lambda_alloc \
1017 and not ipProto and not ipSrc and not ipDst \
1018 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001019 cmd = "add-point-intent"
1020
1021
andrewonlab289e4b72014-10-21 21:24:18 -04001022 else:
andrewonlab36af3822014-11-18 17:48:18 -05001023 cmd = "add-point-intent"
andrewonlab9a130be2014-10-22 12:44:56 -04001024
andrewonlab0c0a6772014-10-22 12:31:18 -04001025 if ethType:
andrewonlab289e4b72014-10-21 21:24:18 -04001026 cmd += " --ethType " + str(ethType)
1027 if ethSrc:
1028 cmd += " --ethSrc " + str(ethSrc)
1029 if ethDst:
1030 cmd += " --ethDst " + str(ethDst)
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001031 if bandwidth:
1032 cmd += " --bandwidth " + str(bandwidth)
1033 if lambda_alloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001034 cmd += " --lambda "
1035 if ipProto:
1036 cmd += " --ipProto " + str(ipProto)
1037 if ipSrc:
1038 cmd += " --ipSrc " + str(ipSrc)
1039 if ipDst:
1040 cmd += " --ipDst " + str(ipDst)
1041 if tcpSrc:
1042 cmd += " --tcpSrc " + str(tcpSrc)
1043 if tcpDst:
1044 cmd += " --tcpDst " + str(tcpDst)
andrewonlab289e4b72014-10-21 21:24:18 -04001045
andrewonlab36af3822014-11-18 17:48:18 -05001046 #Check whether the user appended the port
1047 #or provided it as an input
1048 if "/" in ingress_device:
1049 cmd += " "+str(ingress_device)
1050 else:
1051 if not port_ingress:
1052 main.log.error("You must specify "+
1053 "the ingress port")
1054 #TODO: perhaps more meaningful return
1055 return main.FALSE
1056
1057 cmd += " "+ \
1058 str(ingress_device) + "/" +\
1059 str(port_ingress) + " "
1060
1061 if "/" in egress_device:
1062 cmd += " "+str(egress_device)
1063 else:
1064 if not port_egress:
1065 main.log.error("You must specify "+
1066 "the egress port")
1067 return main.FALSE
1068
1069 cmd += " "+\
1070 str(egress_device) + "/" +\
1071 str(port_egress)
andrewonlab4dbb4d82014-10-17 18:22:31 -04001072
andrewonlab289e4b72014-10-21 21:24:18 -04001073 self.handle.sendline(cmd)
andrewonlab36af3822014-11-18 17:48:18 -05001074
1075 main.log.info(cmd + " sent")
andrewonlab4dbb4d82014-10-17 18:22:31 -04001076 i = self.handle.expect([
1077 "Error",
1078 "onos>"])
andrewonlab4dbb4d82014-10-17 18:22:31 -04001079
1080 if i == 0:
1081 main.log.error("Error in adding point-to-point intent")
1082 return handle
1083 else:
1084 return main.TRUE
andrewonlab289e4b72014-10-21 21:24:18 -04001085
andrewonlab4dbb4d82014-10-17 18:22:31 -04001086 except pexpect.EOF:
1087 main.log.error(self.name + ": EOF exception found")
1088 main.log.error(self.name + ": " + self.handle.before)
1089 main.cleanup()
1090 main.exit()
1091 except:
1092 main.log.info(self.name+" ::::::")
1093 main.log.error( traceback.print_exc())
1094 main.log.info(self.name+" ::::::")
1095 main.cleanup()
1096 main.exit()
1097
andrewonlab9a50dfe2014-10-17 17:22:31 -04001098 def remove_intent(self, intent_id):
1099 '''
1100 Remove intent for specified intent id
1101 '''
1102 try:
1103 self.handle.sendline("")
1104 self.handle.expect("onos>")
1105
1106 self.handle.sendline("remove-intent "+str(intent_id))
1107 i = self.handle.expect([
1108 "Error",
1109 "onos>"])
1110
1111 handle = self.handle.before
1112
1113 if i == 0:
1114 main.log.error("Error in removing intent")
1115 return handle
1116 else:
1117 return handle
1118
1119 except pexpect.EOF:
1120 main.log.error(self.name + ": EOF exception found")
1121 main.log.error(self.name + ": " + self.handle.before)
1122 main.cleanup()
1123 main.exit()
1124 except:
1125 main.log.info(self.name+" ::::::")
1126 main.log.error( traceback.print_exc())
1127 main.log.info(self.name+" ::::::")
1128 main.cleanup()
1129 main.exit()
1130
pingping-lindabe7972014-11-17 19:29:44 -08001131 # This method should be used after installing application: onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001132 def routes(self, json_format=False):
1133 '''
1134 Optional:
1135 * json_format: enable output formatting in json
1136 Description:
1137 Obtain all routes in the system
1138 '''
1139 try:
1140 if json_format:
1141 self.handle.sendline("routes -j")
1142 self.handle.expect("routes -j")
1143 self.handle.expect("onos>")
1144 handle_tmp = self.handle.before
1145
1146 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1147 handle = ansi_escape.sub('', handle_tmp)
1148
1149 else:
1150 self.handle.sendline("")
1151 self.handle.expect("onos>")
1152
1153 self.handle.sendline("routes")
1154 self.handle.expect("onos>")
1155 handle = self.handle.before
1156
1157 return handle
1158
1159 except pexpect.EOF:
1160 main.log.error(self.name + ": EOF exception found")
1161 main.log.error(self.name + ": " + self.handle.before)
1162 main.cleanup()
1163 main.exit()
1164 except:
1165 main.log.info(self.name + " ::::::")
1166 main.log.error(traceback.print_exc())
1167 main.log.info(self.name + " ::::::")
1168 main.cleanup()
1169 main.exit()
1170
andrewonlab377693f2014-10-21 16:00:30 -04001171 def intents(self, json_format = False):
andrewonlabe6745342014-10-17 14:29:13 -04001172 '''
andrewonlab377693f2014-10-21 16:00:30 -04001173 Optional:
1174 * json_format: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001175 Description:
1176 Obtain intents currently installed
1177 '''
1178 try:
andrewonlab377693f2014-10-21 16:00:30 -04001179 if json_format:
1180 self.handle.sendline("intents -j")
1181 self.handle.expect("intents -j")
1182 self.handle.expect("onos>")
andrewonlab377693f2014-10-21 16:00:30 -04001183 handle = self.handle.before
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001184
1185 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1186 handle = ansi_escape.sub('', handle)
andrewonlab377693f2014-10-21 16:00:30 -04001187 else:
1188 self.handle.sendline("")
1189 self.handle.expect("onos>")
andrewonlabe6745342014-10-17 14:29:13 -04001190
andrewonlab377693f2014-10-21 16:00:30 -04001191 self.handle.sendline("intents")
1192 self.handle.expect("onos>")
andrewonlab377693f2014-10-21 16:00:30 -04001193 handle = self.handle.before
andrewonlabe6745342014-10-17 14:29:13 -04001194
1195 return handle
1196
1197 except pexpect.EOF:
1198 main.log.error(self.name + ": EOF exception found")
1199 main.log.error(self.name + ": " + self.handle.before)
1200 main.cleanup()
1201 main.exit()
1202 except:
1203 main.log.info(self.name+" ::::::")
1204 main.log.error( traceback.print_exc())
1205 main.log.info(self.name+" ::::::")
1206 main.cleanup()
1207 main.exit()
1208
Shreya Shah0f01c812014-10-26 20:15:28 -04001209 def flows(self, json_format = False):
1210 '''
1211 Optional:
1212 * json_format: enable output formatting in json
1213 Description:
1214 Obtain flows currently installed
1215 '''
1216 try:
1217 if json_format:
1218 self.handle.sendline("flows -j")
1219 self.handle.expect("flows -j")
1220 self.handle.expect("onos>")
1221 handle = self.handle.before
Jon Hallb1290e82014-11-18 16:17:48 -05001222 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1223 handle = ansi_escape.sub('', handle)
Shreya Shah0f01c812014-10-26 20:15:28 -04001224
1225 else:
1226 self.handle.sendline("")
1227 self.handle.expect("onos>")
1228 self.handle.sendline("flows")
1229 self.handle.expect("onos>")
1230 handle = self.handle.before
Jon Hallb1290e82014-11-18 16:17:48 -05001231 if re.search("Error\sexecuting\scommand:", handle):
1232 main.log.error(self.name + ".flows() response: " + str(handle))
Shreya Shah0f01c812014-10-26 20:15:28 -04001233
1234 return handle
1235
1236 except pexpect.EOF:
1237 main.log.error(self.name + ": EOF exception found")
1238 main.log.error(self.name + ": " + self.handle.before)
1239 main.cleanup()
1240 main.exit()
1241 except:
1242 main.log.info(self.name+" ::::::")
1243 main.log.error( traceback.print_exc())
1244 main.log.info(self.name+" ::::::")
1245 main.cleanup()
1246 main.exit()
1247
andrewonlab87852b02014-11-19 18:44:19 -05001248 def push_test_intents(self, dpid_src, dpid_dst, num_intents,
1249 report=True):
1250 '''
1251 Description:
1252 Push a number of intents in a batch format to
1253 a specific point-to-point intent definition
1254 Required:
1255 * dpid_src: specify source dpid
1256 * dpid_dst: specify destination dpid
1257 * num_intents: specify number of intents to push
1258 Optional:
1259 * report: default True, returns latency information
1260 '''
1261 try:
1262 cmd = "push-test-intents "+\
1263 str(dpid_src)+" "+str(dpid_dst)+" "+\
1264 str(num_intents)
1265 self.handle.sendline(cmd)
1266 self.handle.expect(cmd)
1267 self.handle.expect("onos>")
1268
1269 handle = self.handle.before
1270
1271 #Some color thing that we want to escape
1272 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1273 handle = ansi_escape.sub('', handle)
1274
1275 if report:
1276 main.log.info(handle)
1277 return handle
1278 else:
1279 return main.TRUE
1280
1281 except pexpect.EOF:
1282 main.log.error(self.name + ": EOF exception found")
1283 main.log.error(self.name + ": " + self.handle.before)
1284 main.cleanup()
1285 main.exit()
1286 except:
1287 main.log.info(self.name+" ::::::")
1288 main.log.error( traceback.print_exc())
1289 main.log.info(self.name+" ::::::")
1290 main.cleanup()
1291 main.exit()
1292
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001293 def intents_events_metrics(self, json_format=True):
1294 '''
1295 Description:Returns topology metrics
1296 Optional:
1297 * json_format: enable json formatting of output
1298 '''
1299 try:
1300 if json_format:
1301 self.handle.sendline("intents-events-metrics -j")
1302 self.handle.expect("intents-events-metrics -j")
1303 self.handle.expect("onos>")
1304
1305 handle = self.handle.before
1306
1307 #Some color thing that we want to escape
1308 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1309 handle = ansi_escape.sub('', handle)
1310
1311 else:
1312 self.handle.sendline("intents-events-metrics")
1313 self.handle.expect("intents-events-metrics")
1314 self.handle.expect("onos>")
1315
1316 handle = self.handle.before
Shreya Shah0f01c812014-10-26 20:15:28 -04001317
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001318 return handle
1319
1320 except pexpect.EOF:
1321 main.log.error(self.name + ": EOF exception found")
1322 main.log.error(self.name + ": " + self.handle.before)
1323 main.cleanup()
1324 main.exit()
1325 except:
1326 main.log.info(self.name+" ::::::")
1327 main.log.error( traceback.print_exc())
1328 main.log.info(self.name+" ::::::")
1329 main.cleanup()
1330 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001331
andrewonlab867212a2014-10-22 20:13:38 -04001332 def topology_events_metrics(self, json_format=True):
1333 '''
1334 Description:Returns topology metrics
1335 Optional:
1336 * json_format: enable json formatting of output
1337 '''
1338 try:
1339 if json_format:
1340 self.handle.sendline("topology-events-metrics -j")
1341 self.handle.expect("topology-events-metrics -j")
1342 self.handle.expect("onos>")
1343
1344 handle = self.handle.before
1345
1346 #Some color thing that we want to escape
1347 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1348 handle = ansi_escape.sub('', handle)
1349
1350 else:
1351 self.handle.sendline("topology-events-metrics")
1352 self.handle.expect("topology-events-metrics")
1353 self.handle.expect("onos>")
1354
1355 handle = self.handle.before
1356
1357 return handle
1358
1359 except pexpect.EOF:
1360 main.log.error(self.name + ": EOF exception found")
1361 main.log.error(self.name + ": " + self.handle.before)
1362 main.cleanup()
1363 main.exit()
1364 except:
1365 main.log.info(self.name+" ::::::")
1366 main.log.error( traceback.print_exc())
1367 main.log.info(self.name+" ::::::")
1368 main.cleanup()
1369 main.exit()
1370
andrewonlab3e15ead2014-10-15 14:21:34 -04001371 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -04001372 #Wrapper functions use existing driver
1373 #functions and extends their use case.
1374 #For example, we may use the output of
1375 #a normal driver function, and parse it
1376 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001377
andrewonlab9a50dfe2014-10-17 17:22:31 -04001378 def get_all_intents_id(self):
1379 '''
1380 Description:
1381 Obtain all intent id's in a list
1382 '''
1383 try:
1384 #Obtain output of intents function
1385 intents_str = self.intents()
1386 all_intent_list = []
1387 intent_id_list = []
1388
1389 #Parse the intents output for ID's
1390 intents_list = [s.strip() for s in intents_str.splitlines()]
1391 for intents in intents_list:
1392 if "onos>" in intents:
1393 continue
1394 elif "intents" in intents:
1395 continue
1396 else:
1397 line_list = intents.split(" ")
1398 all_intent_list.append(line_list[0])
1399
1400 all_intent_list = all_intent_list[1:-2]
1401
1402 for intents in all_intent_list:
1403 if not intents:
1404 continue
1405 else:
1406 intent_id_list.append(intents)
1407
1408 return intent_id_list
1409
1410 except pexpect.EOF:
1411 main.log.error(self.name + ": EOF exception found")
1412 main.log.error(self.name + ": " + self.handle.before)
1413 main.cleanup()
1414 main.exit()
1415 except:
1416 main.log.info(self.name+" ::::::")
1417 main.log.error( traceback.print_exc())
1418 main.log.info(self.name+" ::::::")
1419 main.cleanup()
1420 main.exit()
1421
andrewonlab7e4d2d32014-10-15 13:23:21 -04001422 def get_all_devices_id(self):
1423 '''
1424 Use 'devices' function to obtain list of all devices
1425 and parse the result to obtain a list of all device
1426 id's. Returns this list. Returns empty list if no
1427 devices exist
1428 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -04001429
1430 This function may be useful if you are not sure of the
1431 device id, and wish to execute other commands using
1432 the ids. By obtaining the list of device ids on the fly,
1433 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -04001434 '''
1435 try:
1436 #Call devices and store result string
andrewonlab9a50dfe2014-10-17 17:22:31 -04001437 devices_str = self.devices(json_format=False)
andrewonlab7e4d2d32014-10-15 13:23:21 -04001438 id_list = []
1439
1440 if not devices_str:
1441 main.log.info("There are no devices to get id from")
1442 return id_list
1443
1444 #Split the string into list by comma
1445 device_list = devices_str.split(",")
1446 #Get temporary list of all arguments with string 'id='
1447 temp_list = [dev for dev in device_list if "id=" in dev]
1448 #Split list further into arguments before and after string
1449 # 'id='. Get the latter portion (the actual device id) and
1450 # append to id_list
1451 for arg in temp_list:
1452 id_list.append(arg.split("id=")[1])
andrewonlab7e4d2d32014-10-15 13:23:21 -04001453 return id_list
1454
1455 except pexpect.EOF:
1456 main.log.error(self.name + ": EOF exception found")
1457 main.log.error(self.name + ": " + self.handle.before)
1458 main.cleanup()
1459 main.exit()
1460 except:
1461 main.log.info(self.name+" ::::::")
1462 main.log.error( traceback.print_exc())
1463 main.log.info(self.name+" ::::::")
1464 main.cleanup()
1465 main.exit()
1466
andrewonlab7c211572014-10-15 16:45:20 -04001467 def get_all_nodes_id(self):
1468 '''
1469 Uses 'nodes' function to obtain list of all nodes
1470 and parse the result of nodes to obtain just the
1471 node id's.
1472 Returns:
1473 list of node id's
1474 '''
1475 try:
1476 nodes_str = self.nodes()
1477 id_list = []
1478
1479 if not nodes_str:
1480 main.log.info("There are no nodes to get id from")
1481 return id_list
1482
1483 #Sample nodes_str output
1484 #id=local, address=127.0.0.1:9876, state=ACTIVE *
1485
1486 #Split the string into list by comma
1487 nodes_list = nodes_str.split(",")
1488 temp_list = [node for node in nodes_list if "id=" in node]
1489 for arg in temp_list:
1490 id_list.append(arg.split("id=")[1])
1491
1492 return id_list
1493
1494 except pexpect.EOF:
1495 main.log.error(self.name + ": EOF exception found")
1496 main.log.error(self.name + ": " + self.handle.before)
1497 main.cleanup()
1498 main.exit()
1499 except:
1500 main.log.info(self.name+" ::::::")
1501 main.log.error( traceback.print_exc())
1502 main.log.info(self.name+" ::::::")
1503 main.cleanup()
1504 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001505
Jon Halla91c4dc2014-10-22 12:57:04 -04001506 def get_device(self, dpid=None):
1507 '''
1508 Return the first device from the devices api whose 'id' contains 'dpid'
1509 Return None if there is no match
1510 '''
1511 import json
1512 try:
1513 if dpid == None:
1514 return None
1515 else:
1516 dpid = dpid.replace(':', '')
1517 raw_devices = self.devices()
1518 devices_json = json.loads(raw_devices)
1519 #search json for the device with dpid then return the device
1520 for device in devices_json:
1521 #print "%s in %s?" % (dpid, device['id'])
1522 if dpid in device['id']:
1523 return device
1524 return None
1525 except pexpect.EOF:
1526 main.log.error(self.name + ": EOF exception found")
1527 main.log.error(self.name + ": " + self.handle.before)
1528 main.cleanup()
1529 main.exit()
1530 except:
1531 main.log.info(self.name+" ::::::")
1532 main.log.error( traceback.print_exc())
1533 main.log.info(self.name+" ::::::")
1534 main.cleanup()
1535 main.exit()
1536
Jon Hall42db6dc2014-10-24 19:03:48 -04001537 def check_status(self, ip, numoswitch, numolink, log_level="info"):
1538 '''
1539 Checks the number of swithes & links that ONOS sees against the
1540 supplied values. By default this will report to main.log, but the
1541 log level can be specifid.
1542
1543 Params: ip = ip used for the onos cli
1544 numoswitch = expected number of switches
1545 numlink = expected number of links
1546 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
1547
1548
1549 log_level can
1550
1551 Returns: main.TRUE if the number of switchs and links are correct,
1552 main.FALSE if the numer of switches and links is incorrect,
1553 and main.ERROR otherwise
1554 '''
1555
1556 try:
1557 topology = self.get_topology(ip)
1558 if topology == {}:
1559 return main.ERROR
1560 output = ""
1561 #Is the number of switches is what we expected
1562 devices = topology.get('devices',False)
1563 links = topology.get('links',False)
1564 if devices == False or links == False:
1565 return main.ERROR
1566 switch_check = ( int(devices) == int(numoswitch) )
1567 #Is the number of links is what we expected
1568 link_check = ( int(links) == int(numolink) )
1569 if (switch_check and link_check):
1570 #We expected the correct numbers
1571 output = output + "The number of links and switches match "\
1572 + "what was expected"
1573 result = main.TRUE
1574 else:
1575 output = output + \
1576 "The number of links and switches does not match what was expected"
1577 result = main.FALSE
1578 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
1579 % ( int(devices), int(numoswitch), int(links), int(numolink) )
1580 if log_level == "report":
1581 main.log.report(output)
1582 elif log_level == "warn":
1583 main.log.warn(output)
1584 else:
1585 main.log.info(output)
1586 return result
1587 except pexpect.EOF:
1588 main.log.error(self.name + ": EOF exception found")
1589 main.log.error(self.name + ": " + self.handle.before)
1590 main.cleanup()
1591 main.exit()
1592 except:
1593 main.log.info(self.name+" ::::::")
1594 main.log.error( traceback.print_exc())
1595 main.log.info(self.name+" ::::::")
1596 main.cleanup()
1597 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001598
1599 def device_role(self, device_id, onos_node, role="master"):
1600 '''
1601 Calls the device-role cli command.
1602 device_id must be the id of a device as seen in the onos devices command
1603 onos_node is the ip of one of the onos nodes in the cluster
1604 role must be either master, standby, or none
1605
Jon Hall983a1702014-10-28 18:44:22 -04001606 Returns main.TRUE or main.FALSE based argument varification.
1607 When device-role supports errors this should be extended to
Jon Hall1c9e8732014-10-27 19:29:27 -04001608 support that output
1609 '''
Jon Hall1c9e8732014-10-27 19:29:27 -04001610 try:
Jon Hall983a1702014-10-28 18:44:22 -04001611 #print "beginning device_role... \n\tdevice_id:" + device_id
1612 #print "\tonos_node: " + onos_node
1613 #print "\trole: "+ role
Jon Hall1c9e8732014-10-27 19:29:27 -04001614 if role.lower() == "master" or \
1615 role.lower() == "standby" or \
1616 role.lower() == "none":
1617 self.handle.sendline("")
1618 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -04001619 self.handle.sendline("device-role " +
1620 str(device_id) + " " +
1621 str(onos_node) + " " +
1622 str(role))
1623 i= self.handle.expect(["Error","onos>"])
1624 if i == 0:
1625 output = str(self.handle.before)
1626 self.handle.expect("onos>")
1627 output = output + str(self.handle.before)
1628 main.log.error(self.name + ": " +
1629 output + '\033[0m')#end color output to escape any colours from the cli
1630 return main.ERROR
1631 self.handle.sendline("")
Jon Hall1c9e8732014-10-27 19:29:27 -04001632 self.handle.expect("onos>")
1633 return main.TRUE
1634 else:
1635 return main.FALSE
1636
1637 except pexpect.EOF:
1638 main.log.error(self.name + ": EOF exception found")
1639 main.log.error(self.name + ": " + self.handle.before)
1640 main.cleanup()
1641 main.exit()
1642 except:
1643 main.log.info(self.name+" ::::::")
1644 main.log.error( traceback.print_exc())
1645 main.log.info(self.name+" ::::::")
1646 main.cleanup()
1647 main.exit()
1648
Jon Hall73cf9cc2014-11-20 22:28:38 -08001649 def clusters(self, json_format=True):
1650 '''
1651 Lists all clusters
1652 '''
1653 try:
1654 self.handle.sendline("")
1655 self.handle.expect("onos>")
1656
1657 if json_format:
1658 self.handle.sendline("clusters -j")
1659 self.handle.expect("clusters -j")
1660 self.handle.expect("onos>")
1661 handle = self.handle.before
1662 '''
1663 handle variable here contains some ANSI escape color code
1664 sequences at the end which are invisible in the print command
1665 output. To make that escape sequence visible, use repr() function.
1666 The repr(handle) output when printed shows the ANSI escape sequences.
1667 In json.loads(somestring), this somestring variable is actually
1668 repr(somestring) and json.loads would fail with the escape sequence.
1669 So we take off that escape sequence using
1670 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1671 handle1 = ansi_escape.sub('', handle)
1672 '''
1673 #print "repr(handle) =", repr(handle)
1674 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1675 handle1 = ansi_escape.sub('', handle)
1676 #print "repr(handle1) = ", repr(handle1)
1677 return handle1
1678 else:
1679 self.handle.sendline("links")
1680 self.handle.expect("onos>")
1681 handle = self.handle.before
1682 #print "handle =",handle
1683 return handle
1684 except pexpect.EOF:
1685 main.log.error(self.name + ": EOF exception found")
1686 main.log.error(self.name + ": " + self.handle.before)
1687 main.cleanup()
1688 main.exit()
1689 except:
1690 main.log.info(self.name+" ::::::")
1691 main.log.error( traceback.print_exc())
1692 main.log.info(self.name+" ::::::")
1693 main.cleanup()
1694 main.exit()
1695
Jon Hall1c9e8732014-10-27 19:29:27 -04001696
andrewonlab7e4d2d32014-10-15 13:23:21 -04001697 #***********************************