mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			406 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			406 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # 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.
 | |
| 
 | |
| # Import Local Modules
 | |
| from nose.plugins.attrib import attr
 | |
| from marvin.cloudstackTestCase import cloudstackTestCase, unittest
 | |
| from marvin.lib.utils import (validateList,
 | |
|                               cleanup_resources,
 | |
|                               _execute_ssh_command,
 | |
|                               get_host_credentials,
 | |
|                               random_gen)
 | |
| from marvin.lib.base import (PhysicalNetwork,
 | |
|                              Host,
 | |
|                              TrafficType,
 | |
|                              Domain,
 | |
|                              Network,
 | |
|                              NetworkOffering,
 | |
|                              VirtualMachine,
 | |
|                              ServiceOffering,
 | |
|                              Zone)
 | |
| from marvin.lib.common import (get_domain,
 | |
|                                get_zone,
 | |
|                                get_template,
 | |
|                                list_virtual_machines)
 | |
| 
 | |
| import logging
 | |
| 
 | |
| class TestMultipleNetworkCreation(cloudstackTestCase):
 | |
|     @classmethod
 | |
|     def setUpClass(cls):
 | |
|         cls.testClient = super(
 | |
|             TestMultipleNetworkCreation,
 | |
|             cls).getClsTestClient()
 | |
|         cls.apiclient = cls.testClient.getApiClient()
 | |
|         cls.testdata = cls.testClient.getParsedTestDataConfig()
 | |
|         cls.services = cls.testClient.getParsedTestDataConfig()
 | |
|         cls.domain = get_domain(cls.apiclient)
 | |
|         zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
 | |
|         cls.zone = Zone(zone.__dict__)
 | |
|         cls.template = get_template(cls.apiclient, cls.zone.id)
 | |
|         cls._cleanup = []
 | |
| 
 | |
|         cls.logger = logging.getLogger("TestMultipleNetworkCreation")
 | |
|         cls.stream_handler = logging.StreamHandler()
 | |
|         cls.logger.setLevel(logging.DEBUG)
 | |
|         cls.logger.addHandler(cls.stream_handler)
 | |
| 
 | |
|         # Disable the zone to create physical networks
 | |
|         cls.zone.update(
 | |
|             cls.apiclient,
 | |
|             allocationstate="Disabled"
 | |
|         )
 | |
| 
 | |
|         try:
 | |
|             cls.physical_network = PhysicalNetwork.create(
 | |
|                 cls.apiclient,
 | |
|                 cls.services["l2-network"],
 | |
|                 zoneid=cls.zone.id
 | |
|             )
 | |
|             cls._cleanup.append(cls.physical_network)
 | |
| 
 | |
|             cls.physical_network_2 = PhysicalNetwork.create(
 | |
|                 cls.apiclient,
 | |
|                 cls.services["l2-network"],
 | |
|                 zoneid=cls.zone.id
 | |
|             )
 | |
|             cls._cleanup.append(cls.physical_network_2)
 | |
|         except Exception as e:
 | |
|             cls.tearDownClass()
 | |
|             raise unittest.SkipTest(e)
 | |
| 
 | |
|         cls.kvmnetworklabel=None
 | |
|         try:
 | |
|             hosts = Host.list(cls.apiclient, type='Routing')
 | |
|             if isinstance(hosts, list) and len(hosts) > 0:
 | |
|                 host = hosts[0]
 | |
|             else:
 | |
|                 return
 | |
|             if host.hypervisor.lower() not in "kvm":
 | |
|                 return
 | |
|             host.user, host.passwd = get_host_credentials(cls.config, host.ipaddress)
 | |
|             bridges = _execute_ssh_command(host.ipaddress, 22, host.user, host.passwd, "brctl show |grep cloudbr |awk '{print $1}'")
 | |
|             existing_physical_networks = PhysicalNetwork.list(cls.apiclient)
 | |
|             for existing_physical_network in existing_physical_networks:
 | |
|                 trafficTypes = TrafficType.list(
 | |
|                     cls.apiclient,
 | |
|                     physicalnetworkid=existing_physical_network.id)
 | |
|                 if trafficTypes is None:
 | |
|                     continue
 | |
|                 for traffic_type in trafficTypes:
 | |
