blob: 90267af70e9e1b5b22d1eea9e4d51aac6446a277 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions 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
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
Jon Hall30b82fa2015-03-04 17:15:43 -080022import json
23import types
Jon Hallbd16b922015-03-26 17:53:15 -070024import time
kelvin8ec71442015-01-15 16:57:00 -080025sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040026from drivers.common.clidriver import CLI
27
andrewonlab95ce8322014-10-13 14:12:04 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
andrewonlab95ce8322014-10-13 14:12:04 -040042 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080043 """
andrewonlab95ce8322014-10-13 14:12:04 -040044 try:
45 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080046 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070047 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040048 for key in self.options:
49 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080050 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040051 break
kelvin-onlabfb521662015-02-27 09:52:40 -080052 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054
kelvin8ec71442015-01-15 16:57:00 -080055 self.name = self.options[ 'name' ]
56 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080057 user_name=self.user_name,
58 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080059 port=self.port,
60 pwd=self.pwd,
61 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040062
kelvin8ec71442015-01-15 16:57:00 -080063 self.handle.sendline( "cd " + self.home )
64 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 if self.handle:
66 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080067 else:
68 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040069 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080070 except TypeError:
71 main.log.exception( self.name + ": Object not as expected" )
72 return None
andrewonlab95ce8322014-10-13 14:12:04 -040073 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080074 main.log.error( self.name + ": EOF exception found" )
75 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080078 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080079 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040080 main.cleanup()
81 main.exit()
82
kelvin8ec71442015-01-15 16:57:00 -080083 def disconnect( self ):
84 """
andrewonlab95ce8322014-10-13 14:12:04 -040085 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080086 """
Jon Halld61331b2015-02-17 16:35:47 -080087 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040088 try:
Jon Hall61282e32015-03-19 11:34:11 -070089 if self.handle:
90 i = self.logout()
91 if i == main.TRUE:
92 self.handle.sendline( "" )
93 self.handle.expect( "\$" )
94 self.handle.sendline( "exit" )
95 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080096 except TypeError:
97 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080098 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800100 main.log.error( self.name + ": EOF exception found" )
101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700102 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700103 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700104 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 response = main.FALSE
108 return response
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def logout( self ):
111 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500112 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700113 Returns main.TRUE if exited CLI and
114 main.FALSE on timeout (not guranteed you are disconnected)
115 None on TypeError
116 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800117 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500118 try:
Jon Hall61282e32015-03-19 11:34:11 -0700119 if self.handle:
120 self.handle.sendline( "" )
121 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
122 timeout=10 )
123 if i == 0: # In ONOS CLI
124 self.handle.sendline( "logout" )
125 self.handle.expect( "\$" )
126 return main.TRUE
127 elif i == 1: # not in CLI
128 return main.TRUE
129 elif i == 3: # Timeout
130 return main.FALSE
131 else:
andrewonlab9627f432014-11-14 12:45:10 -0500132 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800133 except TypeError:
134 main.log.exception( self.name + ": Object not as expected" )
135 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800137 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700138 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 main.cleanup()
140 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700141 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700142 main.log.error( self.name +
143 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800145 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500146 main.cleanup()
147 main.exit()
148
kelvin-onlabd3b64892015-01-20 13:26:24 -0800149 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800150 """
andrewonlab95ce8322014-10-13 14:12:04 -0400151 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800152
andrewonlab95ce8322014-10-13 14:12:04 -0400153 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800154 """
andrewonlab95ce8322014-10-13 14:12:04 -0400155 try:
156 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400158 main.cleanup()
159 main.exit()
160 else:
kelvin8ec71442015-01-15 16:57:00 -0800161 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800162 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800163 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400164 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800165 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800166 handleBefore = self.handle.before
167 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800168 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800169 self.handle.sendline("")
170 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800171 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400172
kelvin-onlabd3b64892015-01-20 13:26:24 -0800173 main.log.info( "Cell call returned: " + handleBefore +
174 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400175
176 return main.TRUE
177
Jon Halld4d4b372015-01-28 16:02:41 -0800178 except TypeError:
179 main.log.exception( self.name + ": Object not as expected" )
180 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400181 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800182 main.log.error( self.name + ": eof exception found" )
183 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400184 main.cleanup()
185 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800186 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800187 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400188 main.cleanup()
189 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800190
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800192 """
Jon Hallefbd9792015-03-05 16:11:36 -0800193 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800194 by user would be used to set the current karaf shell idle timeout.
195 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800196 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 Below is an example to start a session with 60 seconds idle timeout
198 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800199
Hari Krishna25d42f72015-01-05 15:08:28 -0800200 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800202
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 Note: karafTimeout is left as str so that this could be read
204 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrewonlab95ce8322014-10-13 14:12:04 -0400206 try:
kelvin8ec71442015-01-15 16:57:00 -0800207 self.handle.sendline( "" )
208 x = self.handle.expect( [
209 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500210
211 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800212 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500213 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400214
kelvin8ec71442015-01-15 16:57:00 -0800215 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800217 i = self.handle.expect( [
218 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800219 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400220
221 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 # If failed, send ctrl+c to process and try again
234 main.log.info( "Starting CLI failed. Retrying..." )
235 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800237 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
238 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400239 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800241 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800242 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800243 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "config:property-set -p org.apache.karaf.shell\
245 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800246 karafTimeout )
247 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800249 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400250 return main.TRUE
251 else:
kelvin8ec71442015-01-15 16:57:00 -0800252 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400254 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400255
Jon Halld4d4b372015-01-28 16:02:41 -0800256 except TypeError:
257 main.log.exception( self.name + ": Object not as expected" )
258 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.error( self.name + ": EOF exception found" )
261 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400262 main.cleanup()
263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800265 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400266 main.cleanup()
267 main.exit()
268
Jon Hallefbd9792015-03-05 16:11:36 -0800269 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800270 """
271 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800273 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800274 Available level: DEBUG, TRACE, INFO, WARN, ERROR
275 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800276 """
277 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800278 lvlStr = ""
279 if level:
280 lvlStr = "--level=" + level
281
kelvin-onlab9f541032015-02-04 16:19:53 -0800282 self.handle.sendline( "" )
283 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800284 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800285 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800286
kelvin-onlab9f541032015-02-04 16:19:53 -0800287 response = self.handle.before
288 if re.search( "Error", response ):
289 return main.FALSE
290 return main.TRUE
291
292 except pexpect.EOF:
293 main.log.error( self.name + ": EOF exception found" )
294 main.log.error( self.name + ": " + self.handle.before )
295 main.cleanup()
296 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800297 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800298 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400299 main.cleanup()
300 main.exit()
301
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800303 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800304 Send a completely user specified string to
305 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400306 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800307
andrewonlaba18f6bf2014-10-13 19:31:54 -0400308 Warning: There are no sanity checking to commands
309 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800310 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400311 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800312 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
313 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800314 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800315 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
316 response = self.handle.before
317 if i == 2:
318 self.handle.sendline()
319 self.handle.expect( "\$" )
320 response += self.handle.before
321 print response
322 try:
323 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700324 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800325 pass
326 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800327 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800328 + self.name + "." )
Jon Hall7bdfc122015-01-23 11:45:32 -0800329 # Remove control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800330 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800331 response = ansiEscape.sub( '', response )
kelvin-onlabfb521662015-02-27 09:52:40 -0800332 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800333 response = re.sub( r"\s\r", "", response )
334 response = response.strip()
335 # parse for just the output, remove the cmd from response
336 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800337 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800338 except TypeError:
339 main.log.exception( self.name + ": Object not as expected" )
340 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400341 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800342 main.log.error( self.name + ": EOF exception found" )
343 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400344 main.cleanup()
345 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800346 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800347 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400348 main.cleanup()
349 main.exit()
350
kelvin8ec71442015-01-15 16:57:00 -0800351 # IMPORTANT NOTE:
352 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 # the cli command changing 'a:b' with 'aB'.
354 # Ex ) onos:topology > onosTopology
355 # onos:links > onosLinks
356 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800357
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800359 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400360 Adds a new cluster node by ID and address information.
361 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800362 * nodeId
363 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400364 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800365 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800366 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400367 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 cmdStr = "add-node " + str( nodeId ) + " " +\
369 str( ONOSIp ) + " " + str( tcpPort )
370 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800371 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800372 main.log.error( "Error in adding node" )
373 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800374 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400375 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800376 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400377 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800378 except TypeError:
379 main.log.exception( self.name + ": Object not as expected" )
380 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800382 main.log.error( self.name + ": EOF exception found" )
383 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400384 main.cleanup()
385 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800386 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800387 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400388 main.cleanup()
389 main.exit()
390
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800392 """
andrewonlab86dc3082014-10-13 18:18:38 -0400393 Removes a cluster by ID
394 Issues command: 'remove-node [<node-id>]'
395 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800396 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800397 """
andrewonlab86dc3082014-10-13 18:18:38 -0400398 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400399
kelvin-onlabd3b64892015-01-20 13:26:24 -0800400 cmdStr = "remove-node " + str( nodeId )
401 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800402 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400403
404 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800405
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400412 main.cleanup()
413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400416 main.cleanup()
417 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400418
Jon Hall61282e32015-03-19 11:34:11 -0700419 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800420 """
andrewonlab7c211572014-10-15 16:45:20 -0400421 List the nodes currently visible
422 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700423 Optional argument:
424 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800425 """
andrewonlab7c211572014-10-15 16:45:20 -0400426 try:
Jon Hall61282e32015-03-19 11:34:11 -0700427 if jsonFormat:
428 cmdStr = "nodes -j"
429 output = self.sendline( cmdStr )
430 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
431 parsedOutput = ansiEscape.sub( '', output )
432 return parsedOutput
433 else:
434 cmdStr = "nodes"
435 output = self.sendline( cmdStr )
436 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800437 except TypeError:
438 main.log.exception( self.name + ": Object not as expected" )
439 return None
andrewonlab7c211572014-10-15 16:45:20 -0400440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400443 main.cleanup()
444 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800445 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800446 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400447 main.cleanup()
448 main.exit()
449
kelvin8ec71442015-01-15 16:57:00 -0800450 def topology( self ):
451 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700452 Definition:
453 Returns the ouput of topology command.
454 Return:
455 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlab95ce8322014-10-13 14:12:04 -0400457 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800458 # either onos:topology or 'topology' will work in CLI
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700459 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 handle = self.sendline( cmdStr )
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700461 main.log.info( "topology -j returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400462 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800463 except TypeError:
464 main.log.exception( self.name + ": Object not as expected" )
465 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400466 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400469 main.cleanup()
470 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800472 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400473 main.cleanup()
474 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800475
kelvin-onlabd3b64892015-01-20 13:26:24 -0800476 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800477 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800478 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800480 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400481 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800482 cmdStr = "feature:install " + str( featureStr )
483 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800484 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400485 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800486 except TypeError:
487 main.log.exception( self.name + ": Object not as expected" )
488 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400489 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800490 main.log.error( self.name + ": EOF exception found" )
491 main.log.error( self.name + ": " + self.handle.before )
492 main.log.report( "Failed to install feature" )
493 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400494 main.cleanup()
495 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800496 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800497 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800498 main.log.report( "Failed to install feature" )
499 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400500 main.cleanup()
501 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800502
kelvin-onlabd3b64892015-01-20 13:26:24 -0800503 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800504 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400505 Uninstalls a specified feature
506 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800507 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400508 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800509 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
510 handle = self.sendline( cmdStr )
511 if handle != '':
512 cmdStr = "feature:uninstall " + str( featureStr )
513 self.sendline( cmdStr )
514 # TODO: Check for possible error responses from karaf
515 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800516 main.log.info( "Feature needs to be installed before " +
517 "uninstalling it" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400518 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800519 except TypeError:
520 main.log.exception( self.name + ": Object not as expected" )
521 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400525 main.cleanup()
526 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800527 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800528 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400529 main.cleanup()
530 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800531
jenkins7ead5a82015-03-13 10:28:21 -0700532 def deviceRemove( self, deviceId ):
533 """
534 Removes particular device from storage
535
536 TODO: refactor this function
537 """
538 try:
539 cmdStr = "device-remove "+str(deviceId)
Jon Hallbe379602015-03-24 13:39:32 -0700540 self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -0700541 return main.TRUE
542 except TypeError:
543 main.log.exception( self.name + ": Object not as expected" )
544 return None
545 except pexpect.EOF:
546 main.log.error( self.name + ": EOF exception found" )
547 main.log.error( self.name + ": " + self.handle.before )
548 main.cleanup()
549 main.exit()
550 except Exception:
551 main.log.exception( self.name + ": Uncaught exception!" )
552 main.cleanup()
553 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700554
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800556 """
Jon Hall7b02d952014-10-17 20:14:54 -0400557 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400558 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlab86dc3082014-10-13 18:18:38 -0400561 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 if jsonFormat:
563 cmdStr = "devices -j"
564 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800565 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800566 handle variable here contains some ANSI escape color code
567 sequences at the end which are invisible in the print command
568 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800569 function. The repr( handle ) output when printed shows the
570 ANSI escape sequences. In json.loads( somestring ), this
571 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800572 json.loads would fail with the escape sequence. So we take off
573 that escape sequence using:
574
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
576 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800577 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
579 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400580 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400581 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 cmdStr = "devices"
583 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400584 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800585 except TypeError:
586 main.log.exception( self.name + ": Object not as expected" )
587 return None
andrewonlab7c211572014-10-15 16:45:20 -0400588 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800589 main.log.error( self.name + ": EOF exception found" )
590 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400591 main.cleanup()
592 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800593 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800594 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400595 main.cleanup()
596 main.exit()
597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800599 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800600 This balances the devices across all controllers
601 by issuing command: 'onos> onos:balance-masters'
602 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800604 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 cmdStr = "onos:balance-masters"
606 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800607 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800608 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800609 except TypeError:
610 main.log.exception( self.name + ": Object not as expected" )
611 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800613 main.log.error( self.name + ": EOF exception found" )
614 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800615 main.cleanup()
616 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800617 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800618 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800619 main.cleanup()
620 main.exit()
621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800623 """
Jon Halle8217482014-10-17 13:49:14 -0400624 Lists all core links
625 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800627 """
Jon Halle8217482014-10-17 13:49:14 -0400628 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 if jsonFormat:
630 cmdStr = "links -j"
631 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800632 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800633 handle variable here contains some ANSI escape color code
634 sequences at the end which are invisible in the print command
635 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800636 function. The repr( handle ) output when printed shows the ANSI
637 escape sequences. In json.loads( somestring ), this somestring
638 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800639 fail with the escape sequence. So we take off that escape
640 sequence using:
641
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
643 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800644 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800645 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
646 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400647 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400648 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800649 cmdStr = "links"
650 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400651 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800652 except TypeError:
653 main.log.exception( self.name + ": Object not as expected" )
654 return None
Jon Halle8217482014-10-17 13:49:14 -0400655 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800656 main.log.error( self.name + ": EOF exception found" )
657 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400658 main.cleanup()
659 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800660 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800661 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400662 main.cleanup()
663 main.exit()
664
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800666 """
Jon Halle8217482014-10-17 13:49:14 -0400667 Lists all ports
668 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800669 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800670 """
Jon Halle8217482014-10-17 13:49:14 -0400671 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 if jsonFormat:
673 cmdStr = "ports -j"
674 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800675 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800676 handle variable here contains some ANSI escape color code
677 sequences at the end which are invisible in the print command
678 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800679 function. The repr( handle ) output when printed shows the ANSI
680 escape sequences. In json.loads( somestring ), this somestring
681 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800682 fail with the escape sequence. So we take off that escape
Jon Hallefbd9792015-03-05 16:11:36 -0800683 sequence using the following commands:
Jon Halle3f39ff2015-01-13 11:50:53 -0800684
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
686 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800687 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
689 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400690 return handle1
691
Jon Halle8217482014-10-17 13:49:14 -0400692 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 cmdStr = "ports"
694 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800695 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800696 except TypeError:
697 main.log.exception( self.name + ": Object not as expected" )
698 return None
Jon Halle8217482014-10-17 13:49:14 -0400699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400702 main.cleanup()
703 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400706 main.cleanup()
707 main.exit()
708
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800710 """
Jon Hall983a1702014-10-28 18:44:22 -0400711 Lists all devices and the controllers with roles assigned to them
712 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800714 """
andrewonlab7c211572014-10-15 16:45:20 -0400715 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 if jsonFormat:
717 cmdStr = "roles -j"
718 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800719 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800720 handle variable here contains some ANSI escape color code
721 sequences at the end which are invisible in the print command
722 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800723 function. The repr( handle ) output when printed shows the ANSI
724 escape sequences. In json.loads( somestring ), this somestring
725 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800726 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500727
Jon Halle3f39ff2015-01-13 11:50:53 -0800728 So we take off that escape sequence using the following
729 commads:
730
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
732 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800733 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
735 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400736 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400737
andrewonlab7c211572014-10-15 16:45:20 -0400738 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 cmdStr = "roles"
740 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800741 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800742 except TypeError:
743 main.log.exception( self.name + ": Object not as expected" )
744 return None
Jon Hall983a1702014-10-28 18:44:22 -0400745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400748 main.cleanup()
749 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800750 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800751 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400752 main.cleanup()
753 main.exit()
754
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800756 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800757 Given the a string containing the json representation of the "roles"
758 cli command and a partial or whole device id, returns a json object
759 containing the roles output for the first device whose id contains
760 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400761
762 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800763 A dict of the role assignments for the given device or
764 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall983a1702014-10-28 18:44:22 -0400766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400768 return None
769 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 rawRoles = self.roles()
771 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800772 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800774 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400776 return device
777 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800778 except TypeError:
779 main.log.exception( self.name + ": Object not as expected" )
780 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400784 main.cleanup()
785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800787 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400788 main.cleanup()
789 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800790
kelvin-onlabd3b64892015-01-20 13:26:24 -0800791 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800792 """
Jon Hall94fd0472014-12-08 11:52:42 -0800793 Iterates through each device and checks if there is a master assigned
794 Returns: main.TRUE if each device has a master
795 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800796 """
Jon Hall94fd0472014-12-08 11:52:42 -0800797 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 rawRoles = self.roles()
799 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800800 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800802 # print device
803 if device[ 'master' ] == "none":
804 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800805 return main.FALSE
806 return main.TRUE
807
Jon Halld4d4b372015-01-28 16:02:41 -0800808 except TypeError:
809 main.log.exception( self.name + ": Object not as expected" )
810 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800811 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.error( self.name + ": EOF exception found" )
813 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800814 main.cleanup()
815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800817 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800818 main.cleanup()
819 main.exit()
820
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800822 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400823 Returns string of paths, and the cost.
824 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800825 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400826 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
828 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800829 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800830 main.log.error( "Error in getting paths" )
831 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400832 else:
kelvin8ec71442015-01-15 16:57:00 -0800833 path = handle.split( ";" )[ 0 ]
834 cost = handle.split( ";" )[ 1 ]
835 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800836 except TypeError:
837 main.log.exception( self.name + ": Object not as expected" )
838 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400839 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400842 main.cleanup()
843 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800844 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800845 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400846 main.cleanup()
847 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800848
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800850 """
Jon Hallffb386d2014-11-21 13:43:38 -0800851 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800854 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400855 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 if jsonFormat:
857 cmdStr = "hosts -j"
858 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800859 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800860 handle variable here contains some ANSI escape color code
861 sequences at the end which are invisible in the print command
862 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800863 function. The repr( handle ) output when printed shows the ANSI
864 escape sequences. In json.loads( somestring ), this somestring
865 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800866 fail with the escape sequence. So we take off that escape
867 sequence using:
868
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
870 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800871 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
873 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400874 return handle1
875 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 cmdStr = "hosts"
877 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400878 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800879 except TypeError:
880 main.log.exception( self.name + ": Object not as expected" )
881 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800883 main.log.error( self.name + ": EOF exception found" )
884 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400885 main.cleanup()
886 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800887 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800888 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400889 main.cleanup()
890 main.exit()
891
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800893 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400894 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800895
Jon Hallefbd9792015-03-05 16:11:36 -0800896 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800897 partial mac address
898
Jon Hall42db6dc2014-10-24 19:03:48 -0400899 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800900 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400901 try:
kelvin8ec71442015-01-15 16:57:00 -0800902 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400903 return None
904 else:
905 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 rawHosts = self.hosts()
907 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800908 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800910 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800911 if not host:
912 pass
913 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400914 return host
915 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800916 except TypeError:
917 main.log.exception( self.name + ": Object not as expected" )
918 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( self.name + ": EOF exception found" )
921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400922 main.cleanup()
923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400926 main.cleanup()
927 main.exit()
928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800930 """
931 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400932 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800933
andrewonlab3f0a4af2014-10-17 12:25:14 -0400934 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400936 IMPORTANT:
937 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800938 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400939 Furthermore, it assumes that value of VLAN is '-1'
940 Description:
kelvin8ec71442015-01-15 16:57:00 -0800941 Converts mininet hosts ( h1, h2, h3... ) into
942 ONOS format ( 00:00:00:00:00:01/-1 , ... )
943 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400944 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400946
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800948 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 hostHex = hex( int( host ) ).zfill( 12 )
950 hostHex = str( hostHex ).replace( 'x', '0' )
951 i = iter( str( hostHex ) )
952 hostHex = ":".join( a + b for a, b in zip( i, i ) )
953 hostHex = hostHex + "/-1"
954 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400957
Jon Halld4d4b372015-01-28 16:02:41 -0800958 except TypeError:
959 main.log.exception( self.name + ": Object not as expected" )
960 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400964 main.cleanup()
965 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800966 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800967 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400968 main.cleanup()
969 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlabe6745342014-10-17 14:29:13 -0400973 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 * hostIdOne: ONOS host id for host1
975 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400976 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800977 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500978 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800979 Returns:
980 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800981 """
andrewonlabe6745342014-10-17 14:29:13 -0400982 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 cmdStr = "add-host-intent " + str( hostIdOne ) +\
984 " " + str( hostIdTwo )
985 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800986 if re.search( "Error", handle ):
987 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700988 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800989 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800990 else:
991 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800992 str( hostIdOne ) + " and " + str( hostIdTwo ) )
993 match = re.search('id=0x([\da-f]+),', handle)
994 if match:
995 return match.group()[3:-1]
996 else:
997 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700998 main.log.debug( "Response from ONOS was: " +
999 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001000 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001001 except TypeError:
1002 main.log.exception( self.name + ": Object not as expected" )
1003 return None
andrewonlabe6745342014-10-17 14:29:13 -04001004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.error( self.name + ": EOF exception found" )
1006 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001007 main.cleanup()
1008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001011 main.cleanup()
1012 main.exit()
1013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab7b31d232014-10-24 13:31:47 -04001016 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 * ingressDevice: device id of ingress device
1018 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001019 Optional:
1020 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001021 Description:
1022 Adds an optical intent by specifying an ingress and egress device
1023 Returns:
1024 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001025 """
andrewonlab7b31d232014-10-24 13:31:47 -04001026 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1028 " " + str( egressDevice )
1029 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001030 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001031 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001032 main.log.error( "Error in adding Optical intent" )
1033 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001034 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001035 main.log.info( "Optical intent installed between " +
1036 str( ingressDevice ) + " and " +
1037 str( egressDevice ) )
1038 match = re.search('id=0x([\da-f]+),', handle)
1039 if match:
1040 return match.group()[3:-1]
1041 else:
1042 main.log.error( "Error, intent ID not found" )
1043 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001044 except TypeError:
1045 main.log.exception( self.name + ": Object not as expected" )
1046 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001048 main.log.error( self.name + ": EOF exception found" )
1049 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001050 main.cleanup()
1051 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001052 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001053 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001054 main.cleanup()
1055 main.exit()
1056
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001058 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 ingressDevice,
1060 egressDevice,
1061 portIngress="",
1062 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001063 ethType="",
1064 ethSrc="",
1065 ethDst="",
1066 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001067 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001068 ipProto="",
1069 ipSrc="",
1070 ipDst="",
1071 tcpSrc="",
1072 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001077 Optional:
1078 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001079 * ethSrc: specify ethSrc ( i.e. src mac addr )
1080 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001081 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001083 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001085 * ipSrc: specify ip source address
1086 * ipDst: specify ip destination address
1087 * tcpSrc: specify tcp source port
1088 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001089 Description:
kelvin8ec71442015-01-15 16:57:00 -08001090 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001091 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001092 Returns:
1093 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001094
Jon Halle3f39ff2015-01-13 11:50:53 -08001095 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001096 options developers provide for point-to-point
1097 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001098 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001099 try:
kelvin8ec71442015-01-15 16:57:00 -08001100 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001101 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001103 and not ipProto and not ipSrc and not ipDst \
1104 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001105 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001106
andrewonlab289e4b72014-10-21 21:24:18 -04001107 else:
andrewonlab36af3822014-11-18 17:48:18 -05001108 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001109
andrewonlab0c0a6772014-10-22 12:31:18 -04001110 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001111 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001112 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001113 cmd += " --ethSrc " + str( ethSrc )
1114 if ethDst:
1115 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001116 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001117 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001119 cmd += " --lambda "
1120 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001121 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001122 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001123 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001124 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001125 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001126 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001127 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001128 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001129 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001130
kelvin8ec71442015-01-15 16:57:00 -08001131 # Check whether the user appended the port
1132 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 if "/" in ingressDevice:
1134 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001135 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001137 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001138 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001139 # Would it make sense to throw an exception and exit
1140 # the test?
1141 return None
andrewonlab36af3822014-11-18 17:48:18 -05001142
kelvin8ec71442015-01-15 16:57:00 -08001143 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 str( ingressDevice ) + "/" +\
1145 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001146
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 if "/" in egressDevice:
1148 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001149 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001151 main.log.error( "You must specify the egress port" )
1152 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001153
kelvin8ec71442015-01-15 16:57:00 -08001154 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 str( egressDevice ) + "/" +\
1156 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001157
kelvin-onlab898a6c62015-01-16 14:13:53 -08001158 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001159 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001160 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001161 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001162 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001163 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 # TODO: print out all the options in this message?
1165 main.log.info( "Point-to-point intent installed between " +
1166 str( ingressDevice ) + " and " +
1167 str( egressDevice ) )
1168 match = re.search('id=0x([\da-f]+),', handle)
1169 if match:
1170 return match.group()[3:-1]
1171 else:
1172 main.log.error( "Error, intent ID not found" )
1173 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001174 except TypeError:
1175 main.log.exception( self.name + ": Object not as expected" )
1176 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001180 main.cleanup()
1181 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001182 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001183 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001184 main.cleanup()
1185 main.exit()
1186
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001188 self,
shahshreyac2f97072015-03-19 17:04:29 -07001189 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001191 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001193 ethType="",
1194 ethSrc="",
1195 ethDst="",
1196 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001198 ipProto="",
1199 ipSrc="",
1200 ipDst="",
1201 tcpSrc="",
1202 tcpDst="",
1203 setEthSrc="",
1204 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001205 """
shahshreyad0c80432014-12-04 16:56:05 -08001206 Note:
shahshreya70622b12015-03-19 17:19:00 -07001207 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001208 is same. That is, all ingress devices include port numbers
1209 with a "/" or all ingress devices could specify device
1210 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001211 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001212 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001213 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001215 Optional:
1216 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001217 * ethSrc: specify ethSrc ( i.e. src mac addr )
1218 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001219 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001221 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001222 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001223 * ipSrc: specify ip source address
1224 * ipDst: specify ip destination address
1225 * tcpSrc: specify tcp source port
1226 * tcpDst: specify tcp destination port
1227 * setEthSrc: action to Rewrite Source MAC Address
1228 * setEthDst: action to Rewrite Destination MAC Address
1229 Description:
kelvin8ec71442015-01-15 16:57:00 -08001230 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001231 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 Returns:
1233 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001234
Jon Halle3f39ff2015-01-13 11:50:53 -08001235 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001236 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001237 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001238 """
shahshreyad0c80432014-12-04 16:56:05 -08001239 try:
kelvin8ec71442015-01-15 16:57:00 -08001240 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001241 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001243 and not ipProto and not ipSrc and not ipDst\
1244 and not tcpSrc and not tcpDst and not setEthSrc\
1245 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001246 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001247
1248 else:
1249 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001250
shahshreyad0c80432014-12-04 16:56:05 -08001251 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001252 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001253 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " --ethSrc " + str( ethSrc )
1255 if ethDst:
1256 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001257 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001258 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001260 cmd += " --lambda "
1261 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001262 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001263 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001264 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001265 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001267 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001268 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001269 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001270 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001271 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001272 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001273 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001274 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001275
kelvin8ec71442015-01-15 16:57:00 -08001276 # Check whether the user appended the port
1277 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001278
1279 if portIngressList is None:
1280 for ingressDevice in ingressDeviceList:
1281 if "/" in ingressDevice:
1282 cmd += " " + str( ingressDevice )
1283 else:
1284 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001285 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001286 # TODO: perhaps more meaningful return
1287 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001288 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001289 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hallbe379602015-03-24 13:39:32 -07001290 for ingressDevice, portIngress in zip( ingressDeviceList, portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001291 cmd += " " + \
1292 str( ingressDevice ) + "/" +\
1293 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001294 else:
1295 main.log.error( "Device list and port list does not have the same length" )
1296 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 if "/" in egressDevice:
1298 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001299 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001301 main.log.error( "You must specify " +
1302 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001303 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001304
kelvin8ec71442015-01-15 16:57:00 -08001305 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 str( egressDevice ) + "/" +\
1307 str( portEgress )
shahshreyac2f97072015-03-19 17:04:29 -07001308
kelvin8ec71442015-01-15 16:57:00 -08001309 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001310 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001311 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001312 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001313 main.log.error( "Error in adding multipoint-to-singlepoint " +
1314 "intent" )
1315 return None
shahshreyad0c80432014-12-04 16:56:05 -08001316 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001317 match = re.search('id=0x([\da-f]+),', handle)
1318 if match:
1319 return match.group()[3:-1]
1320 else:
1321 main.log.error( "Error, intent ID not found" )
1322 return None
1323 except TypeError:
1324 main.log.exception( self.name + ": Object not as expected" )
1325 return None
1326 except pexpect.EOF:
1327 main.log.error( self.name + ": EOF exception found" )
1328 main.log.error( self.name + ": " + self.handle.before )
1329 main.cleanup()
1330 main.exit()
1331 except Exception:
1332 main.log.exception( self.name + ": Uncaught exception!" )
1333 main.cleanup()
1334 main.exit()
1335
1336 def addSinglepointToMultipointIntent(
1337 self,
1338 ingressDevice,
1339 egressDeviceList,
1340 portIngress="",
1341 portEgressList=None,
1342 ethType="",
1343 ethSrc="",
1344 ethDst="",
1345 bandwidth="",
1346 lambdaAlloc=False,
1347 ipProto="",
1348 ipSrc="",
1349 ipDst="",
1350 tcpSrc="",
1351 tcpDst="",
1352 setEthSrc="",
1353 setEthDst="" ):
1354 """
1355 Note:
1356 This function assumes the format of all egress devices
1357 is same. That is, all egress devices include port numbers
1358 with a "/" or all egress devices could specify device
1359 ids and port numbers seperately.
1360 Required:
1361 * EgressDeviceList: List of device ids of egress device
1362 ( Atleast 2 eress devices required in the list )
1363 * ingressDevice: device id of ingress device
1364 Optional:
1365 * ethType: specify ethType
1366 * ethSrc: specify ethSrc ( i.e. src mac addr )
1367 * ethDst: specify ethDst ( i.e. dst mac addr )
1368 * bandwidth: specify bandwidth capacity of link
1369 * lambdaAlloc: if True, intent will allocate lambda
1370 for the specified intent
1371 * ipProto: specify ip protocol
1372 * ipSrc: specify ip source address
1373 * ipDst: specify ip destination address
1374 * tcpSrc: specify tcp source port
1375 * tcpDst: specify tcp destination port
1376 * setEthSrc: action to Rewrite Source MAC Address
1377 * setEthDst: action to Rewrite Destination MAC Address
1378 Description:
1379 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1380 specifying device id's and optional fields
1381 Returns:
1382 A string of the intent id or None on error
1383
1384 NOTE: This function may change depending on the
1385 options developers provide for singlepoint-to-multipoint
1386 intent via cli
1387 """
1388 try:
1389 # If there are no optional arguments
1390 if not ethType and not ethSrc and not ethDst\
1391 and not bandwidth and not lambdaAlloc\
1392 and not ipProto and not ipSrc and not ipDst\
1393 and not tcpSrc and not tcpDst and not setEthSrc\
1394 and not setEthDst:
1395 cmd = "add-single-to-multi-intent"
1396
1397 else:
1398 cmd = "add-single-to-multi-intent"
1399
1400 if ethType:
1401 cmd += " --ethType " + str( ethType )
1402 if ethSrc:
1403 cmd += " --ethSrc " + str( ethSrc )
1404 if ethDst:
1405 cmd += " --ethDst " + str( ethDst )
1406 if bandwidth:
1407 cmd += " --bandwidth " + str( bandwidth )
1408 if lambdaAlloc:
1409 cmd += " --lambda "
1410 if ipProto:
1411 cmd += " --ipProto " + str( ipProto )
1412 if ipSrc:
1413 cmd += " --ipSrc " + str( ipSrc )
1414 if ipDst:
1415 cmd += " --ipDst " + str( ipDst )
1416 if tcpSrc:
1417 cmd += " --tcpSrc " + str( tcpSrc )
1418 if tcpDst:
1419 cmd += " --tcpDst " + str( tcpDst )
1420 if setEthSrc:
1421 cmd += " --setEthSrc " + str( setEthSrc )
1422 if setEthDst:
1423 cmd += " --setEthDst " + str( setEthDst )
1424
1425 # Check whether the user appended the port
1426 # or provided it as an input
1427
1428 if "/" in ingressDevice:
1429 cmd += " " + str( ingressDevice )
1430 else:
1431 if not portIngress:
1432 main.log.error( "You must specify " +
1433 "the Ingress port" )
1434 return main.FALSE
1435
1436 cmd += " " +\
1437 str( ingressDevice ) + "/" +\
1438 str( portIngress )
1439
1440 if portEgressList is None:
1441 for egressDevice in egressDeviceList:
1442 if "/" in egressDevice:
1443 cmd += " " + str( egressDevice )
1444 else:
1445 main.log.error( "You must specify " +
1446 "the egress port" )
1447 # TODO: perhaps more meaningful return
1448 return main.FALSE
1449 else:
1450 if len( egressDeviceList ) == len( portEgressList ):
1451 for egressDevice, portEgress in zip( egressDeviceList, portEgressList ):
1452 cmd += " " + \
1453 str( egressDevice ) + "/" +\
1454 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001455 else:
1456 main.log.error( "Device list and port list does not have the same length" )
1457 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001458
1459 print "cmd= ", cmd
1460 handle = self.sendline( cmd )
1461 # If error, return error message
1462 if re.search( "Error", handle ):
1463 main.log.error( "Error in adding singlepoint-to-multipoint " +
1464 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001465 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001466 else:
1467 match = re.search('id=0x([\da-f]+),', handle)
1468 if match:
1469 return match.group()[3:-1]
1470 else:
1471 main.log.error( "Error, intent ID not found" )
1472 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001473 except TypeError:
1474 main.log.exception( self.name + ": Object not as expected" )
1475 return None
shahshreyad0c80432014-12-04 16:56:05 -08001476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001477 main.log.error( self.name + ": EOF exception found" )
1478 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001479 main.cleanup()
1480 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001481 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001482 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001483 main.cleanup()
1484 main.exit()
1485
Hari Krishna9e232602015-04-13 17:29:08 -07001486 def addMplsIntent(
1487 self,
1488 ingressDevice,
1489 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001490 ingressPort="",
1491 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001492 ethType="",
1493 ethSrc="",
1494 ethDst="",
1495 bandwidth="",
1496 lambdaAlloc=False,
1497 ipProto="",
1498 ipSrc="",
1499 ipDst="",
1500 tcpSrc="",
1501 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001502 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001503 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001504 priority=""):
1505 """
1506 Required:
1507 * ingressDevice: device id of ingress device
1508 * egressDevice: device id of egress device
1509 Optional:
1510 * ethType: specify ethType
1511 * ethSrc: specify ethSrc ( i.e. src mac addr )
1512 * ethDst: specify ethDst ( i.e. dst mac addr )
1513 * bandwidth: specify bandwidth capacity of link
1514 * lambdaAlloc: if True, intent will allocate lambda
1515 for the specified intent
1516 * ipProto: specify ip protocol
1517 * ipSrc: specify ip source address
1518 * ipDst: specify ip destination address
1519 * tcpSrc: specify tcp source port
1520 * tcpDst: specify tcp destination port
1521 * ingressLabel: Ingress MPLS label
1522 * egressLabel: Egress MPLS label
1523 Description:
1524 Adds MPLS intent by
1525 specifying device id's and optional fields
1526 Returns:
1527 A string of the intent id or None on error
1528
1529 NOTE: This function may change depending on the
1530 options developers provide for MPLS
1531 intent via cli
1532 """
1533 try:
1534 # If there are no optional arguments
1535 if not ethType and not ethSrc and not ethDst\
1536 and not bandwidth and not lambdaAlloc \
1537 and not ipProto and not ipSrc and not ipDst \
1538 and not tcpSrc and not tcpDst and not ingressLabel \
1539 and not egressLabel:
1540 cmd = "add-mpls-intent"
1541
1542 else:
1543 cmd = "add-mpls-intent"
1544
1545 if ethType:
1546 cmd += " --ethType " + str( ethType )
1547 if ethSrc:
1548 cmd += " --ethSrc " + str( ethSrc )
1549 if ethDst:
1550 cmd += " --ethDst " + str( ethDst )
1551 if bandwidth:
1552 cmd += " --bandwidth " + str( bandwidth )
1553 if lambdaAlloc:
1554 cmd += " --lambda "
1555 if ipProto:
1556 cmd += " --ipProto " + str( ipProto )
1557 if ipSrc:
1558 cmd += " --ipSrc " + str( ipSrc )
1559 if ipDst:
1560 cmd += " --ipDst " + str( ipDst )
1561 if tcpSrc:
1562 cmd += " --tcpSrc " + str( tcpSrc )
1563 if tcpDst:
1564 cmd += " --tcpDst " + str( tcpDst )
1565 if ingressLabel:
1566 cmd += " --ingressLabel " + str( ingressLabel )
1567 if egressLabel:
1568 cmd += " --egressLabel " + str( egressLabel )
1569 if priority:
1570 cmd += " --priority " + str( priority )
1571
1572 # Check whether the user appended the port
1573 # or provided it as an input
1574 if "/" in ingressDevice:
1575 cmd += " " + str( ingressDevice )
1576 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001577 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001578 main.log.error( "You must specify the ingress port" )
1579 return None
1580
1581 cmd += " " + \
1582 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001583 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001584
1585 if "/" in egressDevice:
1586 cmd += " " + str( egressDevice )
1587 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001588 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001589 main.log.error( "You must specify the egress port" )
1590 return None
1591
1592 cmd += " " +\
1593 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001594 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001595
1596 handle = self.sendline( cmd )
1597 # If error, return error message
1598 if re.search( "Error", handle ):
1599 main.log.error( "Error in adding mpls intent" )
1600 return None
1601 else:
1602 # TODO: print out all the options in this message?
1603 main.log.info( "MPLS intent installed between " +
1604 str( ingressDevice ) + " and " +
1605 str( egressDevice ) )
1606 match = re.search('id=0x([\da-f]+),', handle)
1607 if match:
1608 return match.group()[3:-1]
1609 else:
1610 main.log.error( "Error, intent ID not found" )
1611 return None
1612 except TypeError:
1613 main.log.exception( self.name + ": Object not as expected" )
1614 return None
1615 except pexpect.EOF:
1616 main.log.error( self.name + ": EOF exception found" )
1617 main.log.error( self.name + ": " + self.handle.before )
1618 main.cleanup()
1619 main.exit()
1620 except Exception:
1621 main.log.exception( self.name + ": Uncaught exception!" )
1622 main.cleanup()
1623 main.exit()
1624
Jon Hallefbd9792015-03-05 16:11:36 -08001625 def removeIntent( self, intentId, app='org.onosproject.cli',
1626 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001627 """
shahshreya1c818fc2015-02-26 13:44:08 -08001628 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001629 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001630 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001631 -p or --purge: Purge the intent from the store after removal
1632
Jon Halle3f39ff2015-01-13 11:50:53 -08001633 Returns:
1634 main.False on error and
1635 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001636 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001637 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001638 cmdStr = "remove-intent "
1639 if purge:
1640 cmdStr += " -p"
1641 if sync:
1642 cmdStr += " -s"
1643
1644 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001646 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001647 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001648 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001649 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001650 # TODO: Should this be main.TRUE
1651 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001652 except TypeError:
1653 main.log.exception( self.name + ": Object not as expected" )
1654 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001655 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001656 main.log.error( self.name + ": EOF exception found" )
1657 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001658 main.cleanup()
1659 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001660 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001661 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001662 main.cleanup()
1663 main.exit()
1664
kelvin-onlabd3b64892015-01-20 13:26:24 -08001665 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001666 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001667 NOTE: This method should be used after installing application:
1668 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001669 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001671 Description:
1672 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001673 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001674 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 if jsonFormat:
1676 cmdStr = "routes -j"
1677 handleTmp = self.sendline( cmdStr )
1678 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1679 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001680 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 cmdStr = "routes"
1682 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001683 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001684 except TypeError:
1685 main.log.exception( self.name + ": Object not as expected" )
1686 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001688 main.log.error( self.name + ": EOF exception found" )
1689 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001690 main.cleanup()
1691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001692 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001693 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001694 main.cleanup()
1695 main.exit()
1696
kelvin-onlabd3b64892015-01-20 13:26:24 -08001697 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001698 """
andrewonlab377693f2014-10-21 16:00:30 -04001699 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001701 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001702 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001703 """
andrewonlabe6745342014-10-17 14:29:13 -04001704 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 if jsonFormat:
1706 cmdStr = "intents -j"
1707 handle = self.sendline( cmdStr )
1708 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1709 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001710 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 cmdStr = "intents"
1712 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001713 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001714 except TypeError:
1715 main.log.exception( self.name + ": Object not as expected" )
1716 return None
andrewonlabe6745342014-10-17 14:29:13 -04001717 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001718 main.log.error( self.name + ": EOF exception found" )
1719 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001720 main.cleanup()
1721 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001722 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001723 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001724 main.cleanup()
1725 main.exit()
1726
kelvin-onlab54400a92015-02-26 18:05:51 -08001727 def getIntentState(self, intentsId, intentsJson=None):
1728 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001729 Check intent state.
1730 Accepts a single intent ID (string type) or a list of intent IDs.
1731 Returns the state(string type) of the id if a single intent ID is
1732 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001733 Returns a dictionary with intent IDs as the key and its
1734 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001735 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001736 intentId: intent ID (string type)
1737 intentsJson: parsed json object from the onos:intents api
1738 Returns:
1739 state = An intent's state- INSTALL,WITHDRAWN etc.
1740 stateDict = Dictionary of intent's state. intent ID as the keys and
1741 state as the values.
1742 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001743 try:
1744 state = "State is Undefined"
1745 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001746 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001747 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001748 intentsJsonTemp = json.loads( intentsJson )
1749 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001750 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001751 if intentsId == intent[ 'id' ]:
1752 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001753 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001754 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1755 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001756 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001757 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001758 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001759 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001760 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001761 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001762 if intentsId[ i ] == intents[ 'id' ]:
1763 stateDict[ 'state' ] = intents[ 'state' ]
1764 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001765 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001766 break
Jon Hallefbd9792015-03-05 16:11:36 -08001767 if len( intentsId ) != len( dictList ):
1768 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001769 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001770 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001771 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001772 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001773 except TypeError:
1774 main.log.exception( self.name + ": Object not as expected" )
1775 return None
1776 except pexpect.EOF:
1777 main.log.error( self.name + ": EOF exception found" )
1778 main.log.error( self.name + ": " + self.handle.before )
1779 main.cleanup()
1780 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001781 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001782 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001783 main.cleanup()
1784 main.exit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001785
1786 def checkIntentState( self, intentsId, expectedState = 'INSTALLED' ):
1787 """
1788 Description:
1789 Check intents state
1790 Required:
1791 intentsId - List of intents ID to be checked
1792 Optional:
1793 expectedState - Check this expected state of each intents state
1794 in the list. Defaults to INSTALLED
1795 Return:
1796 Returns main.TRUE only if all intent are the same as expectedState,
1797 , otherwise,returns main.FALSE.
1798 """
1799 try:
1800 # Generating a dictionary: intent id as a key and state as value
1801 intentsDict = self.getIntentState( intentsId )
1802 print "len of intentsDict ", str( len( intentsDict ) )
1803 if len( intentsId ) != len( intentsDict ):
1804 main.log.info( self.name + "There is something wrong " +
1805 "getting intents state" )
1806 return main.FALSE
1807 returnValue = main.TRUE
1808 for intents in intentsDict:
1809 if intents.get( 'state' ) != expectedState:
1810 main.log.info( self.name + " : " + intents.get( 'id' ) +
1811 " actual state = " + intents.get( 'state' )
1812 + " does not equal expected state = "
1813 + expectedState )
1814 returnValue = main.FALSE
1815 if returnValue == main.TRUE:
1816 main.log.info( self.name + ": All " +
1817 str( len( intentsDict ) ) +
1818 " intents are in " + expectedState + " state")
1819 return returnValue
1820 except TypeError:
1821 main.log.exception( self.name + ": Object not as expected" )
1822 return None
1823 except pexpect.EOF:
1824 main.log.error( self.name + ": EOF exception found" )
1825 main.log.error( self.name + ": " + self.handle.before )
1826 main.cleanup()
1827 main.exit()
1828 except Exception:
1829 main.log.exception( self.name + ": Uncaught exception!" )
1830 main.cleanup()
1831 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001832
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001834 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001835 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001836 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001837 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001838 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001839 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001840 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 if jsonFormat:
1842 cmdStr = "flows -j"
1843 handle = self.sendline( cmdStr )
1844 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1845 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001846 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 cmdStr = "flows"
1848 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001849 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001850 main.log.error( self.name + ".flows() response: " +
1851 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001852 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001853 except TypeError:
1854 main.log.exception( self.name + ": Object not as expected" )
1855 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001856 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001857 main.log.error( self.name + ": EOF exception found" )
1858 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001859 main.cleanup()
1860 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001861 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001862 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001863 main.cleanup()
1864 main.exit()
1865
kelvin-onlab4df89f22015-04-13 18:10:23 -07001866 def checkFlowsState( self ):
1867 """
1868 Description:
1869 Check the if all the current flows are in ADDED state or
1870 PENDING_ADD state
1871 Return:
1872 returnValue - Returns main.TRUE only if all flows are in
1873 ADDED state or PENDING_ADD, return main.FALSE
1874 otherwise.
1875 """
1876 try:
1877 tempFlows = json.loads( self.flows() )
1878 returnValue = main.TRUE
1879 for device in tempFlows:
1880 for flow in device.get( 'flows' ):
1881 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1882 'PENDING_ADD':
1883 main.log.info( self.name + ": flow Id: " +
1884 flow.get( 'flowId' ) +
1885 " | state:" + flow.get( 'state' ) )
1886 returnValue = main.FALSE
1887 return returnValue
1888 except TypeError:
1889 main.log.exception( self.name + ": Object not as expected" )
1890 return None
1891 except pexpect.EOF:
1892 main.log.error( self.name + ": EOF exception found" )
1893 main.log.error( self.name + ": " + self.handle.before )
1894 main.cleanup()
1895 main.exit()
1896 except Exception:
1897 main.log.exception( self.name + ": Uncaught exception!" )
1898 main.cleanup()
1899 main.exit()
1900
kelvin-onlabd3b64892015-01-20 13:26:24 -08001901 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001902 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001903 """
andrewonlab87852b02014-11-19 18:44:19 -05001904 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001905 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001906 a specific point-to-point intent definition
1907 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001908 * dpidSrc: specify source dpid
1909 * dpidDst: specify destination dpid
1910 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001911 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001912 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001913 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001914 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001915 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001916 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001917 """
andrewonlab87852b02014-11-19 18:44:19 -05001918 try:
kelvin8ec71442015-01-15 16:57:00 -08001919 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1921 str( numIntents )
1922 if numMult:
1923 cmd += " " + str( numMult )
1924 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001925 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001926 if appId:
1927 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001928 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1930 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001931 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001932 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001933 main.log.info( handle )
1934 # Split result by newline
1935 newline = handle.split( "\r\r\n" )
1936 # Ignore the first object of list, which is empty
1937 newline = newline[ 1: ]
1938 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001939 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001940 result = result.split( ": " )
1941 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001942 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1943 main.log.info( latResult )
1944 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001945 else:
1946 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001947 except TypeError:
1948 main.log.exception( self.name + ": Object not as expected" )
1949 return None
andrewonlab87852b02014-11-19 18:44:19 -05001950 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001951 main.log.error( self.name + ": EOF exception found" )
1952 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001953 main.cleanup()
1954 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001955 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001956 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001957 main.cleanup()
1958 main.exit()
1959
kelvin-onlabd3b64892015-01-20 13:26:24 -08001960 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001961 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001962 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001963 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001965 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001966 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 if jsonFormat:
1968 cmdStr = "intents-events-metrics -j"
1969 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001970 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001971 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1972 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001973 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 cmdStr = "intents-events-metrics"
1975 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001976 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001977 except TypeError:
1978 main.log.exception( self.name + ": Object not as expected" )
1979 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001980 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001981 main.log.error( self.name + ": EOF exception found" )
1982 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001983 main.cleanup()
1984 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001985 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001986 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001987 main.cleanup()
1988 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001989
kelvin-onlabd3b64892015-01-20 13:26:24 -08001990 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001991 """
1992 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001993 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001994 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001995 """
andrewonlab867212a2014-10-22 20:13:38 -04001996 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001997 if jsonFormat:
1998 cmdStr = "topology-events-metrics -j"
1999 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002000 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08002001 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2002 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04002003 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002004 cmdStr = "topology-events-metrics"
2005 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002006 if handle:
2007 return handle
2008 else:
Jon Hallbe379602015-03-24 13:39:32 -07002009 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002010 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08002011 except TypeError:
2012 main.log.exception( self.name + ": Object not as expected" )
2013 return None
andrewonlab867212a2014-10-22 20:13:38 -04002014 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002015 main.log.error( self.name + ": EOF exception found" )
2016 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002017 main.cleanup()
2018 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002019 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002020 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002021 main.cleanup()
2022 main.exit()
2023
kelvin8ec71442015-01-15 16:57:00 -08002024 # Wrapper functions ****************
2025 # Wrapper functions use existing driver
2026 # functions and extends their use case.
2027 # For example, we may use the output of
2028 # a normal driver function, and parse it
2029 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04002030
kelvin-onlabd3b64892015-01-20 13:26:24 -08002031 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002032 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002033 Description:
2034 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002035 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002036 try:
kelvin8ec71442015-01-15 16:57:00 -08002037 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002038 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002039 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002040
kelvin8ec71442015-01-15 16:57:00 -08002041 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002042 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2043 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002044 match = re.search('id=0x([\da-f]+),', intents)
2045 if match:
2046 tmpId = match.group()[3:-1]
2047 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002049
Jon Halld4d4b372015-01-28 16:02:41 -08002050 except TypeError:
2051 main.log.exception( self.name + ": Object not as expected" )
2052 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002056 main.cleanup()
2057 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002058 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002059 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002060 main.cleanup()
2061 main.exit()
2062
Jon Hall30b82fa2015-03-04 17:15:43 -08002063 def FlowAddedCount( self, deviceId ):
2064 """
2065 Determine the number of flow rules for the given device id that are
2066 in the added state
2067 """
2068 try:
2069 cmdStr = "flows any " + str( deviceId ) + " | " +\
2070 "grep 'state=ADDED' | wc -l"
2071 handle = self.sendline( cmdStr )
2072 return handle
2073 except pexpect.EOF:
2074 main.log.error( self.name + ": EOF exception found" )
2075 main.log.error( self.name + ": " + self.handle.before )
2076 main.cleanup()
2077 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002078 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002079 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002080 main.cleanup()
2081 main.exit()
2082
kelvin-onlabd3b64892015-01-20 13:26:24 -08002083 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002084 """
andrewonlab95ce8322014-10-13 14:12:04 -04002085 Use 'devices' function to obtain list of all devices
2086 and parse the result to obtain a list of all device
2087 id's. Returns this list. Returns empty list if no
2088 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002089 List is ordered sequentially
2090
andrewonlab95ce8322014-10-13 14:12:04 -04002091 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002092 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002093 the ids. By obtaining the list of device ids on the fly,
2094 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002095 """
andrewonlab95ce8322014-10-13 14:12:04 -04002096 try:
kelvin8ec71442015-01-15 16:57:00 -08002097 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002098 devicesStr = self.devices( jsonFormat=False )
2099 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002100
kelvin-onlabd3b64892015-01-20 13:26:24 -08002101 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002102 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002103 return idList
kelvin8ec71442015-01-15 16:57:00 -08002104
2105 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002106 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002107 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002109 # Split list further into arguments before and after string
2110 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 # append to idList
2112 for arg in tempList:
2113 idList.append( arg.split( "id=" )[ 1 ] )
2114 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002115
Jon Halld4d4b372015-01-28 16:02:41 -08002116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002122 main.cleanup()
2123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002124 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002125 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002126 main.cleanup()
2127 main.exit()
2128
kelvin-onlabd3b64892015-01-20 13:26:24 -08002129 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002130 """
andrewonlab7c211572014-10-15 16:45:20 -04002131 Uses 'nodes' function to obtain list of all nodes
2132 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002133 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002134 Returns:
2135 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002136 """
andrewonlab7c211572014-10-15 16:45:20 -04002137 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002138 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002139 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002140 # Sample nodesStr output
2141 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002143 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002144 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002145 nodesJson = json.loads( nodesStr )
2146 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002147 return idList
kelvin8ec71442015-01-15 16:57:00 -08002148
Jon Halld4d4b372015-01-28 16:02:41 -08002149 except TypeError:
2150 main.log.exception( self.name + ": Object not as expected" )
2151 return None
andrewonlab7c211572014-10-15 16:45:20 -04002152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002153 main.log.error( self.name + ": EOF exception found" )
2154 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002155 main.cleanup()
2156 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002158 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002159 main.cleanup()
2160 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002161
kelvin-onlabd3b64892015-01-20 13:26:24 -08002162 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002163 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002164 Return the first device from the devices api whose 'id' contains 'dpid'
2165 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002166 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002167 try:
kelvin8ec71442015-01-15 16:57:00 -08002168 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002169 return None
2170 else:
kelvin8ec71442015-01-15 16:57:00 -08002171 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002172 rawDevices = self.devices()
2173 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002174 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002175 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002176 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2177 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002178 return device
2179 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002180 except TypeError:
2181 main.log.exception( self.name + ": Object not as expected" )
2182 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002184 main.log.error( self.name + ": EOF exception found" )
2185 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002186 main.cleanup()
2187 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002188 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002189 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002190 main.cleanup()
2191 main.exit()
2192
kelvin-onlabd3b64892015-01-20 13:26:24 -08002193 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002194 """
Jon Hallefbd9792015-03-05 16:11:36 -08002195 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002196 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002197 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002198
Jon Hall42db6dc2014-10-24 19:03:48 -04002199 Params: ip = ip used for the onos cli
2200 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002201 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002202 logLevel = level to log to. Currently accepts
2203 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002204
2205
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002207
Jon Hallefbd9792015-03-05 16:11:36 -08002208 Returns: main.TRUE if the number of switches and links are correct,
2209 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002210 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002211 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002212 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002214 if topology == {}:
2215 return main.ERROR
2216 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002217 # Is the number of switches is what we expected
2218 devices = topology.get( 'devices', False )
2219 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002220 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002221 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002222 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002223 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002224 linkCheck = ( int( links ) == int( numolink ) )
2225 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002226 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002227 output += "The number of links and switches match " +\
2228 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002229 result = main.TRUE
2230 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002231 output += "The number of links and switches does not match " +\
2232 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002233 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002234 output = output + "\n ONOS sees %i devices (%i expected) \
2235 and %i links (%i expected)" % (
2236 int( devices ), int( numoswitch ), int( links ),
2237 int( numolink ) )
2238 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002239 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002240 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002241 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002242 else:
kelvin8ec71442015-01-15 16:57:00 -08002243 main.log.info( output )
2244 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002245 except TypeError:
2246 main.log.exception( self.name + ": Object not as expected" )
2247 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002249 main.log.error( self.name + ": EOF exception found" )
2250 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002251 main.cleanup()
2252 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002254 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002255 main.cleanup()
2256 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002257
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002259 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002260 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002261 deviceId must be the id of a device as seen in the onos devices command
2262 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002263 role must be either master, standby, or none
2264
Jon Halle3f39ff2015-01-13 11:50:53 -08002265 Returns:
2266 main.TRUE or main.FALSE based on argument verification and
2267 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002268 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002269 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002270 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002271 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 cmdStr = "device-role " +\
2273 str( deviceId ) + " " +\
2274 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002275 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002277 if re.search( "Error", handle ):
2278 # end color output to escape any colours
2279 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002280 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002281 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002282 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002283 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002284 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002285 main.log.error( "Invalid 'role' given to device_role(). " +
2286 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002287 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002288 except TypeError:
2289 main.log.exception( self.name + ": Object not as expected" )
2290 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002291 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002292 main.log.error( self.name + ": EOF exception found" )
2293 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002294 main.cleanup()
2295 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002296 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002297 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002298 main.cleanup()
2299 main.exit()
2300
kelvin-onlabd3b64892015-01-20 13:26:24 -08002301 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002302 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002303 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002304 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002305 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002306 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002307 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002308 if jsonFormat:
2309 cmdStr = "clusters -j"
2310 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002311 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002312 handle variable here contains some ANSI escape color code
2313 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08002314 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08002315 function. The repr( handle ) output when printed shows the ANSI
2316 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08002317 variable is actually repr( somestring ) and json.loads would
2318 fail with the escape sequence. So we take off that escape
2319 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08002320
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2322 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002323 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08002324 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2325 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002326 return handle1
2327 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002328 cmdStr = "clusters"
2329 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002330 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002331 except TypeError:
2332 main.log.exception( self.name + ": Object not as expected" )
2333 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002334 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002335 main.log.error( self.name + ": EOF exception found" )
2336 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002337 main.cleanup()
2338 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002339 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002340 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002341 main.cleanup()
2342 main.exit()
2343
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002345 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002346 CLI command to get the current leader for the Election test application
2347 NOTE: Requires installation of the onos-app-election feature
2348 Returns: Node IP of the leader if one exists
2349 None if none exists
2350 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002351 """
Jon Hall94fd0472014-12-08 11:52:42 -08002352 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002353 cmdStr = "election-test-leader"
2354 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002355 # Leader
2356 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002357 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002358 nodeSearch = re.search( leaderPattern, response )
2359 if nodeSearch:
2360 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002361 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002362 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002363 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002364 # no leader
2365 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002366 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002367 nullSearch = re.search( nullPattern, response )
2368 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002369 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002370 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002371 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002372 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002373 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002374 if re.search( errorPattern, response ):
2375 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002376 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002377 return main.FALSE
2378 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002379 main.log.error( "Error in election_test_leader: " +
2380 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002381 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002382 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002383 except TypeError:
2384 main.log.exception( self.name + ": Object not as expected" )
2385 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002386 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002387 main.log.error( self.name + ": EOF exception found" )
2388 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002389 main.cleanup()
2390 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002391 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002392 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002393 main.cleanup()
2394 main.exit()
2395
kelvin-onlabd3b64892015-01-20 13:26:24 -08002396 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002397 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002398 CLI command to run for leadership of the Election test application.
2399 NOTE: Requires installation of the onos-app-election feature
2400 Returns: Main.TRUE on success
2401 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002402 """
Jon Hall94fd0472014-12-08 11:52:42 -08002403 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002404 cmdStr = "election-test-run"
2405 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002406 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002407 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002408 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002409 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002410 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002411 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002412 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002413 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002414 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002415 errorPattern = "Command\snot\sfound"
2416 if re.search( errorPattern, response ):
2417 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002418 return main.FALSE
2419 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002420 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002421 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002422 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002423 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002424 except TypeError:
2425 main.log.exception( self.name + ": Object not as expected" )
2426 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002427 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002428 main.log.error( self.name + ": EOF exception found" )
2429 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002430 main.cleanup()
2431 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002432 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002433 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002434 main.cleanup()
2435 main.exit()
2436
kelvin-onlabd3b64892015-01-20 13:26:24 -08002437 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002438 """
Jon Hall94fd0472014-12-08 11:52:42 -08002439 * CLI command to withdraw the local node from leadership election for
2440 * the Election test application.
2441 #NOTE: Requires installation of the onos-app-election feature
2442 Returns: Main.TRUE on success
2443 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002444 """
Jon Hall94fd0472014-12-08 11:52:42 -08002445 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002446 cmdStr = "election-test-withdraw"
2447 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002448 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002449 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002450 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002451 if re.search( successPattern, response ):
2452 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002453 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002454 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002455 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002456 errorPattern = "Command\snot\sfound"
2457 if re.search( errorPattern, response ):
2458 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002459 return main.FALSE
2460 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002461 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002462 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002463 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002464 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002465 except TypeError:
2466 main.log.exception( self.name + ": Object not as expected" )
2467 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002468 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002469 main.log.error( self.name + ": EOF exception found" )
2470 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002471 main.cleanup()
2472 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002473 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002474 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002475 main.cleanup()
2476 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002477
kelvin8ec71442015-01-15 16:57:00 -08002478 def getDevicePortsEnabledCount( self, dpid ):
2479 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002480 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002481 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002482 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002483 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2485 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002486 if re.search( "No such device", output ):
2487 main.log.error( "Error in getting ports" )
2488 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002489 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002490 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002491 except TypeError:
2492 main.log.exception( self.name + ": Object not as expected" )
2493 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002494 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002495 main.log.error( self.name + ": EOF exception found" )
2496 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002497 main.cleanup()
2498 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002499 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002500 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002501 main.cleanup()
2502 main.exit()
2503
kelvin8ec71442015-01-15 16:57:00 -08002504 def getDeviceLinksActiveCount( self, dpid ):
2505 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002506 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002507 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002508 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002509 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2511 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002512 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002513 main.log.error( "Error in getting ports " )
2514 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002515 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002516 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002517 except TypeError:
2518 main.log.exception( self.name + ": Object not as expected" )
2519 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002520 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002521 main.log.error( self.name + ": EOF exception found" )
2522 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002523 main.cleanup()
2524 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002525 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002526 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002527 main.cleanup()
2528 main.exit()
2529
kelvin8ec71442015-01-15 16:57:00 -08002530 def getAllIntentIds( self ):
2531 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002532 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002533 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002534 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002535 cmdStr = "onos:intents | grep id="
2536 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002537 if re.search( "Error", output ):
2538 main.log.error( "Error in getting ports" )
2539 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002540 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002541 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002542 except TypeError:
2543 main.log.exception( self.name + ": Object not as expected" )
2544 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002545 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002546 main.log.error( self.name + ": EOF exception found" )
2547 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002548 main.cleanup()
2549 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002551 main.log.exception( self.name + ": Uncaught exception!" )
2552 main.cleanup()
2553 main.exit()
2554
Jon Hall73509952015-02-24 16:42:56 -08002555 def intentSummary( self ):
2556 """
Jon Hallefbd9792015-03-05 16:11:36 -08002557 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002558 """
2559 try:
2560 intents = self.intents( )
2561 intentStates = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002562 for intent in json.loads( intents ):
Jon Hall73509952015-02-24 16:42:56 -08002563 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002564 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2565 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002566 return dict( out )
2567 except TypeError:
2568 main.log.exception( self.name + ": Object not as expected" )
2569 return None
2570 except pexpect.EOF:
2571 main.log.error( self.name + ": EOF exception found" )
2572 main.log.error( self.name + ": " + self.handle.before )
2573 main.cleanup()
2574 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002575 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002576 main.log.exception( self.name + ": Uncaught exception!" )
2577 main.cleanup()
2578 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002579
Jon Hall61282e32015-03-19 11:34:11 -07002580 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002581 """
2582 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002583 Optional argument:
2584 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002585 """
2586 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002587 # Sample JSON
2588 # {
2589 # "electedTime": "13m ago",
2590 # "epoch": 4,
2591 # "leader": "10.128.30.17",
2592 # "topic": "intent-partition-3"
2593 # },
Jon Hall63604932015-02-26 17:09:50 -08002594 try:
Jon Hall61282e32015-03-19 11:34:11 -07002595 if jsonFormat:
2596 cmdStr = "onos:leaders -j"
2597 output = self.sendline( cmdStr )
2598 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2599 cleanedOutput = ansiEscape.sub( '', output )
2600 return cleanedOutput
2601 else:
2602 cmdStr = "onos:leaders"
2603 output = self.sendline( cmdStr )
2604 return output
Jon Hall63604932015-02-26 17:09:50 -08002605 except TypeError:
2606 main.log.exception( self.name + ": Object not as expected" )
2607 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002608 except pexpect.EOF:
2609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
2611 main.cleanup()
2612 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002613 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002614 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002615 main.cleanup()
2616 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002617
Jon Hall61282e32015-03-19 11:34:11 -07002618 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002619 """
2620 Returns the output of the intent Pending map.
2621 """
Jon Hall63604932015-02-26 17:09:50 -08002622 try:
Jon Hall61282e32015-03-19 11:34:11 -07002623 if jsonFormat:
2624 cmdStr = "onos:intents -p -j"
2625 output = self.sendline( cmdStr )
2626 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2627 cleanedOutput = ansiEscape.sub( '', output )
2628 return cleanedOutput
2629 else:
2630 cmdStr = "onos:intents -p"
2631 output = self.sendline( cmdStr )
2632 return output
Jon Hall63604932015-02-26 17:09:50 -08002633 except TypeError:
2634 main.log.exception( self.name + ": Object not as expected" )
2635 return None
2636 except pexpect.EOF:
2637 main.log.error( self.name + ": EOF exception found" )
2638 main.log.error( self.name + ": " + self.handle.before )
2639 main.cleanup()
2640 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002641 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002642 main.log.exception( self.name + ": Uncaught exception!" )
2643 main.cleanup()
2644 main.exit()
2645
Jon Hall61282e32015-03-19 11:34:11 -07002646 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002647 """
2648 Returns the output of the raft partitions command for ONOS.
2649 """
Jon Hall61282e32015-03-19 11:34:11 -07002650 # Sample JSON
2651 # {
2652 # "leader": "tcp://10.128.30.11:7238",
2653 # "members": [
2654 # "tcp://10.128.30.11:7238",
2655 # "tcp://10.128.30.17:7238",
2656 # "tcp://10.128.30.13:7238",
2657 # ],
2658 # "name": "p1",
2659 # "term": 3
2660 # },
Jon Hall63604932015-02-26 17:09:50 -08002661 try:
Jon Hall61282e32015-03-19 11:34:11 -07002662 if jsonFormat:
2663 cmdStr = "onos:partitions -j"
2664 output = self.sendline( cmdStr )
2665 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2666 cleanedOutput = ansiEscape.sub( '', output )
2667 return cleanedOutput
2668 else:
2669 cmdStr = "onos:partitions"
2670 output = self.sendline( cmdStr )
2671 return output
Jon Hall63604932015-02-26 17:09:50 -08002672 except TypeError:
2673 main.log.exception( self.name + ": Object not as expected" )
2674 return None
2675 except pexpect.EOF:
2676 main.log.error( self.name + ": EOF exception found" )
2677 main.log.error( self.name + ": " + self.handle.before )
2678 main.cleanup()
2679 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002680 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002681 main.log.exception( self.name + ": Uncaught exception!" )
2682 main.cleanup()
2683 main.exit()
2684
Jon Hallbe379602015-03-24 13:39:32 -07002685 def apps( self, jsonFormat=True ):
2686 """
2687 Returns the output of the apps command for ONOS. This command lists
2688 information about installed ONOS applications
2689 """
2690 # Sample JSON object
2691 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2692 # "description":"ONOS OpenFlow protocol southbound providers",
2693 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2694 # "features":"[onos-openflow]","state":"ACTIVE"}]
2695 try:
2696 if jsonFormat:
2697 cmdStr = "onos:apps -j"
2698 output = self.sendline( cmdStr )
2699 assert "Error executing command" not in output
2700 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2701 cleanedOutput = ansiEscape.sub( '', output )
2702 return cleanedOutput
2703 else:
2704 cmdStr = "onos:apps"
2705 output = self.sendline( cmdStr )
2706 assert "Error executing command" not in output
2707 return output
2708 # FIXME: look at specific exceptions/Errors
2709 except AssertionError:
2710 main.log.error( "Error in processing onos:app command: " +
2711 str( output ) )
2712 return None
2713 except TypeError:
2714 main.log.exception( self.name + ": Object not as expected" )
2715 return None
2716 except pexpect.EOF:
2717 main.log.error( self.name + ": EOF exception found" )
2718 main.log.error( self.name + ": " + self.handle.before )
2719 main.cleanup()
2720 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002721 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002722 main.log.exception( self.name + ": Uncaught exception!" )
2723 main.cleanup()
2724 main.exit()
2725
Jon Hall146f1522015-03-24 15:33:24 -07002726 def appStatus( self, appName ):
2727 """
2728 Uses the onos:apps cli command to return the status of an application.
2729 Returns:
2730 "ACTIVE" - If app is installed and activated
2731 "INSTALLED" - If app is installed and deactivated
2732 "UNINSTALLED" - If app is not installed
2733 None - on error
2734 """
Jon Hall146f1522015-03-24 15:33:24 -07002735 try:
2736 if not isinstance( appName, types.StringType ):
2737 main.log.error( self.name + ".appStatus(): appName must be" +
2738 " a string" )
2739 return None
2740 output = self.apps( jsonFormat=True )
2741 appsJson = json.loads( output )
2742 state = None
2743 for app in appsJson:
2744 if appName == app.get('name'):
2745 state = app.get('state')
2746 break
2747 if state == "ACTIVE" or state == "INSTALLED":
2748 return state
2749 elif state is None:
2750 return "UNINSTALLED"
2751 elif state:
2752 main.log.error( "Unexpected state from 'onos:apps': " +
2753 str( state ) )
2754 return state
2755 except TypeError:
2756 main.log.exception( self.name + ": Object not as expected" )
2757 return None
2758 except pexpect.EOF:
2759 main.log.error( self.name + ": EOF exception found" )
2760 main.log.error( self.name + ": " + self.handle.before )
2761 main.cleanup()
2762 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002763 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002764 main.log.exception( self.name + ": Uncaught exception!" )
2765 main.cleanup()
2766 main.exit()
2767
Jon Hallbe379602015-03-24 13:39:32 -07002768 def app( self, appName, option ):
2769 """
2770 Interacts with the app command for ONOS. This command manages
2771 application inventory.
2772 """
Jon Hallbe379602015-03-24 13:39:32 -07002773 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002774 # Validate argument types
2775 valid = True
2776 if not isinstance( appName, types.StringType ):
2777 main.log.error( self.name + ".app(): appName must be a " +
2778 "string" )
2779 valid = False
2780 if not isinstance( option, types.StringType ):
2781 main.log.error( self.name + ".app(): option must be a string" )
2782 valid = False
2783 if not valid:
2784 return main.FALSE
2785 # Validate Option
2786 option = option.lower()
2787 # NOTE: Install may become a valid option
2788 if option == "activate":
2789 pass
2790 elif option == "deactivate":
2791 pass
2792 elif option == "uninstall":
2793 pass
2794 else:
2795 # Invalid option
2796 main.log.error( "The ONOS app command argument only takes " +
2797 "the values: (activate|deactivate|uninstall)" +
2798 "; was given '" + option + "'")
2799 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002800 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002801 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002802 if "Error executing command" in output:
2803 main.log.error( "Error in processing onos:app command: " +
2804 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002805 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002806 elif "No such application" in output:
2807 main.log.error( "The application '" + appName +
2808 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002809 return main.FALSE
2810 elif "Command not found:" in output:
2811 main.log.error( "Error in processing onos:app command: " +
2812 str( output ) )
2813 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002814 elif "Unsupported command:" in output:
2815 main.log.error( "Incorrect command given to 'app': " +
2816 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002817 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002818 # else: Command was successful
Jon Hall050e1bd2015-03-30 13:33:02 -07002819 #main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002820 return main.TRUE
2821 except TypeError:
2822 main.log.exception( self.name + ": Object not as expected" )
2823 return main.ERROR
2824 except pexpect.EOF:
2825 main.log.error( self.name + ": EOF exception found" )
2826 main.log.error( self.name + ": " + self.handle.before )
2827 main.cleanup()
2828 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002829 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002830 main.log.exception( self.name + ": Uncaught exception!" )
2831 main.cleanup()
2832 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002833
Jon Hallbd16b922015-03-26 17:53:15 -07002834 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002835 """
2836 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002837 appName is the hierarchical app name, not the feature name
2838 If check is True, method will check the status of the app after the
2839 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002840 Returns main.TRUE if the command was successfully sent
2841 main.FALSE if the cli responded with an error or given
2842 incorrect input
2843 """
2844 try:
2845 if not isinstance( appName, types.StringType ):
2846 main.log.error( self.name + ".activateApp(): appName must be" +
2847 " a string" )
2848 return main.FALSE
2849 status = self.appStatus( appName )
2850 if status == "INSTALLED":
2851 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002852 if check and response == main.TRUE:
2853 for i in range(10): # try 10 times then give up
2854 # TODO: Check with Thomas about this delay
2855 status = self.appStatus( appName )
2856 if status == "ACTIVE":
2857 return main.TRUE
2858 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002859 main.log.debug( "The state of application " +
2860 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002861 time.sleep( 1 )
2862 return main.FALSE
2863 else: # not 'check' or command didn't succeed
2864 return response
Jon Hall146f1522015-03-24 15:33:24 -07002865 elif status == "ACTIVE":
2866 return main.TRUE
2867 elif status == "UNINSTALLED":
2868 main.log.error( self.name + ": Tried to activate the " +
2869 "application '" + appName + "' which is not " +
2870 "installed." )
2871 else:
2872 main.log.error( "Unexpected return value from appStatus: " +
2873 str( status ) )
2874 return main.ERROR
2875 except TypeError:
2876 main.log.exception( self.name + ": Object not as expected" )
2877 return main.ERROR
2878 except pexpect.EOF:
2879 main.log.error( self.name + ": EOF exception found" )
2880 main.log.error( self.name + ": " + self.handle.before )
2881 main.cleanup()
2882 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002883 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002884 main.log.exception( self.name + ": Uncaught exception!" )
2885 main.cleanup()
2886 main.exit()
2887
Jon Hallbd16b922015-03-26 17:53:15 -07002888 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002889 """
2890 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002891 appName is the hierarchical app name, not the feature name
2892 If check is True, method will check the status of the app after the
2893 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002894 Returns main.TRUE if the command was successfully sent
2895 main.FALSE if the cli responded with an error or given
2896 incorrect input
2897 """
2898 try:
2899 if not isinstance( appName, types.StringType ):
2900 main.log.error( self.name + ".deactivateApp(): appName must " +
2901 "be a string" )
2902 return main.FALSE
2903 status = self.appStatus( appName )
2904 if status == "INSTALLED":
2905 return main.TRUE
2906 elif status == "ACTIVE":
2907 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002908 if check and response == main.TRUE:
2909 for i in range(10): # try 10 times then give up
2910 status = self.appStatus( appName )
2911 if status == "INSTALLED":
2912 return main.TRUE
2913 else:
2914 time.sleep( 1 )
2915 return main.FALSE
2916 else: # not check or command didn't succeed
2917 return response
Jon Hall146f1522015-03-24 15:33:24 -07002918 elif status == "UNINSTALLED":
2919 main.log.warn( self.name + ": Tried to deactivate the " +
2920 "application '" + appName + "' which is not " +
2921 "installed." )
2922 return main.TRUE
2923 else:
2924 main.log.error( "Unexpected return value from appStatus: " +
2925 str( status ) )
2926 return main.ERROR
2927 except TypeError:
2928 main.log.exception( self.name + ": Object not as expected" )
2929 return main.ERROR
2930 except pexpect.EOF:
2931 main.log.error( self.name + ": EOF exception found" )
2932 main.log.error( self.name + ": " + self.handle.before )
2933 main.cleanup()
2934 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002935 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002936 main.log.exception( self.name + ": Uncaught exception!" )
2937 main.cleanup()
2938 main.exit()
2939
Jon Hallbd16b922015-03-26 17:53:15 -07002940 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002941 """
2942 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002943 appName is the hierarchical app name, not the feature name
2944 If check is True, method will check the status of the app after the
2945 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002946 Returns main.TRUE if the command was successfully sent
2947 main.FALSE if the cli responded with an error or given
2948 incorrect input
2949 """
2950 # TODO: check with Thomas about the state machine for apps
2951 try:
2952 if not isinstance( appName, types.StringType ):
2953 main.log.error( self.name + ".uninstallApp(): appName must " +
2954 "be a string" )
2955 return main.FALSE
2956 status = self.appStatus( appName )
2957 if status == "INSTALLED":
2958 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002959 if check and response == main.TRUE:
2960 for i in range(10): # try 10 times then give up
2961 status = self.appStatus( appName )
2962 if status == "UNINSTALLED":
2963 return main.TRUE
2964 else:
2965 time.sleep( 1 )
2966 return main.FALSE
2967 else: # not check or command didn't succeed
2968 return response
Jon Hall146f1522015-03-24 15:33:24 -07002969 elif status == "ACTIVE":
2970 main.log.warn( self.name + ": Tried to uninstall the " +
2971 "application '" + appName + "' which is " +
2972 "currently active." )
2973 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002974 if check and response == main.TRUE:
2975 for i in range(10): # try 10 times then give up
2976 status = self.appStatus( appName )
2977 if status == "UNINSTALLED":
2978 return main.TRUE
2979 else:
2980 time.sleep( 1 )
2981 return main.FALSE
2982 else: # not check or command didn't succeed
2983 return response
Jon Hall146f1522015-03-24 15:33:24 -07002984 elif status == "UNINSTALLED":
2985 return main.TRUE
2986 else:
2987 main.log.error( "Unexpected return value from appStatus: " +
2988 str( status ) )
2989 return main.ERROR
2990 except TypeError:
2991 main.log.exception( self.name + ": Object not as expected" )
2992 return main.ERROR
2993 except pexpect.EOF:
2994 main.log.error( self.name + ": EOF exception found" )
2995 main.log.error( self.name + ": " + self.handle.before )
2996 main.cleanup()
2997 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002998 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002999 main.log.exception( self.name + ": Uncaught exception!" )
3000 main.cleanup()
3001 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003002
3003 def appIDs( self, jsonFormat=True ):
3004 """
3005 Show the mappings between app id and app names given by the 'app-ids'
3006 cli command
3007 """
3008 try:
3009 cmdStr = "app-ids"
3010 if jsonFormat:
3011 cmdStr += " -j"
3012 output = self.sendline( cmdStr )
3013 assert "Error executing command" not in output
3014 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
3015 cleanedOutput = ansiEscape.sub( '', output )
3016 return cleanedOutput
3017 else:
3018 output = self.sendline( cmdStr )
3019 assert "Error executing command" not in output
3020 return output
3021 except AssertionError:
3022 main.log.error( "Error in processing onos:app-ids command: " +
3023 str( output ) )
3024 return None
3025 except TypeError:
3026 main.log.exception( self.name + ": Object not as expected" )
3027 return None
3028 except pexpect.EOF:
3029 main.log.error( self.name + ": EOF exception found" )
3030 main.log.error( self.name + ": " + self.handle.before )
3031 main.cleanup()
3032 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003033 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003034 main.log.exception( self.name + ": Uncaught exception!" )
3035 main.cleanup()
3036 main.exit()
3037
3038 def appToIDCheck( self ):
3039 """
3040 This method will check that each application's ID listed in 'apps' is
3041 the same as the ID listed in 'app-ids'. The check will also check that
3042 there are no duplicate IDs issued. Note that an app ID should be
3043 a globaly unique numerical identifier for app/app-like features. Once
3044 an ID is registered, the ID is never freed up so that if an app is
3045 reinstalled it will have the same ID.
3046
3047 Returns: main.TRUE if the check passes and
3048 main.FALSE if the check fails or
3049 main.ERROR if there is some error in processing the test
3050 """
3051 try:
3052 ids = json.loads( self.appIDs( jsonFormat=True ) )
3053 apps = json.loads( self.apps( jsonFormat=True ) )
3054 result = main.TRUE
3055 for app in apps:
3056 appID = app.get( 'id' )
3057 if appID is None:
3058 main.log.error( "Error parsing app: " + str( app ) )
3059 result = main.FALSE
3060 appName = app.get( 'name' )
3061 if appName is None:
3062 main.log.error( "Error parsing app: " + str( app ) )
3063 result = main.FALSE
3064 # get the entry in ids that has the same appID
3065 current = filter(lambda item: item[ 'id' ] == appID, ids)
Jon Hall050e1bd2015-03-30 13:33:02 -07003066 # main.log.debug( "Comparing " + str( app ) + " to " +
3067 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003068 if not current: # if ids doesn't have this id
3069 result = main.FALSE
3070 main.log.error( "'app-ids' does not have the ID for " +
3071 str( appName ) + " that apps does." )
3072 elif len( current ) > 1:
3073 # there is more than one app with this ID
3074 result = main.FALSE
3075 # We will log this later in the method
3076 elif not current[0][ 'name' ] == appName:
3077 currentName = current[0][ 'name' ]
3078 result = main.FALSE
3079 main.log.error( "'app-ids' has " + str( currentName ) +
3080 " registered under id:" + str( appID ) +
3081 " but 'apps' has " + str( appName ) )
3082 else:
3083 pass # id and name match!
3084 # now make sure that app-ids has no duplicates
3085 idsList = []
3086 namesList = []
3087 for item in ids:
3088 idsList.append( item[ 'id' ] )
3089 namesList.append( item[ 'name' ] )
3090 if len( idsList ) != len( set( idsList ) ) or\
3091 len( namesList ) != len( set( namesList ) ):
3092 main.log.error( "'app-ids' has some duplicate entries: \n"
3093 + json.dumps( ids,
3094 sort_keys=True,
3095 indent=4,
3096 separators=( ',', ': ' ) ) )
3097 result = main.FALSE
3098 return result
3099 except ( ValueError, TypeError ):
3100 main.log.exception( self.name + ": Object not as expected" )
3101 return main.ERROR
3102 except pexpect.EOF:
3103 main.log.error( self.name + ": EOF exception found" )
3104 main.log.error( self.name + ": " + self.handle.before )
3105 main.cleanup()
3106 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003107 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003108 main.log.exception( self.name + ": Uncaught exception!" )
3109 main.cleanup()
3110 main.exit()
3111