blob: 69349240cae2f5e9bc00ccecb521d24f644dc4e1 [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
27sys.path.append("../")
28from drivers.common.clidriver import CLI
29
30class OnosCliDriver(CLI):
31
32 def __init__(self):
33 '''
34 Initialize client
35 '''
36 super(CLI, self).__init__()
37
38 def connect(self,**connectargs):
39 '''
40 Creates ssh handle for ONOS cli.
41 '''
42 try:
43 for key in connectargs:
44 vars(self)[key] = connectargs[key]
45 self.home = "~/ONOS"
46 for key in self.options:
47 if key == "home":
48 self.home = self.options['home']
49 break
50
51
52 self.name = self.options['name']
53 self.handle = super(OnosCliDriver,self).connect(
54 user_name = self.user_name,
55 ip_address = self.ip_address,
56 port = self.port,
57 pwd = self.pwd,
58 home = self.home)
59
60 self.handle.sendline("cd "+ self.home)
61 self.handle.expect("\$")
62 if self.handle:
63 return self.handle
64 else :
65 main.log.info("NO ONOS HANDLE")
66 return main.FALSE
67 except pexpect.EOF:
68 main.log.error(self.name + ": EOF exception found")
69 main.log.error(self.name + ": " + self.handle.before)
70 main.cleanup()
71 main.exit()
72 except:
73 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
74 main.log.error( traceback.print_exc() )
75 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
76 main.cleanup()
77 main.exit()
78
79 def disconnect(self):
80 '''
81 Called when Test is complete to disconnect the ONOS handle.
82 '''
83 response = ''
84 try:
andrewonlab2a6c9342014-10-16 13:40:15 -040085 self.handle.sendline("")
86 self.handle.expect("onos>")
andrewonlabc2d05aa2014-10-13 16:51:10 -040087 self.handle.sendline("system:shutdown")
88 self.handle.expect("Confirm")
andrewonlab2a6c9342014-10-16 13:40:15 -040089 self.handle.sendline("yes")
andrewonlabc2d05aa2014-10-13 16:51:10 -040090 self.handle.expect("\$")
91
andrewonlab95ce8322014-10-13 14:12:04 -040092 except pexpect.EOF:
93 main.log.error(self.name + ": EOF exception found")
94 main.log.error(self.name + ": " + self.handle.before)
95 except:
96 main.log.error(self.name + ": Connection failed to the host")
97 response = main.FALSE
98 return response
99
100 def set_cell(self, cellname):
101 '''
102 Calls 'cell <name>' to set the environment variables on ONOSbench
103
104 Before issuing any cli commands, set the environment variable first.
105 '''
106 try:
107 if not cellname:
108 main.log.error("Must define cellname")
109 main.cleanup()
110 main.exit()
111 else:
112 self.handle.sendline("cell "+str(cellname))
113 #Expect the cellname in the ONOS_CELL variable.
114 #Note that this variable name is subject to change
115 # and that this driver will have to change accordingly
116 self.handle.expect("ONOS_CELL="+str(cellname))
117 handle_before = self.handle.before
118 handle_after = self.handle.after
119 #Get the rest of the handle
120 self.handle.sendline("")
121 self.handle.expect("\$")
122 handle_more = self.handle.before
123
124 main.log.info("Cell call returned: "+handle_before+
125 handle_after + handle_more)
126
127 return main.TRUE
128
129 except pexpect.EOF:
130 main.log.error(self.name + ": EOF exception found")
131 main.log.error(self.name + ": " + self.handle.before)
132 main.cleanup()
133 main.exit()
134 except:
135 main.log.info(self.name+" ::::::")
136 main.log.error( traceback.print_exc())
137 main.log.info(self.name+" ::::::")
138 main.cleanup()
139 main.exit()
140
andrewonlabc2d05aa2014-10-13 16:51:10 -0400141 def start_onos_cli(self, ONOS_ip):
andrewonlab95ce8322014-10-13 14:12:04 -0400142 try:
143 self.handle.sendline("")
144 self.handle.expect("\$")
145
146 #Wait for onos start (-w) and enter onos cli
andrewonlabc2d05aa2014-10-13 16:51:10 -0400147 self.handle.sendline("onos -w "+str(ONOS_ip))
andrewonlab95ce8322014-10-13 14:12:04 -0400148 self.handle.expect("onos>")
149
150 except pexpect.EOF:
151 main.log.error(self.name + ": EOF exception found")
152 main.log.error(self.name + ": " + self.handle.before)
153 main.cleanup()
154 main.exit()
155 except:
156 main.log.info(self.name+" ::::::")
157 main.log.error( traceback.print_exc())
158 main.log.info(self.name+" ::::::")
159 main.cleanup()
160 main.exit()
161
andrewonlaba18f6bf2014-10-13 19:31:54 -0400162 def sendline(self, cmd_str):
163 '''
164 Send a completely user specified string to
165 the onos> prompt. Use this function if you have
166 a very specific command to send.
167
168 Warning: There are no sanity checking to commands
169 sent using this method.
170 '''
171 try:
172 self.handle.sendline("")
173 self.handle.expect("onos>")
174
175 self.handle.sendline(cmd_str)
176 self.handle.expect("onos>")
177
178 handle = self.handle.before
179
180 self.handle.sendline("")
181 self.handle.expect("onos>")
182
183 handle += self.handle.before
184 handle += self.handle.after
185
186 main.log.info("Command sent.")
187
188 return handle
189 except pexpect.EOF:
190 main.log.error(self.name + ": EOF exception found")
191 main.log.error(self.name + ": " + self.handle.before)
192 main.cleanup()
193 main.exit()
194 except:
195 main.log.info(self.name+" ::::::")
196 main.log.error( traceback.print_exc())
197 main.log.info(self.name+" ::::::")
198 main.cleanup()
199 main.exit()
200
andrewonlab95ce8322014-10-13 14:12:04 -0400201 #IMPORTANT NOTE:
202 #For all cli commands, naming convention should match
203 #the cli command replacing ':' with '_'.
204 #Ex) onos:topology > onos_topology
205 # onos:links > onos_links
206 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400207
208 def add_node(self, node_id, ONOS_ip, tcp_port=""):
209 '''
210 Adds a new cluster node by ID and address information.
211 Required:
212 * node_id
213 * ONOS_ip
214 Optional:
215 * tcp_port
216 '''
217 try:
218 self.handle.sendline("")
219 self.handle.expect("onos>")
220
221 self.handle.sendline("add-node "+
222 str(node_id)+" "+
223 str(ONOS_ip)+" "+
224 str(tcp_port))
225
226 i = self.handle.expect([
227 "Error",
228 "onos>" ])
229
230 #Clear handle to get previous output
231 self.handle.sendline("")
232 self.handle.expect("onos>")
233
234 handle = self.handle.before
235
236 if i == 0:
237 main.log.error("Error in adding node")
238 main.log.error(handle)
239 return main.FALSE
240 else:
241 main.log.info("Node "+str(ONOS_ip)+" added")
242 return main.TRUE
243
244 except pexpect.EOF:
245 main.log.error(self.name + ": EOF exception found")
246 main.log.error(self.name + ": " + self.handle.before)
247 main.cleanup()
248 main.exit()
249 except:
250 main.log.info(self.name+" ::::::")
251 main.log.error( traceback.print_exc())
252 main.log.info(self.name+" ::::::")
253 main.cleanup()
254 main.exit()
255
andrewonlab86dc3082014-10-13 18:18:38 -0400256 def remove_node(self, node_id):
257 '''
258 Removes a cluster by ID
259 Issues command: 'remove-node [<node-id>]'
260 Required:
261 * node_id
262 '''
263 try:
264 self.handle.sendline("")
265 self.handle.expect("onos>")
266
267 self.handle.sendline("remove-node "+str(node_id))
268 self.handle.expect("onos>")
269
270 return main.TRUE
271
272 except pexpect.EOF:
273 main.log.error(self.name + ": EOF exception found")
274 main.log.error(self.name + ": " + self.handle.before)
275 main.cleanup()
276 main.exit()
277 except:
278 main.log.info(self.name+" ::::::")
279 main.log.error( traceback.print_exc())
280 main.log.info(self.name+" ::::::")
281 main.cleanup()
282 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400283
andrewonlab7c211572014-10-15 16:45:20 -0400284 def nodes(self):
285 '''
286 List the nodes currently visible
287 Issues command: 'nodes'
288 Returns: entire handle of list of nodes
289 '''
290 try:
291 self.handle.sendline("")
292 self.handle.expect("onos>")
293
294 self.handle.sendline("nodes")
295 self.handle.expect("onos>")
296
297 self.handle.sendline("")
298 self.handle.expect("onos>")
299
300 handle = self.handle.before
301
302 return handle
303
304 except pexpect.EOF:
305 main.log.error(self.name + ": EOF exception found")
306 main.log.error(self.name + ": " + self.handle.before)
307 main.cleanup()
308 main.exit()
309 except:
310 main.log.info(self.name+" ::::::")
311 main.log.error( traceback.print_exc())
312 main.log.info(self.name+" ::::::")
313 main.cleanup()
314 main.exit()
315
andrewonlab38d6ae22014-10-15 14:23:45 -0400316 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400317 '''
318 Shows the current state of the topology
319 by issusing command: 'onos> onos:topology'
320 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400321 try:
322 self.handle.sendline("")
323 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400324 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400325 self.handle.sendline("onos:topology")
326 self.handle.expect("onos>")
327
328 handle = self.handle.before
329
330 main.log.info("onos:topology returned: " +
331 str(handle))
332
333 return handle
334
335 except pexpect.EOF:
336 main.log.error(self.name + ": EOF exception found")
337 main.log.error(self.name + ": " + self.handle.before)
338 main.cleanup()
339 main.exit()
340 except:
341 main.log.info(self.name+" ::::::")
342 main.log.error( traceback.print_exc())
343 main.log.info(self.name+" ::::::")
344 main.cleanup()
345 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400346
347 def feature_install(self, feature_str):
348 '''
349 Installs a specified feature
350 by issuing command: 'onos> feature:install <feature_str>'
351 '''
352 try:
353 self.handle.sendline("")
354 self.handle.expect("onos>")
355
356 self.handle.sendline("feature:install "+str(feature_str))
357 self.handle.expect("onos>")
358
359 return main.TRUE
360
361 except pexpect.EOF:
362 main.log.error(self.name + ": EOF exception found")
363 main.log.error(self.name + ": " + self.handle.before)
364 main.cleanup()
365 main.exit()
366 except:
367 main.log.info(self.name+" ::::::")
368 main.log.error( traceback.print_exc())
369 main.log.info(self.name+" ::::::")
370 main.cleanup()
371 main.exit()
372
373 def feature_uninstall(self, feature_str):
374 '''
375 Uninstalls a specified feature
376 by issuing command: 'onos> feature:uninstall <feature_str>'
377 '''
378 try:
379 self.handle.sendline("")
380 self.handle.expect("onos>")
381
382 self.handle.sendline("feature:uninstall "+str(feature_str))
383 self.handle.expect("onos>")
384
385 return main.TRUE
386
387 except pexpect.EOF:
388 main.log.error(self.name + ": EOF exception found")
389 main.log.error(self.name + ": " + self.handle.before)
390 main.cleanup()
391 main.exit()
392 except:
393 main.log.info(self.name+" ::::::")
394 main.log.error( traceback.print_exc())
395 main.log.info(self.name+" ::::::")
396 main.cleanup()
397 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400398
Jon Halle8217482014-10-17 13:49:14 -0400399 def devices(self, json_format=True, grep_str=""):
andrewonlab86dc3082014-10-13 18:18:38 -0400400 '''
401 Lists all infrastructure devices
402 Optional argument:
403 * grep_str - pass in a string to grep
404 '''
405 try:
406 self.handle.sendline("")
407 self.handle.expect("onos>")
Jon Halle8217482014-10-17 13:49:14 -0400408
409 if json_format:
410 if not grep_str:
411 self.handle.sendline("devices -j")
412 self.handle.expect("devices -j")
413 self.handle.expect("onos>")
414 else:
415 self.handle.sendline("devices -j | grep '"+
andrewonlab86dc3082014-10-13 18:18:38 -0400416 str(grep_str)+"'")
Jon Halle8217482014-10-17 13:49:14 -0400417 self.handle.expect("devices -j | grep '"+str(grep_str)+"'")
418 self.handle.expect("onos>")
419 else:
420 if not grep_str:
421 self.handle.sendline("devices")
422 self.handle.expect("devices")
423 self.handle.expect("onos>")
424 else:
425 self.handle.sendline("devices | grep '"+
426 str(grep_str)+"'")
427 self.handle.expect("devices | grep '"+str(grep_str)+"'")
428 self.handle.expect("onos>")
andrewonlab86dc3082014-10-13 18:18:38 -0400429
430 handle = self.handle.before
Jon Halle8217482014-10-17 13:49:14 -0400431 print "handle =",handle
andrewonlab86dc3082014-10-13 18:18:38 -0400432 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400433 except pexpect.EOF:
434 main.log.error(self.name + ": EOF exception found")
435 main.log.error(self.name + ": " + self.handle.before)
436 main.cleanup()
437 main.exit()
438 except:
439 main.log.info(self.name+" ::::::")
440 main.log.error( traceback.print_exc())
441 main.log.info(self.name+" ::::::")
442 main.cleanup()
443 main.exit()
444
Jon Halle8217482014-10-17 13:49:14 -0400445
446 def links(self, json_format=True, grep_str=""):
447 '''
448 Lists all core links
449 Optional argument:
450 * grep_str - pass in a string to grep
451 '''
452 try:
453 self.handle.sendline("")
454 self.handle.expect("onos>")
455
456 if json_format:
457 if not grep_str:
458 self.handle.sendline("links -j")
459 self.handle.expect("links -j")
460 self.handle.expect("onos>")
461 else:
462 self.handle.sendline("links -j | grep '"+
463 str(grep_str)+"'")
464 self.handle.expect("links -j | grep '"+str(grep_str)+"'")
465 self.handle.expect("onos>")
466 else:
467 if not grep_str:
468 self.handle.sendline("links")
469 self.handle.expect("links")
470 self.handle.expect("onos>")
471 else:
472 self.handle.sendline("links | grep '"+
473 str(grep_str)+"'")
474 self.handle.expect("links | grep '"+str(grep_str)+"'")
475 self.handle.expect("onos>")
476
477 handle = self.handle.before
478 print "handle =",handle
479 return handle
480 except pexpect.EOF:
481 main.log.error(self.name + ": EOF exception found")
482 main.log.error(self.name + ": " + self.handle.before)
483 main.cleanup()
484 main.exit()
485 except:
486 main.log.info(self.name+" ::::::")
487 main.log.error( traceback.print_exc())
488 main.log.info(self.name+" ::::::")
489 main.cleanup()
490 main.exit()
491
492
493 def ports(self, json_format=True, grep_str=""):
494 '''
495 Lists all ports
496 Optional argument:
497 * grep_str - pass in a string to grep
498 '''
499 try:
500 self.handle.sendline("")
501 self.handle.expect("onos>")
502
503 if json_format:
504 if not grep_str:
505 self.handle.sendline("ports -j")
506 self.handle.expect("ports -j")
507 self.handle.expect("onos>")
508 else:
509 self.handle.sendline("ports -j | grep '"+
510 str(grep_str)+"'")
511 self.handle.expect("ports -j | grep '"+str(grep_str)+"'")
512 self.handle.expect("onos>")
513 else:
514 if not grep_str:
515 self.handle.sendline("ports")
516 self.handle.expect("ports")
517 self.handle.expect("onos>")
518 else:
519 self.handle.sendline("ports | grep '"+
520 str(grep_str)+"'")
521 self.handle.expect("ports | grep '"+str(grep_str)+"'")
522 self.handle.expect("onos>")
523
524 handle = self.handle.before
525 print "handle =",handle
526 return handle
527 except pexpect.EOF:
528 main.log.error(self.name + ": EOF exception found")
529 main.log.error(self.name + ": " + self.handle.before)
530 main.cleanup()
531 main.exit()
532 except:
533 main.log.info(self.name+" ::::::")
534 main.log.error( traceback.print_exc())
535 main.log.info(self.name+" ::::::")
536 main.cleanup()
537 main.exit()
538
539
andrewonlab7c211572014-10-15 16:45:20 -0400540 def device_role(self, device_id, node_id, role):
541 '''
542 Set device role for specified device and node with role
543 Required:
544 * device_id : may be obtained by function get_all_devices_id
545 * node_id : may be obtained by function get_all_nodes_id
546 * role: specify one of the following roles:
547 - master
548 - standby
549 - none
550 '''
551 try:
552 self.handle.sendline("")
553 self.handle.expect("onos>")
554
555 self.handle.sendline("device-role "+
556 str(device_id) + " " +
557 str(node_id) + " " +
558 str(role))
559 i = self.handle.expect([
560 "Error",
561 "onos>"])
562
563 self.handle.sendline("")
564 self.handle.expect("onos>")
565
566 handle = self.handle.before
567
568 if i == 0:
569 main.log.error("device-role command returned error")
570 return handle
571 else:
572 return main.TRUE
573
andrewonlab86dc3082014-10-13 18:18:38 -0400574 except pexpect.EOF:
575 main.log.error(self.name + ": EOF exception found")
576 main.log.error(self.name + ": " + self.handle.before)
577 main.cleanup()
578 main.exit()
579 except:
580 main.log.info(self.name+" ::::::")
581 main.log.error( traceback.print_exc())
582 main.log.info(self.name+" ::::::")
583 main.cleanup()
584 main.exit()
andrewonlab2a6c9342014-10-16 13:40:15 -0400585
andrewonlab3e15ead2014-10-15 14:21:34 -0400586 def paths(self, src_id, dst_id):
587 '''
588 Returns string of paths, and the cost.
589 Issues command: onos:paths <src> <dst>
590 '''
591 try:
592 self.handle.sendline("")
593 self.handle.expect("onos>")
594
595 self.handle.sendline("onos:paths "+
596 str(src_id) + " " + str(dst_id))
597 i = self.handle.expect([
598 "Error",
599 "onos>"])
600
601 self.handle.sendline("")
602 self.handle.expect("onos>")
603
604 handle = self.handle.before
605
606 if i == 0:
607 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400608 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400609 else:
610 path = handle.split(";")[0]
611 cost = handle.split(";")[1]
612 return (path, cost)
613
614 except pexpect.EOF:
615 main.log.error(self.name + ": EOF exception found")
616 main.log.error(self.name + ": " + self.handle.before)
617 main.cleanup()
618 main.exit()
619 except:
620 main.log.info(self.name+" ::::::")
621 main.log.error( traceback.print_exc())
622 main.log.info(self.name+" ::::::")
623 main.cleanup()
624 main.exit()
625
andrewonlab3e15ead2014-10-15 14:21:34 -0400626 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -0400627 #Wrapper functions use existing driver
628 #functions and extends their use case.
629 #For example, we may use the output of
630 #a normal driver function, and parse it
631 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -0400632
andrewonlab7e4d2d32014-10-15 13:23:21 -0400633 def get_all_devices_id(self):
634 '''
635 Use 'devices' function to obtain list of all devices
636 and parse the result to obtain a list of all device
637 id's. Returns this list. Returns empty list if no
638 devices exist
639 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -0400640
641 This function may be useful if you are not sure of the
642 device id, and wish to execute other commands using
643 the ids. By obtaining the list of device ids on the fly,
644 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -0400645 '''
646 try:
647 #Call devices and store result string
648 devices_str = self.devices()
649 id_list = []
650
651 if not devices_str:
652 main.log.info("There are no devices to get id from")
653 return id_list
654
655 #Split the string into list by comma
656 device_list = devices_str.split(",")
657 #Get temporary list of all arguments with string 'id='
658 temp_list = [dev for dev in device_list if "id=" in dev]
659 #Split list further into arguments before and after string
660 # 'id='. Get the latter portion (the actual device id) and
661 # append to id_list
662 for arg in temp_list:
663 id_list.append(arg.split("id=")[1])
664
665 return id_list
666
667 except pexpect.EOF:
668 main.log.error(self.name + ": EOF exception found")
669 main.log.error(self.name + ": " + self.handle.before)
670 main.cleanup()
671 main.exit()
672 except:
673 main.log.info(self.name+" ::::::")
674 main.log.error( traceback.print_exc())
675 main.log.info(self.name+" ::::::")
676 main.cleanup()
677 main.exit()
678
andrewonlab7c211572014-10-15 16:45:20 -0400679 def get_all_nodes_id(self):
680 '''
681 Uses 'nodes' function to obtain list of all nodes
682 and parse the result of nodes to obtain just the
683 node id's.
684 Returns:
685 list of node id's
686 '''
687 try:
688 nodes_str = self.nodes()
689 id_list = []
690
691 if not nodes_str:
692 main.log.info("There are no nodes to get id from")
693 return id_list
694
695 #Sample nodes_str output
696 #id=local, address=127.0.0.1:9876, state=ACTIVE *
697
698 #Split the string into list by comma
699 nodes_list = nodes_str.split(",")
700 temp_list = [node for node in nodes_list if "id=" in node]
701 for arg in temp_list:
702 id_list.append(arg.split("id=")[1])
703
704 return id_list
705
706 except pexpect.EOF:
707 main.log.error(self.name + ": EOF exception found")
708 main.log.error(self.name + ": " + self.handle.before)
709 main.cleanup()
710 main.exit()
711 except:
712 main.log.info(self.name+" ::::::")
713 main.log.error( traceback.print_exc())
714 main.log.info(self.name+" ::::::")
715 main.cleanup()
716 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -0400717
718 #***********************************