blob: 4916ba5c11091955f0e816c7c73cceb1d258c0ce [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("\$")
Jon Hallffb386d2014-11-21 13:43:38 -080093 self.handle.sendline("")
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...")
Jon Hallffb386d2014-11-21 13:43:38 -0800197 self.handle.send("\x03")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400198 self.handle.sendline("onos -w "+str(ONOS_ip))
199 i = self.handle.expect(["onos>",pexpect.TIMEOUT],
200 timeout=30)
201 if i == 0:
andrewonlab28ca4b22014-11-20 13:15:59 -0500202 main.log.info(str(ONOS_ip)+" CLI Started "+
203 "successfully after retry attempt")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400204 return main.TRUE
205 else:
206 main.log.error("Connection to CLI "+\
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400207 str(ONOS_ip)+" timeout")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400208 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400209
210 except pexpect.EOF:
211 main.log.error(self.name + ": EOF exception found")
212 main.log.error(self.name + ": " + self.handle.before)
213 main.cleanup()
214 main.exit()
215 except:
216 main.log.info(self.name+" ::::::")
217 main.log.error( traceback.print_exc())
218 main.log.info(self.name+" ::::::")
219 main.cleanup()
220 main.exit()
221
andrewonlaba18f6bf2014-10-13 19:31:54 -0400222 def sendline(self, cmd_str):
223 '''
224 Send a completely user specified string to
225 the onos> prompt. Use this function if you have
226 a very specific command to send.
227
228 Warning: There are no sanity checking to commands
229 sent using this method.
230 '''
231 try:
232 self.handle.sendline("")
233 self.handle.expect("onos>")
234
235 self.handle.sendline(cmd_str)
236 self.handle.expect("onos>")
237
238 handle = self.handle.before
239
240 self.handle.sendline("")
241 self.handle.expect("onos>")
242
243 handle += self.handle.before
244 handle += self.handle.after
245
246 main.log.info("Command sent.")
Jon Hall42db6dc2014-10-24 19:03:48 -0400247 ansi_escape = re.compile(r'\x1b[^m]*m')
248 handle = ansi_escape.sub('', handle)
andrewonlaba18f6bf2014-10-13 19:31:54 -0400249
250 return handle
251 except pexpect.EOF:
252 main.log.error(self.name + ": EOF exception found")
253 main.log.error(self.name + ": " + self.handle.before)
254 main.cleanup()
255 main.exit()
256 except:
257 main.log.info(self.name+" ::::::")
258 main.log.error( traceback.print_exc())
259 main.log.info(self.name+" ::::::")
260 main.cleanup()
261 main.exit()
262
andrewonlab95ce8322014-10-13 14:12:04 -0400263 #IMPORTANT NOTE:
264 #For all cli commands, naming convention should match
265 #the cli command replacing ':' with '_'.
266 #Ex) onos:topology > onos_topology
267 # onos:links > onos_links
268 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400269
270 def add_node(self, node_id, ONOS_ip, tcp_port=""):
271 '''
272 Adds a new cluster node by ID and address information.
273 Required:
274 * node_id
275 * ONOS_ip
276 Optional:
277 * tcp_port
278 '''
279 try:
280 self.handle.sendline("")
281 self.handle.expect("onos>")
282
283 self.handle.sendline("add-node "+
284 str(node_id)+" "+
285 str(ONOS_ip)+" "+
286 str(tcp_port))
287
288 i = self.handle.expect([
289 "Error",
290 "onos>" ])
291
292 #Clear handle to get previous output
293 self.handle.sendline("")
294 self.handle.expect("onos>")
295
296 handle = self.handle.before
297
298 if i == 0:
299 main.log.error("Error in adding node")
300 main.log.error(handle)
301 return main.FALSE
302 else:
303 main.log.info("Node "+str(ONOS_ip)+" added")
304 return main.TRUE
305
306 except pexpect.EOF:
307 main.log.error(self.name + ": EOF exception found")
308 main.log.error(self.name + ": " + self.handle.before)
309 main.cleanup()
310 main.exit()
311 except:
312 main.log.info(self.name+" ::::::")
313 main.log.error( traceback.print_exc())
314 main.log.info(self.name+" ::::::")
315 main.cleanup()
316 main.exit()
317
andrewonlab86dc3082014-10-13 18:18:38 -0400318 def remove_node(self, node_id):
319 '''
320 Removes a cluster by ID
321 Issues command: 'remove-node [<node-id>]'
322 Required:
323 * node_id
324 '''
325 try:
326 self.handle.sendline("")
327 self.handle.expect("onos>")
328
329 self.handle.sendline("remove-node "+str(node_id))
330 self.handle.expect("onos>")
331
332 return main.TRUE
333
334 except pexpect.EOF:
335 main.log.error(self.name + ": EOF exception found")
336 main.log.error(self.name + ": " + self.handle.before)
337 main.cleanup()
338 main.exit()
339 except:
340 main.log.info(self.name+" ::::::")
341 main.log.error( traceback.print_exc())
342 main.log.info(self.name+" ::::::")
343 main.cleanup()
344 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400345
andrewonlab7c211572014-10-15 16:45:20 -0400346 def nodes(self):
347 '''
348 List the nodes currently visible
349 Issues command: 'nodes'
350 Returns: entire handle of list of nodes
351 '''
352 try:
353 self.handle.sendline("")
354 self.handle.expect("onos>")
355
356 self.handle.sendline("nodes")
357 self.handle.expect("onos>")
358
359 self.handle.sendline("")
360 self.handle.expect("onos>")
361
362 handle = self.handle.before
363
364 return handle
365
366 except pexpect.EOF:
367 main.log.error(self.name + ": EOF exception found")
368 main.log.error(self.name + ": " + self.handle.before)
369 main.cleanup()
370 main.exit()
371 except:
372 main.log.info(self.name+" ::::::")
373 main.log.error( traceback.print_exc())
374 main.log.info(self.name+" ::::::")
375 main.cleanup()
376 main.exit()
377
andrewonlab38d6ae22014-10-15 14:23:45 -0400378 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400379 '''
380 Shows the current state of the topology
381 by issusing command: 'onos> onos:topology'
382 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400383 try:
384 self.handle.sendline("")
385 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400386 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400387 self.handle.sendline("onos:topology")
388 self.handle.expect("onos>")
389
390 handle = self.handle.before
391
392 main.log.info("onos:topology returned: " +
393 str(handle))
394
395 return handle
396
397 except pexpect.EOF:
398 main.log.error(self.name + ": EOF exception found")
399 main.log.error(self.name + ": " + self.handle.before)
400 main.cleanup()
401 main.exit()
402 except:
403 main.log.info(self.name+" ::::::")
404 main.log.error( traceback.print_exc())
405 main.log.info(self.name+" ::::::")
406 main.cleanup()
407 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400408
409 def feature_install(self, feature_str):
410 '''
411 Installs a specified feature
412 by issuing command: 'onos> feature:install <feature_str>'
413 '''
414 try:
415 self.handle.sendline("")
416 self.handle.expect("onos>")
417
418 self.handle.sendline("feature:install "+str(feature_str))
419 self.handle.expect("onos>")
420
421 return main.TRUE
422
423 except pexpect.EOF:
424 main.log.error(self.name + ": EOF exception found")
425 main.log.error(self.name + ": " + self.handle.before)
andrewonlabbf225b02014-11-12 12:14:05 -0500426 main.log.report("Failed to install feature")
427 main.log.report("Exiting test")
andrewonlabc2d05aa2014-10-13 16:51:10 -0400428 main.cleanup()
429 main.exit()
430 except:
431 main.log.info(self.name+" ::::::")
432 main.log.error( traceback.print_exc())
andrewonlabbf225b02014-11-12 12:14:05 -0500433 main.log.report("Failed to install feature")
434 main.log.report("Exiting test")
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 main.log.info(self.name+" ::::::")
436 main.cleanup()
437 main.exit()
438
439 def feature_uninstall(self, feature_str):
440 '''
441 Uninstalls a specified feature
442 by issuing command: 'onos> feature:uninstall <feature_str>'
443 '''
444 try:
445 self.handle.sendline("")
446 self.handle.expect("onos>")
447
448 self.handle.sendline("feature:uninstall "+str(feature_str))
449 self.handle.expect("onos>")
450
451 return main.TRUE
452
453 except pexpect.EOF:
454 main.log.error(self.name + ": EOF exception found")
455 main.log.error(self.name + ": " + self.handle.before)
456 main.cleanup()
457 main.exit()
458 except:
459 main.log.info(self.name+" ::::::")
460 main.log.error( traceback.print_exc())
461 main.log.info(self.name+" ::::::")
462 main.cleanup()
463 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800464
465 def devices(self, json_format=True):
andrewonlab86dc3082014-10-13 18:18:38 -0400466 '''
Jon Hall7b02d952014-10-17 20:14:54 -0400467 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400468 Optional argument:
Jon Hallffb386d2014-11-21 13:43:38 -0800469 * json_format - boolean indicating if you want output in json
andrewonlab86dc3082014-10-13 18:18:38 -0400470 '''
471 try:
472 self.handle.sendline("")
473 self.handle.expect("onos>")
Jon Hallffb386d2014-11-21 13:43:38 -0800474
Jon Halle8217482014-10-17 13:49:14 -0400475 if json_format:
Jon Hallffb386d2014-11-21 13:43:38 -0800476 self.handle.sendline("devices -j")
477 self.handle.expect("devices -j")
478 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400479 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400480 '''
481 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
482 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 -0400483 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 -0400484 So we take off that escape sequence using
Jon Halld815ce42014-10-17 19:52:30 -0400485 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hall983a1702014-10-28 18:44:22 -0400486 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400487 '''
488 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400489 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
490 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400491 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400492 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400493 else:
Jon Hallffb386d2014-11-21 13:43:38 -0800494 self.handle.sendline("devices")
495 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400496 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400497 #print "handle =",handle
Jon Hallcd707292014-10-17 19:06:17 -0400498 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400499 except pexpect.EOF:
500 main.log.error(self.name + ": EOF exception found")
501 main.log.error(self.name + ": " + self.handle.before)
502 main.cleanup()
503 main.exit()
504 except:
505 main.log.info(self.name+" ::::::")
506 main.log.error( traceback.print_exc())
507 main.log.info(self.name+" ::::::")
508 main.cleanup()
509 main.exit()
510
Jon Hallffb386d2014-11-21 13:43:38 -0800511 def links(self, json_format=True):
Jon Halle8217482014-10-17 13:49:14 -0400512 '''
513 Lists all core links
514 Optional argument:
Jon Hallffb386d2014-11-21 13:43:38 -0800515 * json_format - boolean indicating if you want output in json
Jon Halle8217482014-10-17 13:49:14 -0400516 '''
517 try:
518 self.handle.sendline("")
519 self.handle.expect("onos>")
Jon Hallffb386d2014-11-21 13:43:38 -0800520
Jon Halle8217482014-10-17 13:49:14 -0400521 if json_format:
Jon Hallffb386d2014-11-21 13:43:38 -0800522 self.handle.sendline("links -j")
523 self.handle.expect("links -j")
524 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400525 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400526 '''
527 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
528 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 -0400529 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Hallffb386d2014-11-21 13:43:38 -0800530 So we take off that escape sequence using
Jon Halld815ce42014-10-17 19:52:30 -0400531 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hallffb386d2014-11-21 13:43:38 -0800532 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400533 '''
534 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400535 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
536 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400537 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400538 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400539 else:
Jon Hallffb386d2014-11-21 13:43:38 -0800540 self.handle.sendline("links")
541 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400542 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400543 #print "handle =",handle
Jon Halla001c392014-10-17 18:50:59 -0400544 return handle
Jon Halle8217482014-10-17 13:49:14 -0400545 except pexpect.EOF:
546 main.log.error(self.name + ": EOF exception found")
547 main.log.error(self.name + ": " + self.handle.before)
548 main.cleanup()
549 main.exit()
550 except:
551 main.log.info(self.name+" ::::::")
552 main.log.error( traceback.print_exc())
553 main.log.info(self.name+" ::::::")
554 main.cleanup()
555 main.exit()
556
557
Jon Hallffb386d2014-11-21 13:43:38 -0800558 def ports(self, json_format=True):
Jon Halle8217482014-10-17 13:49:14 -0400559 '''
560 Lists all ports
561 Optional argument:
Jon Hallffb386d2014-11-21 13:43:38 -0800562 * json_format - boolean indicating if you want output in json
Jon Halle8217482014-10-17 13:49:14 -0400563 '''
564 try:
565 self.handle.sendline("")
566 self.handle.expect("onos>")
Jon Hallffb386d2014-11-21 13:43:38 -0800567
Jon Halle8217482014-10-17 13:49:14 -0400568 if json_format:
Jon Hallffb386d2014-11-21 13:43:38 -0800569 self.handle.sendline("ports -j")
570 self.handle.expect("ports -j")
571 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400572 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400573 '''
574 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
575 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 -0400576 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Hallffb386d2014-11-21 13:43:38 -0800577 So we take off that escape sequence using the following commads:
Jon Halld815ce42014-10-17 19:52:30 -0400578 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hallffb386d2014-11-21 13:43:38 -0800579 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400580 '''
581 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400582 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
583 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400584 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400585 return handle1
586
Jon Halle8217482014-10-17 13:49:14 -0400587 else:
Jon Hallffb386d2014-11-21 13:43:38 -0800588 self.handle.sendline("ports")
589 self.handle.expect("onos>")
590 self.handle.sendline("")
591 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400592 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400593 #print "handle =",handle
Jon Hallffb386d2014-11-21 13:43:38 -0800594 return handle
Jon Halle8217482014-10-17 13:49:14 -0400595 except pexpect.EOF:
596 main.log.error(self.name + ": EOF exception found")
597 main.log.error(self.name + ": " + self.handle.before)
598 main.cleanup()
599 main.exit()
600 except:
601 main.log.info(self.name+" ::::::")
602 main.log.error( traceback.print_exc())
603 main.log.info(self.name+" ::::::")
604 main.cleanup()
605 main.exit()
606
607
Jon Hallffb386d2014-11-21 13:43:38 -0800608 def roles(self, json_format=True):
andrewonlab7c211572014-10-15 16:45:20 -0400609 '''
Jon Hall983a1702014-10-28 18:44:22 -0400610 Lists all devices and the controllers with roles assigned to them
611 Optional argument:
Jon Hallffb386d2014-11-21 13:43:38 -0800612 * json_format - boolean indicating if you want output in json
andrewonlab7c211572014-10-15 16:45:20 -0400613 '''
614 try:
615 self.handle.sendline("")
616 self.handle.expect("onos>")
Jon Hallb1290e82014-11-18 16:17:48 -0500617
Jon Hall983a1702014-10-28 18:44:22 -0400618 if json_format:
Jon Hallb1290e82014-11-18 16:17:48 -0500619 self.handle.sendline("roles -j")
620 self.handle.expect("roles -j")
621 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -0400622 handle = self.handle.before
623 '''
Jon Hallb1290e82014-11-18 16:17:48 -0500624 handle variable here contains some ANSI escape color code sequences at the
625 end which are invisible in the print command output. To make that escape
626 sequence visible, use repr() function. The repr(handle) output when printed
627 shows the ANSI escape sequences. In json.loads(somestring), this somestring
628 variable is actually repr(somestring) and json.loads would fail with the escape
629 sequence.
630
631 So we take off that escape sequence using the following commads:
Jon Hall983a1702014-10-28 18:44:22 -0400632 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hallb1290e82014-11-18 16:17:48 -0500633 handle1 = ansi_escape.sub('', handle)
Jon Hall983a1702014-10-28 18:44:22 -0400634 '''
635 #print "repr(handle) =", repr(handle)
636 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
637 handle1 = ansi_escape.sub('', handle)
638 #print "repr(handle1) = ", repr(handle1)
639 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400640
andrewonlab7c211572014-10-15 16:45:20 -0400641 else:
Jon Hallb1290e82014-11-18 16:17:48 -0500642 self.handle.sendline("roles")
643 self.handle.expect("onos>")
644 self.handle.sendline("")
645 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -0400646 handle = self.handle.before
647 #print "handle =",handle
Jon Hallffb386d2014-11-21 13:43:38 -0800648 return handle
Jon Hall983a1702014-10-28 18:44:22 -0400649 except pexpect.EOF:
650 main.log.error(self.name + ": EOF exception found")
651 main.log.error(self.name + ": " + self.handle.before)
652 main.cleanup()
653 main.exit()
654 except:
655 main.log.info(self.name+" ::::::")
656 main.log.error( traceback.print_exc())
657 main.log.info(self.name+" ::::::")
658 main.cleanup()
659 main.exit()
660
661 def get_role(self, device_id):
662 '''
663 Given the a string containing the json representation of the "roles" cli command and a
664 partial or whole device id, returns a json object containing the
665 roles output for the first device whose id contains "device_id"
666
667 Returns:
668 Dict of the role assignments for the given device or
669 None if not match
670 '''
671 try:
672 import json
673 if device_id == None:
674 return None
675 else:
676 raw_roles = self.roles()
677 roles_json = json.loads(raw_roles)
678 #search json for the device with id then return the device
679 for device in roles_json:
Jon Hall720653a2014-10-28 19:02:37 -0400680 #print device
Jon Hall983a1702014-10-28 18:44:22 -0400681 if str(device_id) in device['id']:
682 return device
683 return None
andrewonlab7c211572014-10-15 16:45:20 -0400684
andrewonlab86dc3082014-10-13 18:18:38 -0400685 except pexpect.EOF:
686 main.log.error(self.name + ": EOF exception found")
687 main.log.error(self.name + ": " + self.handle.before)
688 main.cleanup()
689 main.exit()
690 except:
691 main.log.info(self.name+" ::::::")
692 main.log.error( traceback.print_exc())
693 main.log.info(self.name+" ::::::")
694 main.cleanup()
695 main.exit()
andrewonlab2a6c9342014-10-16 13:40:15 -0400696
andrewonlab3e15ead2014-10-15 14:21:34 -0400697 def paths(self, src_id, dst_id):
698 '''
699 Returns string of paths, and the cost.
700 Issues command: onos:paths <src> <dst>
701 '''
702 try:
703 self.handle.sendline("")
704 self.handle.expect("onos>")
705
706 self.handle.sendline("onos:paths "+
707 str(src_id) + " " + str(dst_id))
708 i = self.handle.expect([
709 "Error",
710 "onos>"])
711
712 self.handle.sendline("")
713 self.handle.expect("onos>")
714
715 handle = self.handle.before
716
717 if i == 0:
718 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400719 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400720 else:
721 path = handle.split(";")[0]
722 cost = handle.split(";")[1]
723 return (path, cost)
724
725 except pexpect.EOF:
726 main.log.error(self.name + ": EOF exception found")
727 main.log.error(self.name + ": " + self.handle.before)
728 main.cleanup()
729 main.exit()
730 except:
731 main.log.info(self.name+" ::::::")
732 main.log.error( traceback.print_exc())
733 main.log.info(self.name+" ::::::")
734 main.cleanup()
735 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800736
737 def hosts(self, json_format=True):
Jon Hall42db6dc2014-10-24 19:03:48 -0400738 '''
Jon Hallffb386d2014-11-21 13:43:38 -0800739 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400740 Optional argument:
Jon Hallffb386d2014-11-21 13:43:38 -0800741 * json_format - boolean indicating if you want output in json
Jon Hall42db6dc2014-10-24 19:03:48 -0400742 '''
743 try:
744 self.handle.sendline("")
745 self.handle.expect("onos>")
Jon Hallffb386d2014-11-21 13:43:38 -0800746
Jon Hall42db6dc2014-10-24 19:03:48 -0400747 if json_format:
Jon Hallffb386d2014-11-21 13:43:38 -0800748 self.handle.sendline("hosts -j")
749 self.handle.expect("hosts -j")
750 self.handle.expect("onos>")
Jon Hall42db6dc2014-10-24 19:03:48 -0400751 handle = self.handle.before
752 '''
753 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
754 To make that escape sequence visible, use repr() function. The repr(handle) output when printed shows the ANSI escape sequences.
755 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Hallffb386d2014-11-21 13:43:38 -0800756 So we take off that escape sequence using
Jon Hall42db6dc2014-10-24 19:03:48 -0400757 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
Jon Hallffb386d2014-11-21 13:43:38 -0800758 handle1 = ansi_escape.sub('', handle)
Jon Hall42db6dc2014-10-24 19:03:48 -0400759 '''
760 #print "repr(handle) =", repr(handle)
761 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
762 handle1 = ansi_escape.sub('', handle)
763 #print "repr(handle1) = ", repr(handle1)
764 return handle1
765 else:
Jon Hallffb386d2014-11-21 13:43:38 -0800766 self.handle.sendline("hosts")
767 self.handle.expect("onos>")
Jon Hall42db6dc2014-10-24 19:03:48 -0400768 handle = self.handle.before
Jon Hall983a1702014-10-28 18:44:22 -0400769 #print "handle =",handle
Jon Hall42db6dc2014-10-24 19:03:48 -0400770 return handle
771 except pexpect.EOF:
772 main.log.error(self.name + ": EOF exception found")
773 main.log.error(self.name + ": " + self.handle.before)
774 main.cleanup()
775 main.exit()
776 except:
777 main.log.info(self.name+" ::::::")
778 main.log.error( traceback.print_exc())
779 main.log.info(self.name+" ::::::")
780 main.cleanup()
781 main.exit()
782
783 def get_host(self, mac):
784 '''
785 Return the first host from the hosts api whose 'id' contains 'mac'
786 Note: mac must be a colon seperated mac address, but could be a partial mac address
787 Return None if there is no match
788 '''
789 import json
790 try:
791 if mac == None:
792 return None
793 else:
794 mac = mac
795 raw_hosts = self.hosts()
796 hosts_json = json.loads(raw_hosts)
797 #search json for the host with mac then return the device
798 for host in hosts_json:
Jon Hall983a1702014-10-28 18:44:22 -0400799 #print "%s in %s?" % (mac, host['id'])
Jon Hall42db6dc2014-10-24 19:03:48 -0400800 if mac in host['id']:
801 return host
802 return None
803 except pexpect.EOF:
804 main.log.error(self.name + ": EOF exception found")
805 main.log.error(self.name + ": " + self.handle.before)
806 main.cleanup()
807 main.exit()
808 except:
809 main.log.info(self.name+" ::::::")
810 main.log.error( traceback.print_exc())
811 main.log.info(self.name+" ::::::")
812 main.cleanup()
813 main.exit()
814
andrewonlab3f0a4af2014-10-17 12:25:14 -0400815
816 def get_hosts_id(self, host_list):
817 '''
818 Obtain list of hosts
819 Issues command: 'onos> hosts'
820
821 Required:
822 * host_list: List of hosts obtained by Mininet
823 IMPORTANT:
824 This function assumes that you started your
825 topology with the option '--mac'.
826 Furthermore, it assumes that value of VLAN is '-1'
827 Description:
828 Converts mininet hosts (h1, h2, h3...) into
829 ONOS format (00:00:00:00:00:01/-1 , ...)
830 '''
831
832 try:
andrewonlab3f0a4af2014-10-17 12:25:14 -0400833 onos_host_list = []
834
835 for host in host_list:
836 host = host.replace("h", "")
837 host_hex = hex(int(host)).zfill(12)
838 host_hex = str(host_hex).replace('x','0')
839 i = iter(str(host_hex))
840 host_hex = ":".join(a+b for a,b in zip(i,i))
841 host_hex = host_hex + "/-1"
842 onos_host_list.append(host_hex)
843
844 return onos_host_list
845
846 except pexpect.EOF:
847 main.log.error(self.name + ": EOF exception found")
848 main.log.error(self.name + ": " + self.handle.before)
849 main.cleanup()
850 main.exit()
851 except:
852 main.log.info(self.name+" ::::::")
853 main.log.error( traceback.print_exc())
854 main.log.info(self.name+" ::::::")
855 main.cleanup()
856 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400857
andrewonlabe6745342014-10-17 14:29:13 -0400858 def add_host_intent(self, host_id_one, host_id_two):
859 '''
860 Required:
861 * host_id_one: ONOS host id for host1
862 * host_id_two: ONOS host id for host2
863 Description:
864 Adds a host-to-host intent (bidrectional) by
Jon Hallb1290e82014-11-18 16:17:48 -0500865 specifying the two hosts.
andrewonlabe6745342014-10-17 14:29:13 -0400866 '''
867 try:
868 self.handle.sendline("")
869 self.handle.expect("onos>")
Jon Hallb1290e82014-11-18 16:17:48 -0500870
andrewonlabe6745342014-10-17 14:29:13 -0400871 self.handle.sendline("add-host-intent "+
872 str(host_id_one) + " " + str(host_id_two))
873 self.handle.expect("onos>")
874
andrewonlabe6745342014-10-17 14:29:13 -0400875 handle = self.handle.before
Jon Hallffb386d2014-11-21 13:43:38 -0800876 #print "handle =", handle
andrewonlabe6745342014-10-17 14:29:13 -0400877
878 main.log.info("Intent installed between "+
879 str(host_id_one) + " and " + str(host_id_two))
880
881 return handle
Jon Hallb1290e82014-11-18 16:17:48 -0500882
andrewonlabe6745342014-10-17 14:29:13 -0400883 except pexpect.EOF:
884 main.log.error(self.name + ": EOF exception found")
885 main.log.error(self.name + ": " + self.handle.before)
886 main.cleanup()
887 main.exit()
888 except:
889 main.log.info(self.name+" ::::::")
890 main.log.error( traceback.print_exc())
891 main.log.info(self.name+" ::::::")
892 main.cleanup()
893 main.exit()
894
andrewonlab7b31d232014-10-24 13:31:47 -0400895 def add_optical_intent(self, ingress_device, egress_device):
896 '''
897 Required:
898 * ingress_device: device id of ingress device
899 * egress_device: device id of egress device
900 Optional:
901 TODO: Still needs to be implemented via dev side
902 '''
903 try:
904 self.handle.sendline("add-optical-intent "+
905 str(ingress_device) + " " + str(egress_device))
906 self.handle.expect("add-optical-intent")
907 i = self.handle.expect([
908 "Error",
909 "onos>"])
910
911 handle = self.handle.before
912
913 #If error, return error message
914 if i == 0:
915 return handle
916 else:
917 return main.TRUE
918
919 except pexpect.EOF:
920 main.log.error(self.name + ": EOF exception found")
921 main.log.error(self.name + ": " + self.handle.before)
922 main.cleanup()
923 main.exit()
924 except:
925 main.log.info(self.name+" ::::::")
926 main.log.error( traceback.print_exc())
927 main.log.info(self.name+" ::::::")
928 main.cleanup()
929 main.exit()
930
andrewonlab36af3822014-11-18 17:48:18 -0500931 def add_point_intent(self, ingress_device, egress_device,
932 port_ingress="", port_egress="", ethType="", ethSrc="",
andrewonlabfa4ff502014-11-11 16:41:30 -0500933 ethDst="", bandwidth="", lambda_alloc=False,
934 ipProto="", ipSrc="", ipDst="", tcpSrc="", tcpDst=""):
andrewonlab4dbb4d82014-10-17 18:22:31 -0400935 '''
936 Required:
937 * ingress_device: device id of ingress device
938 * egress_device: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -0400939 Optional:
940 * ethType: specify ethType
941 * ethSrc: specify ethSrc (i.e. src mac addr)
942 * ethDst: specify ethDst (i.e. dst mac addr)
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500943 * bandwidth: specify bandwidth capacity of link
andrewonlab40ccd8b2014-11-06 16:23:34 -0500944 * lambda_alloc: if True, intent will allocate lambda
945 for the specified intent
andrewonlabf77e0cb2014-11-11 17:17:59 -0500946 * ipProto: specify ip protocol
947 * ipSrc: specify ip source address
948 * ipDst: specify ip destination address
949 * tcpSrc: specify tcp source port
950 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -0400951 Description:
952 Adds a point-to-point intent (uni-directional) by
andrewonlab289e4b72014-10-21 21:24:18 -0400953 specifying device id's and optional fields
954
andrewonlab4dbb4d82014-10-17 18:22:31 -0400955 NOTE: This function may change depending on the
956 options developers provide for point-to-point
957 intent via cli
958 '''
959 try:
andrewonlab289e4b72014-10-21 21:24:18 -0400960 cmd = ""
961
962 #If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500963 if not ethType and not ethSrc and not ethDst\
andrewonlabfa4ff502014-11-11 16:41:30 -0500964 and not bandwidth and not lambda_alloc \
965 and not ipProto and not ipSrc and not ipDst \
966 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -0500967 cmd = "add-point-intent"
968
969
andrewonlab289e4b72014-10-21 21:24:18 -0400970 else:
andrewonlab36af3822014-11-18 17:48:18 -0500971 cmd = "add-point-intent"
andrewonlab9a130be2014-10-22 12:44:56 -0400972
andrewonlab0c0a6772014-10-22 12:31:18 -0400973 if ethType:
andrewonlab289e4b72014-10-21 21:24:18 -0400974 cmd += " --ethType " + str(ethType)
975 if ethSrc:
976 cmd += " --ethSrc " + str(ethSrc)
977 if ethDst:
978 cmd += " --ethDst " + str(ethDst)
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500979 if bandwidth:
980 cmd += " --bandwidth " + str(bandwidth)
981 if lambda_alloc:
andrewonlabfa4ff502014-11-11 16:41:30 -0500982 cmd += " --lambda "
983 if ipProto:
984 cmd += " --ipProto " + str(ipProto)
985 if ipSrc:
986 cmd += " --ipSrc " + str(ipSrc)
987 if ipDst:
988 cmd += " --ipDst " + str(ipDst)
989 if tcpSrc:
990 cmd += " --tcpSrc " + str(tcpSrc)
991 if tcpDst:
992 cmd += " --tcpDst " + str(tcpDst)
andrewonlab289e4b72014-10-21 21:24:18 -0400993
andrewonlab36af3822014-11-18 17:48:18 -0500994 #Check whether the user appended the port
995 #or provided it as an input
996 if "/" in ingress_device:
997 cmd += " "+str(ingress_device)
998 else:
999 if not port_ingress:
1000 main.log.error("You must specify "+
1001 "the ingress port")
1002 #TODO: perhaps more meaningful return
1003 return main.FALSE
1004
1005 cmd += " "+ \
1006 str(ingress_device) + "/" +\
1007 str(port_ingress) + " "
1008
1009 if "/" in egress_device:
1010 cmd += " "+str(egress_device)
1011 else:
1012 if not port_egress:
1013 main.log.error("You must specify "+
1014 "the egress port")
1015 return main.FALSE
1016
1017 cmd += " "+\
1018 str(egress_device) + "/" +\
1019 str(port_egress)
andrewonlab4dbb4d82014-10-17 18:22:31 -04001020
andrewonlab289e4b72014-10-21 21:24:18 -04001021 self.handle.sendline(cmd)
andrewonlab36af3822014-11-18 17:48:18 -05001022
1023 main.log.info(cmd + " sent")
andrewonlab4dbb4d82014-10-17 18:22:31 -04001024 i = self.handle.expect([
1025 "Error",
1026 "onos>"])
andrewonlab4dbb4d82014-10-17 18:22:31 -04001027
1028 if i == 0:
1029 main.log.error("Error in adding point-to-point intent")
1030 return handle
1031 else:
1032 return main.TRUE
andrewonlab289e4b72014-10-21 21:24:18 -04001033
andrewonlab4dbb4d82014-10-17 18:22:31 -04001034 except pexpect.EOF:
1035 main.log.error(self.name + ": EOF exception found")
1036 main.log.error(self.name + ": " + self.handle.before)
1037 main.cleanup()
1038 main.exit()
1039 except:
1040 main.log.info(self.name+" ::::::")
1041 main.log.error( traceback.print_exc())
1042 main.log.info(self.name+" ::::::")
1043 main.cleanup()
1044 main.exit()
1045
andrewonlab9a50dfe2014-10-17 17:22:31 -04001046 def remove_intent(self, intent_id):
1047 '''
1048 Remove intent for specified intent id
1049 '''
1050 try:
1051 self.handle.sendline("")
1052 self.handle.expect("onos>")
1053
1054 self.handle.sendline("remove-intent "+str(intent_id))
1055 i = self.handle.expect([
1056 "Error",
1057 "onos>"])
1058
1059 handle = self.handle.before
1060
1061 if i == 0:
1062 main.log.error("Error in removing intent")
1063 return handle
1064 else:
1065 return handle
1066
1067 except pexpect.EOF:
1068 main.log.error(self.name + ": EOF exception found")
1069 main.log.error(self.name + ": " + self.handle.before)
1070 main.cleanup()
1071 main.exit()
1072 except:
1073 main.log.info(self.name+" ::::::")
1074 main.log.error( traceback.print_exc())
1075 main.log.info(self.name+" ::::::")
1076 main.cleanup()
1077 main.exit()
1078
pingping-lindabe7972014-11-17 19:29:44 -08001079 # This method should be used after installing application: onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001080 def routes(self, json_format=False):
1081 '''
1082 Optional:
1083 * json_format: enable output formatting in json
1084 Description:
1085 Obtain all routes in the system
1086 '''
1087 try:
1088 if json_format:
1089 self.handle.sendline("routes -j")
1090 self.handle.expect("routes -j")
1091 self.handle.expect("onos>")
1092 handle_tmp = self.handle.before
1093
1094 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1095 handle = ansi_escape.sub('', handle_tmp)
1096
1097 else:
1098 self.handle.sendline("")
1099 self.handle.expect("onos>")
1100
1101 self.handle.sendline("routes")
1102 self.handle.expect("onos>")
1103 handle = self.handle.before
1104
1105 return handle
1106
1107 except pexpect.EOF:
1108 main.log.error(self.name + ": EOF exception found")
1109 main.log.error(self.name + ": " + self.handle.before)
1110 main.cleanup()
1111 main.exit()
1112 except:
1113 main.log.info(self.name + " ::::::")
1114 main.log.error(traceback.print_exc())
1115 main.log.info(self.name + " ::::::")
1116 main.cleanup()
1117 main.exit()
1118
Jon Hallffb386d2014-11-21 13:43:38 -08001119 def intents(self, json_format = True):
andrewonlabe6745342014-10-17 14:29:13 -04001120 '''
andrewonlab377693f2014-10-21 16:00:30 -04001121 Optional:
1122 * json_format: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001123 Description:
1124 Obtain intents currently installed
1125 '''
1126 try:
andrewonlab377693f2014-10-21 16:00:30 -04001127 if json_format:
1128 self.handle.sendline("intents -j")
1129 self.handle.expect("intents -j")
1130 self.handle.expect("onos>")
andrewonlab377693f2014-10-21 16:00:30 -04001131 handle = self.handle.before
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001132
1133 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1134 handle = ansi_escape.sub('', handle)
andrewonlab377693f2014-10-21 16:00:30 -04001135 else:
1136 self.handle.sendline("")
1137 self.handle.expect("onos>")
andrewonlabe6745342014-10-17 14:29:13 -04001138
andrewonlab377693f2014-10-21 16:00:30 -04001139 self.handle.sendline("intents")
1140 self.handle.expect("onos>")
andrewonlab377693f2014-10-21 16:00:30 -04001141 handle = self.handle.before
andrewonlabe6745342014-10-17 14:29:13 -04001142
1143 return handle
1144
1145 except pexpect.EOF:
1146 main.log.error(self.name + ": EOF exception found")
1147 main.log.error(self.name + ": " + self.handle.before)
1148 main.cleanup()
1149 main.exit()
1150 except:
1151 main.log.info(self.name+" ::::::")
1152 main.log.error( traceback.print_exc())
1153 main.log.info(self.name+" ::::::")
1154 main.cleanup()
1155 main.exit()
1156
Jon Hallffb386d2014-11-21 13:43:38 -08001157 def flows(self, json_format = True):
Shreya Shah0f01c812014-10-26 20:15:28 -04001158 '''
1159 Optional:
1160 * json_format: enable output formatting in json
1161 Description:
1162 Obtain flows currently installed
1163 '''
1164 try:
1165 if json_format:
1166 self.handle.sendline("flows -j")
1167 self.handle.expect("flows -j")
1168 self.handle.expect("onos>")
1169 handle = self.handle.before
Jon Hallb1290e82014-11-18 16:17:48 -05001170 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1171 handle = ansi_escape.sub('', handle)
Shreya Shah0f01c812014-10-26 20:15:28 -04001172
1173 else:
1174 self.handle.sendline("")
1175 self.handle.expect("onos>")
1176 self.handle.sendline("flows")
1177 self.handle.expect("onos>")
1178 handle = self.handle.before
Jon Hallb1290e82014-11-18 16:17:48 -05001179 if re.search("Error\sexecuting\scommand:", handle):
1180 main.log.error(self.name + ".flows() response: " + str(handle))
Shreya Shah0f01c812014-10-26 20:15:28 -04001181
1182 return handle
1183
1184 except pexpect.EOF:
1185 main.log.error(self.name + ": EOF exception found")
1186 main.log.error(self.name + ": " + self.handle.before)
1187 main.cleanup()
1188 main.exit()
1189 except:
1190 main.log.info(self.name+" ::::::")
1191 main.log.error( traceback.print_exc())
1192 main.log.info(self.name+" ::::::")
1193 main.cleanup()
1194 main.exit()
1195
andrewonlab87852b02014-11-19 18:44:19 -05001196 def push_test_intents(self, dpid_src, dpid_dst, num_intents,
1197 report=True):
1198 '''
1199 Description:
1200 Push a number of intents in a batch format to
1201 a specific point-to-point intent definition
1202 Required:
1203 * dpid_src: specify source dpid
1204 * dpid_dst: specify destination dpid
1205 * num_intents: specify number of intents to push
1206 Optional:
1207 * report: default True, returns latency information
1208 '''
1209 try:
1210 cmd = "push-test-intents "+\
1211 str(dpid_src)+" "+str(dpid_dst)+" "+\
1212 str(num_intents)
1213 self.handle.sendline(cmd)
1214 self.handle.expect(cmd)
1215 self.handle.expect("onos>")
1216
1217 handle = self.handle.before
1218
1219 #Some color thing that we want to escape
1220 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1221 handle = ansi_escape.sub('', handle)
1222
1223 if report:
1224 main.log.info(handle)
1225 return handle
1226 else:
1227 return main.TRUE
1228
1229 except pexpect.EOF:
1230 main.log.error(self.name + ": EOF exception found")
1231 main.log.error(self.name + ": " + self.handle.before)
1232 main.cleanup()
1233 main.exit()
1234 except:
1235 main.log.info(self.name+" ::::::")
1236 main.log.error( traceback.print_exc())
1237 main.log.info(self.name+" ::::::")
1238 main.cleanup()
1239 main.exit()
1240
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001241 def intents_events_metrics(self, json_format=True):
1242 '''
1243 Description:Returns topology metrics
1244 Optional:
1245 * json_format: enable json formatting of output
1246 '''
1247 try:
1248 if json_format:
1249 self.handle.sendline("intents-events-metrics -j")
1250 self.handle.expect("intents-events-metrics -j")
1251 self.handle.expect("onos>")
1252
1253 handle = self.handle.before
1254
1255 #Some color thing that we want to escape
1256 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1257 handle = ansi_escape.sub('', handle)
1258
1259 else:
1260 self.handle.sendline("intents-events-metrics")
1261 self.handle.expect("intents-events-metrics")
1262 self.handle.expect("onos>")
1263
1264 handle = self.handle.before
Shreya Shah0f01c812014-10-26 20:15:28 -04001265
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001266 return handle
1267
1268 except pexpect.EOF:
1269 main.log.error(self.name + ": EOF exception found")
1270 main.log.error(self.name + ": " + self.handle.before)
1271 main.cleanup()
1272 main.exit()
1273 except:
1274 main.log.info(self.name+" ::::::")
1275 main.log.error( traceback.print_exc())
1276 main.log.info(self.name+" ::::::")
1277 main.cleanup()
1278 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001279
andrewonlab867212a2014-10-22 20:13:38 -04001280 def topology_events_metrics(self, json_format=True):
1281 '''
1282 Description:Returns topology metrics
1283 Optional:
1284 * json_format: enable json formatting of output
1285 '''
1286 try:
1287 if json_format:
1288 self.handle.sendline("topology-events-metrics -j")
1289 self.handle.expect("topology-events-metrics -j")
1290 self.handle.expect("onos>")
1291
1292 handle = self.handle.before
1293
1294 #Some color thing that we want to escape
1295 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1296 handle = ansi_escape.sub('', handle)
1297
1298 else:
1299 self.handle.sendline("topology-events-metrics")
1300 self.handle.expect("topology-events-metrics")
1301 self.handle.expect("onos>")
1302
1303 handle = self.handle.before
1304
1305 return handle
1306
1307 except pexpect.EOF:
1308 main.log.error(self.name + ": EOF exception found")
1309 main.log.error(self.name + ": " + self.handle.before)
1310 main.cleanup()
1311 main.exit()
1312 except:
1313 main.log.info(self.name+" ::::::")
1314 main.log.error( traceback.print_exc())
1315 main.log.info(self.name+" ::::::")
1316 main.cleanup()
1317 main.exit()
1318
andrewonlab3e15ead2014-10-15 14:21:34 -04001319 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -04001320 #Wrapper functions use existing driver
1321 #functions and extends their use case.
1322 #For example, we may use the output of
1323 #a normal driver function, and parse it
1324 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001325
andrewonlab9a50dfe2014-10-17 17:22:31 -04001326 def get_all_intents_id(self):
1327 '''
1328 Description:
1329 Obtain all intent id's in a list
1330 '''
1331 try:
1332 #Obtain output of intents function
1333 intents_str = self.intents()
1334 all_intent_list = []
1335 intent_id_list = []
1336
1337 #Parse the intents output for ID's
1338 intents_list = [s.strip() for s in intents_str.splitlines()]
1339 for intents in intents_list:
1340 if "onos>" in intents:
1341 continue
1342 elif "intents" in intents:
1343 continue
1344 else:
1345 line_list = intents.split(" ")
1346 all_intent_list.append(line_list[0])
1347
1348 all_intent_list = all_intent_list[1:-2]
1349
1350 for intents in all_intent_list:
1351 if not intents:
1352 continue
1353 else:
1354 intent_id_list.append(intents)
1355
1356 return intent_id_list
1357
1358 except pexpect.EOF:
1359 main.log.error(self.name + ": EOF exception found")
1360 main.log.error(self.name + ": " + self.handle.before)
1361 main.cleanup()
1362 main.exit()
1363 except:
1364 main.log.info(self.name+" ::::::")
1365 main.log.error( traceback.print_exc())
1366 main.log.info(self.name+" ::::::")
1367 main.cleanup()
1368 main.exit()
1369
andrewonlab7e4d2d32014-10-15 13:23:21 -04001370 def get_all_devices_id(self):
1371 '''
1372 Use 'devices' function to obtain list of all devices
1373 and parse the result to obtain a list of all device
1374 id's. Returns this list. Returns empty list if no
1375 devices exist
1376 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -04001377
1378 This function may be useful if you are not sure of the
1379 device id, and wish to execute other commands using
1380 the ids. By obtaining the list of device ids on the fly,
1381 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -04001382 '''
1383 try:
1384 #Call devices and store result string
andrewonlab9a50dfe2014-10-17 17:22:31 -04001385 devices_str = self.devices(json_format=False)
andrewonlab7e4d2d32014-10-15 13:23:21 -04001386 id_list = []
1387
1388 if not devices_str:
1389 main.log.info("There are no devices to get id from")
1390 return id_list
1391
1392 #Split the string into list by comma
1393 device_list = devices_str.split(",")
1394 #Get temporary list of all arguments with string 'id='
1395 temp_list = [dev for dev in device_list if "id=" in dev]
1396 #Split list further into arguments before and after string
1397 # 'id='. Get the latter portion (the actual device id) and
1398 # append to id_list
1399 for arg in temp_list:
1400 id_list.append(arg.split("id=")[1])
andrewonlab7e4d2d32014-10-15 13:23:21 -04001401 return id_list
1402
1403 except pexpect.EOF:
1404 main.log.error(self.name + ": EOF exception found")
1405 main.log.error(self.name + ": " + self.handle.before)
1406 main.cleanup()
1407 main.exit()
1408 except:
1409 main.log.info(self.name+" ::::::")
1410 main.log.error( traceback.print_exc())
1411 main.log.info(self.name+" ::::::")
1412 main.cleanup()
1413 main.exit()
1414
andrewonlab7c211572014-10-15 16:45:20 -04001415 def get_all_nodes_id(self):
1416 '''
1417 Uses 'nodes' function to obtain list of all nodes
1418 and parse the result of nodes to obtain just the
1419 node id's.
1420 Returns:
1421 list of node id's
1422 '''
1423 try:
1424 nodes_str = self.nodes()
1425 id_list = []
1426
1427 if not nodes_str:
1428 main.log.info("There are no nodes to get id from")
1429 return id_list
1430
1431 #Sample nodes_str output
1432 #id=local, address=127.0.0.1:9876, state=ACTIVE *
1433
1434 #Split the string into list by comma
1435 nodes_list = nodes_str.split(",")
1436 temp_list = [node for node in nodes_list if "id=" in node]
1437 for arg in temp_list:
1438 id_list.append(arg.split("id=")[1])
1439
1440 return id_list
1441
1442 except pexpect.EOF:
1443 main.log.error(self.name + ": EOF exception found")
1444 main.log.error(self.name + ": " + self.handle.before)
1445 main.cleanup()
1446 main.exit()
1447 except:
1448 main.log.info(self.name+" ::::::")
1449 main.log.error( traceback.print_exc())
1450 main.log.info(self.name+" ::::::")
1451 main.cleanup()
1452 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001453
Jon Halla91c4dc2014-10-22 12:57:04 -04001454 def get_device(self, dpid=None):
1455 '''
1456 Return the first device from the devices api whose 'id' contains 'dpid'
1457 Return None if there is no match
1458 '''
1459 import json
1460 try:
1461 if dpid == None:
1462 return None
1463 else:
1464 dpid = dpid.replace(':', '')
1465 raw_devices = self.devices()
1466 devices_json = json.loads(raw_devices)
1467 #search json for the device with dpid then return the device
1468 for device in devices_json:
1469 #print "%s in %s?" % (dpid, device['id'])
1470 if dpid in device['id']:
1471 return device
1472 return None
1473 except pexpect.EOF:
1474 main.log.error(self.name + ": EOF exception found")
1475 main.log.error(self.name + ": " + self.handle.before)
1476 main.cleanup()
1477 main.exit()
1478 except:
1479 main.log.info(self.name+" ::::::")
1480 main.log.error( traceback.print_exc())
1481 main.log.info(self.name+" ::::::")
1482 main.cleanup()
1483 main.exit()
1484
Jon Hall42db6dc2014-10-24 19:03:48 -04001485 def check_status(self, ip, numoswitch, numolink, log_level="info"):
1486 '''
1487 Checks the number of swithes & links that ONOS sees against the
1488 supplied values. By default this will report to main.log, but the
1489 log level can be specifid.
1490
1491 Params: ip = ip used for the onos cli
1492 numoswitch = expected number of switches
1493 numlink = expected number of links
1494 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
1495
1496
1497 log_level can
1498
1499 Returns: main.TRUE if the number of switchs and links are correct,
1500 main.FALSE if the numer of switches and links is incorrect,
1501 and main.ERROR otherwise
1502 '''
1503
1504 try:
1505 topology = self.get_topology(ip)
1506 if topology == {}:
1507 return main.ERROR
1508 output = ""
1509 #Is the number of switches is what we expected
1510 devices = topology.get('devices',False)
1511 links = topology.get('links',False)
1512 if devices == False or links == False:
1513 return main.ERROR
1514 switch_check = ( int(devices) == int(numoswitch) )
1515 #Is the number of links is what we expected
1516 link_check = ( int(links) == int(numolink) )
1517 if (switch_check and link_check):
1518 #We expected the correct numbers
1519 output = output + "The number of links and switches match "\
1520 + "what was expected"
1521 result = main.TRUE
1522 else:
1523 output = output + \
1524 "The number of links and switches does not match what was expected"
1525 result = main.FALSE
1526 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
1527 % ( int(devices), int(numoswitch), int(links), int(numolink) )
1528 if log_level == "report":
1529 main.log.report(output)
1530 elif log_level == "warn":
1531 main.log.warn(output)
1532 else:
1533 main.log.info(output)
1534 return result
1535 except pexpect.EOF:
1536 main.log.error(self.name + ": EOF exception found")
1537 main.log.error(self.name + ": " + self.handle.before)
1538 main.cleanup()
1539 main.exit()
1540 except:
1541 main.log.info(self.name+" ::::::")
1542 main.log.error( traceback.print_exc())
1543 main.log.info(self.name+" ::::::")
1544 main.cleanup()
1545 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001546
1547 def device_role(self, device_id, onos_node, role="master"):
1548 '''
1549 Calls the device-role cli command.
1550 device_id must be the id of a device as seen in the onos devices command
1551 onos_node is the ip of one of the onos nodes in the cluster
1552 role must be either master, standby, or none
1553
Jon Hall983a1702014-10-28 18:44:22 -04001554 Returns main.TRUE or main.FALSE based argument varification.
1555 When device-role supports errors this should be extended to
Jon Hall1c9e8732014-10-27 19:29:27 -04001556 support that output
1557 '''
Jon Hall1c9e8732014-10-27 19:29:27 -04001558 try:
Jon Hall983a1702014-10-28 18:44:22 -04001559 #print "beginning device_role... \n\tdevice_id:" + device_id
1560 #print "\tonos_node: " + onos_node
1561 #print "\trole: "+ role
Jon Hall1c9e8732014-10-27 19:29:27 -04001562 if role.lower() == "master" or \
1563 role.lower() == "standby" or \
1564 role.lower() == "none":
1565 self.handle.sendline("")
1566 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -04001567 self.handle.sendline("device-role " +
1568 str(device_id) + " " +
1569 str(onos_node) + " " +
1570 str(role))
1571 i= self.handle.expect(["Error","onos>"])
1572 if i == 0:
1573 output = str(self.handle.before)
1574 self.handle.expect("onos>")
1575 output = output + str(self.handle.before)
1576 main.log.error(self.name + ": " +
1577 output + '\033[0m')#end color output to escape any colours from the cli
1578 return main.ERROR
1579 self.handle.sendline("")
Jon Hall1c9e8732014-10-27 19:29:27 -04001580 self.handle.expect("onos>")
1581 return main.TRUE
1582 else:
1583 return main.FALSE
1584
1585 except pexpect.EOF:
1586 main.log.error(self.name + ": EOF exception found")
1587 main.log.error(self.name + ": " + self.handle.before)
1588 main.cleanup()
1589 main.exit()
1590 except:
1591 main.log.info(self.name+" ::::::")
1592 main.log.error( traceback.print_exc())
1593 main.log.info(self.name+" ::::::")
1594 main.cleanup()
1595 main.exit()
1596
Jon Hall73cf9cc2014-11-20 22:28:38 -08001597 def clusters(self, json_format=True):
1598 '''
1599 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001600 Optional argument:
1601 * json_format - boolean indicating if you want output in json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001602 '''
1603 try:
1604 self.handle.sendline("")
1605 self.handle.expect("onos>")
1606
1607 if json_format:
1608 self.handle.sendline("clusters -j")
1609 self.handle.expect("clusters -j")
1610 self.handle.expect("onos>")
1611 handle = self.handle.before
1612 '''
1613 handle variable here contains some ANSI escape color code
1614 sequences at the end which are invisible in the print command
1615 output. To make that escape sequence visible, use repr() function.
1616 The repr(handle) output when printed shows the ANSI escape sequences.
1617 In json.loads(somestring), this somestring variable is actually
1618 repr(somestring) and json.loads would fail with the escape sequence.
1619 So we take off that escape sequence using
1620 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1621 handle1 = ansi_escape.sub('', handle)
1622 '''
1623 #print "repr(handle) =", repr(handle)
1624 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1625 handle1 = ansi_escape.sub('', handle)
1626 #print "repr(handle1) = ", repr(handle1)
1627 return handle1
1628 else:
Jon Hallffb386d2014-11-21 13:43:38 -08001629 self.handle.sendline("clusters")
Jon Hall73cf9cc2014-11-20 22:28:38 -08001630 self.handle.expect("onos>")
1631 handle = self.handle.before
1632 #print "handle =",handle
1633 return handle
1634 except pexpect.EOF:
1635 main.log.error(self.name + ": EOF exception found")
1636 main.log.error(self.name + ": " + self.handle.before)
1637 main.cleanup()
1638 main.exit()
1639 except:
1640 main.log.info(self.name+" ::::::")
1641 main.log.error( traceback.print_exc())
1642 main.log.info(self.name+" ::::::")
1643 main.cleanup()
1644 main.exit()
1645
Jon Hall1c9e8732014-10-27 19:29:27 -04001646
andrewonlab7e4d2d32014-10-15 13:23:21 -04001647 #***********************************