|                     if traffic_type.traffictype == "Guest":
 | |
|                         try:
 | |
|                             for bridge in bridges:
 | |
|                                 if bridge == str(traffic_type.kvmnetworklabel):
 | |
|                                     bridges.remove(bridge)
 | |
|                         except Exception as e:
 | |
|                             continue
 | |
| 
 | |
|             if bridges is not None and len(bridges) > 0:
 | |
|                 cls.kvmnetworklabel = bridges[0]
 | |
|             if cls.kvmnetworklabel is not None:
 | |
|                 cls.logger.debug("Found an unused kvmnetworklabel %s" %cls.kvmnetworklabel)
 | |
|             else:
 | |
|                 cls.logger.debug("Not find an unused kvmnetworklabel")
 | |
|         except Exception as e:
 | |
|             return
 | |
| 
 | |
|     @classmethod
 | |
|     def tearDownClass(cls):
 | |
|         try:
 | |
|             cls.zone.update(
 | |
|                 cls.apiclient,
 | |
|                 allocationstate="Enabled"
 | |
|             )
 | |
|             # Cleanup resources used
 | |
|             super(TestMultipleNetworkCreation, cls).tearDownClass()
 | |
|         except Exception as e:
 | |
|             raise Exception("Warning: Exception during cleanup : %s" % e)
 | |
|         return
 | |
| 
 | |
|     def setUp(self):
 | |
|         self.apiclient = self.testClient.getApiClient()
 | |
|         self.cleanup = []
 | |
| 
 | |
|         return
 | |
| 
 | |
|     def tearDown(self):
 | |
|         super(TestMultipleNetworkCreation, self).tearDown()
 | |
| 
 | |
|     @attr(tags=["advanced"], required_hardware="false")
 | |
|     def test_01_add_traffictype_for_untagged_networks(self):
 | |
|         """
 | |
|         Try to add to traffic type Guest to each of the network
 | |
|         Two physical networks are already created without tags
 | |
| 
 | |
|         1. Try to add traffic type Guest to physcial network
 | |
|         2. Ensure that it throws exception
 | |
|         3. Now add the tags to the physical network
 | |
|         4. Add traffic type Guest to the physical network and it should not throw exception
 | |
|         5. Do the same above steps for the other physical network
 | |
| 
 | |
|         :return:
 | |
|         """
 | |
|         try:
 | |
|             # Add traffic type
 | |
|             self.physical_network.addTrafficType(
 | |
|                 self.apiclient,
 | |
|                 type="Guest"
 | |
|             )
 | |
| 
 | |
|             # If the control comes then there is something wrong with the code.
 | |
|             # The code should throw exception as there are multiple networks with null tags
 | |
|             raise Exception("Exception should occur when adding traffic type since tags are null")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected")
 | |
| 
 | |
|         # Now update the network with tags
 | |
|         self.physical_network.update(
 | |
|             self.apiclient,
 | |
|             tags="Guest"
 | |
|         )
 | |
| 
 | |
|         # try adding traffic type again. it should not throw error
 | |
|         self.physical_network.addTrafficType(
 | |
|             self.apiclient,
 | |
|             type="Guest"
 | |
|         )
 | |
| 
 | |
|         # Do the same thing for the second network
 | |
|         try:
 | |
|             self.physical_network_2.addTrafficType(
 | |
|                 self.apiclient,
 | |
|                 type="Guest"
 | |
|             )
 | |
| 
 | |
|             # It should throw exception and should not come here
 | |
|             raise Exception("Exception should occur when adding traffic type since tags are null")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected")
 | |
| 
 | |
|         # Now update the network with tags
 | |
|         self.physical_network_2.update(
 | |
|             self.apiclient,
 | |
|             tags="Guest"
 | |
|         )
 | |
| 
 | |
|         # try adding traffic type again. it should not throw error
 | |
|         self.physical_network_2.addTrafficType(
 | |
|             self.apiclient,
 | |
|             type="Guest"
 | |
|         )
 | |
| 
 | |
|     @attr(tags=["advanced"], required_hardware="false")
 | |
|     def test_02_created_shared_guest_network(self):
 | |
