blob: d97147148988c2f8e9e5d2197e1255e5d8a6d86d [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
kelvin8ec71442015-01-15 16:57:00 -080024sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin8ec71442015-01-15 16:57:00 -080054 self.name = self.options[ 'name' ]
55 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080056 user_name=self.user_name,
57 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080058 port=self.port,
59 pwd=self.pwd,
60 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040061
kelvin8ec71442015-01-15 16:57:00 -080062 self.handle.sendline( "cd " + self.home )
63 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040064 if self.handle:
65 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080066 else:
67 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040068 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080069 except TypeError:
70 main.log.exception( self.name + ": Object not as expected" )
71 return None
andrewonlab95ce8322014-10-13 14:12:04 -040072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080073 main.log.error( self.name + ": EOF exception found" )
74 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040075 main.cleanup()
76 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080077 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080078 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040079 main.cleanup()
80 main.exit()
81
kelvin8ec71442015-01-15 16:57:00 -080082 def disconnect( self ):
83 """
andrewonlab95ce8322014-10-13 14:12:04 -040084 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080085 """
Jon Halld61331b2015-02-17 16:35:47 -080086 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040087 try:
Jon Hall61282e32015-03-19 11:34:11 -070088 if self.handle:
89 i = self.logout()
90 if i == main.TRUE:
91 self.handle.sendline( "" )
92 self.handle.expect( "\$" )
93 self.handle.sendline( "exit" )
94 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080095 except TypeError:
96 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080097 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040098 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080099 main.log.error( self.name + ": EOF exception found" )
100 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700101 except ValueError:
102 main.log.exception( "Exception in discconect of " + self.name )
103 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800105 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400106 response = main.FALSE
107 return response
108
kelvin8ec71442015-01-15 16:57:00 -0800109 def logout( self ):
110 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500111 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700112 Returns main.TRUE if exited CLI and
113 main.FALSE on timeout (not guranteed you are disconnected)
114 None on TypeError
115 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800116 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500117 try:
Jon Hall61282e32015-03-19 11:34:11 -0700118 if self.handle:
119 self.handle.sendline( "" )
120 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
121 timeout=10 )
122 if i == 0: # In ONOS CLI
123 self.handle.sendline( "logout" )
124 self.handle.expect( "\$" )
125 return main.TRUE
126 elif i == 1: # not in CLI
127 return main.TRUE
128 elif i == 3: # Timeout
129 return main.FALSE
130 else:
andrewonlab9627f432014-11-14 12:45:10 -0500131 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800132 except TypeError:
133 main.log.exception( self.name + ": Object not as expected" )
134 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800136 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700137 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 main.cleanup()
139 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700140 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700141 main.log.error( self.name +
142 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800143 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800144 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500145 main.cleanup()
146 main.exit()
147
kelvin-onlabd3b64892015-01-20 13:26:24 -0800148 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800149 """
andrewonlab95ce8322014-10-13 14:12:04 -0400150 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800151
andrewonlab95ce8322014-10-13 14:12:04 -0400152 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800153 """
andrewonlab95ce8322014-10-13 14:12:04 -0400154 try:
155 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800156 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400157 main.cleanup()
158 main.exit()
159 else:
kelvin8ec71442015-01-15 16:57:00 -0800160 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800161 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800162 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400163 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800164 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800165 handleBefore = self.handle.before
166 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800167 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800168 self.handle.sendline("")
169 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800170 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400171
kelvin-onlabd3b64892015-01-20 13:26:24 -0800172 main.log.info( "Cell call returned: " + handleBefore +
173 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400174
175 return main.TRUE
176
Jon Halld4d4b372015-01-28 16:02:41 -0800177 except TypeError:
178 main.log.exception( self.name + ": Object not as expected" )
179 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800181 main.log.error( self.name + ": eof exception found" )
182 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400183 main.cleanup()
184 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800185 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800186 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400187 main.cleanup()
188 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800189
kelvin-onlabd3b64892015-01-20 13:26:24 -0800190 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800191 """
Jon Hallefbd9792015-03-05 16:11:36 -0800192 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 by user would be used to set the current karaf shell idle timeout.
194 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800195 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800196 Below is an example to start a session with 60 seconds idle timeout
197 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800198
Hari Krishna25d42f72015-01-05 15:08:28 -0800199 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800200 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800201
kelvin-onlabd3b64892015-01-20 13:26:24 -0800202 Note: karafTimeout is left as str so that this could be read
203 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800204 """
andrewonlab95ce8322014-10-13 14:12:04 -0400205 try:
kelvin8ec71442015-01-15 16:57:00 -0800206 self.handle.sendline( "" )
207 x = self.handle.expect( [
208 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500209
210 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800211 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500212 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400213
kelvin8ec71442015-01-15 16:57:00 -0800214 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800216 i = self.handle.expect( [
217 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800218 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400219
220 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800222 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800223 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800224 "config:property-set -p org.apache.karaf.shell\
225 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800226 karafTimeout )
227 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800229 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400230 return main.TRUE
231 else:
kelvin8ec71442015-01-15 16:57:00 -0800232 # If failed, send ctrl+c to process and try again
233 main.log.info( "Starting CLI failed. Retrying..." )
234 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800236 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
237 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400238 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800240 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800241 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800242 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 "config:property-set -p org.apache.karaf.shell\
244 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800245 karafTimeout )
246 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800248 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400249 return main.TRUE
250 else:
kelvin8ec71442015-01-15 16:57:00 -0800251 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400253 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400254
Jon Halld4d4b372015-01-28 16:02:41 -0800255 except TypeError:
256 main.log.exception( self.name + ": Object not as expected" )
257 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400258 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800259 main.log.error( self.name + ": EOF exception found" )
260 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400261 main.cleanup()
262 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800263 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800264 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400265 main.cleanup()
266 main.exit()
267
Jon Hallefbd9792015-03-05 16:11:36 -0800268 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800269 """
270 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800271 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800272 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800273 Available level: DEBUG, TRACE, INFO, WARN, ERROR
274 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800275 """
276 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800277 lvlStr = ""
278 if level:
279 lvlStr = "--level=" + level
280
kelvin-onlab9f541032015-02-04 16:19:53 -0800281 self.handle.sendline( "" )
282 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800283 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800284 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800285
kelvin-onlab9f541032015-02-04 16:19:53 -0800286 response = self.handle.before
287 if re.search( "Error", response ):
288 return main.FALSE
289 return main.TRUE
290
291 except pexpect.EOF:
292 main.log.error( self.name + ": EOF exception found" )
293 main.log.error( self.name + ": " + self.handle.before )
294 main.cleanup()
295 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800296 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800297 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400298 main.cleanup()
299 main.exit()
300
kelvin-onlabd3b64892015-01-20 13:26:24 -0800301 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800302 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800303 Send a completely user specified string to
304 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400305 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800306
andrewonlaba18f6bf2014-10-13 19:31:54 -0400307 Warning: There are no sanity checking to commands
308 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800309 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400310 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800311 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
312 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800314 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
315 response = self.handle.before
316 if i == 2:
317 self.handle.sendline()
318 self.handle.expect( "\$" )
319 response += self.handle.before
320 print response
321 try:
322 print self.handle.after
323 except:
324 pass
325 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800327 + self.name + "." )
Jon Hall7bdfc122015-01-23 11:45:32 -0800328 # Remove control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800329 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800330 response = ansiEscape.sub( '', response )
kelvin-onlabfb521662015-02-27 09:52:40 -0800331 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800332 response = re.sub( r"\s\r", "", response )
333 response = response.strip()
334 # parse for just the output, remove the cmd from response
335 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800336 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800337 except TypeError:
338 main.log.exception( self.name + ": Object not as expected" )
339 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400340 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800341 main.log.error( self.name + ": EOF exception found" )
342 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400343 main.cleanup()
344 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800345 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800346 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400347 main.cleanup()
348 main.exit()
349
kelvin8ec71442015-01-15 16:57:00 -0800350 # IMPORTANT NOTE:
351 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 # the cli command changing 'a:b' with 'aB'.
353 # Ex ) onos:topology > onosTopology
354 # onos:links > onosLinks
355 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800356
kelvin-onlabd3b64892015-01-20 13:26:24 -0800357 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800358 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400359 Adds a new cluster node by ID and address information.
360 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800361 * nodeId
362 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400363 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800364 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800365 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400366 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800367 cmdStr = "add-node " + str( nodeId ) + " " +\
368 str( ONOSIp ) + " " + str( tcpPort )
369 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800370 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800371 main.log.error( "Error in adding node" )
372 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800373 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400374 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800375 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400376 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800377 except TypeError:
378 main.log.exception( self.name + ": Object not as expected" )
379 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400380 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800381 main.log.error( self.name + ": EOF exception found" )
382 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400383 main.cleanup()
384 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800385 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800386 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400387 main.cleanup()
388 main.exit()
389
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800391 """
andrewonlab86dc3082014-10-13 18:18:38 -0400392 Removes a cluster by ID
393 Issues command: 'remove-node [<node-id>]'
394 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800395 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800396 """
andrewonlab86dc3082014-10-13 18:18:38 -0400397 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400398
kelvin-onlabd3b64892015-01-20 13:26:24 -0800399 cmdStr = "remove-node " + str( nodeId )
400 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800401 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400402
403 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800404
Jon Halld4d4b372015-01-28 16:02:41 -0800405 except TypeError:
406 main.log.exception( self.name + ": Object not as expected" )
407 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400408 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400411 main.cleanup()
412 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800413 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800414 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400415 main.cleanup()
416 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417
Jon Hall61282e32015-03-19 11:34:11 -0700418 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800419 """
andrewonlab7c211572014-10-15 16:45:20 -0400420 List the nodes currently visible
421 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700422 Optional argument:
423 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800424 """
andrewonlab7c211572014-10-15 16:45:20 -0400425 try:
Jon Hall61282e32015-03-19 11:34:11 -0700426 if jsonFormat:
427 cmdStr = "nodes -j"
428 output = self.sendline( cmdStr )
429 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
430 parsedOutput = ansiEscape.sub( '', output )
431 return parsedOutput
432 else:
433 cmdStr = "nodes"
434 output = self.sendline( cmdStr )
435 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800436 except TypeError:
437 main.log.exception( self.name + ": Object not as expected" )
438 return None
andrewonlab7c211572014-10-15 16:45:20 -0400439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800440 main.log.error( self.name + ": EOF exception found" )
441 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400442 main.cleanup()
443 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800445 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400446 main.cleanup()
447 main.exit()
448
kelvin8ec71442015-01-15 16:57:00 -0800449 def topology( self ):
450 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700451 Definition:
452 Returns the ouput of topology command.
453 Return:
454 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800455 """
andrewonlab95ce8322014-10-13 14:12:04 -0400456 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800457 # either onos:topology or 'topology' will work in CLI
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700458 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800459 handle = self.sendline( cmdStr )
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700460 main.log.info( "topology -j returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400461 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800462 except TypeError:
463 main.log.exception( self.name + ": Object not as expected" )
464 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400468 main.cleanup()
469 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800470 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800471 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400472 main.cleanup()
473 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800474
kelvin-onlabd3b64892015-01-20 13:26:24 -0800475 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800477 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400478 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400480 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 cmdStr = "feature:install " + str( featureStr )
482 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800483 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400484 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800485 except TypeError:
486 main.log.exception( self.name + ": Object not as expected" )
487 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800489 main.log.error( self.name + ": EOF exception found" )
490 main.log.error( self.name + ": " + self.handle.before )
491 main.log.report( "Failed to install feature" )
492 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400493 main.cleanup()
494 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800495 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800496 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800497 main.log.report( "Failed to install feature" )
498 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400499 main.cleanup()
500 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800501
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400504 Uninstalls a specified feature
505 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800506 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400507 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800508 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
509 handle = self.sendline( cmdStr )
510 if handle != '':
511 cmdStr = "feature:uninstall " + str( featureStr )
512 self.sendline( cmdStr )
513 # TODO: Check for possible error responses from karaf
514 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800515 main.log.info( "Feature needs to be installed before " +
516 "uninstalling it" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400517 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800518 except TypeError:
519 main.log.exception( self.name + ": Object not as expected" )
520 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800522 main.log.error( self.name + ": EOF exception found" )
523 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400524 main.cleanup()
525 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800527 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 main.cleanup()
529 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800530
jenkins7ead5a82015-03-13 10:28:21 -0700531 def deviceRemove( self, deviceId ):
532 """
533 Removes particular device from storage
534
535 TODO: refactor this function
536 """
537 try:
538 cmdStr = "device-remove "+str(deviceId)
Jon Hallbe379602015-03-24 13:39:32 -0700539 self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -0700540 return main.TRUE
541 except TypeError:
542 main.log.exception( self.name + ": Object not as expected" )
543 return None
544 except pexpect.EOF:
545 main.log.error( self.name + ": EOF exception found" )
546 main.log.error( self.name + ": " + self.handle.before )
547 main.cleanup()
548 main.exit()
549 except Exception:
550 main.log.exception( self.name + ": Uncaught exception!" )
551 main.cleanup()
552 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700553
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800555 """
Jon Hall7b02d952014-10-17 20:14:54 -0400556 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400557 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlab86dc3082014-10-13 18:18:38 -0400560 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 if jsonFormat:
562 cmdStr = "devices -j"
563 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800564 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800565 handle variable here contains some ANSI escape color code
566 sequences at the end which are invisible in the print command
567 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800568 function. The repr( handle ) output when printed shows the
569 ANSI escape sequences. In json.loads( somestring ), this
570 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800571 json.loads would fail with the escape sequence. So we take off
572 that escape sequence using:
573
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
575 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800576 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
578 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400579 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400580 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 cmdStr = "devices"
582 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400583 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800584 except TypeError:
585 main.log.exception( self.name + ": Object not as expected" )
586 return None
andrewonlab7c211572014-10-15 16:45:20 -0400587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800588 main.log.error( self.name + ": EOF exception found" )
589 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400590 main.cleanup()
591 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800592 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800593 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400594 main.cleanup()
595 main.exit()
596
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800598 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800599 This balances the devices across all controllers
600 by issuing command: 'onos> onos:balance-masters'
601 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800602 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800603 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800604 cmdStr = "onos:balance-masters"
605 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800606 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800607 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800608 except TypeError:
609 main.log.exception( self.name + ": Object not as expected" )
610 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800612 main.log.error( self.name + ": EOF exception found" )
613 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800614 main.cleanup()
615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800617 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800618 main.cleanup()
619 main.exit()
620
kelvin-onlabd3b64892015-01-20 13:26:24 -0800621 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Jon Halle8217482014-10-17 13:49:14 -0400623 Lists all core links
624 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800626 """
Jon Halle8217482014-10-17 13:49:14 -0400627 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 if jsonFormat:
629 cmdStr = "links -j"
630 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800631 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800632 handle variable here contains some ANSI escape color code
633 sequences at the end which are invisible in the print command
634 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800635 function. The repr( handle ) output when printed shows the ANSI
636 escape sequences. In json.loads( somestring ), this somestring
637 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800638 fail with the escape sequence. So we take off that escape
639 sequence using:
640
kelvin-onlabd3b64892015-01-20 13:26:24 -0800641 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
642 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800643 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
645 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400646 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400647 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 cmdStr = "links"
649 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400650 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800651 except TypeError:
652 main.log.exception( self.name + ": Object not as expected" )
653 return None
Jon Halle8217482014-10-17 13:49:14 -0400654 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800655 main.log.error( self.name + ": EOF exception found" )
656 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400657 main.cleanup()
658 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800659 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800660 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400661 main.cleanup()
662 main.exit()
663
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800665 """
Jon Halle8217482014-10-17 13:49:14 -0400666 Lists all ports
667 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800669 """
Jon Halle8217482014-10-17 13:49:14 -0400670 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 if jsonFormat:
672 cmdStr = "ports -j"
673 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800674 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800675 handle variable here contains some ANSI escape color code
676 sequences at the end which are invisible in the print command
677 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800678 function. The repr( handle ) output when printed shows the ANSI
679 escape sequences. In json.loads( somestring ), this somestring
680 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800681 fail with the escape sequence. So we take off that escape
Jon Hallefbd9792015-03-05 16:11:36 -0800682 sequence using the following commands:
Jon Halle3f39ff2015-01-13 11:50:53 -0800683
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
685 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800686 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
688 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400689 return handle1
690
Jon Halle8217482014-10-17 13:49:14 -0400691 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 cmdStr = "ports"
693 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800694 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800695 except TypeError:
696 main.log.exception( self.name + ": Object not as expected" )
697 return None
Jon Halle8217482014-10-17 13:49:14 -0400698 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400701 main.cleanup()
702 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800703 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800704 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400705 main.cleanup()
706 main.exit()
707
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800709 """
Jon Hall983a1702014-10-28 18:44:22 -0400710 Lists all devices and the controllers with roles assigned to them
711 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800713 """
andrewonlab7c211572014-10-15 16:45:20 -0400714 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
716 cmdStr = "roles -j"
717 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800718 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800719 handle variable here contains some ANSI escape color code
720 sequences at the end which are invisible in the print command
721 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800722 function. The repr( handle ) output when printed shows the ANSI
723 escape sequences. In json.loads( somestring ), this somestring
724 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800725 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500726
Jon Halle3f39ff2015-01-13 11:50:53 -0800727 So we take off that escape sequence using the following
728 commads:
729
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
731 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800732 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
734 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400735 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400736
andrewonlab7c211572014-10-15 16:45:20 -0400737 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 cmdStr = "roles"
739 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800740 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800741 except TypeError:
742 main.log.exception( self.name + ": Object not as expected" )
743 return None
Jon Hall983a1702014-10-28 18:44:22 -0400744 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800745 main.log.error( self.name + ": EOF exception found" )
746 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400747 main.cleanup()
748 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800749 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800750 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400751 main.cleanup()
752 main.exit()
753
kelvin-onlabd3b64892015-01-20 13:26:24 -0800754 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800755 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800756 Given the a string containing the json representation of the "roles"
757 cli command and a partial or whole device id, returns a json object
758 containing the roles output for the first device whose id contains
759 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400760
761 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800762 A dict of the role assignments for the given device or
763 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800764 """
Jon Hall983a1702014-10-28 18:44:22 -0400765 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400767 return None
768 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 rawRoles = self.roles()
770 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800771 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800773 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400775 return device
776 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800777 except TypeError:
778 main.log.exception( self.name + ": Object not as expected" )
779 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400780 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400783 main.cleanup()
784 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400787 main.cleanup()
788 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800789
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800791 """
Jon Hall94fd0472014-12-08 11:52:42 -0800792 Iterates through each device and checks if there is a master assigned
793 Returns: main.TRUE if each device has a master
794 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800795 """
Jon Hall94fd0472014-12-08 11:52:42 -0800796 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 rawRoles = self.roles()
798 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800799 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800801 # print device
802 if device[ 'master' ] == "none":
803 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800804 return main.FALSE
805 return main.TRUE
806
Jon Halld4d4b372015-01-28 16:02:41 -0800807 except TypeError:
808 main.log.exception( self.name + ": Object not as expected" )
809 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800810 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800813 main.cleanup()
814 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800815 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800816 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800817 main.cleanup()
818 main.exit()
819
kelvin-onlabd3b64892015-01-20 13:26:24 -0800820 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800821 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400822 Returns string of paths, and the cost.
823 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800824 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400825 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800826 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
827 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800828 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800829 main.log.error( "Error in getting paths" )
830 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400831 else:
kelvin8ec71442015-01-15 16:57:00 -0800832 path = handle.split( ";" )[ 0 ]
833 cost = handle.split( ";" )[ 1 ]
834 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800835 except TypeError:
836 main.log.exception( self.name + ": Object not as expected" )
837 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400838 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400841 main.cleanup()
842 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800843 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800844 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400845 main.cleanup()
846 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800847
kelvin-onlabd3b64892015-01-20 13:26:24 -0800848 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Hallffb386d2014-11-21 13:43:38 -0800850 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400851 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400854 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 if jsonFormat:
856 cmdStr = "hosts -j"
857 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800858 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800859 handle variable here contains some ANSI escape color code
860 sequences at the end which are invisible in the print command
861 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800862 function. The repr( handle ) output when printed shows the ANSI
863 escape sequences. In json.loads( somestring ), this somestring
864 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800865 fail with the escape sequence. So we take off that escape
866 sequence using:
867
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
869 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800870 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
872 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 return handle1
874 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 cmdStr = "hosts"
876 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400877 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800878 except TypeError:
879 main.log.exception( self.name + ": Object not as expected" )
880 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400881 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400884 main.cleanup()
885 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800887 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400888 main.cleanup()
889 main.exit()
890
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800892 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400893 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800894
Jon Hallefbd9792015-03-05 16:11:36 -0800895 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800896 partial mac address
897
Jon Hall42db6dc2014-10-24 19:03:48 -0400898 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800899 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400900 try:
kelvin8ec71442015-01-15 16:57:00 -0800901 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400902 return None
903 else:
904 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 rawHosts = self.hosts()
906 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800907 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800909 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800910 if not host:
911 pass
912 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400913 return host
914 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800915 except TypeError:
916 main.log.exception( self.name + ": Object not as expected" )
917 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400918 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800919 main.log.error( self.name + ": EOF exception found" )
920 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400921 main.cleanup()
922 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800923 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800924 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400925 main.cleanup()
926 main.exit()
927
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800929 """
930 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400931 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800932
andrewonlab3f0a4af2014-10-17 12:25:14 -0400933 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400935 IMPORTANT:
936 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800937 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400938 Furthermore, it assumes that value of VLAN is '-1'
939 Description:
kelvin8ec71442015-01-15 16:57:00 -0800940 Converts mininet hosts ( h1, h2, h3... ) into
941 ONOS format ( 00:00:00:00:00:01/-1 , ... )
942 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400943 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800947 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800948 hostHex = hex( int( host ) ).zfill( 12 )
949 hostHex = str( hostHex ).replace( 'x', '0' )
950 i = iter( str( hostHex ) )
951 hostHex = ":".join( a + b for a, b in zip( i, i ) )
952 hostHex = hostHex + "/-1"
953 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400954
kelvin-onlabd3b64892015-01-20 13:26:24 -0800955 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400956
Jon Halld4d4b372015-01-28 16:02:41 -0800957 except TypeError:
958 main.log.exception( self.name + ": Object not as expected" )
959 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400960 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800961 main.log.error( self.name + ": EOF exception found" )
962 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400963 main.cleanup()
964 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800965 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800966 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400967 main.cleanup()
968 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400969
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800971 """
andrewonlabe6745342014-10-17 14:29:13 -0400972 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 * hostIdOne: ONOS host id for host1
974 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400975 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800976 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500977 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800978 Returns:
979 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800980 """
andrewonlabe6745342014-10-17 14:29:13 -0400981 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 cmdStr = "add-host-intent " + str( hostIdOne ) +\
983 " " + str( hostIdTwo )
984 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800985 if re.search( "Error", handle ):
986 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700987 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800988 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800989 else:
990 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800991 str( hostIdOne ) + " and " + str( hostIdTwo ) )
992 match = re.search('id=0x([\da-f]+),', handle)
993 if match:
994 return match.group()[3:-1]
995 else:
996 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700997 main.log.debug( "Response from ONOS was: " +
998 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800999 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001000 except TypeError:
1001 main.log.exception( self.name + ": Object not as expected" )
1002 return None
andrewonlabe6745342014-10-17 14:29:13 -04001003 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.error( self.name + ": EOF exception found" )
1005 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001006 main.cleanup()
1007 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001008 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001009 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001010 main.cleanup()
1011 main.exit()
1012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
andrewonlab7b31d232014-10-24 13:31:47 -04001015 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 * ingressDevice: device id of ingress device
1017 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001018 Optional:
1019 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001020 Description:
1021 Adds an optical intent by specifying an ingress and egress device
1022 Returns:
1023 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001024 """
andrewonlab7b31d232014-10-24 13:31:47 -04001025 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1027 " " + str( egressDevice )
1028 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001029 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001030 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001031 main.log.error( "Error in adding Optical intent" )
1032 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001033 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001034 main.log.info( "Optical intent installed between " +
1035 str( ingressDevice ) + " and " +
1036 str( egressDevice ) )
1037 match = re.search('id=0x([\da-f]+),', handle)
1038 if match:
1039 return match.group()[3:-1]
1040 else:
1041 main.log.error( "Error, intent ID not found" )
1042 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001043 except TypeError:
1044 main.log.exception( self.name + ": Object not as expected" )
1045 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001046 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001049 main.cleanup()
1050 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001051 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001052 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001053 main.cleanup()
1054 main.exit()
1055
kelvin-onlabd3b64892015-01-20 13:26:24 -08001056 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001057 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 ingressDevice,
1059 egressDevice,
1060 portIngress="",
1061 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001062 ethType="",
1063 ethSrc="",
1064 ethDst="",
1065 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001067 ipProto="",
1068 ipSrc="",
1069 ipDst="",
1070 tcpSrc="",
1071 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001072 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001073 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 * ingressDevice: device id of ingress device
1075 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001076 Optional:
1077 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001078 * ethSrc: specify ethSrc ( i.e. src mac addr )
1079 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001080 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001082 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001083 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001084 * ipSrc: specify ip source address
1085 * ipDst: specify ip destination address
1086 * tcpSrc: specify tcp source port
1087 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001088 Description:
kelvin8ec71442015-01-15 16:57:00 -08001089 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001090 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 Returns:
1092 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001093
Jon Halle3f39ff2015-01-13 11:50:53 -08001094 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001095 options developers provide for point-to-point
1096 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001097 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001098 try:
kelvin8ec71442015-01-15 16:57:00 -08001099 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001100 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001102 and not ipProto and not ipSrc and not ipDst \
1103 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001104 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001105
andrewonlab289e4b72014-10-21 21:24:18 -04001106 else:
andrewonlab36af3822014-11-18 17:48:18 -05001107 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001108
andrewonlab0c0a6772014-10-22 12:31:18 -04001109 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001110 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001111 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001112 cmd += " --ethSrc " + str( ethSrc )
1113 if ethDst:
1114 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001115 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001116 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001118 cmd += " --lambda "
1119 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001120 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001121 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001122 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001123 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001124 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001125 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001126 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001127 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001128 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001129
kelvin8ec71442015-01-15 16:57:00 -08001130 # Check whether the user appended the port
1131 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 if "/" in ingressDevice:
1133 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001134 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001136 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001137 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001138 # Would it make sense to throw an exception and exit
1139 # the test?
1140 return None
andrewonlab36af3822014-11-18 17:48:18 -05001141
kelvin8ec71442015-01-15 16:57:00 -08001142 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 str( ingressDevice ) + "/" +\
1144 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001145
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 if "/" in egressDevice:
1147 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001148 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001150 main.log.error( "You must specify the egress port" )
1151 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001152
kelvin8ec71442015-01-15 16:57:00 -08001153 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 str( egressDevice ) + "/" +\
1155 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001156
kelvin-onlab898a6c62015-01-16 14:13:53 -08001157 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001158 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001159 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001160 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001161 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001162 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001163 # TODO: print out all the options in this message?
1164 main.log.info( "Point-to-point intent installed between " +
1165 str( ingressDevice ) + " and " +
1166 str( egressDevice ) )
1167 match = re.search('id=0x([\da-f]+),', handle)
1168 if match:
1169 return match.group()[3:-1]
1170 else:
1171 main.log.error( "Error, intent ID not found" )
1172 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001173 except TypeError:
1174 main.log.exception( self.name + ": Object not as expected" )
1175 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001176 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001177 main.log.error( self.name + ": EOF exception found" )
1178 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001179 main.cleanup()
1180 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001181 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001182 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001183 main.cleanup()
1184 main.exit()
1185
kelvin-onlabd3b64892015-01-20 13:26:24 -08001186 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001187 self,
shahshreyac2f97072015-03-19 17:04:29 -07001188 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001189 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001190 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001192 ethType="",
1193 ethSrc="",
1194 ethDst="",
1195 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001197 ipProto="",
1198 ipSrc="",
1199 ipDst="",
1200 tcpSrc="",
1201 tcpDst="",
1202 setEthSrc="",
1203 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001204 """
shahshreyad0c80432014-12-04 16:56:05 -08001205 Note:
shahshreya70622b12015-03-19 17:19:00 -07001206 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001207 is same. That is, all ingress devices include port numbers
1208 with a "/" or all ingress devices could specify device
1209 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001210 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001211 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001212 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001214 Optional:
1215 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001216 * ethSrc: specify ethSrc ( i.e. src mac addr )
1217 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001218 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001220 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001221 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001222 * ipSrc: specify ip source address
1223 * ipDst: specify ip destination address
1224 * tcpSrc: specify tcp source port
1225 * tcpDst: specify tcp destination port
1226 * setEthSrc: action to Rewrite Source MAC Address
1227 * setEthDst: action to Rewrite Destination MAC Address
1228 Description:
kelvin8ec71442015-01-15 16:57:00 -08001229 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001230 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 Returns:
1232 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001233
Jon Halle3f39ff2015-01-13 11:50:53 -08001234 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001235 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001236 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001237 """
shahshreyad0c80432014-12-04 16:56:05 -08001238 try:
kelvin8ec71442015-01-15 16:57:00 -08001239 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001240 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001242 and not ipProto and not ipSrc and not ipDst\
1243 and not tcpSrc and not tcpDst and not setEthSrc\
1244 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001245 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001246
1247 else:
1248 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001249
shahshreyad0c80432014-12-04 16:56:05 -08001250 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001251 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001252 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001253 cmd += " --ethSrc " + str( ethSrc )
1254 if ethDst:
1255 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001256 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001257 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001259 cmd += " --lambda "
1260 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001261 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001262 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001263 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001264 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001265 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001266 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001267 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001268 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001269 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001270 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001271 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001272 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001273 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001274
kelvin8ec71442015-01-15 16:57:00 -08001275 # Check whether the user appended the port
1276 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001277
1278 if portIngressList is None:
1279 for ingressDevice in ingressDeviceList:
1280 if "/" in ingressDevice:
1281 cmd += " " + str( ingressDevice )
1282 else:
1283 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001284 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001285 # TODO: perhaps more meaningful return
1286 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001287 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001288 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hallbe379602015-03-24 13:39:32 -07001289 for ingressDevice, portIngress in zip( ingressDeviceList, portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001290 cmd += " " + \
1291 str( ingressDevice ) + "/" +\
1292 str( portIngress ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001293
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 if "/" in egressDevice:
1295 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001296 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001298 main.log.error( "You must specify " +
1299 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001300 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001301
kelvin8ec71442015-01-15 16:57:00 -08001302 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 str( egressDevice ) + "/" +\
1304 str( portEgress )
shahshreyac2f97072015-03-19 17:04:29 -07001305
kelvin8ec71442015-01-15 16:57:00 -08001306 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001307 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001308 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001309 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001310 main.log.error( "Error in adding multipoint-to-singlepoint " +
1311 "intent" )
1312 return None
shahshreyad0c80432014-12-04 16:56:05 -08001313 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001314 # TODO: print out all the options in this message?
1315 main.log.info( "Multipoint-to-singlepoint intent installed" +
shahshreyac2f97072015-03-19 17:04:29 -07001316 " failed " )
1317 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001318 except TypeError:
1319 main.log.exception( self.name + ": Object not as expected" )
1320 return None
shahshreyad0c80432014-12-04 16:56:05 -08001321 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001324 main.cleanup()
1325 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001326 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001327 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001328 main.cleanup()
1329 main.exit()
1330
Jon Hallefbd9792015-03-05 16:11:36 -08001331 def removeIntent( self, intentId, app='org.onosproject.cli',
1332 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001333 """
shahshreya1c818fc2015-02-26 13:44:08 -08001334 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001335 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001336 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001337 -p or --purge: Purge the intent from the store after removal
1338
Jon Halle3f39ff2015-01-13 11:50:53 -08001339 Returns:
1340 main.False on error and
1341 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001342 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001343 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001344 cmdStr = "remove-intent "
1345 if purge:
1346 cmdStr += " -p"
1347 if sync:
1348 cmdStr += " -s"
1349
1350 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001352 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001353 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001354 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001355 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001356 # TODO: Should this be main.TRUE
1357 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001358 except TypeError:
1359 main.log.exception( self.name + ": Object not as expected" )
1360 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001361 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001362 main.log.error( self.name + ": EOF exception found" )
1363 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001364 main.cleanup()
1365 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001366 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001367 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001368 main.cleanup()
1369 main.exit()
1370
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001372 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001373 NOTE: This method should be used after installing application:
1374 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001375 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001377 Description:
1378 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001379 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001380 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 if jsonFormat:
1382 cmdStr = "routes -j"
1383 handleTmp = self.sendline( cmdStr )
1384 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1385 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001386 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 cmdStr = "routes"
1388 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001389 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001390 except TypeError:
1391 main.log.exception( self.name + ": Object not as expected" )
1392 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.error( self.name + ": EOF exception found" )
1395 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001396 main.cleanup()
1397 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001398 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001399 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001400 main.cleanup()
1401 main.exit()
1402
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001404 """
andrewonlab377693f2014-10-21 16:00:30 -04001405 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001407 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001408 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001409 """
andrewonlabe6745342014-10-17 14:29:13 -04001410 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 if jsonFormat:
1412 cmdStr = "intents -j"
1413 handle = self.sendline( cmdStr )
1414 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1415 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001416 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001417 cmdStr = "intents"
1418 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001419 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001420 except TypeError:
1421 main.log.exception( self.name + ": Object not as expected" )
1422 return None
andrewonlabe6745342014-10-17 14:29:13 -04001423 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001424 main.log.error( self.name + ": EOF exception found" )
1425 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001426 main.cleanup()
1427 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001428 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001429 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001430 main.cleanup()
1431 main.exit()
1432
kelvin-onlab54400a92015-02-26 18:05:51 -08001433 def getIntentState(self, intentsId, intentsJson=None):
1434 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001435 Check intent state.
1436 Accepts a single intent ID (string type) or a list of intent IDs.
1437 Returns the state(string type) of the id if a single intent ID is
1438 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001439 Returns a dictionary with intent IDs as the key and its
1440 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001442 intentId: intent ID (string type)
1443 intentsJson: parsed json object from the onos:intents api
1444 Returns:
1445 state = An intent's state- INSTALL,WITHDRAWN etc.
1446 stateDict = Dictionary of intent's state. intent ID as the keys and
1447 state as the values.
1448 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001449 try:
1450 state = "State is Undefined"
1451 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001452 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001453 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001454 intentsJsonTemp = json.loads( intentsJson )
1455 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001456 for intent in intentsJsonTemp:
1457 if intentsId == intent['id']:
1458 state = intent['state']
1459 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001460 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1461 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001462 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001463 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001464 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001465 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001466 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001467 for intents in intentsJsonTemp:
1468 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001469 stateDict['state'] = intents['state']
1470 stateDict['id'] = ID
Jon Hallefbd9792015-03-05 16:11:36 -08001471 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001472 break
Jon Hallefbd9792015-03-05 16:11:36 -08001473 if len( intentsId ) != len( dictList ):
1474 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001475 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001476 else:
1477 main.log.info("Invalid intents ID entry")
1478 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001479 except TypeError:
1480 main.log.exception( self.name + ": Object not as expected" )
1481 return None
1482 except pexpect.EOF:
1483 main.log.error( self.name + ": EOF exception found" )
1484 main.log.error( self.name + ": " + self.handle.before )
1485 main.cleanup()
1486 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001487 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001488 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001489 main.cleanup()
1490 main.exit()
1491
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001493 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001494 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001496 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001497 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001498 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001499 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 if jsonFormat:
1501 cmdStr = "flows -j"
1502 handle = self.sendline( cmdStr )
1503 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1504 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001505 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 cmdStr = "flows"
1507 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001508 if re.search( "Error:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001509 main.log.error( self.name + ".flows() response: " +
1510 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001511 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001512 except TypeError:
1513 main.log.exception( self.name + ": Object not as expected" )
1514 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001516 main.log.error( self.name + ": EOF exception found" )
1517 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001518 main.cleanup()
1519 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001520 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001521 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001522 main.cleanup()
1523 main.exit()
1524
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001526 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001527 """
andrewonlab87852b02014-11-19 18:44:19 -05001528 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001529 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001530 a specific point-to-point intent definition
1531 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 * dpidSrc: specify source dpid
1533 * dpidDst: specify destination dpid
1534 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001535 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001537 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001539 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001540 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001541 """
andrewonlab87852b02014-11-19 18:44:19 -05001542 try:
kelvin8ec71442015-01-15 16:57:00 -08001543 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1545 str( numIntents )
1546 if numMult:
1547 cmd += " " + str( numMult )
1548 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001549 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 if appId:
1551 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1554 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001555 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001557 main.log.info( handle )
1558 # Split result by newline
1559 newline = handle.split( "\r\r\n" )
1560 # Ignore the first object of list, which is empty
1561 newline = newline[ 1: ]
1562 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001563 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001564 result = result.split( ": " )
1565 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1567 main.log.info( latResult )
1568 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001569 else:
1570 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001571 except TypeError:
1572 main.log.exception( self.name + ": Object not as expected" )
1573 return None
andrewonlab87852b02014-11-19 18:44:19 -05001574 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001575 main.log.error( self.name + ": EOF exception found" )
1576 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001577 main.cleanup()
1578 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001579 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001580 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001581 main.cleanup()
1582 main.exit()
1583
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001585 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001586 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001587 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001588 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001589 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001590 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 if jsonFormat:
1592 cmdStr = "intents-events-metrics -j"
1593 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001594 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1596 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001597 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 cmdStr = "intents-events-metrics"
1599 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001600 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001601 except TypeError:
1602 main.log.exception( self.name + ": Object not as expected" )
1603 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001604 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001605 main.log.error( self.name + ": EOF exception found" )
1606 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001607 main.cleanup()
1608 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001609 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001610 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001611 main.cleanup()
1612 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001613
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001615 """
1616 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001617 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001619 """
andrewonlab867212a2014-10-22 20:13:38 -04001620 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 if jsonFormat:
1622 cmdStr = "topology-events-metrics -j"
1623 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001624 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1626 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001627 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001628 cmdStr = "topology-events-metrics"
1629 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07001630 if handle:
1631 return handle
1632 else:
Jon Hallbe379602015-03-24 13:39:32 -07001633 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07001634 return '{}'
Jon Halld4d4b372015-01-28 16:02:41 -08001635 except TypeError:
1636 main.log.exception( self.name + ": Object not as expected" )
1637 return None
andrewonlab867212a2014-10-22 20:13:38 -04001638 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001639 main.log.error( self.name + ": EOF exception found" )
1640 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001641 main.cleanup()
1642 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001643 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001644 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001645 main.cleanup()
1646 main.exit()
1647
kelvin8ec71442015-01-15 16:57:00 -08001648 # Wrapper functions ****************
1649 # Wrapper functions use existing driver
1650 # functions and extends their use case.
1651 # For example, we may use the output of
1652 # a normal driver function, and parse it
1653 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04001654
kelvin-onlabd3b64892015-01-20 13:26:24 -08001655 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001656 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001657 Description:
1658 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001659 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001660 try:
kelvin8ec71442015-01-15 16:57:00 -08001661 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001662 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001664
kelvin8ec71442015-01-15 16:57:00 -08001665 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001666 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1667 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001668 match = re.search('id=0x([\da-f]+),', intents)
1669 if match:
1670 tmpId = match.group()[3:-1]
1671 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001673
Jon Halld4d4b372015-01-28 16:02:41 -08001674 except TypeError:
1675 main.log.exception( self.name + ": Object not as expected" )
1676 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001677 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001678 main.log.error( self.name + ": EOF exception found" )
1679 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001680 main.cleanup()
1681 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001682 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001683 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001684 main.cleanup()
1685 main.exit()
1686
Jon Hall30b82fa2015-03-04 17:15:43 -08001687 def FlowAddedCount( self, deviceId ):
1688 """
1689 Determine the number of flow rules for the given device id that are
1690 in the added state
1691 """
1692 try:
1693 cmdStr = "flows any " + str( deviceId ) + " | " +\
1694 "grep 'state=ADDED' | wc -l"
1695 handle = self.sendline( cmdStr )
1696 return handle
1697 except pexpect.EOF:
1698 main.log.error( self.name + ": EOF exception found" )
1699 main.log.error( self.name + ": " + self.handle.before )
1700 main.cleanup()
1701 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001702 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08001703 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001704 main.cleanup()
1705 main.exit()
1706
kelvin-onlabd3b64892015-01-20 13:26:24 -08001707 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001708 """
andrewonlab95ce8322014-10-13 14:12:04 -04001709 Use 'devices' function to obtain list of all devices
1710 and parse the result to obtain a list of all device
1711 id's. Returns this list. Returns empty list if no
1712 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001713 List is ordered sequentially
1714
andrewonlab95ce8322014-10-13 14:12:04 -04001715 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001716 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04001717 the ids. By obtaining the list of device ids on the fly,
1718 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001719 """
andrewonlab95ce8322014-10-13 14:12:04 -04001720 try:
kelvin8ec71442015-01-15 16:57:00 -08001721 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 devicesStr = self.devices( jsonFormat=False )
1723 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001724
kelvin-onlabd3b64892015-01-20 13:26:24 -08001725 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001726 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001727 return idList
kelvin8ec71442015-01-15 16:57:00 -08001728
1729 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001730 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001731 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001733 # Split list further into arguments before and after string
1734 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001735 # append to idList
1736 for arg in tempList:
1737 idList.append( arg.split( "id=" )[ 1 ] )
1738 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04001739
Jon Halld4d4b372015-01-28 16:02:41 -08001740 except TypeError:
1741 main.log.exception( self.name + ": Object not as expected" )
1742 return None
andrewonlab95ce8322014-10-13 14:12:04 -04001743 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001744 main.log.error( self.name + ": EOF exception found" )
1745 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04001746 main.cleanup()
1747 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001748 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001749 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04001750 main.cleanup()
1751 main.exit()
1752
kelvin-onlabd3b64892015-01-20 13:26:24 -08001753 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001754 """
andrewonlab7c211572014-10-15 16:45:20 -04001755 Uses 'nodes' function to obtain list of all nodes
1756 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001757 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001758 Returns:
1759 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001760 """
andrewonlab7c211572014-10-15 16:45:20 -04001761 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07001762 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07001764 # Sample nodesStr output
1765 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001767 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07001769 nodesJson = json.loads( nodesStr )
1770 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08001771 return idList
kelvin8ec71442015-01-15 16:57:00 -08001772
Jon Halld4d4b372015-01-28 16:02:41 -08001773 except TypeError:
1774 main.log.exception( self.name + ": Object not as expected" )
1775 return None
andrewonlab7c211572014-10-15 16:45:20 -04001776 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001777 main.log.error( self.name + ": EOF exception found" )
1778 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001779 main.cleanup()
1780 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001781 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001782 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001783 main.cleanup()
1784 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04001785
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001787 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001788 Return the first device from the devices api whose 'id' contains 'dpid'
1789 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001790 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001791 try:
kelvin8ec71442015-01-15 16:57:00 -08001792 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001793 return None
1794 else:
kelvin8ec71442015-01-15 16:57:00 -08001795 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 rawDevices = self.devices()
1797 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001798 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001799 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001800 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1801 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001802 return device
1803 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001804 except TypeError:
1805 main.log.exception( self.name + ": Object not as expected" )
1806 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001807 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001808 main.log.error( self.name + ": EOF exception found" )
1809 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001810 main.cleanup()
1811 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001813 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001814 main.cleanup()
1815 main.exit()
1816
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001818 """
Jon Hallefbd9792015-03-05 16:11:36 -08001819 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001820 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001821 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08001822
Jon Hall42db6dc2014-10-24 19:03:48 -04001823 Params: ip = ip used for the onos cli
1824 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001825 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001826 logLevel = level to log to. Currently accepts
1827 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001828
1829
kelvin-onlabd3b64892015-01-20 13:26:24 -08001830 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001831
Jon Hallefbd9792015-03-05 16:11:36 -08001832 Returns: main.TRUE if the number of switches and links are correct,
1833 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04001834 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001835 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001836 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001837 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001838 if topology == {}:
1839 return main.ERROR
1840 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001841 # Is the number of switches is what we expected
1842 devices = topology.get( 'devices', False )
1843 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001844 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001845 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001846 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001847 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001848 linkCheck = ( int( links ) == int( numolink ) )
1849 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001850 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08001851 output += "The number of links and switches match " +\
1852 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001853 result = main.TRUE
1854 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001855 output += "The number of links and switches does not match " +\
1856 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001857 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 output = output + "\n ONOS sees %i devices (%i expected) \
1859 and %i links (%i expected)" % (
1860 int( devices ), int( numoswitch ), int( links ),
1861 int( numolink ) )
1862 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001863 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001864 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001865 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001866 else:
kelvin8ec71442015-01-15 16:57:00 -08001867 main.log.info( output )
1868 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001879 main.cleanup()
1880 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001881
kelvin-onlabd3b64892015-01-20 13:26:24 -08001882 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001883 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001884 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001885 deviceId must be the id of a device as seen in the onos devices command
1886 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001887 role must be either master, standby, or none
1888
Jon Halle3f39ff2015-01-13 11:50:53 -08001889 Returns:
1890 main.TRUE or main.FALSE based on argument verification and
1891 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001892 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001893 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001894 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001895 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001896 cmdStr = "device-role " +\
1897 str( deviceId ) + " " +\
1898 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001899 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001900 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001901 if re.search( "Error", handle ):
1902 # end color output to escape any colours
1903 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001904 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001905 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001906 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001907 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001908 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001909 main.log.error( "Invalid 'role' given to device_role(). " +
1910 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001911 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001912 except TypeError:
1913 main.log.exception( self.name + ": Object not as expected" )
1914 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001915 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001916 main.log.error( self.name + ": EOF exception found" )
1917 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001918 main.cleanup()
1919 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001920 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001921 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001922 main.cleanup()
1923 main.exit()
1924
kelvin-onlabd3b64892015-01-20 13:26:24 -08001925 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001926 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001927 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001930 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001931 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001932 if jsonFormat:
1933 cmdStr = "clusters -j"
1934 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001935 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001936 handle variable here contains some ANSI escape color code
1937 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001938 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001939 function. The repr( handle ) output when printed shows the ANSI
1940 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 variable is actually repr( somestring ) and json.loads would
1942 fail with the escape sequence. So we take off that escape
1943 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001944
kelvin-onlabd3b64892015-01-20 13:26:24 -08001945 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1946 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001947 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001948 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1949 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001950 return handle1
1951 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001952 cmdStr = "clusters"
1953 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001954 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001955 except TypeError:
1956 main.log.exception( self.name + ": Object not as expected" )
1957 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001959 main.log.error( self.name + ": EOF exception found" )
1960 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001961 main.cleanup()
1962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001964 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001965 main.cleanup()
1966 main.exit()
1967
kelvin-onlabd3b64892015-01-20 13:26:24 -08001968 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001969 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001970 CLI command to get the current leader for the Election test application
1971 NOTE: Requires installation of the onos-app-election feature
1972 Returns: Node IP of the leader if one exists
1973 None if none exists
1974 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001975 """
Jon Hall94fd0472014-12-08 11:52:42 -08001976 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 cmdStr = "election-test-leader"
1978 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001979 # Leader
1980 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001981 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 nodeSearch = re.search( leaderPattern, response )
1983 if nodeSearch:
1984 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001985 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001986 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001987 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001988 # no leader
1989 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001990 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001991 nullSearch = re.search( nullPattern, response )
1992 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001993 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001994 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001995 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001996 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001997 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001998 if re.search( errorPattern, response ):
1999 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002000 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002001 return main.FALSE
2002 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002003 main.log.error( "Error in election_test_leader: " +
2004 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002005 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002006 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002007 except TypeError:
2008 main.log.exception( self.name + ": Object not as expected" )
2009 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002010 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002011 main.log.error( self.name + ": EOF exception found" )
2012 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002013 main.cleanup()
2014 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002015 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002016 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002017 main.cleanup()
2018 main.exit()
2019
kelvin-onlabd3b64892015-01-20 13:26:24 -08002020 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002021 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002022 CLI command to run for leadership of the Election test application.
2023 NOTE: Requires installation of the onos-app-election feature
2024 Returns: Main.TRUE on success
2025 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002026 """
Jon Hall94fd0472014-12-08 11:52:42 -08002027 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 cmdStr = "election-test-run"
2029 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002030 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002031 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002032 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002033 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002034 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002035 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002036 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002037 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002038 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002039 errorPattern = "Command\snot\sfound"
2040 if re.search( errorPattern, response ):
2041 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002042 return main.FALSE
2043 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002044 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002045 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002046 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002047 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002048 except TypeError:
2049 main.log.exception( self.name + ": Object not as expected" )
2050 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002054 main.cleanup()
2055 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002056 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002057 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002058 main.cleanup()
2059 main.exit()
2060
kelvin-onlabd3b64892015-01-20 13:26:24 -08002061 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002062 """
Jon Hall94fd0472014-12-08 11:52:42 -08002063 * CLI command to withdraw the local node from leadership election for
2064 * the Election test application.
2065 #NOTE: Requires installation of the onos-app-election feature
2066 Returns: Main.TRUE on success
2067 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002068 """
Jon Hall94fd0472014-12-08 11:52:42 -08002069 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002070 cmdStr = "election-test-withdraw"
2071 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002072 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002073 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002074 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002075 if re.search( successPattern, response ):
2076 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002077 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002078 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002079 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002080 errorPattern = "Command\snot\sfound"
2081 if re.search( errorPattern, response ):
2082 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002083 return main.FALSE
2084 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002085 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002086 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002087 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002088 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002089 except TypeError:
2090 main.log.exception( self.name + ": Object not as expected" )
2091 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002093 main.log.error( self.name + ": EOF exception found" )
2094 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002095 main.cleanup()
2096 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002098 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002099 main.cleanup()
2100 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002101
kelvin8ec71442015-01-15 16:57:00 -08002102 def getDevicePortsEnabledCount( self, dpid ):
2103 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002104 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002105 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002106 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002107 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2109 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002110 if re.search( "No such device", output ):
2111 main.log.error( "Error in getting ports" )
2112 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002113 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002114 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002115 except TypeError:
2116 main.log.exception( self.name + ": Object not as expected" )
2117 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002119 main.log.error( self.name + ": EOF exception found" )
2120 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002121 main.cleanup()
2122 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002123 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002124 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002125 main.cleanup()
2126 main.exit()
2127
kelvin8ec71442015-01-15 16:57:00 -08002128 def getDeviceLinksActiveCount( self, dpid ):
2129 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002130 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002131 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002132 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002133 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2135 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002136 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002137 main.log.error( "Error in getting ports " )
2138 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002139 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002140 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002141 except TypeError:
2142 main.log.exception( self.name + ": Object not as expected" )
2143 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002144 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002145 main.log.error( self.name + ": EOF exception found" )
2146 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002147 main.cleanup()
2148 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002149 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002150 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002151 main.cleanup()
2152 main.exit()
2153
kelvin8ec71442015-01-15 16:57:00 -08002154 def getAllIntentIds( self ):
2155 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002156 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002157 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002158 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002159 cmdStr = "onos:intents | grep id="
2160 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002161 if re.search( "Error", output ):
2162 main.log.error( "Error in getting ports" )
2163 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002164 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002165 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002166 except TypeError:
2167 main.log.exception( self.name + ": Object not as expected" )
2168 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002170 main.log.error( self.name + ": EOF exception found" )
2171 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002172 main.cleanup()
2173 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002174 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002175 main.log.exception( self.name + ": Uncaught exception!" )
2176 main.cleanup()
2177 main.exit()
2178
Jon Hall73509952015-02-24 16:42:56 -08002179 def intentSummary( self ):
2180 """
Jon Hallefbd9792015-03-05 16:11:36 -08002181 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002182 """
2183 try:
2184 intents = self.intents( )
2185 intentStates = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002186 for intent in json.loads( intents ):
Jon Hall73509952015-02-24 16:42:56 -08002187 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002188 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2189 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002190 return dict( out )
2191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return None
2194 except pexpect.EOF:
2195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
2197 main.cleanup()
2198 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002199 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002200 main.log.exception( self.name + ": Uncaught exception!" )
2201 main.cleanup()
2202 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002203
Jon Hall61282e32015-03-19 11:34:11 -07002204 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002205 """
2206 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002207 Optional argument:
2208 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002209 """
2210 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002211 # Sample JSON
2212 # {
2213 # "electedTime": "13m ago",
2214 # "epoch": 4,
2215 # "leader": "10.128.30.17",
2216 # "topic": "intent-partition-3"
2217 # },
Jon Hall63604932015-02-26 17:09:50 -08002218 try:
Jon Hall61282e32015-03-19 11:34:11 -07002219 if jsonFormat:
2220 cmdStr = "onos:leaders -j"
2221 output = self.sendline( cmdStr )
2222 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2223 cleanedOutput = ansiEscape.sub( '', output )
2224 return cleanedOutput
2225 else:
2226 cmdStr = "onos:leaders"
2227 output = self.sendline( cmdStr )
2228 return output
Jon Hall63604932015-02-26 17:09:50 -08002229 except TypeError:
2230 main.log.exception( self.name + ": Object not as expected" )
2231 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002232 except pexpect.EOF:
2233 main.log.error( self.name + ": EOF exception found" )
2234 main.log.error( self.name + ": " + self.handle.before )
2235 main.cleanup()
2236 main.exit()
2237 except:
Jon Hall63604932015-02-26 17:09:50 -08002238 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002239 main.cleanup()
2240 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002241
Jon Hall61282e32015-03-19 11:34:11 -07002242 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002243 """
2244 Returns the output of the intent Pending map.
2245 """
Jon Hall63604932015-02-26 17:09:50 -08002246 try:
Jon Hall61282e32015-03-19 11:34:11 -07002247 if jsonFormat:
2248 cmdStr = "onos:intents -p -j"
2249 output = self.sendline( cmdStr )
2250 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2251 cleanedOutput = ansiEscape.sub( '', output )
2252 return cleanedOutput
2253 else:
2254 cmdStr = "onos:intents -p"
2255 output = self.sendline( cmdStr )
2256 return output
Jon Hall63604932015-02-26 17:09:50 -08002257 except TypeError:
2258 main.log.exception( self.name + ": Object not as expected" )
2259 return None
2260 except pexpect.EOF:
2261 main.log.error( self.name + ": EOF exception found" )
2262 main.log.error( self.name + ": " + self.handle.before )
2263 main.cleanup()
2264 main.exit()
2265 except:
2266 main.log.exception( self.name + ": Uncaught exception!" )
2267 main.cleanup()
2268 main.exit()
2269
Jon Hall61282e32015-03-19 11:34:11 -07002270 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002271 """
2272 Returns the output of the raft partitions command for ONOS.
2273 """
Jon Hall61282e32015-03-19 11:34:11 -07002274 # Sample JSON
2275 # {
2276 # "leader": "tcp://10.128.30.11:7238",
2277 # "members": [
2278 # "tcp://10.128.30.11:7238",
2279 # "tcp://10.128.30.17:7238",
2280 # "tcp://10.128.30.13:7238",
2281 # ],
2282 # "name": "p1",
2283 # "term": 3
2284 # },
Jon Hall63604932015-02-26 17:09:50 -08002285 try:
Jon Hall61282e32015-03-19 11:34:11 -07002286 if jsonFormat:
2287 cmdStr = "onos:partitions -j"
2288 output = self.sendline( cmdStr )
2289 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2290 cleanedOutput = ansiEscape.sub( '', output )
2291 return cleanedOutput
2292 else:
2293 cmdStr = "onos:partitions"
2294 output = self.sendline( cmdStr )
2295 return output
Jon Hall63604932015-02-26 17:09:50 -08002296 except TypeError:
2297 main.log.exception( self.name + ": Object not as expected" )
2298 return None
2299 except pexpect.EOF:
2300 main.log.error( self.name + ": EOF exception found" )
2301 main.log.error( self.name + ": " + self.handle.before )
2302 main.cleanup()
2303 main.exit()
2304 except:
2305 main.log.exception( self.name + ": Uncaught exception!" )
2306 main.cleanup()
2307 main.exit()
2308
Jon Hallbe379602015-03-24 13:39:32 -07002309 def apps( self, jsonFormat=True ):
2310 """
2311 Returns the output of the apps command for ONOS. This command lists
2312 information about installed ONOS applications
2313 """
2314 # Sample JSON object
2315 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2316 # "description":"ONOS OpenFlow protocol southbound providers",
2317 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2318 # "features":"[onos-openflow]","state":"ACTIVE"}]
2319 try:
2320 if jsonFormat:
2321 cmdStr = "onos:apps -j"
2322 output = self.sendline( cmdStr )
2323 assert "Error executing command" not in output
2324 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
2325 cleanedOutput = ansiEscape.sub( '', output )
2326 return cleanedOutput
2327 else:
2328 cmdStr = "onos:apps"
2329 output = self.sendline( cmdStr )
2330 assert "Error executing command" not in output
2331 return output
2332 # FIXME: look at specific exceptions/Errors
2333 except AssertionError:
2334 main.log.error( "Error in processing onos:app command: " +
2335 str( output ) )
2336 return None
2337 except TypeError:
2338 main.log.exception( self.name + ": Object not as expected" )
2339 return None
2340 except pexpect.EOF:
2341 main.log.error( self.name + ": EOF exception found" )
2342 main.log.error( self.name + ": " + self.handle.before )
2343 main.cleanup()
2344 main.exit()
2345 except:
2346 main.log.exception( self.name + ": Uncaught exception!" )
2347 main.cleanup()
2348 main.exit()
2349
Jon Hall146f1522015-03-24 15:33:24 -07002350 def appStatus( self, appName ):
2351 """
2352 Uses the onos:apps cli command to return the status of an application.
2353 Returns:
2354 "ACTIVE" - If app is installed and activated
2355 "INSTALLED" - If app is installed and deactivated
2356 "UNINSTALLED" - If app is not installed
2357 None - on error
2358 """
2359 # FIXME also use app-ids to see if an uninstalled app is registered?
2360 # FIXME "UNREGISTERED"?
2361 try:
2362 if not isinstance( appName, types.StringType ):
2363 main.log.error( self.name + ".appStatus(): appName must be" +
2364 " a string" )
2365 return None
2366 output = self.apps( jsonFormat=True )
2367 appsJson = json.loads( output )
2368 state = None
2369 for app in appsJson:
2370 if appName == app.get('name'):
2371 state = app.get('state')
2372 break
2373 if state == "ACTIVE" or state == "INSTALLED":
2374 return state
2375 elif state is None:
2376 return "UNINSTALLED"
2377 elif state:
2378 main.log.error( "Unexpected state from 'onos:apps': " +
2379 str( state ) )
2380 return state
2381 except TypeError:
2382 main.log.exception( self.name + ": Object not as expected" )
2383 return None
2384 except pexpect.EOF:
2385 main.log.error( self.name + ": EOF exception found" )
2386 main.log.error( self.name + ": " + self.handle.before )
2387 main.cleanup()
2388 main.exit()
2389 except:
2390 main.log.exception( self.name + ": Uncaught exception!" )
2391 main.cleanup()
2392 main.exit()
2393
Jon Hallbe379602015-03-24 13:39:32 -07002394 def app( self, appName, option ):
2395 """
2396 Interacts with the app command for ONOS. This command manages
2397 application inventory.
2398 """
2399 # Validate argument types
Jon Hall146f1522015-03-24 15:33:24 -07002400 valid = True
2401 if not isinstance( appName, types.StringType ):
Jon Hallbe379602015-03-24 13:39:32 -07002402 main.log.error( self.name + ".app(): appName must be a string" )
Jon Hall146f1522015-03-24 15:33:24 -07002403 valid = False
2404 if not isinstance( option, types.StringType ):
2405 main.log.error( self.name + ".app(): option must be a string" )
2406 valid = False
2407 if not valid:
2408 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002409 # Validate Option
2410 option = option.lower()
2411 # NOTE: Install may become a valid option
2412 if option == "activate":
2413 pass
2414 elif option == "deactivate":
2415 pass
2416 elif option == "uninstall":
2417 pass
2418 else:
2419 # Invalid option
2420 main.log.error( "The ONOS app command argument only takes the " +
Jon Hall146f1522015-03-24 15:33:24 -07002421 "values: (activate|deactivate|uninstall); was " +
2422 "given '" + option + "'")
Jon Hallbe379602015-03-24 13:39:32 -07002423 return main.FALSE
2424 try:
Jon Hall146f1522015-03-24 15:33:24 -07002425 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002426 output = self.sendline( cmdStr )
2427 # FIXME: look at specific exceptions/Errors
2428 # Some Possible outputs:
2429 # app a b -> No such application:
2430 # app a -> Error executing command onos:app: argument name is required
2431 if "Error executing command" in output:
2432 main.log.error( "Error in processing onos:app command: " +
2433 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002434 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002435 elif "No such application" in output:
2436 main.log.error( "The application '" + appName +
2437 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002438 return main.FALSE
2439 elif "Command not found:" in output:
2440 main.log.error( "Error in processing onos:app command: " +
2441 str( output ) )
2442 return main.FALSE
2443
Jon Hallbe379602015-03-24 13:39:32 -07002444 # NOTE: we may need to add more checks here
2445 main.log.debug( "app response: " + str( output ) )
2446 return main.TRUE
2447 except TypeError:
2448 main.log.exception( self.name + ": Object not as expected" )
2449 return main.ERROR
2450 except pexpect.EOF:
2451 main.log.error( self.name + ": EOF exception found" )
2452 main.log.error( self.name + ": " + self.handle.before )
2453 main.cleanup()
2454 main.exit()
2455 except:
2456 main.log.exception( self.name + ": Uncaught exception!" )
2457 main.cleanup()
2458 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002459
2460 def activateApp( self, appName ):
2461 """
2462 Activate an app that is already installed in ONOS
2463 Returns main.TRUE if the command was successfully sent
2464 main.FALSE if the cli responded with an error or given
2465 incorrect input
2466 """
2467 try:
2468 if not isinstance( appName, types.StringType ):
2469 main.log.error( self.name + ".activateApp(): appName must be" +
2470 " a string" )
2471 return main.FALSE
2472 status = self.appStatus( appName )
2473 if status == "INSTALLED":
2474 response = self.app( appName, "activate" )
2475 return response
2476 elif status == "ACTIVE":
2477 return main.TRUE
2478 elif status == "UNINSTALLED":
2479 main.log.error( self.name + ": Tried to activate the " +
2480 "application '" + appName + "' which is not " +
2481 "installed." )
2482 else:
2483 main.log.error( "Unexpected return value from appStatus: " +
2484 str( status ) )
2485 return main.ERROR
2486 except TypeError:
2487 main.log.exception( self.name + ": Object not as expected" )
2488 return main.ERROR
2489 except pexpect.EOF:
2490 main.log.error( self.name + ": EOF exception found" )
2491 main.log.error( self.name + ": " + self.handle.before )
2492 main.cleanup()
2493 main.exit()
2494 except:
2495 main.log.exception( self.name + ": Uncaught exception!" )
2496 main.cleanup()
2497 main.exit()
2498
2499 def deactivateApp( self, appName ):
2500 """
2501 Deactivate an app that is already activated in ONOS
2502 Returns main.TRUE if the command was successfully sent
2503 main.FALSE if the cli responded with an error or given
2504 incorrect input
2505 """
2506 try:
2507 if not isinstance( appName, types.StringType ):
2508 main.log.error( self.name + ".deactivateApp(): appName must " +
2509 "be a string" )
2510 return main.FALSE
2511 status = self.appStatus( appName )
2512 if status == "INSTALLED":
2513 return main.TRUE
2514 elif status == "ACTIVE":
2515 response = self.app( appName, "deactivate" )
2516 return response
2517 elif status == "UNINSTALLED":
2518 main.log.warn( self.name + ": Tried to deactivate the " +
2519 "application '" + appName + "' which is not " +
2520 "installed." )
2521 return main.TRUE
2522 else:
2523 main.log.error( "Unexpected return value from appStatus: " +
2524 str( status ) )
2525 return main.ERROR
2526 except TypeError:
2527 main.log.exception( self.name + ": Object not as expected" )
2528 return main.ERROR
2529 except pexpect.EOF:
2530 main.log.error( self.name + ": EOF exception found" )
2531 main.log.error( self.name + ": " + self.handle.before )
2532 main.cleanup()
2533 main.exit()
2534 except:
2535 main.log.exception( self.name + ": Uncaught exception!" )
2536 main.cleanup()
2537 main.exit()
2538
2539 def uninstallApp( self, appName ):
2540 """
2541 Uninstall an app that is already installed in ONOS
2542 Returns main.TRUE if the command was successfully sent
2543 main.FALSE if the cli responded with an error or given
2544 incorrect input
2545 """
2546 # TODO: check with Thomas about the state machine for apps
2547 try:
2548 if not isinstance( appName, types.StringType ):
2549 main.log.error( self.name + ".uninstallApp(): appName must " +
2550 "be a string" )
2551 return main.FALSE
2552 status = self.appStatus( appName )
2553 if status == "INSTALLED":
2554 response = self.app( appName, "uninstall" )
2555 return response
2556 elif status == "ACTIVE":
2557 main.log.warn( self.name + ": Tried to uninstall the " +
2558 "application '" + appName + "' which is " +
2559 "currently active." )
2560 response = self.app( appName, "uninstall" )
2561 return response
2562 elif status == "UNINSTALLED":
2563 return main.TRUE
2564 else:
2565 main.log.error( "Unexpected return value from appStatus: " +
2566 str( status ) )
2567 return main.ERROR
2568 except TypeError:
2569 main.log.exception( self.name + ": Object not as expected" )
2570 return main.ERROR
2571 except pexpect.EOF:
2572 main.log.error( self.name + ": EOF exception found" )
2573 main.log.error( self.name + ": " + self.handle.before )
2574 main.cleanup()
2575 main.exit()
2576 except:
2577 main.log.exception( self.name + ": Uncaught exception!" )
2578 main.cleanup()
2579 main.exit()