blob: 2391d3ae35063724a41678903ed5834fa6c501db [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>")
andrewonlabb66dfa12014-12-02 15:51:10 -0500474
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
andrewonlabb66dfa12014-12-02 15:51:10 -05001196 def push_test_intents(self, dpid_src, dpid_dst, num_intents,
1197 num_mult="", app_id="", report=True):
andrewonlab87852b02014-11-19 18:44:19 -05001198 '''
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:
andrewonlabb66dfa12014-12-02 15:51:10 -05001207 * num_mult: number multiplier for multiplying
1208 the number of intents specified
1209 * app_id: specify the application id init to further
1210 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001211 * report: default True, returns latency information
1212 '''
1213 try:
1214 cmd = "push-test-intents "+\
1215 str(dpid_src)+" "+str(dpid_dst)+" "+\
1216 str(num_intents)
andrewonlabb66dfa12014-12-02 15:51:10 -05001217
1218 if num_mult:
1219 cmd += " " + str(num_mult)
1220 if app_id:
1221 cmd += " " + str(app_id)
1222
andrewonlab87852b02014-11-19 18:44:19 -05001223 self.handle.sendline(cmd)
1224 self.handle.expect(cmd)
1225 self.handle.expect("onos>")
1226
1227 handle = self.handle.before
1228
1229 #Some color thing that we want to escape
1230 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1231 handle = ansi_escape.sub('', handle)
1232
1233 if report:
andrewonlabb66dfa12014-12-02 15:51:10 -05001234 lat_result = []
andrewonlab87852b02014-11-19 18:44:19 -05001235 main.log.info(handle)
andrewonlabb66dfa12014-12-02 15:51:10 -05001236 #Split result by newline
1237 newline = handle.split("\r\r\n")
1238 #Ignore the first object of list, which is empty
1239 newline = newline[1:]
1240 #Some sloppy parsing method to get the latency
1241 for result in newline:
1242 result = result.split(": ")
1243 #Append the first result of second parse
1244 lat_result.append(result[1].split(" ")[0])
1245
1246 print lat_result
1247 return lat_result
andrewonlab87852b02014-11-19 18:44:19 -05001248 else:
1249 return main.TRUE
1250
1251 except pexpect.EOF:
1252 main.log.error(self.name + ": EOF exception found")
1253 main.log.error(self.name + ": " + self.handle.before)
1254 main.cleanup()
1255 main.exit()
1256 except:
1257 main.log.info(self.name+" ::::::")
1258 main.log.error( traceback.print_exc())
1259 main.log.info(self.name+" ::::::")
1260 main.cleanup()
1261 main.exit()
1262
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001263 def intents_events_metrics(self, json_format=True):
1264 '''
1265 Description:Returns topology metrics
1266 Optional:
1267 * json_format: enable json formatting of output
1268 '''
1269 try:
1270 if json_format:
1271 self.handle.sendline("intents-events-metrics -j")
1272 self.handle.expect("intents-events-metrics -j")
1273 self.handle.expect("onos>")
1274
1275 handle = self.handle.before
1276
1277 #Some color thing that we want to escape
1278 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1279 handle = ansi_escape.sub('', handle)
1280
1281 else:
1282 self.handle.sendline("intents-events-metrics")
1283 self.handle.expect("intents-events-metrics")
1284 self.handle.expect("onos>")
1285
1286 handle = self.handle.before
Shreya Shah0f01c812014-10-26 20:15:28 -04001287
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001288 return handle
1289
1290 except pexpect.EOF:
1291 main.log.error(self.name + ": EOF exception found")
1292 main.log.error(self.name + ": " + self.handle.before)
1293 main.cleanup()
1294 main.exit()
1295 except:
1296 main.log.info(self.name+" ::::::")
1297 main.log.error( traceback.print_exc())
1298 main.log.info(self.name+" ::::::")
1299 main.cleanup()
1300 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001301
andrewonlab867212a2014-10-22 20:13:38 -04001302 def topology_events_metrics(self, json_format=True):
1303 '''
1304 Description:Returns topology metrics
1305 Optional:
1306 * json_format: enable json formatting of output
1307 '''
1308 try:
1309 if json_format:
1310 self.handle.sendline("topology-events-metrics -j")
1311 self.handle.expect("topology-events-metrics -j")
1312 self.handle.expect("onos>")
1313
1314 handle = self.handle.before
1315
1316 #Some color thing that we want to escape
1317 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1318 handle = ansi_escape.sub('', handle)
1319
1320 else:
1321 self.handle.sendline("topology-events-metrics")
1322 self.handle.expect("topology-events-metrics")
1323 self.handle.expect("onos>")
1324
1325 handle = self.handle.before
1326
1327 return handle
1328
1329 except pexpect.EOF:
1330 main.log.error(self.name + ": EOF exception found")
1331 main.log.error(self.name + ": " + self.handle.before)
1332 main.cleanup()
1333 main.exit()
1334 except:
1335 main.log.info(self.name+" ::::::")
1336 main.log.error( traceback.print_exc())
1337 main.log.info(self.name+" ::::::")
1338 main.cleanup()
1339 main.exit()
1340
andrewonlab3e15ead2014-10-15 14:21:34 -04001341 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -04001342 #Wrapper functions use existing driver
1343 #functions and extends their use case.
1344 #For example, we may use the output of
1345 #a normal driver function, and parse it
1346 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001347
andrewonlab9a50dfe2014-10-17 17:22:31 -04001348 def get_all_intents_id(self):
1349 '''
1350 Description:
1351 Obtain all intent id's in a list
1352 '''
1353 try:
1354 #Obtain output of intents function
1355 intents_str = self.intents()
1356 all_intent_list = []
1357 intent_id_list = []
1358
1359 #Parse the intents output for ID's
1360 intents_list = [s.strip() for s in intents_str.splitlines()]
1361 for intents in intents_list:
1362 if "onos>" in intents:
1363 continue
1364 elif "intents" in intents:
1365 continue
1366 else:
1367 line_list = intents.split(" ")
1368 all_intent_list.append(line_list[0])
1369
1370 all_intent_list = all_intent_list[1:-2]
1371
1372 for intents in all_intent_list:
1373 if not intents:
1374 continue
1375 else:
1376 intent_id_list.append(intents)
1377
1378 return intent_id_list
1379
1380 except pexpect.EOF:
1381 main.log.error(self.name + ": EOF exception found")
1382 main.log.error(self.name + ": " + self.handle.before)
1383 main.cleanup()
1384 main.exit()
1385 except:
1386 main.log.info(self.name+" ::::::")
1387 main.log.error( traceback.print_exc())
1388 main.log.info(self.name+" ::::::")
1389 main.cleanup()
1390 main.exit()
1391
andrewonlab7e4d2d32014-10-15 13:23:21 -04001392 def get_all_devices_id(self):
1393 '''
1394 Use 'devices' function to obtain list of all devices
1395 and parse the result to obtain a list of all device
1396 id's. Returns this list. Returns empty list if no
1397 devices exist
1398 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -04001399
1400 This function may be useful if you are not sure of the
1401 device id, and wish to execute other commands using
1402 the ids. By obtaining the list of device ids on the fly,
1403 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -04001404 '''
1405 try:
1406 #Call devices and store result string
andrewonlab9a50dfe2014-10-17 17:22:31 -04001407 devices_str = self.devices(json_format=False)
andrewonlab7e4d2d32014-10-15 13:23:21 -04001408 id_list = []
1409
1410 if not devices_str:
1411 main.log.info("There are no devices to get id from")
1412 return id_list
1413
1414 #Split the string into list by comma
1415 device_list = devices_str.split(",")
1416 #Get temporary list of all arguments with string 'id='
1417 temp_list = [dev for dev in device_list if "id=" in dev]
1418 #Split list further into arguments before and after string
1419 # 'id='. Get the latter portion (the actual device id) and
1420 # append to id_list
1421 for arg in temp_list:
1422 id_list.append(arg.split("id=")[1])
andrewonlab7e4d2d32014-10-15 13:23:21 -04001423 return id_list
1424
1425 except pexpect.EOF:
1426 main.log.error(self.name + ": EOF exception found")
1427 main.log.error(self.name + ": " + self.handle.before)
1428 main.cleanup()
1429 main.exit()
1430 except:
1431 main.log.info(self.name+" ::::::")
1432 main.log.error( traceback.print_exc())
1433 main.log.info(self.name+" ::::::")
1434 main.cleanup()
1435 main.exit()
1436
andrewonlab7c211572014-10-15 16:45:20 -04001437 def get_all_nodes_id(self):
1438 '''
1439 Uses 'nodes' function to obtain list of all nodes
1440 and parse the result of nodes to obtain just the
1441 node id's.
1442 Returns:
1443 list of node id's
1444 '''
1445 try:
1446 nodes_str = self.nodes()
1447 id_list = []
1448
1449 if not nodes_str:
1450 main.log.info("There are no nodes to get id from")
1451 return id_list
1452
1453 #Sample nodes_str output
1454 #id=local, address=127.0.0.1:9876, state=ACTIVE *
1455
1456 #Split the string into list by comma
1457 nodes_list = nodes_str.split(",")
1458 temp_list = [node for node in nodes_list if "id=" in node]
1459 for arg in temp_list:
1460 id_list.append(arg.split("id=")[1])
1461
1462 return id_list
1463
1464 except pexpect.EOF:
1465 main.log.error(self.name + ": EOF exception found")
1466 main.log.error(self.name + ": " + self.handle.before)
1467 main.cleanup()
1468 main.exit()
1469 except:
1470 main.log.info(self.name+" ::::::")
1471 main.log.error( traceback.print_exc())
1472 main.log.info(self.name+" ::::::")
1473 main.cleanup()
1474 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001475
Jon Halla91c4dc2014-10-22 12:57:04 -04001476 def get_device(self, dpid=None):
1477 '''
1478 Return the first device from the devices api whose 'id' contains 'dpid'
1479 Return None if there is no match
1480 '''
1481 import json
1482 try:
1483 if dpid == None:
1484 return None
1485 else:
1486 dpid = dpid.replace(':', '')
1487 raw_devices = self.devices()
1488 devices_json = json.loads(raw_devices)
1489 #search json for the device with dpid then return the device
1490 for device in devices_json:
1491 #print "%s in %s?" % (dpid, device['id'])
1492 if dpid in device['id']:
1493 return device
1494 return None
1495 except pexpect.EOF:
1496 main.log.error(self.name + ": EOF exception found")
1497 main.log.error(self.name + ": " + self.handle.before)
1498 main.cleanup()
1499 main.exit()
1500 except:
1501 main.log.info(self.name+" ::::::")
1502 main.log.error( traceback.print_exc())
1503 main.log.info(self.name+" ::::::")
1504 main.cleanup()
1505 main.exit()
1506
Jon Hall42db6dc2014-10-24 19:03:48 -04001507 def check_status(self, ip, numoswitch, numolink, log_level="info"):
1508 '''
1509 Checks the number of swithes & links that ONOS sees against the
1510 supplied values. By default this will report to main.log, but the
1511 log level can be specifid.
1512
1513 Params: ip = ip used for the onos cli
1514 numoswitch = expected number of switches
1515 numlink = expected number of links
1516 log_level = level to log to. Currently accepts 'info', 'warn' and 'report'
1517
1518
1519 log_level can
1520
1521 Returns: main.TRUE if the number of switchs and links are correct,
1522 main.FALSE if the numer of switches and links is incorrect,
1523 and main.ERROR otherwise
1524 '''
1525
1526 try:
1527 topology = self.get_topology(ip)
1528 if topology == {}:
1529 return main.ERROR
1530 output = ""
1531 #Is the number of switches is what we expected
1532 devices = topology.get('devices',False)
1533 links = topology.get('links',False)
1534 if devices == False or links == False:
1535 return main.ERROR
1536 switch_check = ( int(devices) == int(numoswitch) )
1537 #Is the number of links is what we expected
1538 link_check = ( int(links) == int(numolink) )
1539 if (switch_check and link_check):
1540 #We expected the correct numbers
1541 output = output + "The number of links and switches match "\
1542 + "what was expected"
1543 result = main.TRUE
1544 else:
1545 output = output + \
1546 "The number of links and switches does not match what was expected"
1547 result = main.FALSE
1548 output = output + "\n ONOS sees %i devices (%i expected) and %i links (%i expected)"\
1549 % ( int(devices), int(numoswitch), int(links), int(numolink) )
1550 if log_level == "report":
1551 main.log.report(output)
1552 elif log_level == "warn":
1553 main.log.warn(output)
1554 else:
1555 main.log.info(output)
1556 return result
1557 except pexpect.EOF:
1558 main.log.error(self.name + ": EOF exception found")
1559 main.log.error(self.name + ": " + self.handle.before)
1560 main.cleanup()
1561 main.exit()
1562 except:
1563 main.log.info(self.name+" ::::::")
1564 main.log.error( traceback.print_exc())
1565 main.log.info(self.name+" ::::::")
1566 main.cleanup()
1567 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001568
1569 def device_role(self, device_id, onos_node, role="master"):
1570 '''
1571 Calls the device-role cli command.
1572 device_id must be the id of a device as seen in the onos devices command
1573 onos_node is the ip of one of the onos nodes in the cluster
1574 role must be either master, standby, or none
1575
Jon Hall983a1702014-10-28 18:44:22 -04001576 Returns main.TRUE or main.FALSE based argument varification.
1577 When device-role supports errors this should be extended to
Jon Hall1c9e8732014-10-27 19:29:27 -04001578 support that output
1579 '''
Jon Hall1c9e8732014-10-27 19:29:27 -04001580 try:
Jon Hall983a1702014-10-28 18:44:22 -04001581 #print "beginning device_role... \n\tdevice_id:" + device_id
1582 #print "\tonos_node: " + onos_node
1583 #print "\trole: "+ role
Jon Hall1c9e8732014-10-27 19:29:27 -04001584 if role.lower() == "master" or \
1585 role.lower() == "standby" or \
1586 role.lower() == "none":
1587 self.handle.sendline("")
1588 self.handle.expect("onos>")
Jon Hall983a1702014-10-28 18:44:22 -04001589 self.handle.sendline("device-role " +
1590 str(device_id) + " " +
1591 str(onos_node) + " " +
1592 str(role))
1593 i= self.handle.expect(["Error","onos>"])
1594 if i == 0:
1595 output = str(self.handle.before)
1596 self.handle.expect("onos>")
1597 output = output + str(self.handle.before)
1598 main.log.error(self.name + ": " +
1599 output + '\033[0m')#end color output to escape any colours from the cli
1600 return main.ERROR
1601 self.handle.sendline("")
Jon Hall1c9e8732014-10-27 19:29:27 -04001602 self.handle.expect("onos>")
1603 return main.TRUE
1604 else:
1605 return main.FALSE
1606
1607 except pexpect.EOF:
1608 main.log.error(self.name + ": EOF exception found")
1609 main.log.error(self.name + ": " + self.handle.before)
1610 main.cleanup()
1611 main.exit()
1612 except:
1613 main.log.info(self.name+" ::::::")
1614 main.log.error( traceback.print_exc())
1615 main.log.info(self.name+" ::::::")
1616 main.cleanup()
1617 main.exit()
1618
Jon Hall73cf9cc2014-11-20 22:28:38 -08001619 def clusters(self, json_format=True):
1620 '''
1621 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001622 Optional argument:
1623 * json_format - boolean indicating if you want output in json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001624 '''
1625 try:
1626 self.handle.sendline("")
1627 self.handle.expect("onos>")
1628
1629 if json_format:
1630 self.handle.sendline("clusters -j")
1631 self.handle.expect("clusters -j")
1632 self.handle.expect("onos>")
1633 handle = self.handle.before
1634 '''
1635 handle variable here contains some ANSI escape color code
1636 sequences at the end which are invisible in the print command
1637 output. To make that escape sequence visible, use repr() function.
1638 The repr(handle) output when printed shows the ANSI escape sequences.
1639 In json.loads(somestring), this somestring variable is actually
1640 repr(somestring) and json.loads would fail with the escape sequence.
1641 So we take off that escape sequence using
1642 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1643 handle1 = ansi_escape.sub('', handle)
1644 '''
1645 #print "repr(handle) =", repr(handle)
1646 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
1647 handle1 = ansi_escape.sub('', handle)
1648 #print "repr(handle1) = ", repr(handle1)
1649 return handle1
1650 else:
Jon Hallffb386d2014-11-21 13:43:38 -08001651 self.handle.sendline("clusters")
Jon Hall73cf9cc2014-11-20 22:28:38 -08001652 self.handle.expect("onos>")
1653 handle = self.handle.before
1654 #print "handle =",handle
1655 return handle
1656 except pexpect.EOF:
1657 main.log.error(self.name + ": EOF exception found")
1658 main.log.error(self.name + ": " + self.handle.before)
1659 main.cleanup()
1660 main.exit()
1661 except:
1662 main.log.info(self.name+" ::::::")
1663 main.log.error( traceback.print_exc())
1664 main.log.info(self.name+" ::::::")
1665 main.cleanup()
1666 main.exit()
1667
Jon Hall1c9e8732014-10-27 19:29:27 -04001668
andrewonlab7e4d2d32014-10-15 13:23:21 -04001669 #***********************************