# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. """ P1 tests for Add Remove Network to VM Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Add+Remove+networks+to+VM+Test+cases Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-645 Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Add+Remove+Networks+to+VMs """ import random import time import unittest from ddt import ddt, data from marvin.cloudstackAPI import (addNicToVirtualMachine, removeNicFromVirtualMachine, updateDefaultNicForVirtualMachine) from marvin.cloudstackTestCase import cloudstackTestCase from marvin.codes import PASS from marvin.lib.base import ( Account, Domain, ServiceOffering, VirtualMachine, NetworkOffering, Network, VpcOffering, VPC, PublicIPAddress, FireWallRule, NATRule ) from marvin.lib.common import (get_domain, get_zone, get_template, list_virtual_machines, list_events, list_zones, get_free_vlan, update_resource_limit, list_nat_rules ) from marvin.lib.utils import (validateList, random_gen, get_hypervisor_type) # Import Local Modules from nose.plugins.attrib import attr class Services: """Test Add Remove Network Services """ def __init__(self): self.services = { "sleep": 60, "ostype": "CentOS 5.3 (64-bit)", # Cent OS 5.3 (64 bit) "isolated_network_offering": { "name": 'Test Isolated Network offering', "displaytext": 'Test Isolated Network offering', "guestiptype": 'Isolated', "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding', "traffictype": 'GUEST', "availability": 'Optional', "serviceProviderList": { "Dhcp": 'VirtualRouter', "Dns": 'VirtualRouter', "SourceNat": 'VirtualRouter', "PortForwarding": 'VirtualRouter', }, }, "shared_network_offering": { "name": 'Test Shared Network Offering', "displaytext": 'Test Shared Network Offering', "guestiptype": 'Shared', "supportedservices": 'Dhcp,Dns,UserData', "specifyVlan": "True", "specifyIpRanges": "True", "traffictype": 'GUEST', "serviceProviderList": { "Dhcp": 'VirtualRouter', "Dns": 'VirtualRouter', "UserData": 'VirtualRouter' }, }, "shared_network": { "name": "Test Shared Network", "displaytext": "Test Shared Network", "gateway": "172.16.17.1", "netmask": "255.255.255.0", "startip": "172.16.17.2", "endip": "172.16.17.20", }, "shared_network_2": { "name": "Test Shared Network", "displaytext": "Test Shared Network", "gateway": "172.16.18.1", "netmask": "255.255.255.0", "startip": "172.16.18.2", "endip": "172.16.18.20", }, "isolated_network": { "name": "Test Isolated Network", "displaytext": "Test Isolated Network", }, "service_offering": { "name": "Tiny Instance", "displaytext": "Tiny Instance", "cpunumber": 1, "cpuspeed": 100, # in MHz "memory": 256, # In MBs }, "account": { "email": "test@test.com", "firstname": "Test_add_remove_network_vm", "lastname": "User", "username": "test_add_remove_network_vm", "password": "password", }, "domain": { "name": "Domain_add_nw_to_vm", }, "virtual_machine": { "displayname": "testserver", "username": "root", # VM creds for SSH "password": "password", "ssh_port": 22, "hypervisor": 'XenServer', "privateport": 22, "publicport": 22, "protocol": 'TCP', }, "vpc_offering": { "name": 'VPC off add remove network', "displaytext": 'VPC off add remove network', "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,NetworkACL', }, "vpc": { "name": "TestVPC add remove network", "displaytext": "TestVPC add remove network", "cidr": '10.0.0.1/24' }, "natrule": { "privateport": 22, "publicport": 22, "protocol": "TCP" }, } @ddt class TestAddNetworkToVirtualMachine(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestAddNetworkToVirtualMachine, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") cls.services = Services().services # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) cls.defaultNetworkId = cls.virtual_machine.nic[0].networkid cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.shared_network_offering = NetworkOffering.create(cls.api_client, cls.services["shared_network_offering"]) cls._cleanup.append(cls.shared_network_offering) cls.shared_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) cls.services["shared_network"]["vlan"] = get_free_vlan(cls.api_client, cls.zone.id)[1] shared_network_subnet_number = random.randrange(1, 254) cls.services["shared_network"]["gateway"] = "172.16." + str(shared_network_subnet_number) + ".1" cls.services["shared_network"]["startip"] = "172.16." + str(shared_network_subnet_number) + ".2" cls.services["shared_network"]["endip"] = "172.16." + str(shared_network_subnet_number) + ".20" cls.shared_nw_endip = cls.services["shared_network"]["endip"] cls.shared_network = Network.create(cls.api_client, cls.services["shared_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.shared_network_offering.id) cls._cleanup.append(cls.shared_network) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.addednics = [] shared_network_subnet_number = random.randrange(1, 254) self.services["shared_network"]["gateway"] = "172.16." + str(shared_network_subnet_number) + ".1" self.services["shared_network"]["startip"] = "172.16." + str(shared_network_subnet_number) + ".2" self.services["shared_network"]["endip"] = "172.16." + str(shared_network_subnet_number) + ".20" self.services["shared_network_2"]["gateway"] = "172.16." + str(shared_network_subnet_number + 1) + ".1" self.services["shared_network_2"]["startip"] = "172.16." + str(shared_network_subnet_number + 1) + ".2" self.services["shared_network_2"]["endip"] = "172.16." + str(shared_network_subnet_number + 1) + ".20" self.cleanup = [] def tearDown(self): try: for nic in self.addednics: self.virtual_machine.remove_nic(self.apiclient, nic.id) except Exception as e: self.debug("Exception during removal of nics : %s" % e) super(TestAddNetworkToVirtualMachine, self).tearDown() @classmethod def tearDownClass(cls): try: # Disable Network Offerings cls.isolated_network_offering.update(cls.api_client, state='Disabled') cls.shared_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disable of networks : %s" % e) super(TestAddNetworkToVirtualMachine, cls).tearDownClass() def addNetworkToVm(self, network, vm, ipaddress=None): """Add network to VM and check if new nic added in the VM""" self.debug("Adding %s Network: %s to virtual machine %s" % (network.type, network.id, vm.id)) vm.add_nic(self.apiclient, network.id, ipaddress=ipaddress) vm_list = list_virtual_machines(self.apiclient, id=vm.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) self.debug("virtual machine nics: %s" % vm_list[0].nic) nics = [x for x in vm_list[0].nic if x.networkid == network.id] self.debug("Filtered nics list: %s:" % nics) # Only the nics added to self.virtual_machine should be added to this list # Nics added to their list are removed before execution of next test case because we are using # same virtual machine in all test cases, so it is important that the common # virtual machine should contain only the default nic whenever new test case # execution starts if vm.id == self.virtual_machine.id: self.addednics.append(nics[-1]) self.assertTrue(len(nics) == 1, "nics list should contain the nic of added isolated network,\ the number of nics for the network should be 1, instead they are %s" % len(nics)) if ipaddress is not None: self.assertEqual(nics[0].ipaddress, ipaddress, "The ip address of nic does not match with \ the ip address passed while adding network to vm. ip address of nic is %s \ while passed ip address is %s" % (nics[0].ipaddress, ipaddress)) return @attr(tags=["advanced", "dvs"]) @data("isolated", "shared") def test_01_add_nw_running_vm(self, value): """Add network to running VM""" # 1. Deploy VM in an account # 2. Add isolated/shared network to the VM which is in running state # Validate the following: # 1. New nic is generated for the added network # 2. Event NIC.CREATE is generated network = None # The network which we are adding to the vm if value == "isolated": network = self.isolated_network elif value == "shared": network = self.shared_network if network is None: self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) self.addNetworkToVm(network, self.virtual_machine) self.debug("Retrieving the list of events matching 'NIC.CREATE' in account: %s" % self.account.name) events = list_events(self.apiclient, account=self.account.name, domainid=self.account.domainid, type='NIC.CREATE') event_list_validation_result = validateList(events) self.assertEqual(event_list_validation_result[0], PASS, "event list validation failed due to %s" % event_list_validation_result[2]) self.debug("Events list contains event NIC.CREATE") return @attr(tags=["advanced", "dvs"]) @data("isolated", "shared") def test_02_add_nw_stopped_vm(self, value): """Add network to stopped VM""" # 1. Deploy VM in an account # 2. Stop the VM # 3. Add isolated/shared network to the stopped VM # Validate the following: # 1. New nic is generated for the added network try: self.virtual_machine.stop(self.apiclient) except Exception as e: self.fail("Failed to stop VM: %s" % e) network = None # The network which we are adding to the vm if value == "isolated": network = self.isolated_network elif value == "shared": network = self.shared_network if network is None: self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) self.addNetworkToVm(network, self.virtual_machine) self.debug("Starting Virtual Machine: %s" % self.virtual_machine.id) self.virtual_machine.start(self.apiclient) return @attr(tags=["advanced", "dvs"]) @data("isolated", "shared") def test_03_add_nw_multiple_times(self, value): """Add same network multiple times to running VM""" # 1. Deploy VM in an account # 2. Add isolated/shared network to the VM # 3. Try Adding same network again to the VM # Validate the following: # 1. Adding same network to vm multiple times fails network = None # The network which we are adding to the vm if value == "isolated": network = self.isolated_network elif value == "shared": network = self.shared_network if network is None: self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) try: virtual_machine = VirtualMachine.create( self.api_client, self.services["virtual_machine"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype, networkids=[self.defaultNetworkId]) self.cleanup.append(virtual_machine) except Exception as e: self.fail("Failed to deply virtual machine: %s" % e) # Adding network to vm for the first time self.addNetworkToVm(network, virtual_machine) # Trying to add same network to vm for the second time with self.assertRaises(Exception) as e: self.addNetworkToVm(network, virtual_machine) self.debug("Adding same network again failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) @data("isolated") def test_04_vpc_nw_running_vm(self, value): """Add VPC network to running VM belonging to isolated network""" # 1. Deploy VM in an account # 2. Add isolated network to the VM # 3. Create VPC # 4. Try adding VPC to the VM # Validate the following: # 1. Adding VPC to vm should fail try: virtual_machine = VirtualMachine.create( self.api_client, self.services["virtual_machine"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype, networkids=[self.defaultNetworkId]) self.cleanup.append(virtual_machine) except Exception as e: self.fail("Failed to deply virtual machine: %s" % e) network = self.isolated_network self.addNetworkToVm(network, virtual_machine) self.debug("Creating VPC offering") vpc_off = VpcOffering.create(self.api_client, self.services["vpc_offering"]) self.cleanup.append(vpc_off) self.debug("Created VPC offering: %s" % vpc_off.id) self.debug("Enabling the VPC offering") vpc_off.update(self.apiclient, state='Enabled') self.debug("Creating VPC") vpc = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=vpc_off.id, zoneid=self.zone.id, account=self.account.name, domainid=self.account.domainid) self.cleanup.append(vpc) self.debug("Trying to add VPC to vm belonging to isolated network, this should fail") with self.assertRaises(Exception): virtual_machine.add_nic(self.apiclient, vpc.id) self.debug("Disabling vpc offering: %s" % vpc_off.id) vpc_off.update(self.apiclient, state='Disabled') return @attr(tags=["advanced", "dvs"]) @data("isolated") def test_05_add_vpc_nw_stopped_vm(self, value): """Add VPC network to stopped VM belonging to isolated network""" # 1. Deploy VM in an account # 2. Stop the VM # 3. Add isolated network to the VM # 4. Create VPC # 5. Try adding VPC to the stopped VM # Validate the following: # 1. Adding VPC to vm should fail try: self.virtual_machine.stop(self.apiclient) except Exception as e: self.fail("Failed to stop virtual machine: %s" % e) self.addNetworkToVm(self.isolated_network, self.virtual_machine) self.debug("Creating VPC offering") vpc_off = VpcOffering.create(self.api_client, self.services["vpc_offering"]) self.cleanup.append(vpc_off) self.debug("Created VPC offering: %s" % vpc_off.id) self.debug("Enabling the VPC offering") vpc_off.update(self.apiclient, state='Enabled') self.debug("Creating VPC") vpc = VPC.create(self.apiclient, self.services["vpc"], vpcofferingid=vpc_off.id, zoneid=self.zone.id, account=self.account.name, domainid=self.account.domainid) self.cleanup.append(vpc) self.debug("Trying to add VPC to vm belonging to isolated network, this should fail") with self.assertRaises(Exception): self.virtual_machine.add_nic(self.apiclient, vpc.id) self.debug("Starting virtual machine") self.virtual_machine.start(self.apiclient) self.debug("Disabling vpc offering: %s" % vpc_off.id) vpc_off.update(self.apiclient, state='Disabled') return @attr(tags=["advanced", "dvs"]) def test_06_add_nw_ipaddress_running_vm(self): """Add network and ip address to running VM""" # 1. Deploy VM in an account # 2. Add shared network and ip address to this VM # Validate the following: # 1. New nic gets added for the shared network # 2. The newly added nic has the ip address same as # that passed while adding the network try: virtual_machine = VirtualMachine.create( self.api_client, self.services["virtual_machine"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype, networkids=[self.defaultNetworkId]) self.cleanup.append(virtual_machine) except Exception as e: self.fail("Failed to deply virtual machine: %s" % e) ipaddress = self.shared_nw_endip self.debug("Adding network to vm with ip address %s: " % ipaddress) self.addNetworkToVm(self.shared_network, virtual_machine, ipaddress=ipaddress) return @attr(tags=["advanced", "dvs"]) def test_10_add_nw_invalid_ipaddress_running_vm(self): """Add network with invalid ip address to running VM""" # 1. Deploy VM in an account # 2. Add shared network with invalid ip address to this VM # Validate the following: # 1. Adding network to VM should fail because of invalid ip address ipaddress = "257.257.257.257" # Invalid ip address self.debug("Adding network to vm with ip address %s: " % ipaddress) with self.assertRaises(Exception) as e: self.addNetworkToVm(self.shared_network, self.virtual_machine, ipaddress=ipaddress) self.debug("API failed with exception: %s" % e.exception) return # was tags=["advanced", "dvs"], # the apiclient that is being used to test this has to much rights? @attr(tags=["TODO"]) @data("isolated", "shared") def test_14_add_nw_different_account(self, value): """Add network to running VM""" # 1. Deploy VM in an account # 2. Create new account under same domain and create network in that account # 3. Add isolated/shared network belonging to other account to the VM in first account # Validate the following: # 1. Adding network should fail network = None # The network which we are adding to the vm account = Account.create(self.apiclient, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) if value == "isolated": network = Network.create(self.api_client, self.services["isolated_network"], account.name, account.domainid, networkofferingid=self.isolated_network_offering.id) self.cleanup.append(network) elif value == "shared": self.services["shared_network_2"]["zoneid"] = self.zone.id self.services["shared_network_2"]["vlan"] = get_free_vlan(self.apiclient, self.zone.id)[1] network = Network.create(self.api_client, self.services["shared_network_2"], account.name, account.domainid, networkofferingid=self.shared_network_offering.id) self.cleanup.append(network) if network is None: self.skipTest("Network should not be none. Case not handled for Network of type %s" % value) self.debug("Trying to %s network in account %s to a vm in account %s, This should fail" % (network.type, account.name, self.account.name)) try: vm_with_nic = self.virtual_machine.add_nic(self.apiclient, network.id) nics = [x for x in vm_with_nic.nic if x.networkid == network.id] self.addednics.append(nics[-1]) except Exception: pass else: self.fail("User was able to add NIC, test failed! This issue has been hit: CLOUDSTACK-10071") return @attr(tags=["advanced", "dvs"]) def test_24_add_nw_different_domain(self): """Add network to running VM""" # 1. Create two domains # 2. Create network in one domain and create virtual machine in other domain # 3. Ad isolated/shared network belonging to one domain to the vm belonging to other domain # Validate the following: # 1. Adding network should fail network = None # The network which we are adding to the vm try: self.child_domain_1 = Domain.create(self.apiclient, services=self.services["domain"], parentdomainid=self.domain.id) self.cleanup.append(self.child_domain_1) self.child_do_admin_1 = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.child_domain_1.id ) self.cleanup.append(self.child_do_admin_1) self.child_domain_2 = Domain.create(self.apiclient, services=self.services["domain"], parentdomainid=self.domain.id) self.cleanup.append(self.child_domain_2) self.child_do_admin_2 = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.child_domain_2.id) self.cleanup.append(self.child_do_admin_2) except Exception as e: self.fail(e) network = Network.create(self.api_client, self.services["isolated_network"], self.child_do_admin_1.name, self.child_do_admin_1.domainid, networkofferingid=self.isolated_network_offering.id) self.cleanup.append(network) virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], accountid=self.child_do_admin_2.name, domainid=self.child_do_admin_2.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) self.cleanup.append(virtual_machine) time.sleep(self.services["sleep"]) self.debug("Trying to %s network in domain %s to a vm in domain %s, This should fail" % (network.type, self.child_domain_1.name, self.child_domain_2.name)) with self.assertRaises(Exception) as e: virtual_machine.add_nic(self.apiclient, network.id) self.debug("Operation failed with exception %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_25_add_nw_above_account_limit(self): """Add network to VM with maximum network limit reached""" # 1. Create an account and create maximum allowed networks in the account # 2. Deploy VM in this account # 3. Create a network in other account and add to this VM # Validate the following: # 1. Adding network should fail self.debug("Creating account 1") account_1 = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) self.cleanup.append(account_1) self.debug("setting network limit of account: %s as 1" % account_1.name) update_resource_limit( self.apiclient, 6, # Network max=1, account=account_1.name, domainid=account_1.domainid ) self.debug("Creating isolated network in account: %s" % account_1.name) network_1 = Network.create(self.api_client, self.services["isolated_network"], account_1.name, account_1.domainid, networkofferingid=self.isolated_network_offering.id) self.cleanup.append(network_1) self.debug("created network %s" % network_1.name) self.debug("Deploying virtual machine in account: %s" % account_1.name) virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], accountid=account_1.name, domainid=account_1.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) self.cleanup.append(virtual_machine) self.debug("Deployed virtual machine : %s" % virtual_machine.id) self.debug("Creating another account") account_2 = Account.create( self.apiclient, self.services["account"], domainid=self.domain.id ) self.cleanup.append(account_2) self.debug("Created account %s" % account_2.name) self.debug("Creating network in account %s" % account_2.name) network_2 = Network.create(self.api_client, self.services["isolated_network"], account_2.name, account_2.domainid, networkofferingid=self.isolated_network_offering.id) self.cleanup.append(network_2) self.debug("Created network %s" % network_2.name) self.debug("Trying to add netwrok %s to VM %s, this should fail" % (network_2.name, virtual_machine.id)) with self.assertRaises(Exception) as e: virtual_machine.add_nic(self.apiclient, network_2.id) self.debug("Operation failed with exception %s" % e.exception) return class TestRemoveNetworkFromVirtualMachine(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestRemoveNetworkFromVirtualMachine, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] self.addednics = [] def tearDown(self): try: for nic in self.addednics: self.virtual_machine.remove_nic(self.apiclient, nic.id) except Exception as e: self.debug("Exception during removal of nics : %s" % e) super(TestRemoveNetworkFromVirtualMachine, self).tearDown() @classmethod def tearDownClass(cls): try: cls.isolated_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disabling network offering : %s" % e) super(TestRemoveNetworkFromVirtualMachine, cls).tearDownClass() def addNetworkToVm(self, network, vm): """Add network to VM and check if new nic added in the VM""" self.debug("Adding %s Network: %s to virtual machine %s" % (network.type, network.id, vm.id)) vm.add_nic(self.apiclient, network.id) vm_list = list_virtual_machines(self.apiclient, id=vm.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) self.debug("virtual machine nics: %s" % vm_list[0].nic) # Add nic of network to list so that it can be deleted later accessing its id from this list self.nics = [x for x in vm_list[0].nic if x.networkid == network.id] self.debug("Filtered nics list: %s:" % self.nics) self.assertTrue(len(self.nics) == 1, "nics list should contain the nic of added isolated network,\ the number of nics for the network should be 1, instead they are %s" % len(self.nics)) return self.nics @attr(tags=["advanced", "dvs"]) def test_07_remove_nic_running_vm(self): """Remove nic from running VM""" # 1. Deploy Vm in account # 2. Add network to VM # 3. Remove the nic added by the newly added network # Validate the following: # 1. Newly added nic is removed # 2. Event NIC.DELETE is generated self.addNetworkToVm(self.isolated_network, self.virtual_machine) # Access the nic of the added network from self.nics object which is fillled # in addNetworkToVm function self.debug("Removing added nic %s from vm %s" % (self.nics[0].id, self.virtual_machine.id)) self.virtual_machine.remove_nic(self.apiclient, self.nics[0].id) vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) self.debug("virtual machine nics: %s" % vm_list[0].nic) # Verify the nic is removed from the virtual machine self.debug("Verifying the nic is removed from the virtual machine") self.assertFalse(any(x.networkid == self.isolated_network.id for x in vm_list[0].nic), "nic still present in the virtual machine nic list") self.debug("nic removed successfully") self.debug("Retrieving events list matching events 'NIC.DELETE'") events = list_events( self.apiclient, account=self.account.name, domainid=self.account.domainid, type='NIC.DELETE' ) event_list_validation_result = validateList(events) self.assertEqual(event_list_validation_result[0], PASS, "vm list validation failed due to %s" % event_list_validation_result[2]) self.debug("Events list contains event NIC.DELETE") self.debug("events: %s" % events) return @attr(tags=["advanced", "dvs"]) def test_08_remove_default_nic(self): """Test Remove default nic of running VM""" # 1. Deploy Vm in account # 2. Try to remove the default nic of the VM # Validate the following: # 1. Default nic of vm is not removed vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) self.debug("virtual machine nics: %s" % vm_list[0].nic) self.assertEqual(len(vm_list[0].nic), 1, "There should only be default nic present in the vm") self.debug("Trying to remove the default nic of vm : %s, this should fail" % self.virtual_machine.id) with self.assertRaises(Exception): self.virtual_machine.remove_nic(self.apiclient, vm_list[0].nic[0].id) self.debug("Removing default nic of vm failed") return @attr(tags=["advanced", "dvs"]) def test_09_remove_foreign_nic(self): """Remove nic which does not belong to VM""" # 1. Add VM in an account # 1. Add new account and deploy vm in it # 2. Try to remove nic of the new vm from first vm # Validate the following: # 1. Nic remove operation should fail self.debug("Creating new account") account = Account.create( self.api_client, self.services["account"], domainid=self.domain.id ) self.cleanup.append(account) self.debug("created new account : %s" % account.name) self.debug("Deploying virtual machine in this account") virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], accountid=account.name, domainid=account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) self.debug("Deployed virtual machine: %s" % virtual_machine.id) self.debug("Trying to remove nic of new virtual machine from existing virtual machine, This \ operation should fail") with self.assertRaises(Exception) as e: self.virtual_machine.remove_nic(self.apiclient, virtual_machine.nic[0].id) self.debug("Operation failed with exception: %s" % e.exception) return @attr(tags=["advanced"], required_hardware="true") def test_29_remove_nic_CS22503(self): """Test to verify remove nic from vm if the nic ip is same as another vm ip in another network""" # 1. Deploy vm v1 with networks n1 and n2 # 2. Check the ip address of nic in n2 say ip1 # 3. Deployed vm v2 in another network say n3 with same IP address as ip1 using # 'deployVirtualMachine' api with 'ipaddress' as one of the parameters. # 4. Acquire public IP in n3 network. # 5. Configure PF on the acquired IP and assign it to vm v2 # 6. Try to remove nic n2 from v1. Should be successful # There was a bug due to both vms has same ip address, so not allowing to remove nic vm1 = self.virtual_machine nic2 = self.addNetworkToVm(self.isolated_network, vm1) self.addednics.append(nic2) # get the ip address of the nic added in 2nd network vm1_ip = nic2[0].ipaddress self.assertIsNotNone(vm1_ip, "New nic did not get the ip address") # Create network n3 self.network3 = Network.create( self.api_client, self.services["isolated_network"], self.account.name, self.account.domainid, networkofferingid=self.isolated_network_offering.id ) self.cleanup.append(self.network3) self.vm2 = VirtualMachine.create( self.api_client, self.services["virtual_machine"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, networkids=[self.network3.id], ipaddress=vm1_ip, mode=self.zone.networktype ) self.cleanup.append(self.vm2) vm2 = VirtualMachine.list( self.api_client, id=self.vm2.id ) self.assertEqual(validateList(vm2)[0], PASS, "list vms returned invalid response") self.assertIsNotNone(vm2[0].nic[0].ipaddress, "vm2 didn't get the ip address") self.assertEqual( vm1_ip, vm2[0].nic[0].ipaddress, "vm2 did not get the ip address passed while deploying vm" ) ip_address = PublicIPAddress.create( self.apiclient, self.account.name, self.zone.id, self.account.domainid, self.services["virtual_machine"], self.network3.id ) self.cleanup.append(ip_address) # Open up firewall port for SSH FireWallRule.create( self.apiclient, ipaddressid=ip_address.ipaddress.id, protocol=self.services["natrule"]["protocol"], cidrlist=['0.0.0.0/0'], startport=self.services["natrule"]["publicport"], endport=self.services["natrule"]["publicport"] ) # Create NAT rule nat_rule = NATRule.create( self.apiclient, self.vm2, self.services["natrule"], ip_address.ipaddress.id ) list_nat_rule_response = list_nat_rules( self.apiclient, id=nat_rule.id ) self.assertEqual( validateList(list_nat_rule_response)[0], PASS, "Check list response returns a valid list" ) self.assertEqual( list_nat_rule_response[0].id, nat_rule.id, "Check Correct Port forwarding Rule is returned" ) # Try to remove nic 2 from vm1 try: vm1.remove_nic(self.apiclient, self.nics[0].id) vm1_res = VirtualMachine.list(self.apiclient, id=vm1.id) self.assertEqual(validateList(vm1_res)[0], PASS, "invalid listvm response") self.assertEqual( len(vm1_res[0].nic), 1, "VM has more than one nic even after removing the 2nd nic" ) except Exception as e: self.fail("Failed to delete the nic from vm") return @attr(tags=["advanced"], required_hardware="true") def test_30_remove_nic_reattach(self): """ Test to verify vm start after NIC removal and reattach # 1.Create vm which has 3 nics(e.g. #0,#1,#2) # 2.Stop the vm # 3.Remove second nic(#1) # 4.Add/Reattach same network(#1) # 5.Start the instance """ self.ntwk2 = Network.create( self.apiclient, self.services["isolated_network"], self.account.name, self.account.domainid, networkofferingid=self.isolated_network_offering.id ) self.cleanup.append(self.ntwk2) self.ntwk3 = Network.create( self.apiclient, self.services["isolated_network"], self.account.name, self.account.domainid, networkofferingid=self.isolated_network_offering.id ) self.cleanup.append(self.ntwk3) self.test_vm = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype, networkids=[self.isolated_network.id, self.ntwk2.id, self.ntwk3.id] ) self.cleanup.append(self.test_vm) self.assertIsNotNone(self.test_vm, "Failed to create vm with 3 nics") vm_res = VirtualMachine.list( self.apiclient, id=self.test_vm.id ) self.assertEqual(validateList(vm_res)[0], PASS, "Invalid list vm response") self.nics = vm_res[0].nic self.assertEqual( validateList(self.nics)[0], PASS, "vm response does not contain nics info" ) self.assertEqual(len(self.nics), 3, "Not all nics found in vm response") self.test_vm.stop(self.apiclient) vm_res2 = VirtualMachine.list( self.apiclient, id=self.test_vm.id ) self.assertEqual(validateList(vm_res2)[0], PASS, "Invalid response") self.assertEqual( vm_res2[0].state, "Stopped", "VM did not stop properly" ) """ get the network id of the nic which we are remove from the nic, so that we can use that network id for reattach """ nic_to_attach = [x for x in [self.isolated_network, self.ntwk2, self.ntwk3] \ if x.id == self.nics[1].networkid] self.assertEqual(validateList(nic_to_attach)[0], PASS, "No matching nics") self.assertEqual(len(nic_to_attach), 1, "More than one nic in same network") try: self.test_vm.remove_nic(self.apiclient, nicId=self.nics[1].id) self.test_vm.add_nic( self.apiclient, nic_to_attach[0].id ) self.test_vm.start(self.apiclient) except Exception as e: self.fail("Failed to start vm after nic removal and attachment") vm_res3 = VirtualMachine.list(self.apiclient, id=self.test_vm.id) self.assertEqual( validateList(vm_res3)[0], PASS, "Invalid listvm response after nic detach and attach" ) self.assertEqual( vm_res3[0].state, "Running", "VM didn't come to running state after nic detach and attach" ) vm_nics = vm_res3[0].nic self.assertEqual(validateList(vm_nics)[0], PASS, "Invalid nics after vm stop/start") self.assertEqual( len(vm_nics), 3, "Nic is not attached/detected" ) self.addednics.extend(vm_nics) return class TestUpdateVirtualMachineNIC(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestUpdateVirtualMachineNIC, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"]) cls._cleanup.append(cls.isolated_network_offering) cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] self.addednics = [] def tearDown(self): try: for nic in self.addednics: self.virtual_machine.remove_nic(self.apiclient, nic.id) except Exception as e: self.debug("Exception during removal of nics : %s" % e) super(TestUpdateVirtualMachineNIC, self).tearDown() @classmethod def tearDownClass(cls): try: cls.isolated_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disable of network offering : %s" % e) super(TestUpdateVirtualMachineNIC, cls).tearDownClass() def addNetworkToVm(self, network, vm): """Add network to VM and check if new nic added in the VM""" self.debug("Adding %s Network: %s to virtual machine %s" % (network.type, network.id, vm.id)) vm.add_nic(self.apiclient, network.id) vm_list = list_virtual_machines(self.apiclient, id=vm.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) self.debug("virtual machine nics: %s" % vm_list[0].nic) # Add nic of network to list so that it can be deleted later accessing its id from this list self.nics = [x for x in vm_list[0].nic if x.networkid == network.id] self.debug("Filtered nics list: %s:" % self.nics) self.assertTrue(len(self.nics) == 1, "nics list should contain the nic of added isolated network,\ the number of nics for the network should be 1, instead they are %s" % len(self.nics)) self.addednics.append(self.nics[0]) return @attr(tags=["advanced", "dvs"]) def test_11_update_nic_running_vm(self): """update default nic of running VM""" # 1. Deploy Vm in account # 2. Add network to VM # 3. Update default nic of VM (Make the newly added NIC as default) # Validate the following: # 1. Default nic is updated # 2. Previous default nic is now non-default # 3. Event NIC.UPDATE is generated self.addNetworkToVm(self.isolated_network, self.virtual_machine) self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") defaultNicIdBeforeUpdate = None nonDefaultNicIdBeforeUpdate = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdBeforeUpdate = nic.id else: nonDefaultNicIdBeforeUpdate = nic.id self.debug("Default nic of VM is %s and non default nic of VM is %s" % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) self.debug("Making non default nic as default nic") self.virtual_machine.update_default_nic(self.apiclient, nicId=nonDefaultNicIdBeforeUpdate) self.debug("Again listing the NIC list of VM to verify the update operation was successful") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdAfterUpdate = nic.id self.assertEqual(nonDefaultNicIdBeforeUpdate, defaultNicIdAfterUpdate, "old non default NIC not made\ default one, update_default_nic API failed") self.debug("Retrieving events list matching events 'NIC.UPDATE'") events = list_events( self.apiclient, account=self.account.name, domainid=self.account.domainid, type='NIC.UPDATE' ) event_list_validation_result = validateList(events) self.assertEqual(event_list_validation_result[0], PASS, "event list validation failed due to %s" % event_list_validation_result[2]) self.debug("Events list contains event NIC.UPDATE") self.debug("events: %s" % events) return @attr(tags=["advanced", "dvs"]) def test_12_make_default_nic_as_default(self): """Try to set default nic of vm again as default""" # 1. Deploy Vm in account # 2. Set default nic of vm again as default # Validate the following: # 1. updateDefaultNic API fails self.debug("Listing virtual machine to get default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) defaultNicId = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicId = nic.id self.debug("Trying to set default nic again as default nic, This should fail") with self.assertRaises(Exception) as e: self.virtual_machine.update_default_nic(self.apiclient, nicId=defaultNicId) self.debug("updateDefaultNic operation failed as expected with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_13_set_foreign_nic_as_default(self): """set nic which does not belong to VM as its default one""" # 1. Add VM in an account # 1. Add new account and deploy vm in it # 2. Try to set nic of the new vm as default nic of first vm # Validate the following: # 1. updateDefaultNic operation should fail self.debug("Creating new account") account = Account.create(self.api_client, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) self.debug("created new account : %s" % account.name) self.debug("Deploying virtual machine in this account") virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], accountid=account.name, domainid=account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) self.cleanup.append(virtual_machine) time.sleep(self.services["sleep"]) self.debug("Deployed virtual machine: %s" % virtual_machine.id) foreignNicId = virtual_machine.nic[0].id self.debug("Trying to set nic of new virtual machine as default nic of existing virtual machine, This \ operation should fail") with self.assertRaises(Exception) as e: self.virtual_machine.update_default_nic(self.apiclient, nicId=foreignNicId) self.debug("updateDefaultNic operation failed as expected with exception: %s" % e.exception) return class TestFailureScenariosAddNetworkToVM(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestFailureScenariosAddNetworkToVM, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"], ) cls._cleanup.append(cls.isolated_network_offering) cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] def tearDown(self): super(TestFailureScenariosAddNetworkToVM, self).tearDown() @classmethod def tearDownClass(cls): try: cls.isolated_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disabling network offering : %s" % e) super(TestFailureScenariosAddNetworkToVM, cls).tearDownClass() @attr(tags=["advanced", "dvs"]) def test_15_add_nic_wrong_vm_id(self): """Add network to vm with wrong vm id""" # 1. Call add network to VM API with correct network id but wrong vm id # Validate the following: # 1. API should throw exception saying unable to find virtual machine cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = random_gen(id="virtual_machine", size=30) cmd.networkid = self.isolated_network.id with self.assertRaises(Exception) as e: self.apiclient.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_16_add_nic_wrong_network_id(self): """Add network to vm with wrong network id""" # 1. Call add network to VM API with correct network id but wrong network id # Validate the following: # 1. API should throw exception saying unable to find a network cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.networkid = random_gen(id="network_id", size=30) with self.assertRaises(Exception) as e: self.apiclient.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_17_add_nic_different_zone(self): """Add network to vm where both belong to different zones""" # 1. Deploy a VM in zone 1 # 2. Create a network in zone 2 # 3. Try to add this network to the VM (both belong to different zones) # Validate the following: # 1. API should throw exception vminstance is in zone, but network is in zone foreignZoneId = None zones = list_zones(self.apiclient, available=True) list_zones_validation_result = validateList(zones) self.assertEqual(list_zones_validation_result[0], PASS, "list zones validation failed due to: %s" % list_zones_validation_result[2]) if len(zones) >= 2: for zone in zones: if zone.id != self.zone.id: foreignZoneId = zone.id break else: self.skipTest("This test requires at least two zones to be present in the setup") self.services["isolated_network"]["zoneid"] = foreignZoneId self.debug("Creating isolated network in zone %s which is foreign to VM" % foreignZoneId) isolated_network = Network.create(self.apiclient, self.services["isolated_network"], self.account.name, self.account.domainid, networkofferingid=self.isolated_network_offering.id) self.cleanup.append(isolated_network) self.debug("Created isolated network %s in zone %s" % (isolated_network.id, foreignZoneId)) self.debug("Trying to add network to VM, both belonging to different zones") cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.networkid = isolated_network.id with self.assertRaises(Exception) as e: time.sleep(5) self.apiclient.addNicToVirtualMachine(cmd) self.debug("addNicToVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["invalid"]) def test_18_add_nic_basic_zone(self): """Add network to vm in basic zone""" # 1. Deploy a vm and create network in basic zone # 2. Try adding network to vm # Validate following # 1. API should throw exception saying Can't add a new nic to vm in basic network basicZone = None zones = list_zones(self.apiclient, available=True) list_zones_validation_result = validateList(zones) self.assertEqual(list_zones_validation_result[0], PASS, "list zones validation failed due to: %s" % list_zones_validation_result[2]) for zone in zones: if zone.networktype.lower() == 'BASIC': basicZone = zone.id break if basicZone is None: self.skipTest("This test requires at least one basic zone to be present in the setup") self.services["isolated_network"]["zoneid"] = basicZone.id self.debug("Creating isolated network in basic zone: %s" % basicZone.id) isolated_network = Network.create(self.apiclient, self.services["isolated_network"], networkofferingid=self.isolated_network_offering.id) self.cleanup.append(isolated_network) self.debug("Created isolated network %s:" % isolated_network.id) self.services["virtual_machine"]["zoneid"] = basicZone.id self.debug("Deploying virtual machine in basic zone: %s" % basicZone.id) virtual_machine = VirtualMachine.create(self.apiclient, self.services["virtual_machine"], serviceofferingid=self.service_offering.id, mode=basicZone.networktype) self.cleanup.append(virtual_machine) time.sleep(self.services["sleep"]) self.debug("Deployed virtual machine %s: " % virtual_machine.id) cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = virtual_machine.id cmd.networkid = isolated_network.id self.dedbug("Trying to add isolated network to VM (both in basic zone,\ this operation should fail") with self.assertRaises(Exception) as e: time.sleep(5) self.apiclient.addNicToVirtualMachine(cmd) return @attr(tags=["advanced", "dvs"]) def test_26_add_nic_insufficient_permission(self): """Try to add network to vm with insufficient permission""" # 1. Call add network to VM API with api client of other account # Validate the following: # 1. API should throw exception saying insufficient permission cmd = addNicToVirtualMachine.addNicToVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.networkid = self.isolated_network.id self.debug("Creating new account") account = Account.create(self.apiclient, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Trying to add network to vm with this api client, this should fail due to \ insufficient permission") with self.assertRaises(Exception) as e: time.sleep(5) api_client.addNicToVirtualMachine(cmd) return class TestFailureScenariosRemoveNicFromVM(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestFailureScenariosRemoveNicFromVM, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"], ) cls._cleanup.append(cls.isolated_network_offering) cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] def tearDown(self): super(TestFailureScenariosRemoveNicFromVM, self).tearDown() @classmethod def tearDownClass(cls): try: cls.isolated_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disabling of network offering : %s" % e) super(TestFailureScenariosRemoveNicFromVM, cls).tearDownClass() @attr(tags=["advanced", "dvs"]) def test_19_remove_nic_wrong_vm_id(self): """Try to remove nic from a vm providing wrong vm id to API""" # (Frist two steps are perfromed in setupClass) # 1. Deploy Vm in account # 2. Add network to VM # 3. Remove the nic added by the newly added network providing wrong vm id to the API # Validate the following: # 1. API throws exception unable to find a virtual machine with id vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) vm = vm_list_validation_result[1] nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] self.assertEqual(len(nics), 1, "There should be exactly one nic corresponding to the isolate\ network %s" % self.isolated_network.id) cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id + random_gen() cmd.nicid = nics[0].id with self.assertRaises(Exception) as e: self.apiclient.removeNicFromVirtualMachine(cmd) self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_20_remove_nic_wrong_nic_id(self): """Try to remove nic from a vm providing wrong nic id to API""" # (Frist two steps are perfromed in setupClass) # 1. Deploy Vm in account # 2. Add network to VM # 3. Remove the nic added by the newly added network providing wrong nic id to the API # Validate the following: # 1. API throws exception unable to find nic with id vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) vm = vm_list_validation_result[1] nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] self.assertEqual(len(nics), 1, "There should be exactly one nic corresponding to the isolate\ network %s" % self.isolated_network.id) cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.nicid = nics[0].id + random_gen() with self.assertRaises(Exception) as e: self.apiclient.removeNicFromVirtualMachine(cmd) self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_27_remove_nic_insufficient_permission(self): """Try to remove nic from vm with insufficient permission""" # 1. Call remove network from VM API with api client of other account # Validate the following: # 1. API should throw exception saying insufficient permission vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) vm = vm_list_validation_result[1] nics = [x for x in vm.nic if x.networkid == self.isolated_network.id] self.assertEqual(len(nics), 1, "There should be exactly one nic corresponding to the isolate\ network %s" % self.isolated_network.id) cmd = removeNicFromVirtualMachine.removeNicFromVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.nicid = nics[0].id self.debug("Creating new account") account = Account.create(self.apiclient, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Trying to add network to vm with this api client, this should fail due to \ insufficient permission") with self.assertRaises(Exception) as e: api_client.removeNicFromVirtualMachine(cmd) self.debug("removeNicFromVirtualMachine API failed with exception: %s" % e.exception) self.apiclient.removeNicFromVirtualMachine(cmd) return class TestFailureScenariosUpdateVirtualMachineNIC(cloudstackTestCase): @classmethod def setUpClass(cls): cls.testClient = super(TestFailureScenariosUpdateVirtualMachineNIC, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.services = Services().services hypervisor = get_hypervisor_type(cls.api_client) if hypervisor.lower() not in ["xenserver", "kvm"]: raise unittest.SkipTest("This feature is supported only on XenServer and KVM") # Get Zone, Domain and templates cls.domain = get_domain(cls.api_client) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) # Set Zones and disk offerings cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = template.id # Create Accounts & networks cls.services["isolated_network"]["zoneid"] = cls.zone.id cls.services["shared_network"]["zoneid"] = cls.zone.id cls._cleanup = [] cls.addednics = [] cls.account = Account.create(cls.api_client, cls.services["account"], domainid=cls.domain.id) cls._cleanup.append(cls.account) cls.service_offering = ServiceOffering.create(cls.api_client, cls.services["service_offering"]) cls._cleanup.append(cls.service_offering) cls.virtual_machine = VirtualMachine.create(cls.api_client, cls.services["virtual_machine"], accountid=cls.account.name, domainid=cls.account.domainid, serviceofferingid=cls.service_offering.id, mode=cls.zone.networktype) cls._cleanup.append(cls.virtual_machine) cls.defaultNetworkId = cls.virtual_machine.nic[0].networkid # Create Shared Network Offering cls.isolated_network_offering = NetworkOffering.create(cls.api_client, cls.services["isolated_network_offering"], ) cls._cleanup.append(cls.isolated_network_offering) # Enable Isolated Network offering cls.isolated_network_offering.update(cls.api_client, state='Enabled') cls.isolated_network = Network.create(cls.api_client, cls.services["isolated_network"], cls.account.name, cls.account.domainid, networkofferingid=cls.isolated_network_offering.id) cls._cleanup.append(cls.isolated_network) vm_with_nic = cls.virtual_machine.add_nic(cls.api_client, cls.isolated_network.id) nics = [x for x in vm_with_nic.nic if x.networkid == cls.isolated_network.id] cls.addednics.append(nics[-1]) return def setUp(self): self.apiclient = self.testClient.getApiClient() self.dbclient = self.testClient.getDbConnection() self.cleanup = [] def tearDown(self): super(TestFailureScenariosUpdateVirtualMachineNIC, self).tearDown() @classmethod def tearDownClass(cls): try: for nic in cls.addednics: cls.virtual_machine.remove_nic(cls.apiclient, nic.id) except Exception as e: cls.debug("Exception during removal of nics : %s" % e) try: cls.isolated_network_offering.update(cls.api_client, state='Disabled') except Exception as e: cls.debug("Exception during disabling of network offering : %s" % e) super(TestFailureScenariosUpdateVirtualMachineNIC, cls).tearDownClass() @attr(tags=["advanced", "dvs"]) def test_21_update_nic_wrong_vm_id(self): """update default nic of vm providing wrong vm id to the API""" # (First two steps are performed in setupClass) # 1. Deploy Vm in account # 2. Add network to VM # 3. Update default nic of VM (Make the newly added NIC as default) by providing wrong # vm id to the API # Validate the following: # 1. API throws exception saying can't find the virtual machine self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") defaultNicIdBeforeUpdate = None nonDefaultNicIdBeforeUpdate = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdBeforeUpdate = nic.id else: nonDefaultNicIdBeforeUpdate = nic.id self.debug("Default nic of VM is %s and non default nic of VM is %s" % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) self.debug("Making non default nic as default nic") cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id + random_gen() cmd.nicid = nonDefaultNicIdBeforeUpdate with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_22_update_nic_wrong_nic_id(self): """update default nic of vm providing wrong nic id to the API""" # (First two steps are performed in setupClass) # 1. Deploy Vm in account # 2. Add network to VM # 3. Update default nic of VM (Make the newly added NIC as default) by providing wrong # nic id to the API # Validate the following: # 1. API throws exception saying can't find the nic with id self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") defaultNicIdBeforeUpdate = None nonDefaultNicIdBeforeUpdate = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdBeforeUpdate = nic.id else: nonDefaultNicIdBeforeUpdate = nic.id self.debug("Default nic of VM is %s and non default nic of VM is %s" % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) self.debug("Making non default nic as default nic") cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.nicid = nonDefaultNicIdBeforeUpdate + random_gen() with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_23_update_nic_incorrect_vm_state(self): """update default nic of vm when vm is state is not Running or Stopped""" # (First two steps are performed in setupClass) # 1. Deploy Vm in account # 2. Add network to VM # 3. Destroy virtual machine so that the VM state becomes Destroyed or Expunging # 4. Update default nic of VM (Make the newly added NIC as default) # Validate the following: # 1. API throws exception instance is not Running or Stopped self.debug("Creating new account") account = Account.create(self.apiclient, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) self.debug("Creating virtual machine in the account %s" % account.name) virtual_machine = VirtualMachine.create(self.api_client, self.services["virtual_machine"], accountid=account.name, domainid=account.domainid, serviceofferingid=self.service_offering.id, mode=self.zone.networktype) time.sleep(self.services["sleep"]) self.debug("Created virtual machine %s" % virtual_machine.id) self.debug("Creating isolated network in account %s" % account.name) isolated_network = Network.create(self.apiclient, self.services["isolated_network"], account.name, account.domainid, networkofferingid=self.isolated_network_offering.id) self.debug("Created isolated network %s" % isolated_network.id) self.debug("Adding isolated network %s to vm %s" % (isolated_network.id, virtual_machine.id)) virtual_machine.add_nic(self.apiclient, isolated_network.id) self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=virtual_machine.id, listall=True) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") defaultNicIdBeforeUpdate = None nonDefaultNicIdBeforeUpdate = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdBeforeUpdate = nic.id else: nonDefaultNicIdBeforeUpdate = nic.id self.debug("Default nic of VM is %s and non default nic of VM is %s" % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) self.debug("Destroying VM %s" % virtual_machine.id) virtual_machine.delete(self.apiclient, expunge=False) self.debug("Making non default nic as default nic") cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() cmd.virtualmachineid = virtual_machine.id cmd.nicid = nonDefaultNicIdBeforeUpdate with self.assertRaises(Exception) as e: self.apiclient.updateDefaultNicForVirtualMachine(cmd) self.debug("updateDefaultNicForVirtualMachine API failed with exception: %s" % e.exception) return @attr(tags=["advanced", "dvs"]) def test_28_update_nic_insufficient_permission(self): """Try to update default nic of vm with insufficient permission""" # 1. Call update nic of VM API with api client of other account # Validate the following: # 1. API should throw exception saying insufficient permission account = Account.create(self.apiclient, self.services["account"], domainid=self.domain.id) self.cleanup.append(account) self.debug("Created account %s" % account.name) self.debug("creating user api client for account: %s" % account.name) api_client = self.testClient.getUserApiClient(UserName=account.name, DomainName=self.account.domain) self.debug("Listing virtual machine so that to retrive the list of non-default and default nic") vm_list = list_virtual_machines(self.apiclient, id=self.virtual_machine.id) vm_list_validation_result = validateList(vm_list) self.assertEqual(vm_list_validation_result[0], PASS, "vm list validation failed due to %s" % vm_list_validation_result[2]) if len(vm_list[0].nic) != 2: self.fail("VM should have exactly two NICs") defaultNicIdBeforeUpdate = None nonDefaultNicIdBeforeUpdate = None for nic in vm_list[0].nic: if nic.isdefault: defaultNicIdBeforeUpdate = nic.id else: nonDefaultNicIdBeforeUpdate = nic.id self.debug("Default nic of VM is %s and non default nic of VM is %s" % (defaultNicIdBeforeUpdate, nonDefaultNicIdBeforeUpdate)) self.debug("Making non default nic as default nic") cmd = updateDefaultNicForVirtualMachine.updateDefaultNicForVirtualMachineCmd() cmd.virtualmachineid = self.virtual_machine.id cmd.nicid = nonDefaultNicIdBeforeUpdate with self.assertRaises(Exception) as e: api_client.updateDefaultNicForVirtualMachine(cmd) return