blob: 44d796a3bbe2a64314883b7a9c63b46839affd0e [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:
andrewonlabc2d05aa2014-10-13 16:51:10 -040084 self.handle.sendline("system:shutdown")
85 self.handle.expect("Confirm")
86 self.handle.sendline("Yes")
87 self.handle.expect("\$")
88
andrewonlab95ce8322014-10-13 14:12:04 -040089 except pexpect.EOF:
90 main.log.error(self.name + ": EOF exception found")
91 main.log.error(self.name + ": " + self.handle.before)
92 except:
93 main.log.error(self.name + ": Connection failed to the host")
94 response = main.FALSE
95 return response
96
97 def set_cell(self, cellname):
98 '''
99 Calls 'cell <name>' to set the environment variables on ONOSbench
100
101 Before issuing any cli commands, set the environment variable first.
102 '''
103 try:
104 if not cellname:
105 main.log.error("Must define cellname")
106 main.cleanup()
107 main.exit()
108 else:
109 self.handle.sendline("cell "+str(cellname))
110 #Expect the cellname in the ONOS_CELL variable.
111 #Note that this variable name is subject to change
112 # and that this driver will have to change accordingly
113 self.handle.expect("ONOS_CELL="+str(cellname))
114 handle_before = self.handle.before
115 handle_after = self.handle.after
116 #Get the rest of the handle
117 self.handle.sendline("")
118 self.handle.expect("\$")
119 handle_more = self.handle.before
120
121 main.log.info("Cell call returned: "+handle_before+
122 handle_after + handle_more)
123
124 return main.TRUE
125
126 except pexpect.EOF:
127 main.log.error(self.name + ": EOF exception found")
128 main.log.error(self.name + ": " + self.handle.before)
129 main.cleanup()
130 main.exit()
131 except:
132 main.log.info(self.name+" ::::::")
133 main.log.error( traceback.print_exc())
134 main.log.info(self.name+" ::::::")
135 main.cleanup()
136 main.exit()
137
andrewonlabc2d05aa2014-10-13 16:51:10 -0400138 def start_onos_cli(self, ONOS_ip):
andrewonlab95ce8322014-10-13 14:12:04 -0400139 try:
140 self.handle.sendline("")
141 self.handle.expect("\$")
142
143 #Wait for onos start (-w) and enter onos cli
andrewonlabc2d05aa2014-10-13 16:51:10 -0400144 self.handle.sendline("onos -w "+str(ONOS_ip))
andrewonlab95ce8322014-10-13 14:12:04 -0400145 self.handle.expect("onos>")
146
147 except pexpect.EOF:
148 main.log.error(self.name + ": EOF exception found")
149 main.log.error(self.name + ": " + self.handle.before)
150 main.cleanup()
151 main.exit()
152 except:
153 main.log.info(self.name+" ::::::")
154 main.log.error( traceback.print_exc())
155 main.log.info(self.name+" ::::::")
156 main.cleanup()
157 main.exit()
158
andrewonlaba18f6bf2014-10-13 19:31:54 -0400159 def sendline(self, cmd_str):
160 '''
161 Send a completely user specified string to
162 the onos> prompt. Use this function if you have
163 a very specific command to send.
164
165 Warning: There are no sanity checking to commands
166 sent using this method.
167 '''
168 try:
169 self.handle.sendline("")
170 self.handle.expect("onos>")
171
172 self.handle.sendline(cmd_str)
173 self.handle.expect("onos>")
174
175 handle = self.handle.before
176
177 self.handle.sendline("")
178 self.handle.expect("onos>")
179
180 handle += self.handle.before
181 handle += self.handle.after
182
183 main.log.info("Command sent.")
184
185 return handle
186 except pexpect.EOF:
187 main.log.error(self.name + ": EOF exception found")
188 main.log.error(self.name + ": " + self.handle.before)
189 main.cleanup()
190 main.exit()
191 except:
192 main.log.info(self.name+" ::::::")
193 main.log.error( traceback.print_exc())
194 main.log.info(self.name+" ::::::")
195 main.cleanup()
196 main.exit()
197
andrewonlab95ce8322014-10-13 14:12:04 -0400198 #IMPORTANT NOTE:
199 #For all cli commands, naming convention should match
200 #the cli command replacing ':' with '_'.
201 #Ex) onos:topology > onos_topology
202 # onos:links > onos_links
203 # feature:list > feature_list
andrewonlabc2d05aa2014-10-13 16:51:10 -0400204
205 def add_node(self, node_id, ONOS_ip, tcp_port=""):
206 '''
207 Adds a new cluster node by ID and address information.
208 Required:
209 * node_id
210 * ONOS_ip
211 Optional:
212 * tcp_port
213 '''
214 try:
215 self.handle.sendline("")
216 self.handle.expect("onos>")
217
218 self.handle.sendline("add-node "+
219 str(node_id)+" "+
220 str(ONOS_ip)+" "+
221 str(tcp_port))
222
223 i = self.handle.expect([
224 "Error",
225 "onos>" ])
226
227 #Clear handle to get previous output
228 self.handle.sendline("")
229 self.handle.expect("onos>")
230
231 handle = self.handle.before
232
233 if i == 0:
234 main.log.error("Error in adding node")
235 main.log.error(handle)
236 return main.FALSE
237 else:
238 main.log.info("Node "+str(ONOS_ip)+" added")
239 return main.TRUE
240
241 except pexpect.EOF:
242 main.log.error(self.name + ": EOF exception found")
243 main.log.error(self.name + ": " + self.handle.before)
244 main.cleanup()
245 main.exit()
246 except:
247 main.log.info(self.name+" ::::::")
248 main.log.error( traceback.print_exc())
249 main.log.info(self.name+" ::::::")
250 main.cleanup()
251 main.exit()
252
andrewonlab86dc3082014-10-13 18:18:38 -0400253 def remove_node(self, node_id):
254 '''
255 Removes a cluster by ID
256 Issues command: 'remove-node [<node-id>]'
257 Required:
258 * node_id
259 '''
260 try:
261 self.handle.sendline("")
262 self.handle.expect("onos>")
263
264 self.handle.sendline("remove-node "+str(node_id))
265 self.handle.expect("onos>")
266
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()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400280
andrewonlab7c211572014-10-15 16:45:20 -0400281 def nodes(self):
282 '''
283 List the nodes currently visible
284 Issues command: 'nodes'
285 Returns: entire handle of list of nodes
286 '''
287 try:
288 self.handle.sendline("")
289 self.handle.expect("onos>")
290
291 self.handle.sendline("nodes")
292 self.handle.expect("onos>")
293
294 self.handle.sendline("")
295 self.handle.expect("onos>")
296
297 handle = self.handle.before
298
299 return handle
300
301 except pexpect.EOF:
302 main.log.error(self.name + ": EOF exception found")
303 main.log.error(self.name + ": " + self.handle.before)
304 main.cleanup()
305 main.exit()
306 except:
307 main.log.info(self.name+" ::::::")
308 main.log.error( traceback.print_exc())
309 main.log.info(self.name+" ::::::")
310 main.cleanup()
311 main.exit()
312
andrewonlab38d6ae22014-10-15 14:23:45 -0400313 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400314 '''
315 Shows the current state of the topology
316 by issusing command: 'onos> onos:topology'
317 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400318 try:
319 self.handle.sendline("")
320 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400321 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400322 self.handle.sendline("onos:topology")
323 self.handle.expect("onos>")
324
325 handle = self.handle.before
326
327 main.log.info("onos:topology returned: " +
328 str(handle))
329
330 return handle
331
332 except pexpect.EOF:
333 main.log.error(self.name + ": EOF exception found")
334 main.log.error(self.name + ": " + self.handle.before)
335 main.cleanup()
336 main.exit()
337 except:
338 main.log.info(self.name+" ::::::")
339 main.log.error( traceback.print_exc())
340 main.log.info(self.name+" ::::::")
341 main.cleanup()
342 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400343
344 def feature_install(self, feature_str):
345 '''
346 Installs a specified feature
347 by issuing command: 'onos> feature:install <feature_str>'
348 '''
349 try:
350 self.handle.sendline("")
351 self.handle.expect("onos>")
352
353 self.handle.sendline("feature:install "+str(feature_str))
354 self.handle.expect("onos>")
355
356 return main.TRUE
357
358 except pexpect.EOF:
359 main.log.error(self.name + ": EOF exception found")
360 main.log.error(self.name + ": " + self.handle.before)
361 main.cleanup()
362 main.exit()
363 except:
364 main.log.info(self.name+" ::::::")
365 main.log.error( traceback.print_exc())
366 main.log.info(self.name+" ::::::")
367 main.cleanup()
368 main.exit()
369
370 def feature_uninstall(self, feature_str):
371 '''
372 Uninstalls a specified feature
373 by issuing command: 'onos> feature:uninstall <feature_str>'
374 '''
375 try:
376 self.handle.sendline("")
377 self.handle.expect("onos>")
378
379 self.handle.sendline("feature:uninstall "+str(feature_str))
380 self.handle.expect("onos>")
381
382 return main.TRUE
383
384 except pexpect.EOF:
385 main.log.error(self.name + ": EOF exception found")
386 main.log.error(self.name + ": " + self.handle.before)
387 main.cleanup()
388 main.exit()
389 except:
390 main.log.info(self.name+" ::::::")
391 main.log.error( traceback.print_exc())
392 main.log.info(self.name+" ::::::")
393 main.cleanup()
394 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400395
andrewonlab86dc3082014-10-13 18:18:38 -0400396 def devices(self, grep_str=""):
397 '''
398 Lists all infrastructure devices
399 Optional argument:
400 * grep_str - pass in a string to grep
401 '''
402 try:
403 self.handle.sendline("")
404 self.handle.expect("onos>")
405
406 if not grep_str:
407 self.handle.sendline("devices")
408 self.handle.expect("onos>")
409 else:
410 self.handle.sendline("devices | grep '"+
411 str(grep_str)+"'")
412 self.handle.expect("onos>")
413
414 handle = self.handle.before
415 handle += self.handle.after
416
417 self.handle.sendline("")
418 self.handle.expect("onos>")
419
420 handle += self.handle.before
421 handle += self.handle.after
422
423 return handle
andrewonlab7c211572014-10-15 16:45:20 -0400424
425 except pexpect.EOF:
426 main.log.error(self.name + ": EOF exception found")
427 main.log.error(self.name + ": " + self.handle.before)
428 main.cleanup()
429 main.exit()
430 except:
431 main.log.info(self.name+" ::::::")
432 main.log.error( traceback.print_exc())
433 main.log.info(self.name+" ::::::")
434 main.cleanup()
435 main.exit()
436
437 def device_role(self, device_id, node_id, role):
438 '''
439 Set device role for specified device and node with role
440 Required:
441 * device_id : may be obtained by function get_all_devices_id
442 * node_id : may be obtained by function get_all_nodes_id
443 * role: specify one of the following roles:
444 - master
445 - standby
446 - none
447 '''
448 try:
449 self.handle.sendline("")
450 self.handle.expect("onos>")
451
452 self.handle.sendline("device-role "+
453 str(device_id) + " " +
454 str(node_id) + " " +
455 str(role))
456 i = self.handle.expect([
457 "Error",
458 "onos>"])
459
460 self.handle.sendline("")
461 self.handle.expect("onos>")
462
463 handle = self.handle.before
464
465 if i == 0:
466 main.log.error("device-role command returned error")
467 return handle
468 else:
469 return main.TRUE
470
andrewonlab86dc3082014-10-13 18:18:38 -0400471 except pexpect.EOF:
472 main.log.error(self.name + ": EOF exception found")
473 main.log.error(self.name + ": " + self.handle.before)
474 main.cleanup()
475 main.exit()
476 except:
477 main.log.info(self.name+" ::::::")
478 main.log.error( traceback.print_exc())
479 main.log.info(self.name+" ::::::")
480 main.cleanup()
481 main.exit()
482
andrewonlab3e15ead2014-10-15 14:21:34 -0400483 def paths(self, src_id, dst_id):
484 '''
485 Returns string of paths, and the cost.
486 Issues command: onos:paths <src> <dst>
487 '''
488 try:
489 self.handle.sendline("")
490 self.handle.expect("onos>")
491
492 self.handle.sendline("onos:paths "+
493 str(src_id) + " " + str(dst_id))
494 i = self.handle.expect([
495 "Error",
496 "onos>"])
497
498 self.handle.sendline("")
499 self.handle.expect("onos>")
500
501 handle = self.handle.before
502
503 if i == 0:
504 main.log.error("Error in getting paths")
andrewonlab7c211572014-10-15 16:45:20 -0400505 return (handle, "Error")
andrewonlab3e15ead2014-10-15 14:21:34 -0400506 else:
507 path = handle.split(";")[0]
508 cost = handle.split(";")[1]
509 return (path, cost)
510
511 except pexpect.EOF:
512 main.log.error(self.name + ": EOF exception found")
513 main.log.error(self.name + ": " + self.handle.before)
514 main.cleanup()
515 main.exit()
516 except:
517 main.log.info(self.name+" ::::::")
518 main.log.error( traceback.print_exc())
519 main.log.info(self.name+" ::::::")
520 main.cleanup()
521 main.exit()
522
523
524
525 #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 #***********************************