blob: d0c8d3ac210143798e1703da2e157a7c33c8ef23 [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:
74 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
75 main.log.error( traceback.print_exc() )
76 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
77 main.cleanup()
78 main.exit()
79
80 def disconnect(self):
81 '''
82 Called when Test is complete to disconnect the ONOS handle.
83 '''
84 response = ''
85 try:
andrewonlab2a6c9342014-10-16 13:40:15 -040086 self.handle.sendline("")
Jon Hall7e5b9172014-10-22 12:32:47 -040087 i = self.handle.expect(["onos>","\$"])
88 if i == 0:
89 self.handle.sendline("system:shutdown")
90 self.handle.expect("Confirm")
91 self.handle.sendline("yes")
92 self.handle.expect("\$")
93 self.handle.sendline("\n")
andrewonlabc2d05aa2014-10-13 16:51:10 -040094 self.handle.expect("\$")
Jon Hall7e5b9172014-10-22 12:32:47 -040095 self.handle.sendline("exit")
96 self.handle.expect("closed")
andrewonlabc2d05aa2014-10-13 16:51:10 -040097
andrewonlab95ce8322014-10-13 14:12:04 -040098 except pexpect.EOF:
99 main.log.error(self.name + ": EOF exception found")
100 main.log.error(self.name + ": " + self.handle.before)
101 except:
102 main.log.error(self.name + ": Connection failed to the host")
103 response = main.FALSE
104 return response
105
106 def set_cell(self, cellname):
107 '''
108 Calls 'cell <name>' to set the environment variables on ONOSbench
109
110 Before issuing any cli commands, set the environment variable first.
111 '''
112 try:
113 if not cellname:
114 main.log.error("Must define cellname")
115 main.cleanup()
116 main.exit()
117 else:
118 self.handle.sendline("cell "+str(cellname))
119 #Expect the cellname in the ONOS_CELL variable.
120 #Note that this variable name is subject to change
121 # and that this driver will have to change accordingly
122 self.handle.expect("ONOS_CELL="+str(cellname))
123 handle_before = self.handle.before
124 handle_after = self.handle.after
125 #Get the rest of the handle
126 self.handle.sendline("")
127 self.handle.expect("\$")
128 handle_more = self.handle.before
129
130 main.log.info("Cell call returned: "+handle_before+
131 handle_after + handle_more)
132
133 return main.TRUE
134
135 except pexpect.EOF:
136 main.log.error(self.name + ": EOF exception found")
137 main.log.error(self.name + ": " + self.handle.before)
138 main.cleanup()
139 main.exit()
140 except:
141 main.log.info(self.name+" ::::::")
142 main.log.error( traceback.print_exc())
143 main.log.info(self.name+" ::::::")
144 main.cleanup()
145 main.exit()
146
andrewonlabc2d05aa2014-10-13 16:51:10 -0400147 def start_onos_cli(self, ONOS_ip):
andrewonlab95ce8322014-10-13 14:12:04 -0400148 try:
149 self.handle.sendline("")
150 self.handle.expect("\$")
151
152 #Wait for onos start (-w) and enter onos cli
andrewonlabc2d05aa2014-10-13 16:51:10 -0400153 self.handle.sendline("onos -w "+str(ONOS_ip))
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400154 i = self.handle.expect([
155 "onos>",
156 pexpect.TIMEOUT],timeout=60)
157
158 if i == 0:
159 main.log.info(str(ONOS_ip)+" CLI Started successfully")
160 return main.TRUE
161 else:
andrewonlab3a7c3c72014-10-24 17:21:03 -0400162 #If failed, send ctrl+c to process and try again
andrewonlabf47993a2014-10-24 17:56:01 -0400163 main.log.info("Starting CLI failed. Retrying...")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400164 self.handle.sendline("\x03")
165 self.handle.sendline("onos -w "+str(ONOS_ip))
166 i = self.handle.expect(["onos>",pexpect.TIMEOUT],
167 timeout=30)
168 if i == 0:
169 return main.TRUE
170 else:
171 main.log.error("Connection to CLI "+\
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400172 str(ONOS_ip)+" timeout")
andrewonlab3a7c3c72014-10-24 17:21:03 -0400173 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400174
175 except pexpect.EOF:
176 main.log.error(self.name + ": EOF exception found")
177 main.log.error(self.name + ": " + self.handle.before)
178 main.cleanup()
179 main.exit()
180 except:
181 main.log.info(self.name+" ::::::")
182 main.log.error( traceback.print_exc())
183 main.log.info(self.name+" ::::::")
184 main.cleanup()
185 main.exit()
186
andrewonlaba18f6bf2014-10-13 19:31:54 -0400187 def sendline(self, cmd_str):
188 '''
189 Send a completely user specified string to
190 the onos> prompt. Use this function if you have
191 a very specific command to send.
192
193 Warning: There are no sanity checking to commands
194 sent using this method.
195 '''
196 try:
197 self.handle.sendline("")
198 self.handle.expect("onos>")
199
200 self.handle.sendline(cmd_str)
201 self.handle.expect("onos>")
202
203 handle = self.handle.before
204
205 self.handle.sendline("")
206 self.handle.expect("onos>")
207
208 handle += self.handle.before
209 handle += self.handle.after
210
211 main.log.info("Command sent.")
212
213 return handle
214 except pexpect.EOF:
215 main.log.error(self.name + ": EOF exception found")
216 main.log.error(self.name + ": " + self.handle.before)
217 main.cleanup()
218 main.exit()
219 except:
220 main.log.info(self.name+" ::::::")
221 main.log.error( traceback.print_exc())
222 main.log.info(self.name+" ::::::")
223 main.cleanup()
224 main.exit()
225
andrewonlab95ce8322014-10-13 14:12:04 -0400226 #IMPORTANT NOTE:
227 #For all cli commands, naming convention should match
228 #the cli command replacing ':' with '_'.
229 #Ex) onos:topology > onos_topology
230 # onos:links > onos_links
231 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400232
233 def add_node(self, node_id, ONOS_ip, tcp_port=""):
234 '''
235 Adds a new cluster node by ID and address information.
236 Required:
237 * node_id
238 * ONOS_ip
239 Optional:
240 * tcp_port
241 '''
242 try:
243 self.handle.sendline("")
244 self.handle.expect("onos>")
245
246 self.handle.sendline("add-node "+
247 str(node_id)+" "+
248 str(ONOS_ip)+" "+
249 str(tcp_port))
250
251 i = self.handle.expect([
252 "Error",
253 "onos>" ])
254
255 #Clear handle to get previous output
256 self.handle.sendline("")
257 self.handle.expect("onos>")
258
259 handle = self.handle.before
260
261 if i == 0:
262 main.log.error("Error in adding node")
263 main.log.error(handle)
264 return main.FALSE
265 else:
266 main.log.info("Node "+str(ONOS_ip)+" added")
267 return main.TRUE
268
269 except pexpect.EOF:
270 main.log.error(self.name + ": EOF exception found")
271 main.log.error(self.name + ": " + self.handle.before)
272 main.cleanup()
273 main.exit()
274 except:
275 main.log.info(self.name+" ::::::")
276 main.log.error( traceback.print_exc())
277 main.log.info(self.name+" ::::::")
278 main.cleanup()
279 main.exit()
280
andrewonlab86dc3082014-10-13 18:18:38 -0400281 def remove_node(self, node_id):
282 '''
283 Removes a cluster by ID
284 Issues command: 'remove-node [<node-id>]'
285 Required:
286 * node_id
287 '''
288 try:
289 self.handle.sendline("")
290 self.handle.expect("onos>")
291
292 self.handle.sendline("remove-node "+str(node_id))
293 self.handle.expect("onos>")
294
295 return main.TRUE
296
297 except pexpect.EOF:
298 main.log.error(self.name + ": EOF exception found")
299 main.log.error(self.name + ": " + self.handle.before)
300 main.cleanup()
301 main.exit()
302 except:
303 main.log.info(self.name+" ::::::")
304 main.log.error( traceback.print_exc())
305 main.log.info(self.name+" ::::::")
306 main.cleanup()
307 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400308
andrewonlab7c211572014-10-15 16:45:20 -0400309 def nodes(self):
310 '''
311 List the nodes currently visible
312 Issues command: 'nodes'
313 Returns: entire handle of list of nodes
314 '''
315 try:
316 self.handle.sendline("")
317 self.handle.expect("onos>")
318
319 self.handle.sendline("nodes")
320 self.handle.expect("onos>")
321
322 self.handle.sendline("")
323 self.handle.expect("onos>")
324
325 handle = self.handle.before
326
327 return handle
328
329 except pexpect.EOF:
330 main.log.error(self.name + ": EOF exception found")
331 main.log.error(self.name + ": " + self.handle.before)
332 main.cleanup()
333 main.exit()
334 except:
335 main.log.info(self.name+" ::::::")
336 main.log.error( traceback.print_exc())
337 main.log.info(self.name+" ::::::")
338 main.cleanup()
339 main.exit()
340
andrewonlab38d6ae22014-10-15 14:23:45 -0400341 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400342 '''
343 Shows the current state of the topology
344 by issusing command: 'onos> onos:topology'
345 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400346 try:
347 self.handle.sendline("")
348 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400349 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400350 self.handle.sendline("onos:topology")
351 self.handle.expect("onos>")
352
353 handle = self.handle.before
354
355 main.log.info("onos:topology returned: " +
356 str(handle))
357
358 return handle
359
360 except pexpect.EOF:
361 main.log.error(self.name + ": EOF exception found")
362 main.log.error(self.name + ": " + self.handle.before)
363 main.cleanup()
364 main.exit()
365 except:
366 main.log.info(self.name+" ::::::")
367 main.log.error( traceback.print_exc())
368 main.log.info(self.name+" ::::::")
369 main.cleanup()
370 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400371
372 def feature_install(self, feature_str):
373 '''
374 Installs a specified feature
375 by issuing command: 'onos> feature:install <feature_str>'
376 '''
377 try:
378 self.handle.sendline("")
379 self.handle.expect("onos>")
380
381 self.handle.sendline("feature:install "+str(feature_str))
382 self.handle.expect("onos>")
383
384 return main.TRUE
385
386 except pexpect.EOF:
387 main.log.error(self.name + ": EOF exception found")
388 main.log.error(self.name + ": " + self.handle.before)
389 main.cleanup()
390 main.exit()
391 except:
392 main.log.info(self.name+" ::::::")
393 main.log.error( traceback.print_exc())
394 main.log.info(self.name+" ::::::")
395 main.cleanup()
396 main.exit()
397
398 def feature_uninstall(self, feature_str):
399 '''
400 Uninstalls a specified feature
401 by issuing command: 'onos> feature:uninstall <feature_str>'
402 '''
403 try:
404 self.handle.sendline("")
405 self.handle.expect("onos>")
406
407 self.handle.sendline("feature:uninstall "+str(feature_str))
408 self.handle.expect("onos>")
409
410 return main.TRUE
411
412 except pexpect.EOF:
413 main.log.error(self.name + ": EOF exception found")
414 main.log.error(self.name + ": " + self.handle.before)
415 main.cleanup()
416 main.exit()
417 except:
418 main.log.info(self.name+" ::::::")
419 main.log.error( traceback.print_exc())
420 main.log.info(self.name+" ::::::")
421 main.cleanup()
422 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400423
Jon Halle8217482014-10-17 13:49:14 -0400424 def devices(self, json_format=True, grep_str=""):
andrewonlab86dc3082014-10-13 18:18:38 -0400425 '''
Jon Hall7b02d952014-10-17 20:14:54 -0400426 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400427 Optional argument:
428 * grep_str - pass in a string to grep
429 '''
430 try:
431 self.handle.sendline("")
432 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400433
434 if json_format:
435 if not grep_str:
436 self.handle.sendline("devices -j")
437 self.handle.expect("devices -j")
438 self.handle.expect("onos>")
439 else:
440 self.handle.sendline("devices -j | grep '"+
andrewonlab86dc3082014-10-13 18:18:38 -0400441 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400442 self.handle.expect("devices -j | grep '"+str(grep_str)+"'")
443 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400444 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400445 '''
446 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
447 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 -0400448 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Halld815ce42014-10-17 19:52:30 -0400449 So we take off that escape sequence using
450 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
451 handle1 = ansi_escape.sub('', handle)
452 '''
453 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400454 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
455 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400456 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400457 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400458 else:
459 if not grep_str:
460 self.handle.sendline("devices")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400461 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400462 else:
463 self.handle.sendline("devices | grep '"+
464 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400465 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400466 handle = self.handle.before
467 print "handle =",handle
468 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400469 except pexpect.EOF:
470 main.log.error(self.name + ": EOF exception found")
471 main.log.error(self.name + ": " + self.handle.before)
472 main.cleanup()
473 main.exit()
474 except:
475 main.log.info(self.name+" ::::::")
476 main.log.error( traceback.print_exc())
477 main.log.info(self.name+" ::::::")
478 main.cleanup()
479 main.exit()
480
Jon Halle8217482014-10-17 13:49:14 -0400481 def links(self, json_format=True, grep_str=""):
482 '''
483 Lists all core links
484 Optional argument:
485 * grep_str - pass in a string to grep
486 '''
487 try:
488 self.handle.sendline("")
489 self.handle.expect("onos>")
490
491 if json_format:
492 if not grep_str:
493 self.handle.sendline("links -j")
494 self.handle.expect("links -j")
495 self.handle.expect("onos>")
496 else:
497 self.handle.sendline("links -j | grep '"+
498 str(grep_str)+"'")
499 self.handle.expect("links -j | grep '"+str(grep_str)+"'")
500 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400501 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400502 '''
503 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
504 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 -0400505 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Jon Halld815ce42014-10-17 19:52:30 -0400506 So we take off that escape sequence using
507 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
508 handle1 = ansi_escape.sub('', handle)
509 '''
510 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400511 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
512 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400513 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400514 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400515 else:
516 if not grep_str:
517 self.handle.sendline("links")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400518 self.handle.expect("onos>")
519 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400520 self.handle.expect("onos>")
521 else:
522 self.handle.sendline("links | grep '"+
523 str(grep_str)+"'")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400524 self.handle.expect("onos>")
525 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400526 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400527 handle = self.handle.before
528 print "handle =",handle
529 return handle
Jon Halle8217482014-10-17 13:49:14 -0400530 except pexpect.EOF:
531 main.log.error(self.name + ": EOF exception found")
532 main.log.error(self.name + ": " + self.handle.before)
533 main.cleanup()
534 main.exit()
535 except:
536 main.log.info(self.name+" ::::::")
537 main.log.error( traceback.print_exc())
538 main.log.info(self.name+" ::::::")
539 main.cleanup()
540 main.exit()
541
542
543 def ports(self, json_format=True, grep_str=""):
544 '''
545 Lists all ports
546 Optional argument:
547 * grep_str - pass in a string to grep
548 '''
549 try:
550 self.handle.sendline("")
551 self.handle.expect("onos>")
552
553 if json_format:
554 if not grep_str:
555 self.handle.sendline("ports -j")
556 self.handle.expect("ports -j")
557 self.handle.expect("onos>")
558 else:
559 self.handle.sendline("ports -j | grep '"+
560 str(grep_str)+"'")
561 self.handle.expect("ports -j | grep '"+str(grep_str)+"'")
562 self.handle.expect("onos>")
Jon Hallcd707292014-10-17 19:06:17 -0400563 handle = self.handle.before
Jon Halld815ce42014-10-17 19:52:30 -0400564 '''
565 handle variable here contains some ANSI escape color code sequences at the end which are invisible in the print command output
566 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 -0400567 In json.loads(somestring), this somestring variable is actually repr(somestring) and json.loads would fail with the escape sequence.
Shreya Shah0c525cc2014-10-17 20:20:24 -0400568 So we take off that escape sequence using the following commads:
Jon Halld815ce42014-10-17 19:52:30 -0400569 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
570 handle1 = ansi_escape.sub('', handle)
571 '''
572 #print "repr(handle) =", repr(handle)
Jon Halla001c392014-10-17 18:50:59 -0400573 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
574 handle1 = ansi_escape.sub('', handle)
Jon Halld815ce42014-10-17 19:52:30 -0400575 #print "repr(handle1) = ", repr(handle1)
Jon Halla001c392014-10-17 18:50:59 -0400576 return handle1
577
Jon Halle8217482014-10-17 13:49:14 -0400578 else:
579 if not grep_str:
580 self.handle.sendline("ports")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400581 self.handle.expect("onos>")
582 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400583 self.handle.expect("onos>")
584 else:
585 self.handle.sendline("ports | grep '"+
586 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400587 self.handle.expect("onos>")
andrewonlab9a50dfe2014-10-17 17:22:31 -0400588 self.handle.sendline("")
Jon Halle8217482014-10-17 13:49:14 -0400589 self.handle.expect("onos>")
Jon Halla001c392014-10-17 18:50:59 -0400590 handle = self.handle.before
591 print "handle =",handle
Jon Hallcd707292014-10-17 19:06:17 -0400592 return handle
Jon Halle8217482014-10-17 13:49:14 -0400593 except pexpect.EOF:
594 main.log.error(self.name + ": EOF exception found")
595 main.log.error(self.name + ": " + self.handle.before)
596 main.cleanup()
597 main.exit()
598 except:
599 main.log.info(self.name+" ::::::")
600 main.log.error( traceback.print_exc())
601 main.log.info(self.name+" ::::::")
602 main.cleanup()
603 main.exit()
604
605
andrewonlab7c211572014-10-15 16:45:20 -0400606 def device_role(self, device_id, node_id, role):
607 '''
608 Set device role for specified device and node with role
609 Required:
610 * device_id : may be obtained by function get_all_devices_id
611 * node_id : may be obtained by function get_all_nodes_id
612 * role: specify one of the following roles:
613 - master
614 - standby
615 - none
616 '''
617 try:
618 self.handle.sendline("")
619 self.handle.expect("onos>")
620
621 self.handle.sendline("device-role "+
622 str(device_id) + " " +
623 str(node_id) + " " +
624 str(role))
625 i = self.handle.expect([
626 "Error",
627 "onos>"])
628
629 self.handle.sendline("")
630 self.handle.expect("onos>")
631
632 handle = self.handle.before
633
634 if i == 0:
635 main.log.error("device-role command returned error")
636 return handle
637 else:
638 return main.TRUE
639
andrewonlab86dc3082014-10-13 18:18:38 -0400640 except pexpect.EOF:
641 main.log.error(self.name + ": EOF exception found")
642 main.log.error(self.name + ": " + self.handle.before)
643 main.cleanup()
644 main.exit()
645 except:
646 main.log.info(self.name+" ::::::")
647 main.log.error( traceback.print_exc())
648 main.log.info(self.name+" ::::::")
649 main.cleanup()
650 main.exit()
andrewonlab2a6c9342014-10-16 13:40:15 -0400651
andrewonlab3e15ead2014-10-15 14:21:34 -0400652 def paths(self, src_id, dst_id):
653 '''
654 Returns string of paths, and the cost.
655 Issues command: onos:paths <src> <dst>
656 '''
657 try:
658 self.handle.sendline("")
659 self.handle.expect("onos>")
660
661 self.handle.sendline("onos:paths "+
662 str(src_id) + " " + str(dst_id))
663 i = self.handle.expect([
664 "Error",
665 "onos>"])
666
667 self.handle.sendline("")
668 self.handle.expect("onos>")
669
670 handle = self.handle.before
671
672 if i == 0:
673 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400674 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400675 else:
676 path = handle.split(";")[0]
677 cost = handle.split(";")[1]
678 return (path, cost)
679
680 except pexpect.EOF:
681 main.log.error(self.name + ": EOF exception found")
682 main.log.error(self.name + ": " + self.handle.before)
683 main.cleanup()
684 main.exit()
685 except:
686 main.log.info(self.name+" ::::::")
687 main.log.error( traceback.print_exc())
688 main.log.info(self.name+" ::::::")
689 main.cleanup()
690 main.exit()
andrewonlab3f0a4af2014-10-17 12:25:14 -0400691
692 #TODO:
693 #def hosts(self):
694
695 def get_hosts_id(self, host_list):
696 '''
697 Obtain list of hosts
698 Issues command: 'onos> hosts'
699
700 Required:
701 * host_list: List of hosts obtained by Mininet
702 IMPORTANT:
703 This function assumes that you started your
704 topology with the option '--mac'.
705 Furthermore, it assumes that value of VLAN is '-1'
706 Description:
707 Converts mininet hosts (h1, h2, h3...) into
708 ONOS format (00:00:00:00:00:01/-1 , ...)
709 '''
710
711 try:
Shreya Shahd7310c52014-10-20 16:44:37 -0400712 #self.handle.sendline("")
713 #self.handle.expect("onos>")
andrewonlab3f0a4af2014-10-17 12:25:14 -0400714
715 onos_host_list = []
716
717 for host in host_list:
718 host = host.replace("h", "")
719 host_hex = hex(int(host)).zfill(12)
720 host_hex = str(host_hex).replace('x','0')
721 i = iter(str(host_hex))
722 host_hex = ":".join(a+b for a,b in zip(i,i))
723 host_hex = host_hex + "/-1"
724 onos_host_list.append(host_hex)
725
726 return onos_host_list
727
728 except pexpect.EOF:
729 main.log.error(self.name + ": EOF exception found")
730 main.log.error(self.name + ": " + self.handle.before)
731 main.cleanup()
732 main.exit()
733 except:
734 main.log.info(self.name+" ::::::")
735 main.log.error( traceback.print_exc())
736 main.log.info(self.name+" ::::::")
737 main.cleanup()
738 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400739
andrewonlabe6745342014-10-17 14:29:13 -0400740 def add_host_intent(self, host_id_one, host_id_two):
741 '''
742 Required:
743 * host_id_one: ONOS host id for host1
744 * host_id_two: ONOS host id for host2
745 Description:
746 Adds a host-to-host intent (bidrectional) by
747 specifying the two hosts.
748 '''
749 try:
750 self.handle.sendline("")
751 self.handle.expect("onos>")
752
753 self.handle.sendline("add-host-intent "+
754 str(host_id_one) + " " + str(host_id_two))
755 self.handle.expect("onos>")
756
757 self.handle.sendline("")
758 self.handle.expect("onos>")
759
760 handle = self.handle.before
761
762 main.log.info("Intent installed between "+
763 str(host_id_one) + " and " + str(host_id_two))
764
765 return handle
766
767 except pexpect.EOF:
768 main.log.error(self.name + ": EOF exception found")
769 main.log.error(self.name + ": " + self.handle.before)
770 main.cleanup()
771 main.exit()
772 except:
773 main.log.info(self.name+" ::::::")
774 main.log.error( traceback.print_exc())
775 main.log.info(self.name+" ::::::")
776 main.cleanup()
777 main.exit()
778
andrewonlab7b31d232014-10-24 13:31:47 -0400779 def add_optical_intent(self, ingress_device, egress_device):
780 '''
781 Required:
782 * ingress_device: device id of ingress device
783 * egress_device: device id of egress device
784 Optional:
785 TODO: Still needs to be implemented via dev side
786 '''
787 try:
788 self.handle.sendline("add-optical-intent "+
789 str(ingress_device) + " " + str(egress_device))
790 self.handle.expect("add-optical-intent")
791 i = self.handle.expect([
792 "Error",
793 "onos>"])
794
795 handle = self.handle.before
796
797 #If error, return error message
798 if i == 0:
799 return handle
800 else:
801 return main.TRUE
802
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
andrewonlab4dbb4d82014-10-17 18:22:31 -0400815 def add_point_intent(self, ingress_device, port_ingress,
andrewonlab289e4b72014-10-21 21:24:18 -0400816 egress_device, port_egress, ethType="", ethSrc="",
817 ethDst=""):
andrewonlab4dbb4d82014-10-17 18:22:31 -0400818 '''
819 Required:
820 * ingress_device: device id of ingress device
821 * egress_device: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -0400822 Optional:
823 * ethType: specify ethType
824 * ethSrc: specify ethSrc (i.e. src mac addr)
825 * ethDst: specify ethDst (i.e. dst mac addr)
andrewonlab4dbb4d82014-10-17 18:22:31 -0400826 Description:
827 Adds a point-to-point intent (uni-directional) by
andrewonlab289e4b72014-10-21 21:24:18 -0400828 specifying device id's and optional fields
829
andrewonlab4dbb4d82014-10-17 18:22:31 -0400830 NOTE: This function may change depending on the
831 options developers provide for point-to-point
832 intent via cli
833 '''
834 try:
andrewonlab289e4b72014-10-21 21:24:18 -0400835 cmd = ""
836
837 #If there are no optional arguments
838 if not ethType and not ethSrc and not ethDst:
839 cmd = "add-point-intent "+\
840 str(ingress_device) + "/" + str(port_ingress) + " " +\
841 str(egress_device) + "/" + str(port_egress)
842
843 else:
andrewonlab9a130be2014-10-22 12:44:56 -0400844 cmd = "add-point-intent "
845
andrewonlab0c0a6772014-10-22 12:31:18 -0400846 if ethType:
andrewonlab289e4b72014-10-21 21:24:18 -0400847 cmd += " --ethType " + str(ethType)
848 if ethSrc:
849 cmd += " --ethSrc " + str(ethSrc)
850 if ethDst:
851 cmd += " --ethDst " + str(ethDst)
andrewonlab9a130be2014-10-22 12:44:56 -0400852
853 cmd += " "+str(ingress_device) + "/" + str(port_ingress) + " " +\
854 str(egress_device) + "/" + str(port_egress)
andrewonlab289e4b72014-10-21 21:24:18 -0400855
andrewonlab4dbb4d82014-10-17 18:22:31 -0400856 self.handle.sendline("")
857 self.handle.expect("onos>")
858
andrewonlab289e4b72014-10-21 21:24:18 -0400859 self.handle.sendline(cmd)
andrewonlab4dbb4d82014-10-17 18:22:31 -0400860 i = self.handle.expect([
861 "Error",
862 "onos>"])
andrewonlab289e4b72014-10-21 21:24:18 -0400863
andrewonlab4dbb4d82014-10-17 18:22:31 -0400864 self.handle.sendline("")
865 self.handle.expect("onos>")
866
867 handle = self.handle.before
868
869 if i == 0:
870 main.log.error("Error in adding point-to-point intent")
871 return handle
872 else:
873 return main.TRUE
andrewonlab289e4b72014-10-21 21:24:18 -0400874
andrewonlab4dbb4d82014-10-17 18:22:31 -0400875 except pexpect.EOF:
876 main.log.error(self.name + ": EOF exception found")
877 main.log.error(self.name + ": " + self.handle.before)
878 main.cleanup()
879 main.exit()
880 except:
881 main.log.info(self.name+" ::::::")
882 main.log.error( traceback.print_exc())
883 main.log.info(self.name+" ::::::")
884 main.cleanup()
885 main.exit()
886
andrewonlab9a50dfe2014-10-17 17:22:31 -0400887 def remove_intent(self, intent_id):
888 '''
889 Remove intent for specified intent id
890 '''
891 try:
892 self.handle.sendline("")
893 self.handle.expect("onos>")
894
895 self.handle.sendline("remove-intent "+str(intent_id))
896 i = self.handle.expect([
897 "Error",
898 "onos>"])
899
900 handle = self.handle.before
901
902 if i == 0:
903 main.log.error("Error in removing intent")
904 return handle
905 else:
906 return handle
907
908 except pexpect.EOF:
909 main.log.error(self.name + ": EOF exception found")
910 main.log.error(self.name + ": " + self.handle.before)
911 main.cleanup()
912 main.exit()
913 except:
914 main.log.info(self.name+" ::::::")
915 main.log.error( traceback.print_exc())
916 main.log.info(self.name+" ::::::")
917 main.cleanup()
918 main.exit()
919
andrewonlab377693f2014-10-21 16:00:30 -0400920 def intents(self, json_format = False):
andrewonlabe6745342014-10-17 14:29:13 -0400921 '''
andrewonlab377693f2014-10-21 16:00:30 -0400922 Optional:
923 * json_format: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -0400924 Description:
925 Obtain intents currently installed
926 '''
927 try:
andrewonlab377693f2014-10-21 16:00:30 -0400928 if json_format:
929 self.handle.sendline("intents -j")
930 self.handle.expect("intents -j")
931 self.handle.expect("onos>")
andrewonlabe6745342014-10-17 14:29:13 -0400932
andrewonlab377693f2014-10-21 16:00:30 -0400933 handle = self.handle.before
andrewonlabe6745342014-10-17 14:29:13 -0400934
andrewonlab377693f2014-10-21 16:00:30 -0400935 else:
936 self.handle.sendline("")
937 self.handle.expect("onos>")
andrewonlabe6745342014-10-17 14:29:13 -0400938
andrewonlab377693f2014-10-21 16:00:30 -0400939 self.handle.sendline("intents")
940 self.handle.expect("onos>")
941
942 self.handle.sendline("")
943 self.handle.expect("onos>")
944
945 handle = self.handle.before
andrewonlabe6745342014-10-17 14:29:13 -0400946
947 return handle
948
949 except pexpect.EOF:
950 main.log.error(self.name + ": EOF exception found")
951 main.log.error(self.name + ": " + self.handle.before)
952 main.cleanup()
953 main.exit()
954 except:
955 main.log.info(self.name+" ::::::")
956 main.log.error( traceback.print_exc())
957 main.log.info(self.name+" ::::::")
958 main.cleanup()
959 main.exit()
960
andrewonlab867212a2014-10-22 20:13:38 -0400961 def topology_events_metrics(self, json_format=True):
962 '''
963 Description:Returns topology metrics
964 Optional:
965 * json_format: enable json formatting of output
966 '''
967 try:
968 if json_format:
969 self.handle.sendline("topology-events-metrics -j")
970 self.handle.expect("topology-events-metrics -j")
971 self.handle.expect("onos>")
972
973 handle = self.handle.before
974
975 #Some color thing that we want to escape
976 ansi_escape = re.compile(r'\r\r\n\x1b[^m]*m')
977 handle = ansi_escape.sub('', handle)
978
979 else:
980 self.handle.sendline("topology-events-metrics")
981 self.handle.expect("topology-events-metrics")
982 self.handle.expect("onos>")
983
984 handle = self.handle.before
985
986 return handle
987
988 except pexpect.EOF:
989 main.log.error(self.name + ": EOF exception found")
990 main.log.error(self.name + ": " + self.handle.before)
991 main.cleanup()
992 main.exit()
993 except:
994 main.log.info(self.name+" ::::::")
995 main.log.error( traceback.print_exc())
996 main.log.info(self.name+" ::::::")
997 main.cleanup()
998 main.exit()
999
andrewonlab3e15ead2014-10-15 14:21:34 -04001000 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -04001001 #Wrapper functions use existing driver
1002 #functions and extends their use case.
1003 #For example, we may use the output of
1004 #a normal driver function, and parse it
1005 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001006
andrewonlab9a50dfe2014-10-17 17:22:31 -04001007 def get_all_intents_id(self):
1008 '''
1009 Description:
1010 Obtain all intent id's in a list
1011 '''
1012 try:
1013 #Obtain output of intents function
1014 intents_str = self.intents()
1015 all_intent_list = []
1016 intent_id_list = []
1017
1018 #Parse the intents output for ID's
1019 intents_list = [s.strip() for s in intents_str.splitlines()]
1020 for intents in intents_list:
1021 if "onos>" in intents:
1022 continue
1023 elif "intents" in intents:
1024 continue
1025 else:
1026 line_list = intents.split(" ")
1027 all_intent_list.append(line_list[0])
1028
1029 all_intent_list = all_intent_list[1:-2]
1030
1031 for intents in all_intent_list:
1032 if not intents:
1033 continue
1034 else:
1035 intent_id_list.append(intents)
1036
1037 return intent_id_list
1038
1039 except pexpect.EOF:
1040 main.log.error(self.name + ": EOF exception found")
1041 main.log.error(self.name + ": " + self.handle.before)
1042 main.cleanup()
1043 main.exit()
1044 except:
1045 main.log.info(self.name+" ::::::")
1046 main.log.error( traceback.print_exc())
1047 main.log.info(self.name+" ::::::")
1048 main.cleanup()
1049 main.exit()
1050
andrewonlab7e4d2d32014-10-15 13:23:21 -04001051 def get_all_devices_id(self):
1052 '''
1053 Use 'devices' function to obtain list of all devices
1054 and parse the result to obtain a list of all device
1055 id's. Returns this list. Returns empty list if no
1056 devices exist
1057 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -04001058
1059 This function may be useful if you are not sure of the
1060 device id, and wish to execute other commands using
1061 the ids. By obtaining the list of device ids on the fly,
1062 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -04001063 '''
1064 try:
1065 #Call devices and store result string
andrewonlab9a50dfe2014-10-17 17:22:31 -04001066 devices_str = self.devices(json_format=False)
andrewonlab7e4d2d32014-10-15 13:23:21 -04001067 id_list = []
1068
1069 if not devices_str:
1070 main.log.info("There are no devices to get id from")
1071 return id_list
1072
1073 #Split the string into list by comma
1074 device_list = devices_str.split(",")
1075 #Get temporary list of all arguments with string 'id='
1076 temp_list = [dev for dev in device_list if "id=" in dev]
1077 #Split list further into arguments before and after string
1078 # 'id='. Get the latter portion (the actual device id) and
1079 # append to id_list
1080 for arg in temp_list:
1081 id_list.append(arg.split("id=")[1])
andrewonlab7e4d2d32014-10-15 13:23:21 -04001082 return id_list
1083
1084 except pexpect.EOF:
1085 main.log.error(self.name + ": EOF exception found")
1086 main.log.error(self.name + ": " + self.handle.before)
1087 main.cleanup()
1088 main.exit()
1089 except:
1090 main.log.info(self.name+" ::::::")
1091 main.log.error( traceback.print_exc())
1092 main.log.info(self.name+" ::::::")
1093 main.cleanup()
1094 main.exit()
1095
andrewonlab7c211572014-10-15 16:45:20 -04001096 def get_all_nodes_id(self):
1097 '''
1098 Uses 'nodes' function to obtain list of all nodes
1099 and parse the result of nodes to obtain just the
1100 node id's.
1101 Returns:
1102 list of node id's
1103 '''
1104 try:
1105 nodes_str = self.nodes()
1106 id_list = []
1107
1108 if not nodes_str:
1109 main.log.info("There are no nodes to get id from")
1110 return id_list
1111
1112 #Sample nodes_str output
1113 #id=local, address=127.0.0.1:9876, state=ACTIVE *
1114
1115 #Split the string into list by comma
1116 nodes_list = nodes_str.split(",")
1117 temp_list = [node for node in nodes_list if "id=" in node]
1118 for arg in temp_list:
1119 id_list.append(arg.split("id=")[1])
1120
1121 return id_list
1122
1123 except pexpect.EOF:
1124 main.log.error(self.name + ": EOF exception found")
1125 main.log.error(self.name + ": " + self.handle.before)
1126 main.cleanup()
1127 main.exit()
1128 except:
1129 main.log.info(self.name+" ::::::")
1130 main.log.error( traceback.print_exc())
1131 main.log.info(self.name+" ::::::")
1132 main.cleanup()
1133 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001134
Jon Halla91c4dc2014-10-22 12:57:04 -04001135 def get_device(self, dpid=None):
1136 '''
1137 Return the first device from the devices api whose 'id' contains 'dpid'
1138 Return None if there is no match
1139 '''
1140 import json
1141 try:
1142 if dpid == None:
1143 return None
1144 else:
1145 dpid = dpid.replace(':', '')
1146 raw_devices = self.devices()
1147 devices_json = json.loads(raw_devices)
1148 #search json for the device with dpid then return the device
1149 for device in devices_json:
1150 #print "%s in %s?" % (dpid, device['id'])
1151 if dpid in device['id']:
1152 return device
1153 return None
1154 except pexpect.EOF:
1155 main.log.error(self.name + ": EOF exception found")
1156 main.log.error(self.name + ": " + self.handle.before)
1157 main.cleanup()
1158 main.exit()
1159 except:
1160 main.log.info(self.name+" ::::::")
1161 main.log.error( traceback.print_exc())
1162 main.log.info(self.name+" ::::::")
1163 main.cleanup()
1164 main.exit()
1165
andrewonlab7e4d2d32014-10-15 13:23:21 -04001166 #***********************************