blob: 38861b6074e2ea788ce36297df149bc0f47087b4 [file] [log] [blame]
kelvin-onlab44147802015-07-27 17:57:31 -07001"""
2 Wrapper functions for FuncIntent
3 This functions include Onosclidriver and Mininetclidriver driver functions
4 Author: kelvin@onlab.us
5"""
6import time
7import copy
8import json
kelvin-onlab0e684682015-08-11 18:51:41 -07009import types
kelvin-onlab44147802015-07-27 17:57:31 -070010
Jon Hall02758ac2017-05-24 16:20:28 -070011
kelvin-onlab44147802015-07-27 17:57:31 -070012def __init__( self ):
13 self.default = ''
14
Jon Hall02758ac2017-05-24 16:20:28 -070015
Jeremy2f190ca2016-01-29 15:23:57 -080016def installHostIntent( main,
17 name,
18 host1,
19 host2,
20 onosNode=0,
21 ethType="",
22 bandwidth="",
23 lambdaAlloc=False,
24 ipProto="",
25 ipAddresses="",
26 tcp="",
27 sw1="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -070028 sw2="" ):
kelvin-onlab44147802015-07-27 17:57:31 -070029 """
Jeremy2f190ca2016-01-29 15:23:57 -080030 Installs a Host Intent
31
32 Description:
33 Install a host intent using
34 add-host-intent
35
36 Steps:
37 - Fetch host data if not given
38 - Add host intent
39 - Ingress device is the first sender host
40 - Egress devices are the recipient devices
41 - Ports if defined in senders or recipients
42 - MAC address ethSrc loaded from Ingress device
43 - Check intent state with retry
44 Required:
45 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
46 host1 - Dictionary for host1
47 { "name":"h8", "id":"of:0000000000000005/8" }
48 host2 - Dictionary for host2
49 { "name":"h16", "id":"of:0000000000000006/8" }
50 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -070051 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -080052 0 by default so that it will always use the first
53 ONOS node
54 ethType - Ethernet type eg. IPV4, IPV6
55 bandwidth - Bandwidth capacity
56 lambdaAlloc - Allocate lambda, defaults to False
57 ipProto - IP protocol
58 tcp - TCP ports in the same order as the hosts in hostNames
kelvin-onlab44147802015-07-27 17:57:31 -070059 """
kelvin-onlab44147802015-07-27 17:57:31 -070060 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -080061 assert host1, "You must specify host1"
62 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -070063
Jeremy2f190ca2016-01-29 15:23:57 -080064 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -070065 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -070066 onosNode = int( onosNode )
67
Jeremy2f190ca2016-01-29 15:23:57 -080068 main.log.info( itemName + ": Adding single point to multi point intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070069
Jeremydd9bda62016-04-18 12:02:32 -070070 try:
71 if not host1.get( "id" ):
72 main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
73 main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
74 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )
kelvin-onlab44147802015-07-27 17:57:31 -070075
Jeremydd9bda62016-04-18 12:02:32 -070076 if not host2.get( "id" ):
77 main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
78 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -070079 vlanId = host1.get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -070080
Jeremydd9bda62016-04-18 12:02:32 -070081 # Adding host intents
82 main.log.info( itemName + ": Adding host intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070083
Jeremy Songstere7f3b342016-08-17 14:56:49 -070084 intent1 = main.RESTs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
Jon Hall02758ac2017-05-24 16:20:28 -070085 hostIdTwo=host2.get( "id" ),
86 vlanId=vlanId )
kelvin-onlab44147802015-07-27 17:57:31 -070087
Jeremydd9bda62016-04-18 12:02:32 -070088 # Get all intents ID in the system, time delay right after intents are added
89 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -070090 intentsId = main.RESTs[ 0 ].getIntentsId()
91 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -070092 errorMsg = "There was a problem loading the hosts data."
93 if intentsId:
94 errorMsg += " There was a problem installing host to host intent."
95 main.log.error( errorMsg )
96 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -070097
Jeremy Songster306ed7a2016-07-19 10:59:07 -070098 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
99 args=( main, intentsId ), sleep=main.checkIntentSleep, attempts=5 ):
100 main.assertReturnString += 'Install Intent State Passed\n'
101 if flowDuration( main ):
102 main.assertReturnString += 'Flow duration check Passed\n'
103 return intentsId
104 else:
105 main.assertReturnString += 'Flow duration check failed\n'
106 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800107 else:
108 main.log.error( "Host Intent did not install correctly" )
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700109 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800110 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700111
Jon Hall02758ac2017-05-24 16:20:28 -0700112
Jeremy2f190ca2016-01-29 15:23:57 -0800113def testHostIntent( main,
114 name,
115 intentId,
116 host1,
117 host2,
118 onosNode=0,
119 sw1="s5",
120 sw2="s2",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700121 expectedLink=0 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800122 """
123 Test a Host Intent
kelvin-onlab44147802015-07-27 17:57:31 -0700124
Jeremy2f190ca2016-01-29 15:23:57 -0800125 Description:
126 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700127
Jeremy2f190ca2016-01-29 15:23:57 -0800128 Steps:
129 - Fetch host data if not given
130 - Check Intent State
131 - Check Flow State
132 - Check Connectivity
133 - Check Lack of Connectivity Between Hosts not in the Intent
134 - Reroute
135 - Take Expected Link Down
136 - Check Intent State
137 - Check Flow State
138 - Check Topology
139 - Check Connectivity
140 - Bring Expected Link Up
141 - Check Intent State
142 - Check Flow State
143 - Check Topology
144 - Check Connectivity
145 - Remove Topology
kelvin-onlab44147802015-07-27 17:57:31 -0700146
Jeremy2f190ca2016-01-29 15:23:57 -0800147 Required:
148 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
149 intentId - intent ID to be tested ( and removed )
150 host1 - Dictionary for host1
151 { "name":"h8", "id":"of:0000000000000005/8" }
152 host2 - Dictionary for host2
153 { "name":"h16", "id":"of:0000000000000006/8" }
154 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700155 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800156 0 by default so that it will always use the first
157 ONOS node
158 sw1 - First switch to bring down & up for rerouting purpose
159 sw2 - Second switch to bring down & up for rerouting purpose
160 expectedLink - Expected link when the switches are down, it should
161 be two links lower than the links before the two
162 switches are down
kelvin-onlab44147802015-07-27 17:57:31 -0700163
164 """
Jeremy2f190ca2016-01-29 15:23:57 -0800165 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700166 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800167 assert host1, "You must specify host1"
168 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700169
170 global itemName
171 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800172 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700173 onosNode = int( onosNode )
174
Jeremy2f190ca2016-01-29 15:23:57 -0800175 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700176
Jeremydd9bda62016-04-18 12:02:32 -0700177 try:
178 if not host1.get( "id" ):
179 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
180 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700181
Jeremydd9bda62016-04-18 12:02:32 -0700182 if not host2.get( "id" ):
183 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
184 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700185
Jeremydd9bda62016-04-18 12:02:32 -0700186 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
187 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700188 vlanId = host1.get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700189 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700190 main.log.error( "There was a problem loading the hosts data." )
191 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700192
Jeremy2f190ca2016-01-29 15:23:57 -0800193 testResult = main.TRUE
194 main.log.info( itemName + ": Adding single point to multi point intents" )
195
196 # Check intent state
197 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
198 main.assertReturnString += 'Initial Intent State Passed\n'
199 else:
200 main.assertReturnString += 'Initial Intent State Failed\n'
201 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700202
203 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800204 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800205 main.assertReturnString += 'Initial Flow State Passed\n'
206 else:
207 main.assertReturnString += 'Intial Flow State Failed\n'
208 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700209
Jeremy2f190ca2016-01-29 15:23:57 -0800210 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700211 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800212 main.assertReturnString += 'Initial Ping Passed\n'
213 else:
214 main.assertReturnString += 'Initial Ping Failed\n'
215 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700216
217 # Test rerouting if these variables exist
218 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800219 # Take link down
220 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
221 main.assertReturnString += 'Link Down Passed\n'
222 else:
223 main.assertReturnString += 'Link Down Failed\n'
224 testResult = main.FALSE
225
226 # Check intent state
227 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
228 main.assertReturnString += 'Link Down Intent State Passed\n'
229 else:
230 main.assertReturnString += 'Link Down Intent State Failed\n'
231 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700232
233 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800234 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800235 main.assertReturnString += 'Link Down Flow State Passed\n'
236 else:
237 main.assertReturnString += 'Link Down Flow State Failed\n'
238 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700239
240 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800241 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800242 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700243 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800244 main.assertReturnString += 'Link Down Topology State Failed\n'
245 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700246
Jeremy2f190ca2016-01-29 15:23:57 -0800247 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700248 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800249 main.assertReturnString += 'Link Down Pingall Passed\n'
250 else:
251 main.assertReturnString += 'Link Down Pingall Failed\n'
252 testResult = main.FALSE
253
254 # Bring link up
255 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
256 main.assertReturnString += 'Link Up Passed\n'
257 else:
258 main.assertReturnString += 'Link Up Failed\n'
259 testResult = main.FALSE
260
261 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700262 time.sleep( main.rerouteSleep )
263
Jeremy2f190ca2016-01-29 15:23:57 -0800264 # Check Intents
265 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
266 main.assertReturnString += 'Link Up Intent State Passed\n'
267 else:
268 main.assertReturnString += 'Link Up Intent State Failed\n'
269 testResult = main.FALSE
270
kelvin-onlab44147802015-07-27 17:57:31 -0700271 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800272 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800273 main.assertReturnString += 'Link Up Flow State Passed\n'
274 else:
275 main.assertReturnString += 'Link Up Flow State Failed\n'
276 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700277
278 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800279 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
280 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700281 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800282 main.assertReturnString += 'Link Up Topology State Failed\n'
283 testResult = main.FALSE
284
285 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700286 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800287 main.assertReturnString += 'Link Up Pingall Passed\n'
288 else:
289 main.assertReturnString += 'Link Up Pingall Failed\n'
290 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700291
292 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800293 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
294 main.assertReturnString += 'Remove Intents Passed'
295 else:
296 main.assertReturnString += 'Remove Intents Failed'
297 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700298
Jeremy2f190ca2016-01-29 15:23:57 -0800299 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700300
Jon Hall02758ac2017-05-24 16:20:28 -0700301
Jeremy2f190ca2016-01-29 15:23:57 -0800302def installPointIntent( main,
303 name,
304 senders,
305 recipients,
306 onosNode=0,
307 ethType="",
308 bandwidth="",
309 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -0800310 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800311 ipProto="",
312 ipSrc="",
313 ipDst="",
314 tcpSrc="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700315 tcpDst="" ):
Jeremy2f190ca2016-01-29 15:23:57 -0800316 """
317 Installs a Single to Single Point Intent
318
319 Description:
320 Install a single to single point intent
321
322 Steps:
323 - Fetch host data if not given
324 - Add point intent
325 - Ingress device is the first sender device
326 - Egress device is the first recipient device
327 - Ports if defined in senders or recipients
328 - MAC address ethSrc loaded from Ingress device
329 - Check intent state with retry
330 Required:
331 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
332 senders - List of host dictionaries i.e.
333 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
334 recipients - List of host dictionaries i.e.
335 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
336 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700337 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800338 0 by default so that it will always use the first
339 ONOS node
340 ethType - Ethernet type eg. IPV4, IPV6
341 bandwidth - Bandwidth capacity
342 lambdaAlloc - Allocate lambda, defaults to False
343 ipProto - IP protocol
344 tcp - TCP ports in the same order as the hosts in hostNames
345 sw1 - First switch to bring down & up for rerouting purpose
346 sw2 - Second switch to bring down & up for rerouting purpose
347 expectedLink - Expected link when the switches are down, it should
348 be two links lower than the links before the two
349 switches are down
350 """
Jeremy2f190ca2016-01-29 15:23:57 -0800351 assert main, "There is no main variable"
352 assert senders, "You must specify a sender"
353 assert recipients, "You must specify a recipient"
354 # Assert devices or main.hostsData, "You must specify devices"
355
356 global itemName # The name of this run. Used for logs.
357 itemName = name
358 onosNode = int( onosNode )
359
360 main.log.info( itemName + ": Adding single to single point intents" )
361
Jeremydd9bda62016-04-18 12:02:32 -0700362 try:
363 for sender in senders:
364 if not sender.get( "device" ):
365 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
366 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800367
Jeremydd9bda62016-04-18 12:02:32 -0700368 for recipient in recipients:
369 if not recipient.get( "device" ):
370 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
371 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700372 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy2f190ca2016-01-29 15:23:57 -0800373
Jeremydd9bda62016-04-18 12:02:32 -0700374 ingressDevice = senders[ 0 ].get( "device" )
375 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800376
Jeremydd9bda62016-04-18 12:02:32 -0700377 portIngress = senders[ 0 ].get( "port", "" )
378 portEgress = recipients[ 0 ].get( "port", "" )
379 main.log.debug( ingressDevice )
380 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800381
Jeremydd9bda62016-04-18 12:02:32 -0700382 srcMac = senders[ 0 ].get( "mac" )
383 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800384
Jeremydd9bda62016-04-18 12:02:32 -0700385 ipSrc = senders[ 0 ].get( "ip" )
386 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800387
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700388 intent1 = main.RESTs[ onosNode ].addPointIntent(
Jeremydd9bda62016-04-18 12:02:32 -0700389 ingressDevice=ingressDevice,
390 egressDevice=egressDevice,
391 ingressPort=portIngress,
392 egressPort=portEgress,
393 ethType=ethType,
394 ethSrc=srcMac,
395 ethDst=dstMac,
396 bandwidth=bandwidth,
397 lambdaAlloc=lambdaAlloc,
alisonda157272016-12-22 01:13:21 -0800398 protected=protected,
Jeremydd9bda62016-04-18 12:02:32 -0700399 ipProto=ipProto,
400 ipSrc=ipSrc,
401 ipDst=ipDst,
402 tcpSrc=tcpSrc,
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700403 tcpDst=tcpDst,
404 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800405
Jeremydd9bda62016-04-18 12:02:32 -0700406 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700407 intentsId = main.RESTs[ 0 ].getIntentsId()
408 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700409 errorMsg = "There was a problem loading the hosts data."
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700410 if intentsId:
Jeremydd9bda62016-04-18 12:02:32 -0700411 errorMsg += " There was a problem installing Point to Point intent."
412 main.log.error( errorMsg )
413 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800414
Jeremydd9bda62016-04-18 12:02:32 -0700415 # Check intent state
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700416 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
417 args=( main, intentsId ), sleep=main.checkIntentSleep ):
418 main.assertReturnString += 'Install Intent State Passed\n'
419 if flowDuration( main ):
420 main.assertReturnString += 'Flow duration check Passed\n'
421 return intentsId
422 else:
423 main.assertReturnString += 'Flow duration check failed\n'
424 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800425 else:
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700426 main.log.error( "Host Intent did not install correctly" )
427 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800428 return main.FALSE
429
Jon Hall02758ac2017-05-24 16:20:28 -0700430
Jeremy2f190ca2016-01-29 15:23:57 -0800431def testPointIntent( main,
432 name,
433 intentId,
434 senders,
435 recipients,
436 badSenders={},
437 badRecipients={},
438 onosNode=0,
439 ethType="",
440 bandwidth="",
441 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -0800442 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800443 ipProto="",
444 ipAddresses="",
445 tcp="",
446 sw1="s5",
447 sw2="s2",
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700448 expectedLink=0,
449 useTCP=False ):
Jeremy2f190ca2016-01-29 15:23:57 -0800450 """
451 Test a Point Intent
452
453 Description:
454 Test a point intent
455
456 Steps:
457 - Fetch host data if not given
458 - Check Intent State
459 - Check Flow State
460 - Check Connectivity
461 - Check Lack of Connectivity Between Hosts not in the Intent
462 - Reroute
463 - Take Expected Link Down
464 - Check Intent State
465 - Check Flow State
466 - Check Topology
467 - Check Connectivity
468 - Bring Expected Link Up
469 - Check Intent State
470 - Check Flow State
471 - Check Topology
472 - Check Connectivity
473 - Remove Topology
474
475 Required:
476 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
477
478 senders - List of host dictionaries i.e.
479 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
480 recipients - List of host dictionaries i.e.
481 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
482 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700483 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800484 0 by default so that it will always use the first
485 ONOS node
486 ethType - Ethernet type eg. IPV4, IPV6
487 bandwidth - Bandwidth capacity
488 lambdaAlloc - Allocate lambda, defaults to False
489 ipProto - IP protocol
490 tcp - TCP ports in the same order as the hosts in hostNames
491 sw1 - First switch to bring down & up for rerouting purpose
492 sw2 - Second switch to bring down & up for rerouting purpose
493 expectedLink - Expected link when the switches are down, it should
494 be two links lower than the links before the two
495 switches are down
496
497 """
Jeremy2f190ca2016-01-29 15:23:57 -0800498 # Parameter Validity Check
499 assert main, "There is no main variable"
500 assert senders, "You must specify a sender"
501 assert recipients, "You must specify a recipient"
502
503 global itemName
504 itemName = name
505 tempHostsData = {}
506 onosNode = int( onosNode )
507
508 main.log.info( itemName + ": Testing Point Intent" )
509
Jeremydd9bda62016-04-18 12:02:32 -0700510 try:
511 # Names for scapy
512 senderNames = [ x.get( "name" ) for x in senders ]
513 recipientNames = [ x.get( "name" ) for x in recipients ]
514 badSenderNames = [ x.get( "name" ) for x in badSenders ]
515 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800516
Jeremydd9bda62016-04-18 12:02:32 -0700517 for sender in senders:
518 if not sender.get( "device" ):
519 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
520 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800521
Jeremydd9bda62016-04-18 12:02:32 -0700522 for recipient in recipients:
523 if not recipient.get( "device" ):
524 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
525 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jon Hall02758ac2017-05-24 16:20:28 -0700526 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700527 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700528 main.log.error( "There was a problem loading the hosts data." )
529 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800530
531 testResult = main.TRUE
532 main.log.info( itemName + ": Testing point intents" )
533
534 # Check intent state
535 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
536 main.assertReturnString += 'Initial Intent State Passed\n'
537 else:
538 main.assertReturnString += 'Initial Intent State Failed\n'
539 testResult = main.FALSE
540
541 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800542 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800543 main.assertReturnString += 'Initial Flow State Passed\n'
544 else:
545 main.assertReturnString += 'Intial Flow State Failed\n'
546 testResult = main.FALSE
547
548 # Check Connectivity
Jon Hall02758ac2017-05-24 16:20:28 -0700549 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800550 main.assertReturnString += 'Initial Ping Passed\n'
551 else:
552 main.assertReturnString += 'Initial Ping Failed\n'
553 testResult = main.FALSE
554
555 # Check connections that shouldn't work
556 if badSenderNames:
557 main.log.info( "Checking that packets from incorrect sender do not go through" )
Jon Hall02758ac2017-05-24 16:20:28 -0700558 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure": True } ):
Jeremy2f190ca2016-01-29 15:23:57 -0800559 main.assertReturnString += 'Bad Sender Ping Passed\n'
560 else:
561 main.assertReturnString += 'Bad Sender Ping Failed\n'
562 testResult = main.FALSE
563
564 if badRecipientNames:
565 main.log.info( "Checking that packets to incorrect recipients do not go through" )
Jon Hall02758ac2017-05-24 16:20:28 -0700566 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure": True } ):
Jeremy2f190ca2016-01-29 15:23:57 -0800567 main.assertReturnString += 'Bad Recipient Ping Passed\n'
568 else:
569 main.assertReturnString += 'Bad Recipient Ping Failed\n'
570 testResult = main.FALSE
571
572 # Test rerouting if these variables exist
573 if sw1 and sw2 and expectedLink:
574 # Take link down
575 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
576 main.assertReturnString += 'Link Down Passed\n'
577 else:
578 main.assertReturnString += 'Link Down Failed\n'
579 testResult = main.FALSE
580
alisonda157272016-12-22 01:13:21 -0800581 if protected:
582 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -0700583 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
584 args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
alisonda157272016-12-22 01:13:21 -0800585 main.assertReturnString += 'Link down Scapy Packet Received Passed\n'
586 else:
587 main.assertReturnString += 'Link down Scapy Packet Recieved Failed\n'
588 testResult = main.FALSE
589
Jon Hall02758ac2017-05-24 16:20:28 -0700590 if ProtectedIntentCheck( main ):
alisonda157272016-12-22 01:13:21 -0800591 main.assertReturnString += 'Protected Intent Check Passed\n'
592 else:
593 main.assertReturnString += 'Protected Intent Check Failed\n'
594 testResult = main.FALSE
595
Jeremy2f190ca2016-01-29 15:23:57 -0800596 # Check intent state
597 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
598 main.assertReturnString += 'Link Down Intent State Passed\n'
599 else:
600 main.assertReturnString += 'Link Down Intent State Failed\n'
601 testResult = main.FALSE
602
603 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800604 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800605 main.assertReturnString += 'Link Down Flow State Passed\n'
606 else:
607 main.assertReturnString += 'Link Down Flow State Failed\n'
608 testResult = main.FALSE
609
610 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800611 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800612 main.assertReturnString += 'Link Down Topology State Passed\n'
613 else:
614 main.assertReturnString += 'Link Down Topology State Failed\n'
615 testResult = main.FALSE
616
617 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -0700618 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800619 main.assertReturnString += 'Link Down Pingall Passed\n'
620 else:
621 main.assertReturnString += 'Link Down Pingall Failed\n'
622 testResult = main.FALSE
623
624 # Bring link up
625 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
626 main.assertReturnString += 'Link Up Passed\n'
627 else:
628 main.assertReturnString += 'Link Up Failed\n'
629 testResult = main.FALSE
630
631 # Wait for reroute
632 time.sleep( main.rerouteSleep )
633
634 # Check Intents
635 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
636 main.assertReturnString += 'Link Up Intent State Passed\n'
637 else:
638 main.assertReturnString += 'Link Up Intent State Failed\n'
639 testResult = main.FALSE
640
641 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800642 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800643 main.assertReturnString += 'Link Up Flow State Passed\n'
644 else:
645 main.assertReturnString += 'Link Up Flow State Failed\n'
646 testResult = main.FALSE
647
648 # Check OnosTopology
649 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
650 main.assertReturnString += 'Link Up Topology State Passed\n'
651 else:
652 main.assertReturnString += 'Link Up Topology State Failed\n'
653 testResult = main.FALSE
654
655 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -0700656 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800657 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
658 else:
659 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
660 testResult = main.FALSE
661
662 # Remove all intents
663 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
664 main.assertReturnString += 'Remove Intents Passed'
665 else:
666 main.assertReturnString += 'Remove Intents Failed'
667 testResult = main.FALSE
668
669 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700670
Jon Hall02758ac2017-05-24 16:20:28 -0700671
kelvin-onlab0e684682015-08-11 18:51:41 -0700672def pointIntentTcp( main,
673 name,
674 host1,
675 host2,
676 onosNode=0,
677 deviceId1="",
678 deviceId2="",
679 port1="",
680 port2="",
681 ethType="",
682 mac1="",
683 mac2="",
684 bandwidth="",
685 lambdaAlloc=False,
686 ipProto="",
687 ip1="",
688 ip2="",
689 tcp1="",
690 tcp2="",
691 sw1="",
692 sw2="",
693 expectedLink=0 ):
kelvin-onlab0e684682015-08-11 18:51:41 -0700694 """
695 Description:
696 Verify add-point-intent only for TCP
697 Steps:
698 - Get device ids | ports
699 - Add point intents
700 - Check intents
701 - Verify flows
702 - Ping hosts
703 - Reroute
704 - Link down
705 - Verify flows
706 - Check topology
707 - Ping hosts
708 - Link up
709 - Verify flows
710 - Check topology
711 - Ping hosts
712 - Remove intents
713 Required:
714 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
715 host1 - Name of first host
716 host2 - Name of second host
717 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700718 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab0e684682015-08-11 18:51:41 -0700719 0 by default so that it will always use the first
720 ONOS node
721 deviceId1 - ONOS device id of the first switch, the same as the
722 location of the first host eg. of:0000000000000001/1,
723 located at device 1 port 1
724 deviceId2 - ONOS device id of the second switch
725 port1 - The port number where the first host is attached
726 port2 - The port number where the second host is attached
727 ethType - Ethernet type eg. IPV4, IPV6
728 mac1 - Mac address of first host
729 mac2 - Mac address of the second host
730 bandwidth - Bandwidth capacity
731 lambdaAlloc - Allocate lambda, defaults to False
732 ipProto - IP protocol
733 ip1 - IP address of first host
734 ip2 - IP address of second host
735 tcp1 - TCP port of first host
736 tcp2 - TCP port of second host
737 sw1 - First switch to bring down & up for rerouting purpose
738 sw2 - Second switch to bring down & up for rerouting purpose
739 expectedLink - Expected link when the switches are down, it should
740 be two links lower than the links before the two
741 switches are down
742 """
kelvin-onlab0e684682015-08-11 18:51:41 -0700743 assert main, "There is no main variable"
744 assert name, "variable name is empty"
745 assert host1 and host2, "You must specify hosts"
746
747 global itemName
748 itemName = name
749 host1 = host1
750 host2 = host2
751 hostNames = [ host1, host2 ]
752 intentsId = []
753
754 iperfResult = main.TRUE
755 intentResult = main.TRUE
756 removeIntentResult = main.TRUE
757 flowResult = main.TRUE
758 topoResult = main.TRUE
759 linkDownResult = main.TRUE
760 linkUpResult = main.TRUE
761 onosNode = int( onosNode )
762
763 # Adding bidirectional point intents
764 main.log.info( itemName + ": Adding point intents" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700765 intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
Jon Hall02758ac2017-05-24 16:20:28 -0700766 egressDevice=deviceId2,
767 ingressPort=port1,
768 egressPort=port2,
769 ethType=ethType,
770 ethSrc=mac1,
771 ethDst=mac2,
772 bandwidth=bandwidth,
773 lambdaAlloc=lambdaAlloc,
774 ipProto=ipProto,
775 ipSrc=ip1,
776 ipDst=ip2,
777 tcpSrc=tcp1,
778 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700779
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700780 intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
Jon Hall02758ac2017-05-24 16:20:28 -0700781 egressDevice=deviceId1,
782 ingressPort=port2,
783 egressPort=port1,
784 ethType=ethType,
785 ethSrc=mac2,
786 ethDst=mac1,
787 bandwidth=bandwidth,
788 lambdaAlloc=lambdaAlloc,
789 ipProto=ipProto,
790 ipSrc=ip2,
791 ipDst=ip1,
792 tcpSrc=tcp2,
793 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700794
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700795 intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
Jon Hall02758ac2017-05-24 16:20:28 -0700796 egressDevice=deviceId2,
797 ingressPort=port1,
798 egressPort=port2,
799 ethType=ethType,
800 ethSrc=mac1,
801 ethDst=mac2,
802 bandwidth=bandwidth,
803 lambdaAlloc=lambdaAlloc,
804 ipProto=ipProto,
805 ipSrc=ip1,
806 ipDst=ip2,
807 tcpSrc="",
808 tcpDst=tcp2 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700809
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700810 intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
Jon Hall02758ac2017-05-24 16:20:28 -0700811 egressDevice=deviceId1,
812 ingressPort=port2,
813 egressPort=port1,
814 ethType=ethType,
815 ethSrc=mac2,
816 ethDst=mac1,
817 bandwidth=bandwidth,
818 lambdaAlloc=lambdaAlloc,
819 ipProto=ipProto,
820 ipSrc=ip2,
821 ipDst=ip1,
822 tcpSrc="",
823 tcpDst=tcp1 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700824
825 # Get all intents ID in the system, time delay right after intents are added
826 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700827 intentsId = main.RESTs[ 0 ].getIntentsId()
kelvin-onlab0e684682015-08-11 18:51:41 -0700828 # Check intents state
829 time.sleep( main.checkIntentSleep )
830 intentResult = checkIntentState( main, intentsId )
831 # Check flows count in each node
832 checkFlowsCount( main )
833
834 # Check intents state again if first check fails...
835 if not intentResult:
836 intentResult = checkIntentState( main, intentsId )
837
838 # Check flows count in each node
839 checkFlowsCount( main )
840
841 # Verify flows
842 checkFlowsState( main )
843
844 # Run iperf to both host
845 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
846 host2, 10 )
847
848 # Test rerouting if these variables exist
849 if sw1 and sw2 and expectedLink:
850 # link down
851 linkDownResult = link( main, sw1, sw2, "down" )
852 intentResult = intentResult and checkIntentState( main, intentsId )
853
854 # Check flows count in each node
855 checkFlowsCount( main )
856 # Verify flows
857 checkFlowsState( main )
858
859 # Check OnosTopology
860 topoResult = checkTopology( main, expectedLink )
861
862 # Run iperf to both host
863 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
864 host2, 10 )
865
866 intentResult = checkIntentState( main, intentsId )
867
868 # Checks ONOS state in link down
869 if linkDownResult and topoResult and iperfResult and intentResult:
870 main.log.info( itemName + ": Successfully brought link down" )
871 else:
872 main.log.error( itemName + ": Failed to bring link down" )
873
874 # link up
875 linkUpResult = link( main, sw1, sw2, "up" )
876 time.sleep( main.rerouteSleep )
877
878 # Check flows count in each node
879 checkFlowsCount( main )
880 # Verify flows
881 checkFlowsState( main )
882
883 # Check OnosTopology
884 topoResult = checkTopology( main, main.numLinks )
885
886 # Run iperf to both host
887 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
888 host2, 10 )
889
890 intentResult = checkIntentState( main, intentsId )
891
892 # Checks ONOS state in link up
893 if linkUpResult and topoResult and iperfResult and intentResult:
894 main.log.info( itemName + ": Successfully brought link back up" )
895 else:
896 main.log.error( itemName + ": Failed to bring link back up" )
897
898 # Remove all intents
899 removeIntentResult = removeAllIntents( main )
900
901 stepResult = iperfResult and linkDownResult and linkUpResult \
902 and intentResult and removeIntentResult
903
904 return stepResult
905
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700906
907def installSingleToMultiIntent( main,
908 name,
909 senders,
910 recipients,
911 onosNode=0,
912 ethType="",
913 bandwidth="",
914 lambdaAlloc=False,
915 ipProto="",
916 ipAddresses="",
917 tcp="",
918 sw1="",
919 sw2="",
920 partial=False ):
kelvin-onlab44147802015-07-27 17:57:31 -0700921 """
922 Verify Single to Multi Point intents
923 NOTE:If main.hostsData is not defined, variables data should be passed
924 in the same order index wise. All devices in the list should have the
925 same format, either all the devices have its port or it doesn't.
926 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -0700927 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
928 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -0700929 ...
930 Description:
931 Verify add-single-to-multi-intent iterates through the list of given
932 host | devices and add intents
933 Steps:
934 - Get device ids | ports
935 - Add single to multi point intents
936 - Check intents
937 - Verify flows
938 - Ping hosts
939 - Reroute
940 - Link down
941 - Verify flows
942 - Check topology
943 - Ping hosts
944 - Link up
945 - Verify flows
946 - Check topology
947 - Ping hosts
948 - Remove intents
949 Required:
950 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
951 hostNames - List of host names
952 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700953 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -0700954 0 by default so that it will always use the first
955 ONOS node
956 devices - List of device ids in the same order as the hosts
957 in hostNames
958 ports - List of port numbers in the same order as the device in
959 devices
960 ethType - Ethernet type eg. IPV4, IPV6
961 macs - List of hosts mac address in the same order as the hosts in
962 hostNames
963 bandwidth - Bandwidth capacity
964 lambdaAlloc - Allocate lambda, defaults to False
965 ipProto - IP protocol
966 ipAddresses - IP addresses of host in the same order as the hosts in
967 hostNames
968 tcp - TCP ports in the same order as the hosts in hostNames
969 sw1 - First switch to bring down & up for rerouting purpose
970 sw2 - Second switch to bring down & up for rerouting purpose
971 expectedLink - Expected link when the switches are down, it should
972 be two links lower than the links before the two
973 switches are down
974 """
kelvin-onlab44147802015-07-27 17:57:31 -0700975 assert main, "There is no main variable"
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700976 assert senders, "You must specify a sender"
977 assert recipients, "You must specify a recipient"
978 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlab44147802015-07-27 17:57:31 -0700979
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700980 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -0700981 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -0700982 onosNode = int( onosNode )
983
kelvin-onlab44147802015-07-27 17:57:31 -0700984 main.log.info( itemName + ": Adding single point to multi point intents" )
985
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700986 try:
987 for sender in senders:
988 if not sender.get( "device" ):
989 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
990 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700991
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700992 for recipient in recipients:
993 if not recipient.get( "device" ):
994 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
995 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
996 vlanId = senders[ 0 ].get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -0700997
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700998 ingressDevice = senders[ 0 ].get( "device" )
999 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
1000
1001 portIngress = senders[ 0 ].get( "port", "" )
1002 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
1003 if not portEgressList:
1004 portEgressList = []
1005
1006 main.log.debug( ingressDevice )
1007 main.log.debug( egressDeviceList )
1008
1009 srcMac = senders[ 0 ].get( "mac" )
1010 dstMac = []
1011 for r in recipients:
1012 mac = r.get( "mac" )
1013 dstMac.append( mac )
1014
1015 ipSrc = senders[ 0 ].get( "ip" )
1016 ipDst = []
1017 for r in recipients:
1018 ip = r.get( "ip" )
1019 ipDst.append( ip )
1020
1021 # Adding point intent
1022 intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001023 ingressDevice=ingressDevice,
1024 egressDeviceList=egressDeviceList,
1025 portIngress=portIngress,
1026 portEgressList=portEgressList,
1027 ethType=ethType,
1028 ethSrc=srcMac,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001029 #ethDst=dstMac, #Isn't working because of ONOS itself
kelvin-onlab44147802015-07-27 17:57:31 -07001030 bandwidth=bandwidth,
1031 lambdaAlloc=lambdaAlloc,
1032 ipProto=ipProto,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001033 ipSrc=ipSrc,
1034 ipDst=ipDst,
kelvin-onlab44147802015-07-27 17:57:31 -07001035 tcpSrc="",
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001036 tcpDst="",
1037 vlanId=vlanId,
1038 partial=partial )
kelvin-onlab44147802015-07-27 17:57:31 -07001039
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001040 time.sleep( main.addIntentSleep )
1041 intentsId = main.RESTs[ 0 ].getIntentsId()
1042 except ( KeyError, TypeError ):
1043 errorMsg = "There was a problem loading the hosts data."
1044 if intentId:
1045 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
1046 main.log.error( errorMsg )
1047 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001048
1049 # Check intents state
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001050 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
1051 return intentsId
1052 else:
1053 main.log.error( "Single to Multi Intent did not install correctly" )
1054 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001055
Jon Hall02758ac2017-05-24 16:20:28 -07001056
kelvin-onlab44147802015-07-27 17:57:31 -07001057def multiToSingleIntent( main,
1058 name,
1059 hostNames,
1060 onosNode=0,
1061 devices="",
1062 ports=None,
1063 ethType="",
1064 macs=None,
1065 bandwidth="",
1066 lambdaAlloc=False,
1067 ipProto="",
1068 ipAddresses="",
1069 tcp="",
1070 sw1="",
1071 sw2="",
1072 expectedLink=0 ):
1073 """
1074 Verify Single to Multi Point intents
1075 NOTE:If main.hostsData is not defined, variables data should be passed in the
1076 same order index wise. All devices in the list should have the same
1077 format, either all the devices have its port or it doesn't.
1078 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -07001079 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
1080 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -07001081 ...
1082 Description:
1083 Verify add-multi-to-single-intent
1084 Steps:
1085 - Get device ids | ports
1086 - Add multi to single point intents
1087 - Check intents
1088 - Verify flows
1089 - Ping hosts
1090 - Reroute
1091 - Link down
1092 - Verify flows
1093 - Check topology
1094 - Ping hosts
1095 - Link up
1096 - Verify flows
1097 - Check topology
1098 - Ping hosts
1099 - Remove intents
1100 Required:
1101 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1102 hostNames - List of host names
1103 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001104 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -07001105 0 by default so that it will always use the first
1106 ONOS node
1107 devices - List of device ids in the same order as the hosts
1108 in hostNames
1109 ports - List of port numbers in the same order as the device in
1110 devices
1111 ethType - Ethernet type eg. IPV4, IPV6
1112 macs - List of hosts mac address in the same order as the hosts in
1113 hostNames
1114 bandwidth - Bandwidth capacity
1115 lambdaAlloc - Allocate lambda, defaults to False
1116 ipProto - IP protocol
1117 ipAddresses - IP addresses of host in the same order as the hosts in
1118 hostNames
1119 tcp - TCP ports in the same order as the hosts in hostNames
1120 sw1 - First switch to bring down & up for rerouting purpose
1121 sw2 - Second switch to bring down & up for rerouting purpose
1122 expectedLink - Expected link when the switches are down, it should
1123 be two links lower than the links before the two
1124 switches are down
1125 """
kelvin-onlab44147802015-07-27 17:57:31 -07001126 assert main, "There is no main variable"
1127 assert hostNames, "You must specify hosts"
1128 assert devices or main.hostsData, "You must specify devices"
1129
1130 global itemName
1131 itemName = name
1132 tempHostsData = {}
1133 intentsId = []
1134 onosNode = int( onosNode )
1135
1136 macsDict = {}
1137 ipDict = {}
1138 if hostNames and devices:
1139 if len( hostNames ) != len( devices ):
1140 main.log.debug( "hosts and devices does not have the same length" )
1141 #print "len hostNames = ", len( hostNames )
1142 #print "len devices = ", len( devices )
1143 return main.FALSE
1144 if ports:
1145 if len( ports ) != len( devices ):
1146 main.log.error( "Ports and devices does " +
1147 "not have the same length" )
1148 #print "len devices = ", len( devices )
1149 #print "len ports = ", len( ports )
1150 return main.FALSE
1151 else:
1152 main.log.info( "Device Ports are not specified" )
1153 if macs:
1154 for i in range( len( devices ) ):
1155 macsDict[ devices[ i ] ] = macs[ i ]
1156 elif hostNames and not devices and main.hostsData:
1157 devices = []
1158 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1159 for host in hostNames:
Jon Hall02758ac2017-05-24 16:20:28 -07001160 devices.append( main.hostsData.get( host ).get( 'location' ) )
1161 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1162 main.hostsData.get( host ).get( 'mac' )
1163 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1164 main.hostsData.get( host ).get( 'ipAddresses' )
kelvin-onlab44147802015-07-27 17:57:31 -07001165 #print main.hostsData
1166
1167 #print 'host names = ', hostNames
1168 #print 'devices = ', devices
1169 #print "macsDict = ", macsDict
1170
1171 pingResult = main.TRUE
1172 intentResult = main.TRUE
1173 removeIntentResult = main.TRUE
1174 flowResult = main.TRUE
1175 topoResult = main.TRUE
1176 linkDownResult = main.TRUE
1177 linkUpResult = main.TRUE
1178
1179 devicesCopy = copy.copy( devices )
1180 if ports:
1181 portsCopy = copy.copy( ports )
1182 main.log.info( itemName + ": Adding multi point to single point intents" )
1183
1184 # Check flows count in each node
1185 checkFlowsCount( main )
1186
1187 # Adding bidirectional point intents
1188 for i in range( len( devices ) ):
1189 egressDevice = devicesCopy[ i ]
1190 ingressDeviceList = copy.copy( devicesCopy )
1191 ingressDeviceList.remove( egressDevice )
1192 if ports:
1193 portEgress = portsCopy[ i ]
1194 portIngressList = copy.copy( portsCopy )
1195 del portIngressList[ i ]
1196 else:
1197 portEgress = ""
1198 portIngressList = None
1199 if not macsDict:
1200 dstMac = ""
1201 else:
1202 dstMac = macsDict[ egressDevice ]
Jon Hall02758ac2017-05-24 16:20:28 -07001203 if dstMac is None:
kelvin-onlab44147802015-07-27 17:57:31 -07001204 main.log.debug( "There is no MAC in device - " + egressDevice )
1205 dstMac = ""
1206
1207 intentsId.append(
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001208 main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001209 ingressDeviceList=ingressDeviceList,
1210 egressDevice=egressDevice,
1211 portIngressList=portIngressList,
1212 portEgress=portEgress,
1213 ethType=ethType,
1214 ethDst=dstMac,
1215 bandwidth=bandwidth,
1216 lambdaAlloc=lambdaAlloc,
1217 ipProto=ipProto,
1218 ipSrc="",
1219 ipDst="",
1220 tcpSrc="",
1221 tcpDst="" ) )
1222
1223 pingResult = pingallHosts( main, hostNames )
1224
1225 # Check intents state
1226 time.sleep( main.checkIntentSleep )
1227 intentResult = checkIntentState( main, intentsId )
1228
1229 # Check intents state again if first check fails...
1230 if not intentResult:
1231 intentResult = checkIntentState( main, intentsId )
1232
1233 # Check flows count in each node
1234 checkFlowsCount( main )
1235 # Verify flows
1236 checkFlowsState( main )
1237
1238 # Ping hosts
1239 pingResult = pingResult and pingallHosts( main, hostNames )
1240 # Ping hosts again...
1241 pingResult = pingResult and pingallHosts( main, hostNames )
1242
1243 # Test rerouting if these variables exist
1244 if sw1 and sw2 and expectedLink:
1245 # link down
1246 linkDownResult = link( main, sw1, sw2, "down" )
1247 intentResult = intentResult and checkIntentState( main, intentsId )
1248
1249 # Check flows count in each node
1250 checkFlowsCount( main )
1251 # Verify flows
1252 checkFlowsState( main )
1253
1254 # Check OnosTopology
1255 topoResult = checkTopology( main, expectedLink )
1256
1257 # Ping hosts
1258 pingResult = pingResult and pingallHosts( main, hostNames )
1259
1260 intentResult = checkIntentState( main, intentsId )
1261
1262 # Checks ONOS state in link down
1263 if linkDownResult and topoResult and pingResult and intentResult:
1264 main.log.info( itemName + ": Successfully brought link down" )
1265 else:
1266 main.log.error( itemName + ": Failed to bring link down" )
1267
1268 # link up
1269 linkUpResult = link( main, sw1, sw2, "up" )
1270 time.sleep( main.rerouteSleep )
1271
1272 # Check flows count in each node
1273 checkFlowsCount( main )
1274 # Verify flows
1275 checkFlowsState( main )
1276
1277 # Check OnosTopology
1278 topoResult = checkTopology( main, main.numLinks )
1279
1280 # Ping hosts
1281 pingResult = pingResult and pingallHosts( main, hostNames )
1282
1283 intentResult = checkIntentState( main, intentsId )
1284
1285 # Checks ONOS state in link up
1286 if linkUpResult and topoResult and pingResult and intentResult:
1287 main.log.info( itemName + ": Successfully brought link back up" )
1288 else:
1289 main.log.error( itemName + ": Failed to bring link back up" )
1290
1291 # Remove all intents
1292 removeIntentResult = removeAllIntents( main, intentsId )
1293
1294 stepResult = pingResult and linkDownResult and linkUpResult \
1295 and intentResult and removeIntentResult
1296
1297 return stepResult
1298
Jon Hall02758ac2017-05-24 16:20:28 -07001299
kelvin-onlab0e684682015-08-11 18:51:41 -07001300def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001301 # Ping all host in the hosts list variable
1302 print "Pinging : ", hostList
1303 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001304 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001305 return pingResult
1306
Jon Hall02758ac2017-05-24 16:20:28 -07001307
kelvin-onlab0e684682015-08-11 18:51:41 -07001308def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001309 """
1310 Use fwd app and pingall to discover all the hosts
1311 """
kelvin-onlab44147802015-07-27 17:57:31 -07001312 activateResult = main.TRUE
1313 appCheck = main.TRUE
1314 getDataResult = main.TRUE
1315 main.log.info( "Activating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001316 activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001317 if not activateResult:
1318 main.log.error( "Something went wrong installing fwd app" )
1319 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001320 if isinstance( hostList[ 0 ], types.StringType ):
1321 main.Mininet1.pingallHosts( hostList )
1322 elif isinstance( hostList[ 0 ], types.ListType ):
1323 for i in xrange( len( hostList ) ):
1324 main.Mininet1.pingallHosts( hostList[ i ] )
1325
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001326 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
kelvin-onlab44147802015-07-27 17:57:31 -07001327 hosts = main.Mininet1.getHosts().keys()
1328 # TODO: Make better use of new getHosts function
1329 for host in hosts:
1330 main.hostsData[ host ] = {}
1331 main.hostsData[ host ][ 'mac' ] = \
1332 main.Mininet1.getMacAddress( host ).upper()
1333 for hostj in hostsJson:
1334 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1335 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1336 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1337 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -07001338 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
1339 hostj[ 'locations' ][ 0 ][ 'port' ]
kelvin-onlab44147802015-07-27 17:57:31 -07001340 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1341
1342 main.log.info( "Deactivating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001343 deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001344 if activateResult and deactivateResult and main.hostsData:
1345 main.log.info( "Successfully used fwd app to discover hosts " )
1346 getDataResult = main.TRUE
1347 else:
1348 main.log.info( "Failed to use fwd app to discover hosts " )
1349 getDataResult = main.FALSE
1350
1351 print main.hostsData
1352
1353 return getDataResult
1354
Jon Hall02758ac2017-05-24 16:20:28 -07001355
kelvin-onlab44147802015-07-27 17:57:31 -07001356def checkTopology( main, expectedLink ):
1357 statusResult = main.TRUE
1358 # Check onos topology
1359 main.log.info( itemName + ": Checking ONOS topology " )
1360
1361 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001362 statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
Jon Hall02758ac2017-05-24 16:20:28 -07001363 expectedLink )\
kelvin-onlab44147802015-07-27 17:57:31 -07001364 and statusResult
1365 if not statusResult:
1366 main.log.error( itemName + ": Topology mismatch" )
1367 else:
1368 main.log.info( itemName + ": Topology match" )
1369 return statusResult
1370
Jon Hall02758ac2017-05-24 16:20:28 -07001371
kelvin-onlab44147802015-07-27 17:57:31 -07001372def checkIntentState( main, intentsId ):
1373 """
1374 This function will check intent state to make sure all the intents
1375 are in INSTALLED state
1376 """
kelvin-onlab44147802015-07-27 17:57:31 -07001377 intentResult = main.TRUE
1378 results = []
1379
1380 main.log.info( itemName + ": Checking intents state" )
1381 # First check of intents
1382 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001383 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001384 results.append( tempResult )
1385
1386 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1387
1388 if all( result == main.TRUE for result in results ):
1389 main.log.info( itemName + ": Intents are installed correctly" )
1390 else:
1391 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001392 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001393 time.sleep( 5 )
1394 results = []
1395 # Second check of intents since some of the intents may be in
1396 # INSTALLING state, they should be in INSTALLED at this time
1397 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001398 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001399 results.append( tempResult )
1400 if all( result == main.TRUE for result in results ):
1401 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001402 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001403 else:
1404 main.log.error( itemName + ": Intents are NOT installed correctly" )
1405 intentResult = main.FALSE
1406
1407 return intentResult
1408
Jon Hall02758ac2017-05-24 16:20:28 -07001409
kelvin-onlab44147802015-07-27 17:57:31 -07001410def checkFlowsState( main ):
1411
1412 main.log.info( itemName + ": Check flows state" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001413 checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
kelvin-onlab44147802015-07-27 17:57:31 -07001414 return checkFlowsResult
1415
Jon Hall02758ac2017-05-24 16:20:28 -07001416
1417def link( main, sw1, sw2, option ):
kelvin-onlab44147802015-07-27 17:57:31 -07001418
1419 # link down
1420 main.log.info( itemName + ": Bring link " + option + "between " +
1421 sw1 + " and " + sw2 )
1422 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1423 return linkResult
1424
Jon Hall02758ac2017-05-24 16:20:28 -07001425
kelvin-onlab44147802015-07-27 17:57:31 -07001426def removeAllIntents( main ):
1427 """
1428 Remove all intents in the intentsId
1429 """
kelvin-onlab44147802015-07-27 17:57:31 -07001430 onosSummary = []
1431 removeIntentResult = main.TRUE
1432 # Remove intents
Jon Hall02758ac2017-05-24 16:20:28 -07001433 removeIntentResult = main.RESTs[ 0 ].removeAllIntents()
kelvin-onlab44147802015-07-27 17:57:31 -07001434
1435 if removeIntentResult:
1436 main.log.info( itemName + ": There are no more intents remaining, " +
1437 "successfully removed all the intents." )
1438
1439 return removeIntentResult
1440
Jon Hall02758ac2017-05-24 16:20:28 -07001441
kelvin-onlab44147802015-07-27 17:57:31 -07001442def checkFlowsCount( main ):
1443 """
1444 Check flows count in each node
1445 """
kelvin-onlab44147802015-07-27 17:57:31 -07001446 flowsCount = []
1447 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1448 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001449 flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
kelvin-onlab44147802015-07-27 17:57:31 -07001450
1451 if flowsCount:
Jon Hall02758ac2017-05-24 16:20:28 -07001452 if all( flows == flowsCount[ 0 ] for flows in flowsCount ):
kelvin-onlab44147802015-07-27 17:57:31 -07001453 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1454 " flows in all ONOS node" )
1455 else:
1456 for i in range( main.numCtrls ):
1457 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001458 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001459 else:
1460 main.log.error( "Checking flows count failed, check summary command" )
1461 return main.FALSE
1462
1463 return main.TRUE
1464
Jon Hall02758ac2017-05-24 16:20:28 -07001465
Jeremy2f190ca2016-01-29 15:23:57 -08001466def sendDiscoveryArp( main, hosts=None ):
1467 """
1468 Sends Discovery ARP packets from each host provided
1469 Defaults to each host in main.scapyHosts
1470 """
1471 # Send an arp ping from each host
1472 if not hosts:
1473 hosts = main.scapyHosts
1474 for host in hosts:
Jon Hall02758ac2017-05-24 16:20:28 -07001475 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac, host.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001476 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1477 iface = None
1478 for interface in host.getIfList():
1479 if '.' in interface:
1480 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1481 iface = interface
1482 break
1483 host.sendPacket( packet=pkt, iface=iface )
1484 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1485
Jon Hall02758ac2017-05-24 16:20:28 -07001486
Jeremy2f190ca2016-01-29 15:23:57 -08001487def confirmHostDiscovery( main ):
1488 """
1489 Confirms that all ONOS nodes have discovered all scapy hosts
1490 """
1491 import collections
1492 scapyHostCount = len( main.scapyHosts )
1493 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1494 hostFails = [] # Reset for each failed attempt
1495
1496 # Check for matching hosts on each node
1497 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1498 for controller in range( main.numCtrls ):
1499 controllerStr = str( controller + 1 ) # ONOS node number
1500 # Compare Hosts
1501 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001502 try:
1503 if hosts[ controller ]:
1504 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001505 else:
Jeremydd9bda62016-04-18 12:02:32 -07001506 main.log.error( "Problem discovering hosts" )
1507 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1508 try:
1509 hostData = json.loads( hosts[ controller ] )
1510 except ( TypeError, ValueError ):
1511 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001512 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001513 else:
1514 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1515 for x in hostData
1516 if len( x.get( "ipAddresses" ) ) > 0 ]
Jon Hall02758ac2017-05-24 16:20:28 -07001517 if not set( collections.Counter( scapyHostIPs ) ).issubset( set( collections.Counter( onosHostIPs ) ) ):
Jeremydd9bda62016-04-18 12:02:32 -07001518 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1519 hostFails.append( controllerStr )
1520 else:
1521 main.log.error( "Hosts returned nothing or an error." )
1522 hostFails.append( controllerStr )
1523 except IndexError:
1524 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1525 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001526
1527 if hostFails:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001528 main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001529 return main.FALSE
1530 else:
1531 return main.TRUE
1532
Jon Hall02758ac2017-05-24 16:20:28 -07001533
Jeremy2f190ca2016-01-29 15:23:57 -08001534def populateHostData( main ):
1535 """
1536 Populates hostsData
1537 """
1538 import json
1539 try:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001540 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
Jeremy2f190ca2016-01-29 15:23:57 -08001541 hosts = main.Mininet1.getHosts().keys()
1542 # TODO: Make better use of new getHosts function
1543 for host in hosts:
1544 main.hostsData[ host ] = {}
1545 main.hostsData[ host ][ 'mac' ] = \
1546 main.Mininet1.getMacAddress( host ).upper()
1547 for hostj in hostsJson:
1548 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1549 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1550 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1551 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -07001552 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
1553 hostj[ 'locations' ][ 0 ][ 'port' ]
Jeremy2f190ca2016-01-29 15:23:57 -08001554 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1555 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001556 except ValueError:
1557 main.log.error( "ValueError while populating hostsData" )
1558 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001559 except KeyError:
Jon Hall02758ac2017-05-24 16:20:28 -07001560 main.log.error( "KeyError while populating hostsData" )
Jeremy2f190ca2016-01-29 15:23:57 -08001561 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001562 except IndexError:
1563 main.log.error( "IndexError while populating hostsData" )
1564 return main.FALSE
1565 except TypeError:
1566 main.log.error( "TypeError while populating hostsData" )
1567 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001568
Jon Hall02758ac2017-05-24 16:20:28 -07001569
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001570def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001571 """
1572 Checks the connectivity between all given sender hosts and all given recipient hosts
1573 Packet may be specified. Defaults to Ether/IP packet
1574 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1575 Todo: Optional packet and packet filter attributes for sender and recipients
1576 Expect Failure when the sender and recipient are not supposed to have connectivity
1577 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1578
1579 """
1580 connectionsFunctional = main.TRUE
1581
1582 if not packetFilter:
1583 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001584 if useTCP:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001585 packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
Jeremy2f190ca2016-01-29 15:23:57 -08001586 if expectFailure:
1587 timeout = 1
1588 else:
1589 timeout = 10
1590
1591 for sender in senders:
1592 try:
1593 senderComp = getattr( main, sender )
1594 except AttributeError:
1595 main.log.error( "main has no attribute {}".format( sender ) )
1596 connectionsFunctional = main.FALSE
1597 continue
1598
1599 for recipient in recipients:
1600 # Do not send packets to self since recipient CLI will already be busy
1601 if recipient == sender:
1602 continue
1603 try:
1604 recipientComp = getattr( main, recipient )
1605 except AttributeError:
1606 main.log.error( "main has no attribute {}".format( recipient ) )
1607 connectionsFunctional = main.FALSE
1608 continue
1609
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001610 if vlanId:
Jon Hall02758ac2017-05-24 16:20:28 -07001611 recipientComp.startFilter( pktFilter=( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001612 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001613 recipientComp.startFilter( pktFilter=packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001614
1615 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001616 if vlanId:
1617 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1618 senderComp.hostMac,
1619 senderComp.hostIp,
1620 recipientComp.hostMac,
1621 recipientComp.hostIp,
1622 vlanId )
1623 else:
1624 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1625 senderComp.hostMac,
1626 senderComp.hostIp,
1627 recipientComp.hostMac,
1628 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001629 else:
1630 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001631 if vlanId:
1632 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1633 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001634 senderComp.sendPacket( packet=pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001635
1636 if recipientComp.checkFilter( timeout ):
1637 if expectFailure:
Jon Hall02758ac2017-05-24 16:20:28 -07001638 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001639 connectionsFunctional = main.FALSE
1640 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001641 main.log.info( "Packet from {0} successfully received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001642 else:
1643 recipientComp.killFilter()
1644 if expectFailure:
Jon Hall02758ac2017-05-24 16:20:28 -07001645 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001646 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001647 main.log.error( "Packet from {0} was not received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001648 connectionsFunctional = main.FALSE
1649
1650 return connectionsFunctional
1651
Jon Hall02758ac2017-05-24 16:20:28 -07001652
Jeremye1ea0602016-02-08 16:35:05 -08001653def checkLeaderChange( leaders1, leaders2 ):
1654 """
1655 Checks for a change in intent partition leadership.
1656
1657 Takes the output of leaders -c in json string format before and after
1658 a potential change as input
1659
1660 Returns main.TRUE if no mismatches are detected
1661 Returns main.FALSE if there is a mismatch or on error loading the input
1662 """
1663 try:
1664 leaders1 = json.loads( leaders1 )
1665 leaders2 = json.loads( leaders2 )
Jon Hall02758ac2017-05-24 16:20:28 -07001666 except ( AttributeError, TypeError ):
Jeremye1ea0602016-02-08 16:35:05 -08001667 main.log.exception( self.name + ": Object not as expected" )
1668 return main.FALSE
1669 except Exception:
1670 main.log.exception( self.name + ": Uncaught exception!" )
1671 main.cleanup()
1672 main.exit()
1673 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1674 mismatch = False
1675 for dict1 in leaders1:
1676 if "intent" in dict1.get( "topic", [] ):
1677 for dict2 in leaders2:
1678 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
Jon Hall02758ac2017-05-24 16:20:28 -07001679 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
Jeremye1ea0602016-02-08 16:35:05 -08001680 mismatch = True
Jon Hall02758ac2017-05-24 16:20:28 -07001681 main.log.error( "{0} changed leader from {1} to {2}".
1682 format( dict1.get( "topic", "no-topic" ),
1683 dict1.get( "leader", "no-leader" ),
1684 dict2.get( "leader", "no-leader" ) ) )
Jeremye1ea0602016-02-08 16:35:05 -08001685 if mismatch:
1686 return main.FALSE
1687 else:
1688 return main.TRUE
1689
1690
Jeremy2f190ca2016-01-29 15:23:57 -08001691def report( main ):
1692 """
1693 Report errors/warnings/exceptions
1694 """
1695 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1696 [ "INFO",
1697 "FOLLOWER",
1698 "WARN",
1699 "flow",
1700 "ERROR",
1701 "Except" ],
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001702 "s" )
Jeremy2f190ca2016-01-29 15:23:57 -08001703
1704 main.log.info( "ERROR report: \n" )
1705 for i in range( main.numCtrls ):
1706 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001707 [ "ERROR" ],
1708 "d" )
Jeremy2f190ca2016-01-29 15:23:57 -08001709
1710 main.log.info( "EXCEPTIONS report: \n" )
1711 for i in range( main.numCtrls ):
1712 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001713 [ "Except" ],
1714 "d" )
Jeremy2f190ca2016-01-29 15:23:57 -08001715
1716 main.log.info( "WARNING report: \n" )
1717 for i in range( main.numCtrls ):
1718 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001719 [ "WARN" ],
1720 "d" )
1721
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001722
1723def flowDuration( main ):
1724 """
1725 Check age of flows to see if flows are being overwritten
1726 """
1727 import time
1728 main.log.info( "Getting current flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001729 flowsJson1 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001730 try:
1731 flowsJson1 = json.loads( flowsJson1 )
1732 except ValueError:
1733 main.log.error( "Unable to read flows" )
1734 return main.FALSE
1735 flowLife = []
1736 waitFlowLife = []
1737 for flow in flowsJson1:
1738 if flow[ 'appId' ] == "org.onosproject.net.intent":
1739 flowLife.append( flow[ 'life' ] )
1740 main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
1741 time.sleep( main.flowDurationSleep )
1742 main.log.info( "Getting new flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001743 flowsJson2 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001744 try:
1745 flowsJson2 = json.loads( flowsJson2 )
1746 except ValueError:
1747 main.log.error( "Unable to read flows" )
1748 return main.FALSE
1749 for flow in flowsJson2:
1750 if flow[ 'appId' ] == "org.onosproject.net.intent":
1751 waitFlowLife.append( flow[ 'life' ] )
1752 main.log.info( "Determining whether flows where overwritten" )
1753 if len( flowLife ) == len( waitFlowLife ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001754 for i in range( len( flowLife ) ):
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001755 if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
1756 return main.FALSE
1757 else:
1758 return main.FALSE
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001759 return main.TRUE
alisonda157272016-12-22 01:13:21 -08001760
Jon Hall02758ac2017-05-24 16:20:28 -07001761
alisonda157272016-12-22 01:13:21 -08001762def ProtectedIntentCheck( main ):
1763 intent = main.RESTs[ 0 ].intents()
Jon Hall02758ac2017-05-24 16:20:28 -07001764 main.log.debug( intent )
alisonda157272016-12-22 01:13:21 -08001765 main.stop()
1766 if "Protection" in intent:
1767 return main.TRUE
1768 return main.FALSE