From ca1b911a4f1fba55a39322bce3eec009bf4b6269 Mon Sep 17 00:00:00 2001 From: Ashutosh K Date: Tue, 11 Mar 2014 04:05:39 -0400 Subject: [PATCH] CLOUDSTACK-2266: Adding automation tests for IP reservation feature Signed-off-by: SrikanteswaraRao Talluri --- .../component/test_ip_reservation.py | 1131 +++++++++++++++-- tools/marvin/marvin/codes.py | 5 + tools/marvin/marvin/config/config.cfg | 29 + tools/marvin/marvin/integration/lib/common.py | 41 +- tools/marvin/marvin/integration/lib/utils.py | 24 +- 5 files changed, 1086 insertions(+), 144 deletions(-) mode change 100755 => 100644 test/integration/component/test_ip_reservation.py diff --git a/test/integration/component/test_ip_reservation.py b/test/integration/component/test_ip_reservation.py old mode 100755 new mode 100644 index f0001cf0891..46b4edb75be --- a/test/integration/component/test_ip_reservation.py +++ b/test/integration/component/test_ip_reservation.py @@ -15,134 +15,127 @@ # specific language governing permissions and limitations # under the License. """ Tests for IP reservation feature + + Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/IP+Range+Reservation+within+a+Network+Test+Cases + + Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-2266 + + Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/FS+-+IP+Range+Reservation+within+a+Network """ -import marvin -from marvin.cloudstackTestCase import * -from marvin.cloudstackAPI import * -from marvin.cloudstackException import cloudstackAPIException -from marvin.integration.lib.utils import * -from marvin.integration.lib.base import * -from marvin.integration.lib.common import * +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.integration.lib.utils import (cleanup_resources, + validateList, + verifyRouterState) +from marvin.integration.lib.base import (Network, + Account, + ServiceOffering, + VirtualMachine, + Router, + NetworkOffering, + VpcOffering, + VPC) +from marvin.integration.lib.common import (get_domain, + get_zone, + get_template, + createEnabledNetworkOffering, + get_free_vlan, + wait_for_cleanup, + createNetworkRulesForVM) +from marvin.codes import (PASS, + NAT_RULE, + STATIC_NAT_RULE, + FAIL, + UNKNOWN, + FAULT, + MASTER) import netaddr +import random from nose.plugins.attrib import attr +from ddt import ddt, data -class Services(object): - """Test IP Reservation - """ - def __init__(self): - self.services = { - "account": { - "email": "test@test.com", - "firstname": "Test", - "lastname": "User", - "username": "test", - # Random characters are appended for unique - # username - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance ", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 200, # in MHz - "memory": 256, # In MBs - }, - "isolated_network_offering": { - "name": 'Network offering for Isolated Network', - "displaytext": 'Network offering-DA services', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'VirtualRouter', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "isolated_persistent_network_offering": { - "name": 'Network offering for Isolated Network', - "displaytext": 'Network offering-DA services', - "guestiptype": 'Isolated', - "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Firewall,Lb,UserData,StaticNat', - "traffictype": 'GUEST', - "availability": 'Optional', - "ispersistent": 'True', - "serviceProviderList": { - "Dhcp": 'VirtualRouter', - "Dns": 'VirtualRouter', - "SourceNat": 'VirtualRouter', - "PortForwarding": 'VirtualRouter', - "Vpn": 'VirtualRouter', - "Firewall": 'VirtualRouter', - "Lb": 'VirtualRouter', - "UserData": 'VirtualRouter', - "StaticNat": 'VirtualRouter', - }, - }, - "isolated_network": { - "name": "Isolated Network", - "displaytext": "Isolated Network", - "netmask": "255.255.255.0", - "gateway": "10.1.1.1" - }, - # update CIDR according to netmask and gateway in isolated_network - "isolated_network_cidr": "10.1.1.0/24", - "virtual_machine": { - "displayname": "Test VM", - }, - "ostype": 'CentOS 5.3 (64-bit)', - # Cent OS 5.3 (64 bit) - "sleep": 90, - "timeout": 10, - "mode": 'advanced' - } +def createIsolatedNetwork(self, network_offering_id, gateway=None): + """Create isolated network with given network offering and gateway if provided + and return""" + try: + isolated_network = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=network_offering_id,accountid=self.account.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0' if gateway else None) + except Exception as e: + return [FAIL, e] + return [PASS, isolated_network] +def matchNetworkGuestVmCIDR(self, networkid, guestvmcidr): + """List networks with given network id and check if the guestvmcidr matches + with the given cidr""" + networks = Network.list(self.apiclient, id=networkid, listall=True) + self.assertEqual(validateList(networks)[0], PASS, "network list validation failed") + self.assertEqual(str(networks[0].cidr), guestvmcidr, "guestvmcidr of network %s \ + does not match with the given value %s" % (networks[0].cidr, guestvmcidr)) + + return + +def createVirtualMachine(self, network_id=None, ip_address=None): + """Create and return virtual machine within network and ipaddress""" + virtual_machine = VirtualMachine.create(self.apiclient, + self.testData["virtual_machine"], + networkids=network_id, + serviceofferingid=self.service_offering.id, + accountid=self.account.name, + domainid=self.domain.id, + ipaddress=ip_address) + return virtual_machine + +def CreateEnabledNetworkOffering(apiclient, networkServices): + """Create network offering of given test data and enable it""" + + result = createEnabledNetworkOffering(apiclient, networkServices) + assert result[0] == PASS, "Network offering creation/enabling failed due to %s" % result[2] + return result[1] + +@ddt class TestIpReservation(cloudstackTestCase): """Test IP Range Reservation with a Network """ @classmethod def setUpClass(cls): - cls.api_client = super(TestIpReservation, cls).getClsTestClient().getApiClient() - cls.services = Services().services + cloudstackTestClient = super(TestIpReservation, cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill test data from the external config file + cls.testData = cloudstackTestClient.getConfigParser().parsedDict # Get Zone, Domain and templates - cls.domain = get_domain(cls.api_client, cls.services) - cls.zone = get_zone(cls.api_client, cls.services) + cls.domain = get_domain(cls.api_client, cls.testData) + cls.zone = get_zone(cls.api_client, cls.testData) cls.template = get_template( cls.api_client, cls.zone.id, - cls.services["ostype"] + cls.testData["ostype"] ) - cls.services["domainid"] = cls.domain.id - cls.services["zoneid"] = cls.zone.id - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - cls.services["account"] = cls.account.name - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( cls.api_client, - cls.services["service_offering"] + cls.testData["service_offering"] ) - cls.isolated_network_offering = cls.create_isolated_network_offering("isolated_network_offering") - cls.isolated_persistent_network_offering = cls.create_isolated_network_offering("isolated_persistent_network_offering") - cls.isolated_network = cls.create_isolated_network(cls.isolated_network_offering.id) - cls.isolated_persistent_network = cls.create_isolated_network(cls.isolated_persistent_network_offering.id) - # network will be deleted as part of account cleanup - cls._cleanup = [ - cls.account, cls.service_offering, cls.isolated_network_offering, cls.isolated_persistent_network_offering, - ] + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + cls.isolated_network_offering_RVR = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_RVR"]) + cls._cleanup.append(cls.isolated_network_offering_RVR) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) return @classmethod @@ -154,44 +147,902 @@ class TestIpReservation(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced"]) + def test_vm_create_after_reservation(self): + """ Test creating VM in network after IP reservation + # steps + # 1. Create vm in isolated network (LB through VR or Netscaler) with ip in guestvmcidr + # 2. Update guestvmcidr + # 3. Create another VM + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr""" + + networkOffering = self.isolated_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet +".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address = subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + + @attr(tags=["advanced"]) + def test_vm_create_outside_cidr_after_reservation(self): + """ Test create VM outside the range of reserved IPs + # steps + # 1. update guestvmcidr of persistent isolated network (LB through VR or + # Netscaler + # 2. create another VM with ip outside guestvmcidr + """ + # validation + # 1. guest vm cidr should be successfully updated with correct value + # 2 newly created VM should not be created and result in exception + + networkOffering = self.isolated_persistent_network_offering + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, networkOffering.id, gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + try: + createVirtualMachine(self, network_id=self.isolated_network.id, + ip_address=subnet+".9") + self.fail("vm should not be created ") + except Exception as e: + self.debug("exception as IP is outside of guestvmcidr %s" % e) + return + + @attr(tags=["advanced"]) + def test_update_cidr_multiple_vms_not_all_inclusive(self): + """ Test reserve IP range such that one of the VM is not included + # steps + # 1. Create two vms in isolated network + # 2. Update guestvmcidr of network such that only one of the ipaddress of vms + # is in the given range + # validation + # 1. Network updation with this new range should fail""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".9") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + with self.assertRaises(Exception): + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + return + + @attr(tags=["advanced"]) + def test_update_cidr_single_vm_not_inclusive(self): + """ Test reserving IP range in network such that existing VM is outside the range + # steps + # 1. Create vm in isolated network + # 2. Update guestvmcidr of network such that ip address of vm + # is outside the given range + # + # validation + # 1. Network updation with this new range should fail""" + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".9") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + with self.assertRaises(Exception): + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + return + + @data(NAT_RULE, STATIC_NAT_RULE) + @attr(tags=["advanced"]) + def test_nat_rules(self, value): + """ Test NAT rules working with IP reservation + # steps + # 1. Create vm in persistent isolated network with ip in guestvmcidr + # 2. Create NAT/static NAT rule for this VM + # 3. Update guestvmcidr + # 4. Create another VM and create network rules for this vm too + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr + # 4. The network rules should be working""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network = resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + result = createNetworkRulesForVM(self.apiclient, virtual_machine_1,value, + self.account, self.testData) + if result[0] == FAIL: + self.fail("Failed to create network rules for VM: %s" % result[1]) + else: + ipaddress_1 = result[1] + virtual_machine_1.get_ssh_client(ipaddress=ipaddress_1.ipaddress.ipaddress) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + result = createNetworkRulesForVM(self.apiclient, virtual_machine_2, value, + self.account, self.testData) + if result[0] == FAIL: + self.fail("Failed to create network rules for VM: %s" % result[1]) + else: + ipaddress_2 = result[1] + virtual_machine_2.get_ssh_client(ipaddress=ipaddress_2.ipaddress.ipaddress) + return + + @unittest.skip("Skip - WIP") + @attr(tags=["advanced"]) + def test_RVR_network(self): + """ Test IP reservation in network with RVR + # steps + # 1. create vm in isolated network with RVR and ip in guestvmcidr + # 2. update guestvmcidr + # 3. List routers and stop the master router, wait till backup router comes up + # 4. create another VM + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr + # 4. Verify that the network has two routers associated with it + # 5. Backup router should come up when master router is stopped""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering_RVR.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network_RVR= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network_RVR.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_RVR.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_RVR.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + self.debug("Listing routers for network: %s" % isolated_network_RVR.name) + routers = Router.list(self.apiclient, networkid=isolated_network_RVR.id, listall=True) + self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed") + self.assertEqual(len(routers), 2, "Length of the list router should be 2 (Backup & master)") + + if routers[0].redundantstate == MASTER: + master_router = routers[0] + backup_router = routers[1] + else: + master_router = routers[1] + backup_router = routers[0] + + self.debug("Stopping router ID: %s" % master_router.id) + + try: + Router.stop(self.apiclient, id=master_router.id) + except Exception as e: + self.fail("Failed to stop master router due to error %s" % e) + + # wait for VR to update state + wait_for_cleanup(self.apiclient, ["router.check.interval"]) + + result = verifyRouterState(master_router.id, [UNKNOWN,FAULT]) + if result[0] == FAIL: + self.fail(result[1]) + result = verifyRouterState(backup_router.id, [MASTER]) + if result[0] == FAIL: + self.fail(result[1]) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network_RVR.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + + @attr(tags=["advanced"]) + def test_ip_reservation_in_multiple_networks_same_account(self): + """ Test IP reservation in multiple networks created in same account + # steps + # 1. Create two isolated networks with user defined cidr in same account + # Test below conditions for both the networks in the account + # 2. Create vm in persistent isolated network with ip in guestvmcidr + # 3. Update guestvmcidr + # 4. Create another VM + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Newly created VM should get ip in guestvmcidr""" + + account_1 = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(account_1) + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + isolated_network_1 = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=self.isolated_network_offering.id,accountid=account_1.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0') + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_1 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id, + ipaddress="10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_1.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_1.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_2 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_1.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + isolated_network_2 = Network.create(self.apiclient, self.testData["isolated_network"], + networkofferingid=self.isolated_network_offering.id,accountid=account_1.name, + domainid=self.domain.id,zoneid=self.zone.id, + gateway=gateway, netmask='255.255.255.0') + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_3 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id, + ipaddress="10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network_2.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network_2.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_3.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_3.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_4 = VirtualMachine.create(self.apiclient, self.testData["virtual_machine"], + networkids=isolated_network_2.id, serviceofferingid=self.service_offering.id, + accountid=account_1.name, domainid=self.domain.id) + if netaddr.IPAddress(virtual_machine_4.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestRestartNetwork(cloudstackTestCase): + """Test Restart Network + """ @classmethod - def create_isolated_network_offering(cls, network_offering): - isolated_network_offering = NetworkOffering.create( - cls.api_client, - cls.services[network_offering], - conservemode=False - ) - # Update network offering state from disabled to enabled. - network_offering_update_response = NetworkOffering.update( - isolated_network_offering, - cls.api_client, - id=isolated_network_offering.id, - state="enabled" - ) - return isolated_network_offering + def setUpClass(cls): + cloudstackTestClient = super(TestRestartNetwork, cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill test data from the external config file + cls.testData = cloudstackTestClient.getConfigParser().parsedDict + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.testData) + cls.zone = get_zone(cls.api_client, cls.testData) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + return @classmethod - def create_isolated_network(cls, network_offering_id): - isolated_network = Network.create( - cls.api_client, - cls.services["isolated_network"], - networkofferingid=network_offering_id, - accountid=cls.account.name, - domainid=cls.domain.id, - zoneid=cls.zone.id - ) - cls.debug("isolated network is created: " + isolated_network.id) - return isolated_network - - + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() - self.cleanup = [ ] - update_response = Network.update(self.isolated_persistent_network, self.apiclient, id=self.isolated_persistent_network.id, guestvmcidr=self.services["isolated_network_cidr"]) - if self.services["isolated_network_cidr"] <> update_response.cidr: - raise Exception("problem in updating cidr for test setup") + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data(True, False) + @attr(tags=["advanced"]) + def test_restart_network_with_cleanup(self, value): + """ Test IP reservation rules with network restart operation + # steps + # 1. Create vm in isolated network with ip in guestvmcidr + # 2. Update guestvmcidr + # 3. Restart network with cleanup True/False + # 4. Deploy another VM in the network + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Existing guest vm ip should not be changed after reservation + # 3. Network should be restarted successfully with and without cleanup + # 4. Newly created VM should get ip in guestvmcidr""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + #Restart Network + isolated_network.restart(self.apiclient, cleanup=value) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestUpdateIPReservation(cloudstackTestCase): + """Test Updating IP reservation multiple times + """ + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestUpdateIPReservation, cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill test data from the external config file + cls.testData = cloudstackTestClient.getConfigParser().parsedDict + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.testData) + cls.zone = get_zone(cls.api_client, cls.testData) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @data("existingVmInclusive", "existingVmExclusive") + @attr(tags=["advanced"]) + def test_update_network_guestvmcidr(self, value): + """ Test updating guest vm cidr of the network after + VMs are already deployed in previous guest VM cidr + + # steps + # 1. Create isolated network with user defined cidr + # 2. Deploy VM in the network + # 3. Try to update the guestvmcidr of the network with VM ip in the guestvmcidr and + # deploy another VM + # 4. Try to update the guestvmcidr of the network with VM ip outside the guestvmcidr + # + # validation + # 1. When vm IP is in the guestvmcidr, updation should be successful and + # new VM should get IP from this range + # 2. When VM IP is outside the guestvmcidr, updation should be unsuccessful""" + + random_subnet = str(random.randrange(1,254)) + gateway = "10.1." + random_subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = "10.1."+random_subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=u"10.1."+random_subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + + # Update guest vm cidr of network again + if value == "existingVmExclusive": + guest_vm_cidr = "10.1."+random_subnet+".10/29" + + try: + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + self.fail("Network updation should fail") + except Exception as e: + self.debug("Failed to update guest VM cidr of network: %s" % e) + elif value == "existingVmInclusive": + guest_vm_cidr = "10.1."+random_subnet+".0/28" + + try: + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + except Exception as e: + self.fail("Failed to update guest VM cidr of network: %s" % e) + + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + + try: + virtual_machine_3 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_3.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestRouterOperations(cloudstackTestCase): + """Test Router operations of network with IP reservation + """ + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestRouterOperations, cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill test data from the external config file + cls.testData = cloudstackTestClient.getConfigParser().parsedDict + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.testData) + cls.zone = get_zone(cls.api_client, cls.testData) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) + return + + def tearDown(self): + try: + # Clean up, terminate the resources created + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + @attr(tags=["advanced"]) + def test_reservation_after_router_restart(self): + """ Test IP reservation working before and after router is restarted + # steps + # 1. Update guestvmcidr of persistent isolated network + # 2. Reboot router + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. Network cidr should remain same after router restart""" + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_persistent_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + + routers = Router.list(self.apiclient, + networkid=isolated_network.id, + listall=True) + self.assertEqual(validateList(routers)[0], PASS, "routers list validation failed") + if not routers: + self.fail("Router list should not be empty") + + Router.reboot(self.apiclient, routers[0].id) + networks = Network.list(self.apiclient, id=isolated_network.id) + self.assertEqual(validateList(networks)[0], PASS, "networks list validation failed") + self.assertEqual(networks[0].cidr, guest_vm_cidr, "guestvmcidr should match after router reboot") + return + + @attr(tags=["advanced"]) + def test_destroy_recreate_router(self): + """ Test IP reservation working after destroying and recreating router + # steps + # 1. Create isolated network and deploy VM in it and update network with + # guestvmcidr + # 2. List the router associated with network and destroy the router + # 3. Restart the network + # 3. Deploy another VM in the network + # + # validation + # 1. Guest vm cidr should be successfully updated with correct value + # 2. existing guest vm ip should not be changed after reservation + # 3. Router should be destroyed and recreated when network is restarted + # 4. New VM should be deployed in the guestvmcidr""" + + subnet = "10.1."+str(random.randrange(1,254)) + gateway = subnet +".1" + resultSet = createIsolatedNetwork(self, self.isolated_network_offering.id, + gateway=gateway) + if resultSet[0] == FAIL: + self.fail("Failed to create isolated network") + else: + isolated_network= resultSet[1] + guest_vm_cidr = subnet+".0/29" + + try: + virtual_machine_1 = createVirtualMachine(self, network_id=isolated_network.id, + ip_address=subnet+".3") + except Exception as e: + self.fail("VM creation failed: %s" % e) + + isolated_network.update(self.apiclient, guestvmcidr=guest_vm_cidr) + matchNetworkGuestVmCIDR(self, isolated_network.id, guest_vm_cidr) + vms = VirtualMachine.list(self.apiclient, + id=virtual_machine_1.id) + self.assertEqual(validateList(vms)[0], PASS, "vm list validation failed") + self.assertEqual(vms[0].nic[0].ipaddress, + virtual_machine_1.ipaddress, + "VM IP should not change after reservation") + + # List router and destroy it + routers = Router.list(self.apiclient, networkid=isolated_network.id, listall=True) + self.assertEqual(validateList(routers)[0], PASS, "Routers list validation failed") + + # Destroy Router + result = Router.destroy(self.apiclient, id=routers[0].id) + if result[0] == FAIL: + self.fail("Failed to destroy router: %s" % result[2]) + + #Restart Network + isolated_network.restart(self.apiclient) + + try: + virtual_machine_2 = createVirtualMachine(self, network_id=isolated_network.id) + if netaddr.IPAddress(virtual_machine_2.ipaddress) not in netaddr.IPNetwork(guest_vm_cidr): + self.fail("Newly created VM doesn't get IP from reserverd CIDR") + except Exception as e: + self.fail("VM creation failed, cannot validate the condition: %s" % e) + return + +@ddt +class TestFailureScnarios(cloudstackTestCase): + """Test failure scenarios related to IP reservation in network + """ + @classmethod + def setUpClass(cls): + cloudstackTestClient = super(TestFailureScnarios, cls).getClsTestClient() + cls.api_client = cloudstackTestClient.getApiClient() + # Fill test data from the external config file + cls.testData = cloudstackTestClient.getConfigParser().parsedDict + # Get Zone, Domain and templates + cls.domain = get_domain(cls.api_client, cls.testData) + cls.zone = get_zone(cls.api_client, cls.testData) + cls.template = get_template( + cls.api_client, + cls.zone.id, + cls.testData["ostype"] + ) + cls.testData["domainid"] = cls.domain.id + cls.testData["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["zoneid"] = cls.zone.id + cls.testData["virtual_machine"]["template"] = cls.template.id + cls._cleanup = [] + try: + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.testData["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.isolated_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["isolated_network_offering"]) + cls._cleanup.append(cls.isolated_network_offering) + cls.isolated_persistent_network_offering = CreateEnabledNetworkOffering(cls.api_client, + cls.testData["nw_off_isolated_persistent"]) + cls._cleanup.append(cls.isolated_persistent_network_offering) + + cls.testData["shared_network_offering"]["specifyVlan"] = "True" + cls.testData["shared_network_offering"]["specifyIpRanges"] = "True" + + #Create Network Offering + cls.shared_network_offering = NetworkOffering.create(cls.api_client, + cls.testData["shared_network_offering"], + conservemode=False) + cls._cleanup.append(cls.shared_network_offering) + + #Update network offering state from disabled to enabled. + NetworkOffering.update(cls.shared_network_offering,cls.api_client,state="enabled") + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Failure in setUpClass: %s" % e) + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + raise Exception("Warning: Exception during cleanup : %s" % e) + return + + def setUp(self): + self.apiclient = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + try: + self.account = Account.create(self.apiclient, self.testData["account"], + domainid=self.domain.id) + self.cleanup.append(self.account) + except Exception as e: + self.skipTest("Failed to create account: %s" % e) return def tearDown(self): diff --git a/tools/marvin/marvin/codes.py b/tools/marvin/marvin/codes.py index e4a0f6a789a..92d6cf9d208 100644 --- a/tools/marvin/marvin/codes.py +++ b/tools/marvin/marvin/codes.py @@ -52,3 +52,8 @@ ISOLATED_NETWORK = "ISOLATED" SHARED_NETWORK = "SHARED" VPC_NETWORK = "VPC" ERROR_NO_HOST_FOR_MIGRATION = "Could not find suitable host for migration, please ensure setup has required no. of hosts" +NAT_RULE = "nat rule" +STATIC_NAT_RULE = "static nat rule" +UNKNOWN = "UNKNOWN" +FAULT = "FAULT" +MASTER = "MASTER" diff --git a/tools/marvin/marvin/config/config.cfg b/tools/marvin/marvin/config/config.cfg index dfc426301b9..4a5fd75c63f 100644 --- a/tools/marvin/marvin/config/config.cfg +++ b/tools/marvin/marvin/config/config.cfg @@ -262,6 +262,35 @@ "StaticNat": "VirtualRouter" } }, + "nw_off_isolated_RVR": { + "name": "Network offering-RVR services", + "displaytext": "Network off-RVR services", + "guestiptype": "Isolated", + "supportedservices": "Vpn,Dhcp,Dns,SourceNat,PortForwarding,Firewall,Lb,UserData,StaticNat", + "traffictype": "GUEST", + "availability": "Optional", + "ispersistent": "False", + "serviceProviderList": { + "Vpn": "VirtualRouter", + "Dhcp": "VirtualRouter", + "Dns": "VirtualRouter", + "SourceNat": "VirtualRouter", + "PortForwarding": "VirtualRouter", + "Firewall": "VirtualRouter", + "Lb": "VirtualRouter", + "UserData": "VirtualRouter", + "StaticNat": "VirtualRouter" + }, + "serviceCapabilityList": { + "SourceNat": { + "SupportedSourceNatTypes": "peraccount", + "RedundantRouter": "true" + }, + "lb": { + "SupportedLbIsolation": "dedicated" + } + } + }, "nw_off_persistent_RVR": { "name": "Network offering-RVR services", "displaytext": "Network off-RVR services", diff --git a/tools/marvin/marvin/integration/lib/common.py b/tools/marvin/marvin/integration/lib/common.py index 585a05a5c78..d38773afbbc 100644 --- a/tools/marvin/marvin/integration/lib/common.py +++ b/tools/marvin/marvin/integration/lib/common.py @@ -65,13 +65,17 @@ from marvin.integration.lib.base import (Configurations, Host, PublicIPAddress, NetworkOffering, - Network) + Network, + FireWallRule, + NATRule, + StaticNATRule) from marvin.integration.lib.utils import (get_process_status, xsplit, validateList) from marvin.sshClient import SshClient -from marvin.codes import PASS, ISOLATED_NETWORK, VPC_NETWORK, BASIC_ZONE, FAIL +from marvin.codes import (PASS, ISOLATED_NETWORK, VPC_NETWORK, + BASIC_ZONE, FAIL, NAT_RULE, STATIC_NAT_RULE) import random #Import System modules @@ -994,8 +998,39 @@ def verifyComputeOfferingCreation(apiclient, computeofferingid): serviceOfferings = None try: serviceOfferings = apiclient.listServiceOfferings(cmd) - except Exception as e: + except Exception: return FAIL if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0): return FAIL return PASS + +def createNetworkRulesForVM(apiclient, virtualmachine, ruletype, + account, networkruledata): + """Acquire IP, create Firewall and NAT/StaticNAT rule + (associating it with given vm) for that IP""" + + try: + public_ip = PublicIPAddress.create( + apiclient,accountid=account.name, + zoneid=virtualmachine.zoneid,domainid=account.domainid, + networkid=virtualmachine.nic[0].networkid) + + FireWallRule.create( + apiclient,ipaddressid=public_ip.ipaddress.id, + protocol='TCP', cidrlist=[networkruledata["fwrule"]["cidr"]], + startport=networkruledata["fwrule"]["startport"], + endport=networkruledata["fwrule"]["endport"] + ) + + if ruletype == NAT_RULE: + # Create NAT rule + NATRule.create(apiclient, virtualmachine, + networkruledata["natrule"],ipaddressid=public_ip.ipaddress.id, + networkid=virtualmachine.nic[0].networkid) + elif ruletype == STATIC_NAT_RULE: + # Enable Static NAT for VM + StaticNATRule.enable(apiclient,public_ip.ipaddress.id, + virtualmachine.id, networkid=virtualmachine.nic[0].networkid) + except Exception as e: + [FAIL, e] + return [PASS, public_ip] diff --git a/tools/marvin/marvin/integration/lib/utils.py b/tools/marvin/marvin/integration/lib/utils.py index 709fddebe78..7e11d521be3 100644 --- a/tools/marvin/marvin/integration/lib/utils.py +++ b/tools/marvin/marvin/integration/lib/utils.py @@ -28,7 +28,7 @@ import email import socket import urlparse import datetime -from marvin.cloudstackAPI import cloudstackAPIClient, listHosts +from marvin.cloudstackAPI import cloudstackAPIClient, listHosts, listRouters from marvin.sshClient import SshClient from marvin.codes import (FAIL, PASS, @@ -429,3 +429,25 @@ def verifyElementInList(inp, toverify, responsevar=None, pos=0): else: return [FAIL, MATCH_NOT_FOUND] +def verifyRouterState(apiclient, routerid, allowedstates): + """List the router and verify that its state is in allowed states + @output: List, containing [Result, Reason] + Ist Argument ('Result'): FAIL: If router state is not + in allowed states + PASS: If router state is in + allowed states""" + + try: + cmd = listRouters.listRoutersCmd() + cmd.id = routerid + cmd.listall = True + routers = apiclient.listRouters(cmd) + except Exception as e: + return [FAIL, e] + listvalidationresult = validateList(routers) + if listvalidationresult[0] == FAIL: + return [FAIL, listvalidationresult[2]] + if routers[0].redundantstate not in allowedstates: + return [FAIL, "Redundant state of the router should be in %s but is %s" % + (allowedstates, routers[0].redundantstate)] + return [PASS, None]