blob: 11ca425911c359bf3d41bf54d5fc2fc43b08f08d [file] [log] [blame]
kelvin-onlabd48a68c2015-07-13 16:01:36 -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
9
10def __init__( self ):
11 self.default = ''
12
13def hostIntent( main,
14 name,
15 host1,
16 host2,
17 onosNode=0,
18 host1Id="",
19 host2Id="",
20 mac1="",
21 mac2="",
22 vlan1="-1",
23 vlan2="-1",
24 sw1="",
25 sw2="",
26 expectedLink=0 ):
27 """
28 Description:
29 Verify add-host-intent
30 Steps:
31 - Discover hosts
32 - Add host intents
33 - Check intents
34 - Verify flows
35 - Ping hosts
36 - Reroute
37 - Link down
38 - Verify flows
39 - Check topology
40 - Ping hosts
41 - Link up
42 - Verify flows
43 - Check topology
44 - Ping hosts
45 - Remove intents
46 Required:
47 name - Type of host intent to add eg. IPV4 | VLAN | Dualstack
48 host1 - Name of first host
49 host2 - Name of second host
50 Optional:
kelvin-onlabb769f562015-07-15 17:05:10 -070051 onosNode - ONOS node to install the intents in main.CLIs[ ]
52 0 by default so that it will always use the first
53 ONOS node
kelvin-onlabd48a68c2015-07-13 16:01:36 -070054 host1Id - ONOS id of the first host eg. 00:00:00:00:00:01/-1
55 host2Id - ONOS id of the second host
56 mac1 - Mac address of first host
57 mac2 - Mac address of the second host
58 vlan1 - Vlan tag of first host, defaults to -1
59 vlan2 - Vlan tag of second host, defaults to -1
60 sw1 - First switch to bring down & up for rerouting purpose
61 sw2 - Second switch to bring down & up for rerouting purpose
62 expectedLink - Expected link when the switches are down, it should
63 be two links lower than the links before the two
64 switches are down
65 """
66
67 # Assert variables
68 assert main, "There is no main variable"
69 assert name, "variable name is empty"
70 assert host1 and host2, "You must specify hosts"
71
72 global itemName
73 itemName = name
74 h1Id = host1Id
75 h2Id = host2Id
76 h1Mac = mac1
77 h2Mac = mac2
78 vlan1 = vlan1
79 vlan2 = vlan2
80 hostNames = [ host1 , host2 ]
81 intentsId = []
82 stepResult = main.TRUE
83 pingResult = main.TRUE
84 intentResult = main.TRUE
85 removeIntentResult = main.TRUE
86 flowResult = main.TRUE
87 topoResult = main.TRUE
88 linkDownResult = main.TRUE
89 linkUpResult = main.TRUE
90 onosNode = int( onosNode )
91
92 if main.hostsData:
93 if not h1Mac:
94 h1Mac = main.hostsData[ host1 ][ 'mac' ]
95 if not h2Mac:
96 h2Mac = main.hostsData[ host2 ][ 'mac' ]
97 if main.hostsData[ host1 ][ 'vlan' ] != '-1':
98 vlan1 = main.hostsData[ host1 ][ 'vlan' ]
99 if main.hostsData[ host2 ][ 'vlan' ] != '-1':
100 vlan2 = main.hostsData[ host2 ][ 'vlan' ]
101 if not h1Id:
102 h1Id = main.hostsData[ host1 ][ 'id' ]
103 if not h2Id:
104 h2Id = main.hostsData[ host2 ][ 'id' ]
105
106 assert h1Id and h2Id, "You must specify host IDs"
107 if not ( h1Id and h2Id ):
108 main.log.info( "There are no host IDs" )
109 return main.FALSE
110
111 # Discover hosts using arping
112 if not main.hostsData:
113 main.log.info( itemName + ": Discover host using arping" )
114 main.Mininet1.arping( host=host1 )
115 main.Mininet1.arping( host=host2 )
116 host1 = main.CLIs[ 0 ].getHost( mac=h1Mac )
117 host2 = main.CLIs[ 0 ].getHost( mac=h2Mac )
118
119 # Check flows count in each node
120 checkFlowsCount( main )
121
122 # Checking connectivity before installing intents
123 main.log.info( itemName + ": Check hosts connection before adding intents" )
124 checkPing = pingallHosts( main, hostNames )
125 if not checkPing:
126 main.log.info( itemName + ": Ping did not go through " +
127 "before adding intents" )
128 else:
129 main.log.debug( itemName + ": Pinged successful before adding " +
130 "intents,please check fwd app if it is activated" )
131
132 # Adding host intents
133 main.log.info( itemName + ": Adding host intents" )
134 intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=h1Id,
135 hostIdTwo=h2Id )
136 intentsId.append( intent1 )
137
138 # Check intents state
139 time.sleep( main.checkIntentSleep )
140 intentResult = checkIntentState( main, intentsId )
141 checkFlowsCount( main )
142
143 # Check intents state again if first check fails...
144 if not intentResult:
145 intentResult = checkIntentState( main, intentsId )
146
147 # Check flows count in each node
148 checkFlowsCount( main )
149 # Verify flows
150 checkFlowsState( main )
151
152 # Ping hosts
153 firstPingResult = pingallHosts( main, hostNames )
154 if not firstPingResult:
155 main.log.debug( "First ping failed, there must be" +
156 " something wrong with ONOS performance" )
157
158 # Ping hosts again...
159 pingResult = pingResult and pingallHosts( main, hostNames )
160
161 # Test rerouting if these variables exist
162 if sw1 and sw2 and expectedLink:
163 # link down
164 linkDownResult = link( main, sw1, sw2, "down" )
165 intentResult = intentResult and checkIntentState( main, intentsId )
166
167 # Check flows count in each node
168 checkFlowsCount( main )
169 # Verify flows
170 checkFlowsState( main )
171
172 # Check OnosTopology
173 topoResult = checkTopology( main, expectedLink )
174
175 # Ping hosts
176 pingResult = pingResult and pingallHosts( main, hostNames )
177
178 intentResult = checkIntentState( main, intentsId )
179
180 # Checks ONOS state in link down
181 if linkDownResult and topoResult and pingResult and intentResult:
182 main.log.info( itemName + ": Successfully brought link down" )
183 else:
184 main.log.error( itemName + ": Failed to bring link down" )
185
186 # link up
187 linkUpResult = link( main, sw1, sw2, "up" )
188 time.sleep( main.rerouteSleep )
189
190 # Check flows count in each node
191 checkFlowsCount( main )
192 # Verify flows
193 checkFlowsState( main )
194
195 # Check OnosTopology
196 topoResult = checkTopology( main, main.numLinks )
197
198 # Ping hosts
199 pingResult = pingResult and pingallHosts( main, hostNames )
200
201 intentResult = checkIntentState( main, intentsId )
202
203 # Checks ONOS state in link up
204 if linkUpResult and topoResult and pingResult and intentResult:
205 main.log.info( itemName + ": Successfully brought link back up" )
206 else:
207 main.log.error( itemName + ": Failed to bring link back up" )
208
209 # Remove all intents
210 removeIntentResult = removeAllIntents( main, intentsId )
211
212 stepResult = pingResult and linkDownResult and linkUpResult \
213 and intentResult and removeIntentResult
214
215 return stepResult
216
217def pointIntent( main,
218 name,
219 host1,
220 host2,
221 onosNode=0,
222 deviceId1="",
223 deviceId2="",
224 port1="",
225 port2="",
226 ethType="",
227 mac1="",
228 mac2="",
229 bandwidth="",
230 lambdaAlloc=False,
231 ipProto="",
232 ip1="",
233 ip2="",
234 tcp1="",
235 tcp2="",
236 sw1="",
237 sw2="",
238 expectedLink=0 ):
239
240 """
241 Description:
242 Verify add-point-intent
243 Steps:
244 - Get device ids | ports
245 - Add point intents
246 - Check intents
247 - Verify flows
248 - Ping hosts
249 - Reroute
250 - Link down
251 - Verify flows
252 - Check topology
253 - Ping hosts
254 - Link up
255 - Verify flows
256 - Check topology
257 - Ping hosts
258 - Remove intents
259 Required:
260 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
261 host1 - Name of first host
262 host2 - Name of second host
263 Optional:
kelvin-onlabb769f562015-07-15 17:05:10 -0700264 onosNode - ONOS node to install the intents in main.CLIs[ ]
265 0 by default so that it will always use the first
266 ONOS node
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700267 deviceId1 - ONOS device id of the first switch, the same as the
268 location of the first host eg. of:0000000000000001/1,
269 located at device 1 port 1
270 deviceId2 - ONOS device id of the second switch
271 port1 - The port number where the first host is attached
272 port2 - The port number where the second host is attached
273 ethType - Ethernet type eg. IPV4, IPV6
274 mac1 - Mac address of first host
275 mac2 - Mac address of the second host
276 bandwidth - Bandwidth capacity
277 lambdaAlloc - Allocate lambda, defaults to False
278 ipProto - IP protocol
279 ip1 - IP address of first host
280 ip2 - IP address of second host
281 tcp1 - TCP port of first host
282 tcp2 - TCP port of second host
283 sw1 - First switch to bring down & up for rerouting purpose
284 sw2 - Second switch to bring down & up for rerouting purpose
285 expectedLink - Expected link when the switches are down, it should
286 be two links lower than the links before the two
287 switches are down
288 """
289
290 assert main, "There is no main variable"
291 assert name, "variable name is empty"
292 assert host1 and host2, "You must specify hosts"
293
294 global itemName
295 itemName = name
296 host1 = host1
297 host2 = host2
298 hostNames = [ host1, host2 ]
299 intentsId = []
300
301 pingResult = main.TRUE
302 intentResult = main.TRUE
303 removeIntentResult = main.TRUE
304 flowResult = main.TRUE
305 topoResult = main.TRUE
306 linkDownResult = main.TRUE
307 linkUpResult = main.TRUE
308 onosNode = int( onosNode )
309
310 # Checking connectivity before installing intents
311 main.log.info( itemName + ": Check hosts connection before adding intents" )
312 checkPing = pingallHosts( main, hostNames )
313 if not checkPing:
314 main.log.info( itemName + ": Ping did not go through " +
315 "before adding intents" )
316 else:
317 main.log.debug( itemName + ": Pinged successful before adding " +
318 "intents,please check fwd app if it is activated" )
319
320 # Adding bidirectional point intents
321 main.log.info( itemName + ": Adding point intents" )
322 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
323 egressDevice=deviceId2,
324 portIngress=port1,
325 portEgress=port2,
326 ethType=ethType,
327 ethSrc=mac1,
328 ethDst=mac2,
329 bandwidth=bandwidth,
330 lambdaAlloc=lambdaAlloc,
331 ipProto=ipProto,
332 ipSrc=ip1,
333 ipDst=ip2,
334 tcpSrc=tcp1,
335 tcpDst=tcp2 )
336
337 intentsId.append( intent1 )
338 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
339 egressDevice=deviceId1,
340 portIngress=port2,
341 portEgress=port1,
342 ethType=ethType,
343 ethSrc=mac2,
344 ethDst=mac1,
345 bandwidth=bandwidth,
346 lambdaAlloc=lambdaAlloc,
347 ipProto=ipProto,
348 ipSrc=ip2,
349 ipDst=ip1,
350 tcpSrc=tcp2,
351 tcpDst=tcp1 )
352 intentsId.append( intent2 )
353
354 # Check intents state
355 time.sleep( main.checkIntentSleep )
356 intentResult = checkIntentState( main, intentsId )
357 # Check flows count in each node
358 checkFlowsCount( main )
359
360 # Check intents state again if first check fails...
361 if not intentResult:
362 intentResult = checkIntentState( main, intentsId )
363
364 # Check flows count in each node
365 checkFlowsCount( main )
366 # Verify flows
367 checkFlowsState( main )
368
369 # Ping hosts
370 firstPingResult = pingallHosts( main, hostNames )
371 if not firstPingResult:
372 main.log.debug( "First ping failed, there must be" +
373 " something wrong with ONOS performance" )
374
375 # Ping hosts again...
376 pingResult = pingResult and pingallHosts( main, hostNames )
377
378 # Test rerouting if these variables exist
379 if sw1 and sw2 and expectedLink:
380 # link down
381 linkDownResult = link( main, sw1, sw2, "down" )
382 intentResult = intentResult and checkIntentState( main, intentsId )
383
384 # Check flows count in each node
385 checkFlowsCount( main )
386 # Verify flows
387 checkFlowsState( main )
388
389 # Check OnosTopology
390 topoResult = checkTopology( main, expectedLink )
391
392 # Ping hosts
393 pingResult = pingResult and pingallHosts( main, hostNames )
394
395 intentResult = checkIntentState( main, intentsId )
396
397 # Checks ONOS state in link down
398 if linkDownResult and topoResult and pingResult and intentResult:
399 main.log.info( itemName + ": Successfully brought link down" )
400 else:
401 main.log.error( itemName + ": Failed to bring link down" )
402
403 # link up
404 linkUpResult = link( main, sw1, sw2, "up" )
405 time.sleep( main.rerouteSleep )
406
407 # Check flows count in each node
408 checkFlowsCount( main )
409 # Verify flows
410 checkFlowsState( main )
411
412 # Check OnosTopology
413 topoResult = checkTopology( main, main.numLinks )
414
415 # Ping hosts
416 pingResult = pingResult and pingallHosts( main, hostNames )
417
418 intentResult = checkIntentState( main, intentsId )
419
420 # Checks ONOS state in link up
421 if linkUpResult and topoResult and pingResult and intentResult:
422 main.log.info( itemName + ": Successfully brought link back up" )
423 else:
424 main.log.error( itemName + ": Failed to bring link back up" )
425
426 # Remove all intents
427 removeIntentResult = removeAllIntents( main, intentsId )
428
429 stepResult = pingResult and linkDownResult and linkUpResult \
430 and intentResult and removeIntentResult
431
432 return stepResult
433
434def singleToMultiIntent( main,
435 name,
436 hostNames,
437 onosNode=0,
438 devices="",
439 ports=None,
440 ethType="",
441 macs=None,
442 bandwidth="",
443 lambdaAlloc=False,
444 ipProto="",
445 ipAddresses="",
446 tcp="",
447 sw1="",
448 sw2="",
449 expectedLink=0 ):
450 """
451 Verify Single to Multi Point intents
452 NOTE:If main.hostsData is not defined, variables data should be passed in the
453 same order index wise. All devices in the list should have the same
454 format, either all the devices have its port or it doesn't.
455 eg. hostName = [ 'h1', 'h2' ,.. ]
456 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
457 ports = [ '1', '1', ..]
458 ...
459 Description:
460 Verify add-single-to-multi-intent iterates through the list of given
461 host | devices and add intents
462 Steps:
463 - Get device ids | ports
464 - Add single to multi point intents
465 - Check intents
466 - Verify flows
467 - Ping hosts
468 - Reroute
469 - Link down
470 - Verify flows
471 - Check topology
472 - Ping hosts
473 - Link up
474 - Verify flows
475 - Check topology
476 - Ping hosts
477 - Remove intents
478 Required:
479 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
480 hostNames - List of host names
481 Optional:
kelvin-onlabb769f562015-07-15 17:05:10 -0700482 onosNode - ONOS node to install the intents in main.CLIs[ ]
483 0 by default so that it will always use the first
484 ONOS node
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700485 devices - List of device ids in the same order as the hosts
486 in hostNames
487 ports - List of port numbers in the same order as the device in
488 devices
489 ethType - Ethernet type eg. IPV4, IPV6
490 macs - List of hosts mac address in the same order as the hosts in
491 hostNames
492 bandwidth - Bandwidth capacity
493 lambdaAlloc - Allocate lambda, defaults to False
494 ipProto - IP protocol
495 ipAddresses - IP addresses of host in the same order as the hosts in
496 hostNames
497 tcp - TCP ports in the same order as the hosts in hostNames
498 sw1 - First switch to bring down & up for rerouting purpose
499 sw2 - Second switch to bring down & up for rerouting purpose
500 expectedLink - Expected link when the switches are down, it should
501 be two links lower than the links before the two
502 switches are down
503 """
504
505 assert main, "There is no main variable"
506 assert hostNames, "You must specify hosts"
507 assert devices or main.hostsData, "You must specify devices"
508
509 global itemName
510 itemName = name
511 tempHostsData = {}
512 intentsId = []
513 onosNode = int( onosNode )
514
515 macsDict = {}
516 ipDict = {}
517 if hostNames and devices:
518 if len( hostNames ) != len( devices ):
519 main.log.debug( "hosts and devices does not have the same length" )
520 #print "len hostNames = ", len( hostNames )
521 #print "len devices = ", len( devices )
522 return main.FALSE
523 if ports:
524 if len( ports ) != len( devices ):
525 main.log.error( "Ports and devices does " +
526 "not have the same length" )
527 #print "len devices = ", len( devices )
528 #print "len ports = ", len( ports )
529 return main.FALSE
530 else:
531 main.log.info( "Device Ports are not specified" )
532 if macs:
533 for i in range( len( devices ) ):
534 macsDict[ devices[ i ] ] = macs[ i ]
535
536 elif hostNames and not devices and main.hostsData:
537 devices = []
538 main.log.info( "singleToMultiIntent function is using main.hostsData" )
539 for host in hostNames:
540 devices.append( main.hostsData.get( host ).get( 'location' ) )
541 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
542 main.hostsData.get( host ).get( 'mac' )
543 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
544 main.hostsData.get( host ).get( 'ipAddresses' )
545 #print main.hostsData
546
547 #print 'host names = ', hostNames
548 #print 'devices = ', devices
549 #print "macsDict = ", macsDict
550
551 pingResult = main.TRUE
552 intentResult = main.TRUE
553 removeIntentResult = main.TRUE
554 flowResult = main.TRUE
555 topoResult = main.TRUE
556 linkDownResult = main.TRUE
557 linkUpResult = main.TRUE
558
559 devicesCopy = copy.copy( devices )
560 if ports:
561 portsCopy = copy.copy( ports )
562 main.log.info( itemName + ": Adding single point to multi point intents" )
563
564 # Check flows count in each node
565 checkFlowsCount( main )
566
567 # Checking connectivity before installing intents
568 main.log.info( itemName + ": Check hosts connection before adding intents" )
569 checkPing = pingallHosts( main, hostNames )
570 if not checkPing:
571 main.log.info( itemName + ": Ping did not go through " +
572 "before adding intents" )
573 else:
574 main.log.debug( itemName + ": Pinged successful before adding " +
575 "intents,please check fwd app if it is activated" )
576
577 # Adding bidirectional point intents
578 for i in range( len( devices ) ):
579 ingressDevice = devicesCopy[ i ]
580 egressDeviceList = copy.copy( devicesCopy )
581 egressDeviceList.remove( ingressDevice )
582 if ports:
583 portIngress = portsCopy[ i ]
584 portEgressList = copy.copy( portsCopy )
585 del portEgressList[ i ]
586 else:
587 portIngress = ""
588 portEgressList = None
589 if not macsDict:
590 srcMac = ""
591 else:
592 srcMac = macsDict[ ingressDevice ]
593 if srcMac == None:
594 main.log.debug( "There is no MAC in device - " + ingressDevice )
595 srcMac = ""
596
597 intentsId.append(
598 main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
599 ingressDevice=ingressDevice,
600 egressDeviceList=egressDeviceList,
601 portIngress=portIngress,
602 portEgressList=portEgressList,
603 ethType=ethType,
604 ethSrc=srcMac,
605 bandwidth=bandwidth,
606 lambdaAlloc=lambdaAlloc,
607 ipProto=ipProto,
608 ipSrc="",
609 ipDst="",
610 tcpSrc="",
611 tcpDst="" ) )
612
613 # Wait some time for the flow to go through when using multi instance
614 pingResult = pingallHosts( main, hostNames )
615
616 # Check intents state
617 time.sleep( main.checkIntentSleep )
618 intentResult = checkIntentState( main, intentsId )
619
620 # Check intents state again if first check fails...
621 if not intentResult:
622 intentResult = checkIntentState( main, intentsId )
623
624 # Check flows count in each node
625 checkFlowsCount( main )
626 # Verify flows
627 checkFlowsState( main )
628
629 pingResult = pingResult and pingallHosts( main, hostNames )
630
631 # Test rerouting if these variables exist
632 if sw1 and sw2 and expectedLink:
633 # link down
634 linkDownResult = link( main, sw1, sw2, "down" )
635 intentResult = intentResult and checkIntentState( main, intentsId )
636
637 # Check flows count in each node
638 checkFlowsCount( main )
639 # Verify flows
640 checkFlowsState( main )
641
642 # Check OnosTopology
643 topoResult = checkTopology( main, expectedLink )
644
645 # Ping hosts
646 pingResult = pingResult and pingallHosts( main, hostNames )
647
648 intentResult = checkIntentState( main, intentsId )
649
650 # Checks ONOS state in link down
651 if linkDownResult and topoResult and pingResult and intentResult:
652 main.log.info( itemName + ": Successfully brought link down" )
653 else:
654 main.log.error( itemName + ": Failed to bring link down" )
655
656 # link up
657 linkUpResult = link( main, sw1, sw2, "up" )
658 time.sleep( main.rerouteSleep )
659
660 # Check flows count in each node
661 checkFlowsCount( main )
662 # Verify flows
663 checkFlowsState( main )
664
665 # Check OnosTopology
666 topoResult = checkTopology( main, main.numLinks )
667
668 # Ping hosts
669 pingResult = pingResult and pingallHosts( main, hostNames )
670
671 intentResult = checkIntentState( main, intentsId )
672
673 # Checks ONOS state in link up
674 if linkUpResult and topoResult and pingResult and intentResult:
675 main.log.info( itemName + ": Successfully brought link back up" )
676 else:
677 main.log.error( itemName + ": Failed to bring link back up" )
678
679 # Remove all intents
680 removeIntentResult = removeAllIntents( main, intentsId )
681
682 stepResult = pingResult and linkDownResult and linkUpResult \
683 and intentResult and removeIntentResult
684
685 return stepResult
686
687def multiToSingleIntent( main,
688 name,
689 hostNames,
690 onosNode=0,
691 devices="",
692 ports=None,
693 ethType="",
694 macs=None,
695 bandwidth="",
696 lambdaAlloc=False,
697 ipProto="",
698 ipAddresses="",
699 tcp="",
700 sw1="",
701 sw2="",
702 expectedLink=0 ):
703 """
704 Verify Single to Multi Point intents
705 NOTE:If main.hostsData is not defined, variables data should be passed in the
706 same order index wise. All devices in the list should have the same
707 format, either all the devices have its port or it doesn't.
708 eg. hostName = [ 'h1', 'h2' ,.. ]
709 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
710 ports = [ '1', '1', ..]
711 ...
712 Description:
713 Verify add-multi-to-single-intent
714 Steps:
715 - Get device ids | ports
716 - Add multi to single point intents
717 - Check intents
718 - Verify flows
719 - Ping hosts
720 - Reroute
721 - Link down
722 - Verify flows
723 - Check topology
724 - Ping hosts
725 - Link up
726 - Verify flows
727 - Check topology
728 - Ping hosts
729 - Remove intents
730 Required:
731 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
732 hostNames - List of host names
733 Optional:
kelvin-onlabb769f562015-07-15 17:05:10 -0700734 onosNode - ONOS node to install the intents in main.CLIs[ ]
735 0 by default so that it will always use the first
736 ONOS node
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700737 devices - List of device ids in the same order as the hosts
738 in hostNames
739 ports - List of port numbers in the same order as the device in
740 devices
741 ethType - Ethernet type eg. IPV4, IPV6
742 macs - List of hosts mac address in the same order as the hosts in
743 hostNames
744 bandwidth - Bandwidth capacity
745 lambdaAlloc - Allocate lambda, defaults to False
746 ipProto - IP protocol
747 ipAddresses - IP addresses of host in the same order as the hosts in
748 hostNames
749 tcp - TCP ports in the same order as the hosts in hostNames
750 sw1 - First switch to bring down & up for rerouting purpose
751 sw2 - Second switch to bring down & up for rerouting purpose
752 expectedLink - Expected link when the switches are down, it should
753 be two links lower than the links before the two
754 switches are down
755 """
756
757 assert main, "There is no main variable"
758 assert hostNames, "You must specify hosts"
759 assert devices or main.hostsData, "You must specify devices"
760
761 global itemName
762 itemName = name
763 tempHostsData = {}
764 intentsId = []
765 onosNode = int( onosNode )
766
767 macsDict = {}
768 ipDict = {}
769 if hostNames and devices:
770 if len( hostNames ) != len( devices ):
771 main.log.debug( "hosts and devices does not have the same length" )
772 #print "len hostNames = ", len( hostNames )
773 #print "len devices = ", len( devices )
774 return main.FALSE
775 if ports:
776 if len( ports ) != len( devices ):
777 main.log.error( "Ports and devices does " +
778 "not have the same length" )
779 #print "len devices = ", len( devices )
780 #print "len ports = ", len( ports )
781 return main.FALSE
782 else:
783 main.log.info( "Device Ports are not specified" )
784 if macs:
785 for i in range( len( devices ) ):
786 macsDict[ devices[ i ] ] = macs[ i ]
787 elif hostNames and not devices and main.hostsData:
788 devices = []
789 main.log.info( "multiToSingleIntent function is using main.hostsData" )
790 for host in hostNames:
791 devices.append( main.hostsData.get( host ).get( 'location' ) )
792 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
793 main.hostsData.get( host ).get( 'mac' )
794 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
795 main.hostsData.get( host ).get( 'ipAddresses' )
796 #print main.hostsData
797
798 #print 'host names = ', hostNames
799 #print 'devices = ', devices
800 #print "macsDict = ", macsDict
801
802 pingResult = main.TRUE
803 intentResult = main.TRUE
804 removeIntentResult = main.TRUE
805 flowResult = main.TRUE
806 topoResult = main.TRUE
807 linkDownResult = main.TRUE
808 linkUpResult = main.TRUE
809
810 devicesCopy = copy.copy( devices )
811 if ports:
812 portsCopy = copy.copy( ports )
813 main.log.info( itemName + ": Adding multi point to single point intents" )
814
815 # Check flows count in each node
816 checkFlowsCount( main )
817
818 # Checking connectivity before installing intents
819 main.log.info( itemName + ": Check hosts connection before adding intents" )
820 checkPing = pingallHosts( main, hostNames )
821 if not checkPing:
822 main.log.info( itemName + ": Ping did not go through " +
823 "before adding intents" )
824 else:
825 main.log.debug( itemName + ": Pinged successful before adding " +
826 "intents,please check fwd app if it is activated" )
827
828 # Adding bidirectional point intents
829 for i in range( len( devices ) ):
830 egressDevice = devicesCopy[ i ]
831 ingressDeviceList = copy.copy( devicesCopy )
832 ingressDeviceList.remove( egressDevice )
833 if ports:
834 portEgress = portsCopy[ i ]
835 portIngressList = copy.copy( portsCopy )
836 del portIngressList[ i ]
837 else:
838 portEgress = ""
839 portIngressList = None
840 if not macsDict:
841 dstMac = ""
842 else:
843 dstMac = macsDict[ egressDevice ]
844 if dstMac == None:
845 main.log.debug( "There is no MAC in device - " + egressDevice )
846 dstMac = ""
847
848 intentsId.append(
849 main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
850 ingressDeviceList=ingressDeviceList,
851 egressDevice=egressDevice,
852 portIngressList=portIngressList,
853 portEgress=portEgress,
854 ethType=ethType,
855 ethDst=dstMac,
856 bandwidth=bandwidth,
857 lambdaAlloc=lambdaAlloc,
858 ipProto=ipProto,
859 ipSrc="",
860 ipDst="",
861 tcpSrc="",
862 tcpDst="" ) )
863
864 pingResult = pingallHosts( main, hostNames )
865
866 # Check intents state
867 time.sleep( main.checkIntentSleep )
868 intentResult = checkIntentState( main, intentsId )
869
870 # Check intents state again if first check fails...
871 if not intentResult:
872 intentResult = checkIntentState( main, intentsId )
873
874 # Check flows count in each node
875 checkFlowsCount( main )
876 # Verify flows
877 checkFlowsState( main )
878
879 # Ping hosts
880 pingResult = pingResult and pingallHosts( main, hostNames )
881 # Ping hosts again...
882 pingResult = pingResult and pingallHosts( main, hostNames )
883
884 # Test rerouting if these variables exist
885 if sw1 and sw2 and expectedLink:
886 # link down
887 linkDownResult = link( main, sw1, sw2, "down" )
888 intentResult = intentResult and checkIntentState( main, intentsId )
889
890 # Check flows count in each node
891 checkFlowsCount( main )
892 # Verify flows
893 checkFlowsState( main )
894
895 # Check OnosTopology
896 topoResult = checkTopology( main, expectedLink )
897
898 # Ping hosts
899 pingResult = pingResult and pingallHosts( main, hostNames )
900
901 intentResult = checkIntentState( main, intentsId )
902
903 # Checks ONOS state in link down
904 if linkDownResult and topoResult and pingResult and intentResult:
905 main.log.info( itemName + ": Successfully brought link down" )
906 else:
907 main.log.error( itemName + ": Failed to bring link down" )
908
909 # link up
910 linkUpResult = link( main, sw1, sw2, "up" )
911 time.sleep( main.rerouteSleep )
912
913 # Check flows count in each node
914 checkFlowsCount( main )
915 # Verify flows
916 checkFlowsState( main )
917
918 # Check OnosTopology
919 topoResult = checkTopology( main, main.numLinks )
920
921 # Ping hosts
922 pingResult = pingResult and pingallHosts( main, hostNames )
923
924 intentResult = checkIntentState( main, intentsId )
925
926 # Checks ONOS state in link up
927 if linkUpResult and topoResult and pingResult and intentResult:
928 main.log.info( itemName + ": Successfully brought link back up" )
929 else:
930 main.log.error( itemName + ": Failed to bring link back up" )
931
932 # Remove all intents
933 removeIntentResult = removeAllIntents( main, intentsId )
934
935 stepResult = pingResult and linkDownResult and linkUpResult \
936 and intentResult and removeIntentResult
937
938 return stepResult
939
940def pingallHosts( main, hostList, pingType="ipv4" ):
941 # Ping all host in the hosts list variable
942 print "Pinging : ", hostList
943 pingResult = main.TRUE
944 pingResult = main.Mininet1.pingallHosts( hostList, pingType )
945 return pingResult
946
947def getHostsData( main ):
948 """
949 Use fwd app and pingall to discover all the hosts
950 """
951
952 activateResult = main.TRUE
953 appCheck = main.TRUE
954 getDataResult = main.TRUE
955 main.log.info( "Activating reactive forwarding app " )
956 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
957
958 for i in range( main.numCtrls ):
959 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
960 if appCheck != main.TRUE:
961 main.log.warn( main.CLIs[ i ].apps() )
962 main.log.warn( main.CLIs[ i ].appIDs() )
963
964 pingResult = main.Mininet1.pingall( timeout = 600 )
965 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
966 hosts = main.Mininet1.getHosts().keys()
967 # TODO: Make better use of new getHosts function
968 for host in hosts:
969 main.hostsData[ host ] = {}
970 main.hostsData[ host ][ 'mac' ] = \
971 main.Mininet1.getMacAddress( host ).upper()
972 for hostj in hostsJson:
973 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
974 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
975 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
976 main.hostsData[ host ][ 'location' ] = \
977 hostj[ 'location' ][ 'elementId' ] + '/' + \
978 hostj[ 'location' ][ 'port' ]
979 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
980
981 main.log.info( "Deactivating reactive forwarding app " )
982 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
983 if activateResult and deactivateResult and main.hostsData:
984 main.log.info( "Successfully used fwd app to discover hosts " )
985 getDataResult = main.TRUE
986 else:
987 main.log.info( "Failed to use fwd app to discover hosts " )
988 getDataResult = main.FALSE
989
990 print main.hostsData
991
992 return getDataResult
993
994def checkTopology( main, expectedLink ):
995 statusResult = main.TRUE
996 # Check onos topology
997 main.log.info( itemName + ": Checking ONOS topology " )
998
999 for i in range( main.numCtrls ):
1000 topologyResult = main.CLIs[ i ].topology()
1001 statusResult = main.ONOSbench.checkStatus( topologyResult,
1002 main.numSwitch,
1003 expectedLink )\
1004 and statusResult
1005 if not statusResult:
1006 main.log.error( itemName + ": Topology mismatch" )
1007 else:
1008 main.log.info( itemName + ": Topology match" )
1009 return statusResult
1010
1011def checkIntentState( main, intentsId ):
1012 """
1013 This function will check intent state to make sure all the intents
1014 are in INSTALLED state
1015 """
1016
1017 intentResult = main.TRUE
1018 results = []
1019
1020 main.log.info( itemName + ": Checking intents state" )
1021 # First check of intents
1022 for i in range( main.numCtrls ):
1023 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1024 results.append( tempResult )
1025
1026 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1027
1028 if all( result == main.TRUE for result in results ):
1029 main.log.info( itemName + ": Intents are installed correctly" )
1030 else:
1031 # Wait for at least 5 second before checking the intents again
1032 time.sleep( 5 )
1033 results = []
1034 # Second check of intents since some of the intents may be in
1035 # INSTALLING state, they should be in INSTALLED at this time
1036 for i in range( main.numCtrls ):
1037 tempResult = main.CLIs[ i ].checkIntentState(
1038 intentsId=intentsId )
1039 results.append( tempResult )
1040 if all( result == main.TRUE for result in results ):
1041 main.log.info( itemName + ": Intents are installed correctly" )
1042 else:
1043 main.log.error( itemName + ": Intents are NOT installed correctly" )
1044 intentResult = main.FALSE
1045
1046 return intentResult
1047
1048def checkFlowsState( main ):
1049
1050 main.log.info( itemName + ": Check flows state" )
1051 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1052 return checkFlowsResult
1053
1054def link( main, sw1, sw2, option):
1055
1056 # link down
1057 main.log.info( itemName + ": Bring link " + option + "between " +
1058 sw1 + " and " + sw2 )
1059 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1060 return linkResult
1061
1062def removeAllIntents( main, intentsId ):
1063 """
1064 Remove all intents in the intentsId
1065 """
1066
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001067 onosSummary = []
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001068 removeIntentResult = main.TRUE
1069 # Remove intents
1070 for intent in intentsId:
1071 main.CLIs[ 0 ].removeIntent( intentId=intent, purge=True )
1072
1073 time.sleep( 5 )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001074
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001075 # If there is remianing intents then remove intents should fail
1076 for i in range( main.numCtrls ):
1077 onosSummary.append( json.loads( main.CLIs[ i ].summary() ) )
1078
1079 for summary in onosSummary:
1080 if summary.get( 'intents' ) != 0:
1081 main.log.warn( itemName + ": There are " +
1082 str( summary.get( 'intents' ) ) +
1083 " intents remaining in node " +
1084 str( summary.get( 'node' ) ) +
1085 ", failed to remove all the intents " )
1086 removeIntentResult = main.FALSE
1087
1088 if removeIntentResult:
1089 main.log.info( itemName + ": There are no more intents remaining, " +
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001090 "successfully removed all the intents." )
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001091
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001092 return removeIntentResult
1093
1094def checkFlowsCount( main ):
1095 """
1096 Check flows count in each node
1097 """
1098
1099 flowsCount = []
1100 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1101 for i in range( main.numCtrls ):
1102 summaryResult = main.CLIs[ i ].summary()
1103 if not summaryResult:
1104 main.log.error( itemName + ": There is something wrong with " +
1105 "summary command" )
1106 return main.FALSE
1107 else:
1108 summaryJson = json.loads( summaryResult )
1109 flowsCount.append( summaryJson.get( 'flows' ) )
1110
1111 if flowsCount:
1112 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1113 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1114 " flows in all ONOS node" )
1115 else:
1116 for i in range( main.numCtrls ):
1117 main.log.debug( itemName + ": ONOS node " + str( i ) + " has " +
1118 flowsCount[ i ] + " flows" )
1119 else:
1120 main.log.error( "Checking flows count failed, check summary command" )
1121 return main.FALSE
1122
1123 return main.TRUE
1124
acsmarse6b410f2015-07-17 14:39:34 -07001125def checkLeaderChange( leaders1 , leaders2 ):
1126 """
1127 Checks for a change in intent partition leadership.
1128
1129 Takes the output of leaders -c in json string format before and after
1130 a potential change as input
1131
1132 Returns main.TRUE if no mismatches are detected
1133 Returns main.FALSE if there is a mismatch or on error loading the input
1134 """
1135 try:
1136 leaders1 = json.loads( leaders1 )
1137 leaders2 = json.loads( leaders2 )
1138 except ( AttributeError, TypeError):
1139 main.log.exception( self.name + ": Object not as expected" )
1140 return main.FALSE
1141 except Exception:
1142 main.log.exception( self.name + ": Uncaught exception!" )
1143 main.cleanup()
1144 main.exit()
1145 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1146 mismatch = False
1147 for dict1 in leaders1:
1148 if "intent" in dict1.get( "topic", [] ):
1149 for dict2 in leaders2:
1150 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1151 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1152 mismatch = True
1153 main.log.error( "{0} changed leader from {1} to {2}".\
1154 format( dict1.get( "topic", "no-topic" ),\
1155 dict1.get( "leader", "no-leader" ),\
1156 dict2.get( "leader", "no-leader" ) ) )
1157 if mismatch:
1158 return main.FALSE
1159 else:
1160 return main.TRUE