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