|         """
 | |
|         1. Create new physical network
 | |
|         2. Update the network with tags and traffic type "Guest"
 | |
|         3. Create a network offering and shared network based on the above physical network
 | |
|         4. Create a virtual machine using the above created network
 | |
|         4. Ensure that the traffic type is Guest and vlan is same as the shared network
 | |
|         :return:
 | |
|         """
 | |
|         #1. Create a physical network
 | |
|         self.physical_network_3 = PhysicalNetwork.create(
 | |
|             self.apiclient,
 | |
|             self.services["l2-network"],
 | |
|             isolationmethods="VLAN",
 | |
|             zoneid=self.zone.id
 | |
|         )
 | |
|         self.cleanup.append(self.physical_network_3)
 | |
| 
 | |
|         # Enable the network
 | |
|         self.physical_network_3.update(
 | |
|             self.apiclient,
 | |
|             tags="guest",
 | |
|             state="Enabled"
 | |
|         )
 | |
| 
 | |
|         #2. try adding traffic type Guest
 | |
|         TrafficType.add(
 | |
|             self.apiclient,
 | |
|             physicalnetworkid=self.physical_network_3.id,
 | |
|             kvmnetworklabel=self.kvmnetworklabel,
 | |
|             traffictype="Guest"
 | |
|         )
 | |
| 
 | |
|         # Create network offering
 | |
|         self.services["network_offering_shared"]["supportedservices"] = ""
 | |
|         self.services["network_offering_shared"]["serviceProviderList"] = {}
 | |
|         self.services["network_offering_shared"]["tags"] = "guest"
 | |
|         self.network_offering = NetworkOffering.create(
 | |
|             self.apiclient,
 | |
|             self.services["network_offering_shared"]
 | |
|         )
 | |
|         self.cleanup.append(self.network_offering)
 | |
| 
 | |
|         # Enable network offering
 | |
|         self.network_offering.update(
 | |
|             self.apiclient,
 | |
|             state='Enabled'
 | |
|         )
 | |
| 
 | |
|         #3. Create a shared network
 | |
|         self.shared_network = Network.create(
 | |
|             self.apiclient,
 | |
|             self.services["network2"],
 | |
|             networkofferingid=self.network_offering.id,
 | |
|             zoneid=self.zone.id,
 | |
|             domainid=self.domain.id
 | |
|             #physicalnetworkid=self.physical_network_3.id
 | |
|         )
 | |
|         self.cleanup.append(self.shared_network)
 | |
| 
 | |
|         # Create small service offering
 | |
|         self.service_offering = ServiceOffering.create(
 | |
|             self.apiclient,
 | |
|             self.testdata["service_offerings"]["small"]
 | |
|         )
 | |
|         self.cleanup.append(self.service_offering)
 | |
| 
 | |
|         #4. Create virtual machine
 | |
|         self.testdata["virtual_machine"]["zoneid"] = self.zone.id
 | |
|         self.testdata["virtual_machine"]["template"] = self.template.id
 | |
|         self.virtual_machine = VirtualMachine.create(
 | |
|             self.apiclient,
 | |
|             self.testdata["virtual_machine"],
 | |
|             templateid=self.template.id,
 | |
|             serviceofferingid=self.service_offering.id,
 | |
|             networkids=self.shared_network.id
 | |
|         )
 | |
|         self.cleanup.append(self.virtual_machine)
 | |
| 
 | |
|         list_vms = VirtualMachine.list(
 | |
|             self.apiclient,
 | |
|             id=self.virtual_machine.id
 | |
|         )
 | |
| 
 | |
|         vm = list_vms[0]
 | |
|         # make sure that vm uses the same vlan of the network
 | |
|         self.assertEqual(vm.nic[0].traffictype,
 | |
|                          "Guest",
 | |
|                          "Vm traffic type is not same")
 | |
| 
 | |
|         self.assertEqual(vm.nic[0].isolationuri,
 | |
|                          "vlan://" + str(self.services["network2"]["vlan"]),
 | |
|                          "Vm network vlan is not same")
 | |
| 
 | |
|         self.network_offering.update(
 | |
|             self.apiclient,
 | |
|             state='Disabled'
 | |
|         )
 | |
| 
 | |
|         hosts = Host.list(
 | |
|             self.apiclient,
 | |
|             id=vm.hostid
 | |
|         )
 | |
