Skip to content

Commit 0e91468

Browse files
wilderrodriguesremibergsma
authored andcommitted
CLOUDSTACK-9287 - Add integration test to cover the private gateway related changes
1 parent c41edc1 commit 0e91468

File tree

1 file changed

+188
-88
lines changed

1 file changed

+188
-88
lines changed

test/integration/smoke/test_privategw_acl.py

Lines changed: 188 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from marvin.lib.common import *
2626
from nose.plugins.attrib import attr
2727

28+
import time
2829
import logging
2930

3031
class 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

Comments
 (0)