blob: 01e5838c10aec478e8581f0021b4189260680e28 [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
andrewonlab38d6ae22014-10-15 14:23:45 -0400281 def topology(self):
andrewonlabc2d05aa2014-10-13 16:51:10 -0400282 '''
283 Shows the current state of the topology
284 by issusing command: 'onos> onos:topology'
285 '''
andrewonlab95ce8322014-10-13 14:12:04 -0400286 try:
287 self.handle.sendline("")
288 self.handle.expect("onos>")
andrewonlab38d6ae22014-10-15 14:23:45 -0400289 #either onos:topology or 'topology' will work in CLI
andrewonlab95ce8322014-10-13 14:12:04 -0400290 self.handle.sendline("onos:topology")
291 self.handle.expect("onos>")
292
293 handle = self.handle.before
294
295 main.log.info("onos:topology returned: " +
296 str(handle))
297
298 return handle
299
300 except pexpect.EOF:
301 main.log.error(self.name + ": EOF exception found")
302 main.log.error(self.name + ": " + self.handle.before)
303 main.cleanup()
304 main.exit()
305 except:
306 main.log.info(self.name+" ::::::")
307 main.log.error( traceback.print_exc())
308 main.log.info(self.name+" ::::::")
309 main.cleanup()
310 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400311
312 def feature_install(self, feature_str):
313 '''
314 Installs a specified feature
315 by issuing command: 'onos> feature:install <feature_str>'
316 '''
317 try:
318 self.handle.sendline("")
319 self.handle.expect("onos>")
320
321 self.handle.sendline("feature:install "+str(feature_str))
322 self.handle.expect("onos>")
323
324 return main.TRUE
325
326 except pexpect.EOF:
327 main.log.error(self.name + ": EOF exception found")
328 main.log.error(self.name + ": " + self.handle.before)
329 main.cleanup()
330 main.exit()
331 except:
332 main.log.info(self.name+" ::::::")
333 main.log.error( traceback.print_exc())
334 main.log.info(self.name+" ::::::")
335 main.cleanup()
336 main.exit()
337
338 def feature_uninstall(self, feature_str):
339 '''
340 Uninstalls a specified feature
341 by issuing command: 'onos> feature:uninstall <feature_str>'
342 '''
343 try:
344 self.handle.sendline("")
345 self.handle.expect("onos>")
346
347 self.handle.sendline("feature:uninstall "+str(feature_str))
348 self.handle.expect("onos>")
349
350 return main.TRUE
351
352 except pexpect.EOF:
353 main.log.error(self.name + ": EOF exception found")
354 main.log.error(self.name + ": " + self.handle.before)
355 main.cleanup()
356 main.exit()
357 except:
358 main.log.info(self.name+" ::::::")
359 main.log.error( traceback.print_exc())
360 main.log.info(self.name+" ::::::")
361 main.cleanup()
362 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400363
andrewonlab86dc3082014-10-13 18:18:38 -0400364 def devices(self, grep_str=""):
365 '''
366 Lists all infrastructure devices
367 Optional argument:
368 * grep_str - pass in a string to grep
369 '''
370 try:
371 self.handle.sendline("")
372 self.handle.expect("onos>")
373
374 if not grep_str:
375 self.handle.sendline("devices")
376 self.handle.expect("onos>")
377 else:
378 self.handle.sendline("devices | grep '"+
379 str(grep_str)+"'")
380 self.handle.expect("onos>")
381
382 handle = self.handle.before
383 handle += self.handle.after
384
385 self.handle.sendline("")
386 self.handle.expect("onos>")
387
388 handle += self.handle.before
389 handle += self.handle.after
390
391 return handle
392 except pexpect.EOF:
393 main.log.error(self.name + ": EOF exception found")
394 main.log.error(self.name + ": " + self.handle.before)
395 main.cleanup()
396 main.exit()
397 except:
398 main.log.info(self.name+" ::::::")
399 main.log.error( traceback.print_exc())
400 main.log.info(self.name+" ::::::")
401 main.cleanup()
402 main.exit()
403
andrewonlab3e15ead2014-10-15 14:21:34 -0400404 def paths(self, src_id, dst_id):
405 '''
406 Returns string of paths, and the cost.
407 Issues command: onos:paths <src> <dst>
408 '''
409 try:
410 self.handle.sendline("")
411 self.handle.expect("onos>")
412
413 self.handle.sendline("onos:paths "+
414 str(src_id) + " " + str(dst_id))
415 i = self.handle.expect([
416 "Error",
417 "onos>"])
418
419 self.handle.sendline("")
420 self.handle.expect("onos>")
421
422 handle = self.handle.before
423
424 if i == 0:
425 main.log.error("Error in getting paths")
426 return handle
427 else:
428 path = handle.split(";")[0]
429 cost = handle.split(";")[1]
430 return (path, cost)
431
432 except pexpect.EOF:
433 main.log.error(self.name + ": EOF exception found")
434 main.log.error(self.name + ": " + self.handle.before)
435 main.cleanup()
436 main.exit()
437 except:
438 main.log.info(self.name+" ::::::")
439 main.log.error( traceback.print_exc())
440 main.log.info(self.name+" ::::::")
441 main.cleanup()
442 main.exit()
443
444
445
446 #Wrapper functions ****************
andrewonlab7e4d2d32014-10-15 13:23:21 -0400447 #Wrapper functions use existing driver
448 #functions and extends their use case.
449 #For example, we may use the output of
450 #a normal driver function, and parse it
451 #using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -0400452
andrewonlab7e4d2d32014-10-15 13:23:21 -0400453 def get_all_devices_id(self):
454 '''
455 Use 'devices' function to obtain list of all devices
456 and parse the result to obtain a list of all device
457 id's. Returns this list. Returns empty list if no
458 devices exist
459 List is ordered sequentially
andrewonlab3e15ead2014-10-15 14:21:34 -0400460
461 This function may be useful if you are not sure of the
462 device id, and wish to execute other commands using
463 the ids. By obtaining the list of device ids on the fly,
464 you can iterate through the list to get mastership, etc.
andrewonlab7e4d2d32014-10-15 13:23:21 -0400465 '''
466 try:
467 #Call devices and store result string
468 devices_str = self.devices()
469 id_list = []
470
471 if not devices_str:
472 main.log.info("There are no devices to get id from")
473 return id_list
474
475 #Split the string into list by comma
476 device_list = devices_str.split(",")
477 #Get temporary list of all arguments with string 'id='
478 temp_list = [dev for dev in device_list if "id=" in dev]
479 #Split list further into arguments before and after string
480 # 'id='. Get the latter portion (the actual device id) and
481 # append to id_list
482 for arg in temp_list:
483 id_list.append(arg.split("id=")[1])
484
485 return id_list
486
487 except pexpect.EOF:
488 main.log.error(self.name + ": EOF exception found")
489 main.log.error(self.name + ": " + self.handle.before)
490 main.cleanup()
491 main.exit()
492 except:
493 main.log.info(self.name+" ::::::")
494 main.log.error( traceback.print_exc())
495 main.log.info(self.name+" ::::::")
496 main.cleanup()
497 main.exit()
498
499
500 #***********************************