|         if isinstance(hosts, list) and len(hosts) > 0:
 | |
|             host = hosts[0]
 | |
|         else:
 | |
|             raise Exception("Cannot find the host where vm is running on")
 | |
|         if host.hypervisor.lower() not in "kvm":
 | |
|             return
 | |
|         if self.kvmnetworklabel is None:
 | |
|             return
 | |
|         try:
 | |
|             host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
 | |
|             physical_nic_kvmnetworklabel= _execute_ssh_command(host.ipaddress, 22, host.user, host.passwd, "brctl show %s | grep cloudbr |awk '{print $4}'" % self.kvmnetworklabel)
 | |
|             bridge_name = _execute_ssh_command(host.ipaddress, 22, host.user, host.passwd, "virsh domiflist %s |grep vnet |awk '{print $3}'" % vm.instancename)
 | |
|         except Exception as e:
 | |
|             return
 | |
| 
 | |
|         if bridge_name is not None and physical_nic_kvmnetworklabel is not None:
 | |
|             if bridge_name[0].startswith("br%s-" %physical_nic_kvmnetworklabel[0]):
 | |
|                 self.logger.debug("vm is running on physical nic %s and bridge %s" % (physical_nic_kvmnetworklabel[0], bridge_name[0]))
 | |
|             else:
 | |
|                 raise Exception("vm should be running on physical nic %s but on bridge" % (physical_nic_kvmnetworklabel[0], bridge_name[0]))
 | |
| 
 | |
|     @attr(tags=["advanced"], required_hardware="false")
 | |
|     def test_03_update_network_with_null_tags(self):
 | |
|         """
 | |
|         Update the tags to NULL for the existing physical network
 | |
|         Since the zone has already "Management" network of traffic type Guest without any tags,
 | |
|         we cant set the tags to null for the newly created networks
 | |
|         :return:
 | |
|         """
 | |
|         try:
 | |
|             # Set tags to null
 | |
|             self.physical_network.update(
 | |
|                 self.apiclient,
 | |
|                 tags=""
 | |
|             )
 | |
| 
 | |
|             # it should throw exception and should not come here
 | |
|             raise Exception("Tags cannot be removed from network as there are more than 1 network without tags")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected while removing the tags")
 | |
| 
 | |
|         try:
 | |
|             # Do the above steps for the second network
 | |
|             self.physical_network_2.update(
 | |
|                 self.apiclient,
 | |
|                 tags=""
 | |
|             )
 | |
| 
 | |
|             # it should throw exception and should not come here
 | |
|             raise Exception("Tags cannot be removed from network as there are more than 1 network without tags")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected while removing the tags")
 | |
| 
 | |
|     @attr(tags=["advanced"], required_hardware="false")
 | |
|     def test_04_add_invalid_network_tags(self):
 | |
|         """
 | |
|         Try to add other traffic types like "Storage", "Public" and "Management"
 | |
|         It should throw exception as there are physcial networks existing with this tag
 | |
|         :return:
 | |
|         """
 | |
|         try:
 | |
|             # Add traffic type storage
 | |
|             self.physical_network.addTrafficType(
 | |
|                 self.apiclient,
 | |
|                 type="Storage"
 | |
|             )
 | |
| 
 | |
|             # control should not come here
 | |
|             raise Exception("Storage tag should be assigned as there is another network with the same tag")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected while adding traffic type")
 | |
| 
 | |
|         try:
 | |
|             # Add traffic type Public
 | |
|             self.physical_network.addTrafficType(
 | |
|                 self.apiclient,
 | |
|                 type="Public"
 | |
|             )
 | |
| 
 | |
|             # control should not come here
 | |
|             raise Exception("Public tag should be assigned as there is another network with the same tag")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected while adding traffic type")
 | |
| 
 | |
|         try:
 | |
|             # Add traffic type Management
 | |
|             self.physical_network.addTrafficType(
 | |
|                 self.apiclient,
 | |
|                 type="Management"
 | |
|             )
 | |
| 
 | |
|             # control should not come here
 | |
|             raise Exception("Management tag should be assigned as there is another network with the same tag")
 | |
|         except Exception as e:
 | |
|             self.logger.info("Exception happened as expected while adding traffic type")
 |