blob: d023a9936aa5d1a7c5bdef0af53ff4b5d7fa0c72 [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
14
15OCT 13 2014
16
17'''
18
19import sys
20import time
21import pexpect
22import re
23import traceback
24import os.path
25import pydoc
26sys.path.append("../")
27from drivers.common.clidriver import CLI
28
29class OnosCliDriver(CLI):
30
31 def __init__(self):
32 '''
33 Initialize client
34 '''
35 super(CLI, self).__init__()
36
37 def connect(self,**connectargs):
38 '''
39 Creates ssh handle for ONOS cli.
40 '''
41 try:
42 for key in connectargs:
43 vars(self)[key] = connectargs[key]
44 self.home = "~/ONOS"
45 for key in self.options:
46 if key == "home":
47 self.home = self.options['home']
48 break
49
50
51 self.name = self.options['name']
52 self.handle = super(OnosCliDriver,self).connect(
53 user_name = self.user_name,
54 ip_address = self.ip_address,
55 port = self.port,
56 pwd = self.pwd,
57 home = self.home)
58
59 self.handle.sendline("cd "+ self.home)
60 self.handle.expect("\$")
61 if self.handle:
62 return self.handle
63 else :
64 main.log.info("NO ONOS HANDLE")
65 return main.FALSE
66 except pexpect.EOF:
67 main.log.error(self.name + ": EOF exception found")
68 main.log.error(self.name + ": " + self.handle.before)
69 main.cleanup()
70 main.exit()
71 except:
72 main.log.info(self.name + ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
73 main.log.error( traceback.print_exc() )
74 main.log.info(":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::")
75 main.cleanup()
76 main.exit()
77
78 def disconnect(self):
79 '''
80 Called when Test is complete to disconnect the ONOS handle.
81 '''
82 response = ''
83 try:
andrewonlab2a6c9342014-10-16 13:40:15 -040084 self.handle.sendline("")
85 self.handle.expect("onos>")
andrewonlabc2d05aa2014-10-13 16:51:10 -040086 self.handle.sendline("system:shutdown")
87 self.handle.expect("Confirm")
andrewonlab2a6c9342014-10-16 13:40:15 -040088 self.handle.sendline("yes")
andrewonlabc2d05aa2014-10-13 16:51:10 -040089 self.handle.expect("\$")
90
andrewonlab95ce8322014-10-13 14:12:04 -040091 except pexpect.EOF:
92 main.log.error(self.name + ": EOF exception found")
93 main.log.error(self.name + ": " + self.handle.before)
94 except:
95 main.log.error(self.name + ": Connection failed to the host")
96 response = main.FALSE
97 return response
98
99 def set_cell(self, cellname):
100 '''
101 Calls 'cell <name>' to set the environment variables on ONOSbench
102
103 Before issuing any cli commands, set the environment variable first.
104 '''
105 try:
106 if not cellname:
107 main.log.error("Must define cellname")
108 main.cleanup()
109 main.exit()
110 else:
111 self.handle.sendline("cell "+str(cellname))
112 #Expect the cellname in the ONOS_CELL variable.
113 #Note that this variable name is subject to change
114 # and that this driver will have to change accordingly
115 self.handle.expect("ONOS_CELL="+str(cellname))
116 handle_before = self.handle.before
117 handle_after = self.handle.after
118 #Get the rest of the handle
119 self.handle.sendline("")
120 self.handle.expect("\$")
121 handle_more = self.handle.before
122
123 main.log.info("Cell call returned: "+handle_before+
124 handle_after + handle_more)
125
126 return main.TRUE
127
128 except pexpect.EOF:
129 main.log.error(self.name + ": EOF exception found")
130 main.log.error(self.name + ": " + self.handle.before)
131 main.cleanup()
132 main.exit()
133 except:
134 main.log.info(self.name+" ::::::")
135 main.log.error( traceback.print_exc())
136 main.log.info(self.name+" ::::::")
137 main.cleanup()
138 main.exit()
139
andrewonlabc2d05aa2014-10-13 16:51:10 -0400140 def start_onos_cli(self, ONOS_ip):
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
142 self.handle.sendline("")
143 self.handle.expect("\$")
144
145 #Wait for onos start (-w) and enter onos cli
andrewonlabc2d05aa2014-10-13 16:51:10 -0400146 self.handle.sendline("onos -w "+str(ONOS_ip))
andrewonlab95ce8322014-10-13 14:12:04 -0400147 self.handle.expect("onos>")
148
149 except pexpect.EOF:
150 main.log.error(self.name + ": EOF exception found")
151 main.log.error(self.name + ": " + self.handle.before)
152 main.cleanup()
153 main.exit()
154 except:
155 main.log.info(self.name+" ::::::")
156 main.log.error( traceback.print_exc())
157 main.log.info(self.name+" ::::::")
158 main.cleanup()
159 main.exit()
160
andrewonlaba18f6bf2014-10-13 19:31:54 -0400161 def sendline(self, cmd_str):
162 '''
163 Send a completely user specified string to
164 the onos> prompt. Use this function if you have
165 a very specific command to send.
166
167 Warning: There are no sanity checking to commands
168 sent using this method.
169 '''
170 try:
171 self.handle.sendline("")
172 self.handle.expect("onos>")
173
174 self.handle.sendline(cmd_str)
175 self.handle.expect("onos>")
176
177 handle = self.handle.before
178
179 self.handle.sendline("")
180 self.handle.expect("onos>")
181
182 handle += self.handle.before
183 handle += self.handle.after
184
185 main.log.info("Command sent.")
186
187 return handle
188 except pexpect.EOF:
189 main.log.error(self.name + ": EOF exception found")
190 main.log.error(self.name + ": " + self.handle.before)
191 main.cleanup()
192 main.exit()
193 except:
194 main.log.info(self.name+" ::::::")
195 main.log.error( traceback.print_exc())
196 main.log.info(self.name+" ::::::")
197 main.cleanup()
198 main.exit()
199
andrewonlab95ce8322014-10-13 14:12:04 -0400200 #IMPORTANT NOTE:
201 #For all cli commands, naming convention should match
202 #the cli command replacing ':' with '_'.
203 #Ex) onos:topology > onos_topology
204 # onos:links > onos_links
205 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400206
207 def add_node(self, node_id, ONOS_ip, tcp_port=""):
208 '''
209 Adds a new cluster node by ID and address information.
210 Required:
211 * node_id
212 * ONOS_ip
213 Optional:
214 * tcp_port
215 '''
216 try:
217 self.handle.sendline("")
218 self.handle.expect("onos>")
219
220 self.handle.sendline("add-node "+
221 str(node_id)+" "+
222 str(ONOS_ip)+" "+
223 str(tcp_port))
224
225 i = self.handle.expect([
226 "Error",
227 "onos>" ])
228
229 #Clear handle to get previous output
230 self.handle.sendline("")
231 self.handle.expect("onos>")
232
233 handle = self.handle.before
234
235 if i == 0:
236 main.log.error("Error in adding node")
237 main.log.error(handle)
238 return main.FALSE
239 else:
240 main.log.info("Node "+str(ONOS_ip)+" added")
241 return main.TRUE
242
243 except pexpect.EOF:
244 main.log.error(self.name + ": EOF exception found")
245 main.log.error(self.name + ": " + self.handle.before)
246 main.cleanup()
247 main.exit()
248 except:
249 main.log.info(self.name+" ::::::")
250 main.log.error( traceback.print_exc())
251 main.log.info(self.name+" ::::::")
252 main.cleanup()
253 main.exit()
254
andrewonlab86dc3082014-10-13 18:18:38 -0400255 def remove_node(self, node_id):
256 '''
257 Removes a cluster by ID
258 Issues command: 'remove-node [<node-id>]'
259 Required:
260 * node_id
261 '''
262 try:
263 self.handle.sendline("")
264 self.handle.expect("onos>")
265
266 self.handle.sendline("remove-node "+str(node_id))
267 self.handle.expect("onos>")
268
269 return main.TRUE
270
271 except pexpect.EOF:
272 main.log.error(self.name + ": EOF exception found")
273 main.log.error(self.name + ": " + self.handle.before)
274 main.cleanup()
275 main.exit()
276 except:
277 main.log.info(self.name+" ::::::")
278 main.log.error( traceback.print_exc())
279 main.log.info(self.name+" ::::::")
280 main.cleanup()
281 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400282
andrewonlab7c211572014-10-15 16:45:20 -0400283 def nodes(self):
284 '''
285 List the nodes currently visible
286 Issues command: 'nodes'
287 Returns: entire handle of list of nodes
288 '''
289 try:
290 self.handle.sendline("")
291 self.handle.expect("onos>")
292
293 self.handle.sendline("nodes")
294 self.handle.expect("onos>")
295
296 self.handle.sendline("")
297 self.handle.expect("onos>")
298
299 handle = self.handle.before
300
301 return handle
302
303 except pexpect.EOF:
304 main.log.error(self.name + ": EOF exception found")
305 main.log.error(self.name + ": " + self.handle.before)
306 main.cleanup()
307 main.exit()
308 except:
309 main.log.info(self.name+" ::::::")
310 main.log.error( traceback.print_exc())
311 main.log.info(self.name+" ::::::")
312 main.cleanup()
313 main.exit()
314
andrewonlab38d6ae22014-10-15 14:23:45 -0400315 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400316 '''
317 Shows the current state of the topology
318 by issusing command: 'onos> onos:topology'
319 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400320 try:
321 self.handle.sendline("")
322 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400323 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400324 self.handle.sendline("onos:topology")
325 self.handle.expect("onos>")
326
327 handle = self.handle.before
328
329 main.log.info("onos:topology returned: " +
330 str(handle))
331
332 return handle
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
346 def feature_install(self, feature_str):
347 '''
348 Installs a specified feature
349 by issuing command: 'onos> feature:install <feature_str>'
350 '''
351 try:
352 self.handle.sendline("")
353 self.handle.expect("onos>")
354
355 self.handle.sendline("feature:install "+str(feature_str))
356 self.handle.expect("onos>")
357
358 return main.TRUE
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()
371
372 def feature_uninstall(self, feature_str):
373 '''
374 Uninstalls a specified feature
375 by issuing command: 'onos> feature:uninstall <feature_str>'
376 '''
377 try:
378 self.handle.sendline("")
379 self.handle.expect("onos>")
380
381 self.handle.sendline("feature:uninstall "+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()
andrewonlab95ce8322014-10-13 14:12:04 -0400397
andrewonlab86dc3082014-10-13 18:18:38 -0400398 def devices(self, grep_str=""):
399 '''
400 Lists all infrastructure devices
401 Optional argument:
402 * grep_str - pass in a string to grep
403 '''
404 try:
405 self.handle.sendline("")
406 self.handle.expect("onos>")
407
408 if not grep_str:
409 self.handle.sendline("devices")
410 self.handle.expect("onos>")
411 else:
412 self.handle.sendline("devices | grep '"+
413 str(grep_str)+"'")
414 self.handle.expect("onos>")
415
416 handle = self.handle.before
417 handle += self.handle.after
418
419 self.handle.sendline("")
420 self.handle.expect("onos>")
421
422 handle += self.handle.before
423 handle += self.handle.after
424
425 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400426
427 except pexpect.EOF:
428 main.log.error(self.name + ": EOF exception found")
429 main.log.error(self.name + ": " + self.handle.before)
430 main.cleanup()
431 main.exit()
432 except:
433 main.log.info(self.name+" ::::::")
434 main.log.error( traceback.print_exc())
435 main.log.info(self.name+" ::::::")
436 main.cleanup()
437 main.exit()
438
439 def device_role(self, device_id, node_id, role):
440 '''
441 Set device role for specified device and node with role
442 Required:
443 * device_id : may be obtained by function get_all_devices_id
444 * node_id : may be obtained by function get_all_nodes_id
445 * role: specify one of the following roles:
446 - master
447 - standby
448 - none
449 '''
450 try:
451 self.handle.sendline("")
452 self.handle.expect("onos>")
453
454 self.handle.sendline("device-role "+
455 str(device_id) + " " +
456 str(node_id) + " " +
457 str(role))
458 i = self.handle.expect([
459 "Error",
460 "onos>"])
461
462 self.handle.sendline("")
463 self.handle.expect("onos>")
464
465 handle = self.handle.before
466
467 if i == 0:
468 main.log.error("device-role command returned error")
469 return handle
470 else:
471 return main.TRUE
472
andrewonlab86dc3082014-10-13 18:18:38 -0400473 except pexpect.EOF:
474 main.log.error(self.name + ": EOF exception found")
475 main.log.error(self.name + ": " + self.handle.before)
476 main.cleanup()
477 main.exit()
478 except:
479 main.log.info(self.name+" ::::::")
480 main.log.error( traceback.print_exc())
481 main.log.info(self.name+" ::::::")
482 main.cleanup()
483 main.exit()
andrewonlab2a6c9342014-10-16 13:40:15 -0400484
andrewonlab3e15ead2014-10-15 14:21:34 -0400485 def paths(self, src_id, dst_id):
486 '''
487 Returns string of paths, and the cost.
488 Issues command: onos:paths <src> <dst>
489 '''
490 try:
491 self.handle.sendline("")
492 self.handle.expect("onos>")
493
494 self.handle.sendline("onos:paths "+
495 str(src_id) + " " + str(dst_id))
496 i = self.handle.expect([
497 "Error",
498 "onos>"])
499
500 self.handle.sendline("")
501 self.handle.expect("onos>")
502
503 handle = self.handle.before
504
505 if i == 0:
506 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400507 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400508 else:
509 path = handle.split(";")[0]
510 cost = handle.split(";")[1]
511 return (path, cost)
512
513 except pexpect.EOF:
514 main.log.error(self.name + ": EOF exception found")
515 main.log.error(self.name + ": " + self.handle.before)
516 main.cleanup()
517 main.exit()
518 except:
519 main.log.info(self.name+" ::::::")
520 main.log.error( traceback.print_exc())
521 main.log.info(self.name+" ::::::")
522 main.cleanup()
523 main.exit()
524
andrewonlab3e15ead2014-10-15 14:21:34 -0400525 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -0400526 #Wrapper functions use existing driver
527 #functions and extends their use case.
528 #For example, we may use the output of
529 #a normal driver function, and parse it
530 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -0400531
andrewonlab7e4d2d32014-10-15 13:23:21 -0400532 def get_all_devices_id(self):
533 '''
534 Use 'devices' function to obtain list of all devices
535 and parse the result to obtain a list of all device
536 id's. Returns this list. Returns empty list if no
537 devices exist
538 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -0400539
540 This function may be useful if you are not sure of the
541 device id, and wish to execute other commands using
542 the ids. By obtaining the list of device ids on the fly,
543 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -0400544 '''
545 try:
546 #Call devices and store result string
547 devices_str = self.devices()
548 id_list = []
549
550 if not devices_str:
551 main.log.info("There are no devices to get id from")
552 return id_list
553
554 #Split the string into list by comma
555 device_list = devices_str.split(",")
556 #Get temporary list of all arguments with string 'id='
557 temp_list = [dev for dev in device_list if "id=" in dev]
558 #Split list further into arguments before and after string
559 # 'id='. Get the latter portion (the actual device id) and
560 # append to id_list
561 for arg in temp_list:
562 id_list.append(arg.split("id=")[1])
563
564 return id_list
565
566 except pexpect.EOF:
567 main.log.error(self.name + ": EOF exception found")
568 main.log.error(self.name + ": " + self.handle.before)
569 main.cleanup()
570 main.exit()
571 except:
572 main.log.info(self.name+" ::::::")
573 main.log.error( traceback.print_exc())
574 main.log.info(self.name+" ::::::")
575 main.cleanup()
576 main.exit()
577
andrewonlab7c211572014-10-15 16:45:20 -0400578 def get_all_nodes_id(self):
579 '''
580 Uses 'nodes' function to obtain list of all nodes
581 and parse the result of nodes to obtain just the
582 node id's.
583 Returns:
584 list of node id's
585 '''
586 try:
587 nodes_str = self.nodes()
588 id_list = []
589
590 if not nodes_str:
591 main.log.info("There are no nodes to get id from")
592 return id_list
593
594 #Sample nodes_str output
595 #id=local, address=127.0.0.1:9876, state=ACTIVE *
596
597 #Split the string into list by comma
598 nodes_list = nodes_str.split(",")
599 temp_list = [node for node in nodes_list if "id=" in node]
600 for arg in temp_list:
601 id_list.append(arg.split("id=")[1])
602
603 return id_list
604
605 except pexpect.EOF:
606 main.log.error(self.name + ": EOF exception found")
607 main.log.error(self.name + ": " + self.handle.before)
608 main.cleanup()
609 main.exit()
610 except:
611 main.log.info(self.name+" ::::::")
612 main.log.error( traceback.print_exc())
613 main.log.info(self.name+" ::::::")
614 main.cleanup()
615 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -0400616
617 #***********************************