2525from marvin .lib .common import *
2626from nose .plugins .attrib import attr
2727
28+ import time
2829import logging
2930
3031class Services :
@@ -231,9 +232,9 @@ def test_01_vpc_privategw_acl(self):
231232 vpc_off .update (self .apiclient , state = 'Enabled' )
232233
233234 vpc = self .createVPC (vpc_off )
234-
235+
235236 self .cleanup = [vpc , vpc_off , self .account ]
236-
237+
237238 physical_networks = get_physical_networks (self .apiclient , self .zone .id )
238239 if not physical_networks :
239240 self .fail ("No Physical Networks found!" )
@@ -317,7 +318,7 @@ def performVPCTests(self, vpc_off, restart_with_cleanup = False):
317318
318319 self .cleanup .insert (0 , vm1 )
319320 self .cleanup .insert (0 , vm2 )
320-
321+
321322 acl1 = self .createACL (vpc_1 )
322323 self .createACLItem (acl1 .id , cidr = "0.0.0.0/0" )
323324 privateGw_1 = self .createPvtGw (vpc_1 , "10.0.3.100" , "10.0.3.101" , acl1 .id , vlan_1 )
@@ -340,19 +341,17 @@ def performVPCTests(self, vpc_off, restart_with_cleanup = False):
340341 nat_rule_1 = self .create_natrule (vpc_1 , vm1 , public_ip_1 , network_1 )
341342 nat_rule_2 = self .create_natrule (vpc_2 , vm2 , public_ip_2 , network_2 )
342343
343- self .check_pvt_gw_connectivity (vm1 , public_ip_1 , vm2 .nic [0 ].ipaddress )
344- self .check_pvt_gw_connectivity (vm2 , public_ip_2 , vm1 .nic [0 ].ipaddress )
344+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm1 .nic [0 ].ipaddress ])
345345
346346 if restart_with_cleanup :
347347 self .reboot_vpc_with_cleanup (vpc_1 , True )
348348 self .reboot_vpc_with_cleanup (vpc_2 , True )
349349
350- self .check_pvt_gw_connectivity (vm1 , public_ip_1 , vm2 .nic [0 ].ipaddress )
351- self .check_pvt_gw_connectivity (vm2 , public_ip_2 , vm1 .nic [0 ].ipaddress )
350+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm1 .nic [0 ].ipaddress ])
352351
353352 def performPrivateGWInterfaceTests (self , vpc_off ):
354353 self .logger .debug ("Creating VPCs with offering ID %s" % vpc_off .id )
355- vpc_1 = self .createVPC (vpc_off , cidr = '10.0.1 .0/24 ' )
354+ vpc_1 = self .createVPC (vpc_off , cidr = '10.0.0 .0/16 ' )
356355
357356 self .cleanup = [vpc_1 , vpc_off , self .account ]
358357
@@ -363,85 +362,81 @@ def performPrivateGWInterfaceTests(self, vpc_off):
363362 vlans = physical_networks [0 ].vlan .split ('-' )
364363 vlan_1 = int (vlans [0 ])
365364
366- network_1 = self .createNetwork (vpc_1 , gateway = '10.0.1.1' )
365+ net_offering_no_lb = "network_offering_no_lb"
366+
367+ network_1 = self .createNetwork (vpc_1 , gateway = '10.0.0.1' )
368+ network_2 = self .createNetwork (vpc_1 , net_offering = net_offering_no_lb , gateway = '10.0.1.1' )
369+ network_3 = self .createNetwork (vpc_1 , net_offering = net_offering_no_lb , gateway = '10.0.2.1' )
370+ network_4 = self .createNetwork (vpc_1 , net_offering = net_offering_no_lb , gateway = '10.0.3.1' )
367371
368372 vm1 = self .createVM (network_1 )
373+ vm2 = self .createVM (network_2 )
374+ vm3 = self .createVM (network_3 )
375+ vm4 = self .createVM (network_4 )
369376
370377 self .cleanup .insert (0 , vm1 )
371-
378+ self .cleanup .insert (0 , vm2 )
379+ self .cleanup .insert (0 , vm3 )
380+ self .cleanup .insert (0 , vm4 )
381+
372382 acl1 = self .createACL (vpc_1 )
373383 self .createACLItem (acl1 .id , cidr = "0.0.0.0/0" )
374- privateGw_1 = self .createPvtGw (vpc_1 , "10.0.3. 100" , "10.0.3 .101" , acl1 .id , vlan_1 )
384+ privateGw_1 = self .createPvtGw (vpc_1 , "10.1.0. 100" , "10.1.0 .101" , acl1 .id , vlan_1 )
375385 self .replacePvtGwACL (acl1 .id , privateGw_1 .id )
376386
377387 self .replaceNetworkAcl (acl1 .id , network_1 )
378-
379- staticRoute_1 = self .createStaticRoute (privateGw_1 .id , cidr = '10.0.2.0/24' )
388+ self .replaceNetworkAcl (acl1 .id , network_2 )
389+ self .replaceNetworkAcl (acl1 .id , network_3 )
390+ self .replaceNetworkAcl (acl1 .id , network_4 )
380391
381392 public_ip_1 = self .acquire_publicip (vpc_1 , network_1 )
382-
383393 nat_rule_1 = self .create_natrule (vpc_1 , vm1 , public_ip_1 , network_1 )
384394
385395 routers = list_routers (self .apiclient ,
386- account = self .account .name ,
387- domainid = self .account .domainid )
388-
396+ account = self .account .name ,
397+ domainid = self .account .domainid )
398+
389399 self .assertEqual (isinstance (routers , list ), True ,
390400 "Check for list routers response return valid data" )
391401
392402 self .assertEqual (len (routers ), 2 ,
393403 "Check for list routers size returned '%s' instead of 2" % len (routers ))
394404
395- state_holder = {routers [0 ].linklocalip : {"state" : None , "mac" : None },
396- routers [1 ].linklocalip : {"state" : None , "mac" : None }}
397- state = None
398- mac = None
399- for router in routers :
400- if router .isredundantrouter and router .vpcid :
401- hosts = list_hosts (
402- self .apiclient ,
403- id = router .hostid )
404- self .assertEqual (
405- isinstance (hosts , list ),
406- True ,
407- "Check for list hosts response return valid data" )
405+ self .check_private_gateway_interfaces (routers )
408406
409- host = hosts [0 ]
410- host .user = self .services ["configurableData" ]["host" ]["username" ]
411- host .passwd = self .services ["configurableData" ]["host" ]["password" ]
412- host .port = self .services ["configurableData" ]["host" ]["port" ]
413-
414- try :
415- state = get_process_status (
416- host .ipaddress ,
417- host .port ,
418- host .user ,
419- host .passwd ,
420- router .linklocalip ,
421- "ip addr | grep eth3 | grep state | awk '{print $9;}'" )
422-
423- mac = get_process_status (
424- host .ipaddress ,
425- host .port ,
426- host .user ,
427- host .passwd ,
428- router .linklocalip ,
429- "ip addr | grep link/ether | awk '{print $2;}' | sed -n 4p" )
430- except KeyError :
431- self .skipTest (
432- "Provide a marvin config file with host\
433- credentials to run %s" %
434- self ._testMethodName )
435-
436- self .logger .debug ("Result from the Router on IP '%s' is -> state: '%s', mac: '%s'" % (router .linklocalip , state , mac ))
437- state_holder [router .linklocalip ]["state" ] = str (state )
438- state_holder [router .linklocalip ]["mac" ] = str (mac )
407+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm3 .nic [0 ].ipaddress , vm4 .nic [0 ].ipaddress ])
439408
440- check_state = state_holder [routers [0 ].linklocalip ]["state" ].count (state_holder [routers [1 ].linklocalip ]["state" ])
441- check_mac = state_holder [routers [0 ].linklocalip ]["mac" ].count (state_holder [routers [1 ].linklocalip ]["mac" ])
409+ self .reboot_vpc_with_cleanup (vpc_1 , True )
442410
443- self .assertTrue (check_state == 0 , "Routers private gateway interface should not be on the same state!" )
444- self .assertTrue (check_mac == 0 , "Routers private gateway interface should not have the same mac address!" )
411+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm3 .nic [0 ].ipaddress , vm4 .nic [0 ].ipaddress ])
412+
413+ self .stop_router_by_type (routers , status_to_check = "MASTER" )
414+ self .check_routers_state (routers )
415+
416+ self .check_private_gateway_interfaces (routers )
417+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm3 .nic [0 ].ipaddress , vm4 .nic [0 ].ipaddress ])
418+
419+ self .start_routers (routers )
420+ self .check_routers_state (routers )
421+ self .check_private_gateway_interfaces (routers )
422+ self .check_pvt_gw_connectivity (vm1 , public_ip_1 , [vm2 .nic [0 ].ipaddress , vm3 .nic [0 ].ipaddress , vm4 .nic [0 ].ipaddress ])
423+
424+ def stop_router_by_type (self , type , routers ):
425+ self .logger .debug ('Stopping %s router' % type )
426+ for router in routers :
427+ if router .redundantstate == type :
428+ self .stop_router (router )
429+ break
430+
431+ def start_routers (self , routers ):
432+ self .logger .debug ('Starting stopped routers' )
433+ for router in routers :
434+ self .logger .debug ('Router %s has state %s' % (router .id , router .state ))
435+ if router .state == "Stopped" :
436+ self .logger .debug ('Starting stopped router %s' % router .id )
437+ cmd = startRouter .startRouterCmd ()
438+ cmd .id = router .id
439+ self .apiclient .startRouter (cmd )
445440
446441 def createVPC (self , vpc_offering , cidr = '10.1.1.1/16' ):
447442 try :
@@ -524,10 +519,10 @@ def createACLItem(self, aclId, cidr = "0.0.0.0/0"):
524519 except Exception , e :
525520 self .fail ('Unable to create ACL Item due to %s ' % e )
526521
527- def createNetwork (self , vpc , gateway = '10.1.1.1' ):
522+ def createNetwork (self , vpc , net_offering = "network_offering" , gateway = '10.1.1.1' ):
528523 try :
529524 self .logger .debug ('Create NetworkOffering' )
530- net_offerring = self .services ["network_offering" ]
525+ net_offerring = self .services [net_offering ]
531526 net_offerring ["name" ] = "NET_OFF-%s" % gateway
532527 nw_off = NetworkOffering .create (
533528 self .apiclient ,
@@ -584,7 +579,7 @@ def createPvtGw(self, vpc, ip_address, gateway, aclId, vlan):
584579 self .fail ("Failed to create Private Gateway ==> %s" % e )
585580
586581 self .assertIsNotNone (privateGw .id , "Failed to create ACL." )
587-
582+
588583 return privateGw
589584
590585 def replaceNetworkAcl (self , aclId , network ):
@@ -643,33 +638,36 @@ def create_natrule(self, vpc, virtual_machine, public_ip, network):
643638 traffictype = 'Ingress'
644639 )
645640 self .logger .debug ('nwacl_nat=%s' % nwacl_nat .__dict__ )
646-
641+
647642 return nat_rule
648643
649- def check_pvt_gw_connectivity (self , virtual_machine , public_ip , vm_ip ):
650- ssh_command = "ping -c 3 %s" % vm_ip
644+ def check_pvt_gw_connectivity (self , virtual_machine , public_ip , vms_ips ):
645+ for vm_ip in vms_ips :
646+ ssh_command = "ping -c 3 %s" % vm_ip
651647
652- # Should be able to SSH VM
653- result = 'failed'
654- try :
655- self .logger .debug ("SSH into VM: %s" % public_ip .ipaddress .ipaddress )
656-
657- ssh = virtual_machine .get_ssh_client (ipaddress = public_ip .ipaddress .ipaddress )
648+ # Should be able to SSH VM
649+ result = 'failed'
650+ try :
651+ self .logger .debug ("SSH into VM: %s" % public_ip .ipaddress .ipaddress )
658652
659- self .logger .debug ("Ping to VM inside another VPC" )
660- result = str (ssh .execute (ssh_command ))
653+ ssh = virtual_machine .get_ssh_client (ipaddress = public_ip .ipaddress .ipaddress )
661654
662- self .logger .debug ("SSH result: %s; COUNT is ==> %s" % (result , result .count ("3 packets received" )))
663- except Exception as e :
664- self .fail ("SSH Access failed for %s: %s" % \
665- (vmObj .get_ip (), e )
666- )
655+ self .logger .debug ("Ping to VM inside another Network Tier" )
656+ result = str (ssh .execute (ssh_command ))
667657
668- self .assertEqual (
669- result .count ("3 packets received" ),
670- 1 ,
671- "Ping to outside world from VM should be successful"
672- )
658+ self .logger .debug ("SSH result: %s; COUNT is ==> %s" % (result , result .count ("3 packets received" )))
659+ except Exception as e :
660+ self .fail ("SSH Access failed for %s: %s" % \
661+ (vmObj .get_ip (), e )
662+ )
663+
664+ self .assertEqual (
665+ result .count ("3 packets received" ),
666+ 1 ,
667+ "Ping to VM on Network Tier N from VM in Network Tier A should be successful"
668+ )
669+
670+ time .sleep (5 )
673671
674672 def reboot_vpc_with_cleanup (self , vpc , cleanup = True ):
675673 self .logger .debug ("Restarting VPC %s with cleanup" % vpc .id )
@@ -680,3 +678,105 @@ def reboot_vpc_with_cleanup(self, vpc, cleanup = True):
680678 cmd .cleanup = cleanup
681679 cmd .makeredundant = False
682680 self .api_client .restartVPC (cmd )
681+
682+ def check_private_gateway_interfaces (self , routers ):
683+ state_holder = {routers [0 ].linklocalip : {"state" : None , "mac" : None },
684+ routers [1 ].linklocalip : {"state" : None , "mac" : None }}
685+ state = None
686+ mac = None
687+ for router in routers :
688+ hosts = list_hosts (self .apiclient , id = router .hostid )
689+
690+ self .assertEqual (
691+ isinstance (hosts , list ),
692+ True ,
693+ "Check for list hosts response return valid data" )
694+
695+ host = hosts [0 ]
696+ host .user = self .services ["configurableData" ]["host" ]["username" ]
697+ host .passwd = self .services ["configurableData" ]["host" ]["password" ]
698+ host .port = self .services ["configurableData" ]["host" ]["port" ]
699+
700+ try :
701+ state = get_process_status (
702+ host .ipaddress ,
703+ host .port ,
704+ host .user ,
705+ host .passwd ,
706+ router .linklocalip ,
707+ "ip addr | grep eth6 | grep state | awk '{print $9;}'" )
708+
709+ mac = get_process_status (
710+ host .ipaddress ,
711+ host .port ,
712+ host .user ,
713+ host .passwd ,
714+ router .linklocalip ,
715+ "ip addr | grep link/ether | awk '{print $2;}' | sed -n 7p" )
716+ except KeyError :
717+ self .skipTest ("Provide a marvin config file with host credentials to run %s" % self ._testMethodName )
718+
719+ self .logger .debug ("Result from the Router on IP '%s' is -> state: '%s', mac: '%s'" % (router .linklocalip , state , mac ))
720+ state_holder [router .linklocalip ]["state" ] = str (state )
721+ state_holder [router .linklocalip ]["mac" ] = str (mac )
722+
723+ check_state = state_holder [routers [0 ].linklocalip ]["state" ].count (state_holder [routers [1 ].linklocalip ]["state" ])
724+ check_mac = state_holder [routers [0 ].linklocalip ]["mac" ].count (state_holder [routers [1 ].linklocalip ]["mac" ])
725+
726+ self .assertTrue (check_state == 0 , "Routers private gateway interface should not be on the same state!" )
727+ self .assertTrue (check_mac == 0 , "Routers private gateway interface should not have the same mac address!" )
728+
729+ def check_routers_state (self , routers , status_to_check = "MASTER" , expected_count = 1 ):
730+ vals = ["MASTER" , "BACKUP" , "UNKNOWN" ]
731+ cnts = [0 , 0 , 0 ]
732+
733+ result = "UNKNOWN"
734+ for router in routers :
735+ if router .state == "Running" :
736+ hosts = list_hosts (
737+ self .apiclient ,
738+ zoneid = router .zoneid ,
739+ type = 'Routing' ,
740+ state = 'Up' ,
741+ id = router .hostid
742+ )
743+ self .assertEqual (
744+ isinstance (hosts , list ),
745+ True ,
746+ "Check list host returns a valid list"
747+ )
748+ host = hosts [0 ]
749+
750+ if self .hypervisor .lower () in ('vmware' , 'hyperv' ):
751+ result = str (get_process_status (
752+ self .apiclient .connection .mgtSvr ,
753+ 22 ,
754+ self .apiclient .connection .user ,
755+ self .apiclient .connection .passwd ,
756+ router .linklocalip ,
757+ "sh /opt/cloud/bin/checkrouter.sh " ,
758+ hypervisor = self .hypervisor
759+ ))
760+ else :
761+ try :
762+ host .user , host .passwd = get_host_credentials (
763+ self .config , host .ipaddress )
764+ result = str (get_process_status (
765+ host .ipaddress ,
766+ 22 ,
767+ host .user ,
768+ host .passwd ,
769+ router .linklocalip ,
770+ "sh /opt/cloud/bin/checkrouter.sh "
771+ ))
772+
773+ except KeyError :
774+ self .skipTest (
775+ "Marvin configuration has no host credentials to\
776+ check router services" )
777+
778+ if result .count (status_to_check ) == 1 :
779+ cnts [vals .index (status_to_check )] += 1
780+
781+ if cnts [vals .index (status_to_check )] != expected_count :
782+ self .fail ("Expected '%s' routers at state '%s', but found '%s'!" % (expected_count , status_to_check , cnts [vals .index (status_to_check )]))
0 commit comments