| # 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. | |
| # this script will cover VMdeployment with Userdata tests | |
| from marvin.cloudstackTestCase import cloudstackTestCase | |
| from marvin.lib.base import * | |
| from marvin.lib.utils import (validateList, cleanup_resources) | |
| from marvin.lib.common import * | |
| from nose.plugins.attrib import attr | |
| from marvin.codes import PASS,FAIL | |
| _multiprocess_shared_ = True | |
| class Services: | |
| def __init__(self): | |
| self.services = { | |
| "virtual_machine": { | |
| "displayname": "TesVM1", | |
| "username": "root", | |
| "password": "password", | |
| "ssh_port": 22, | |
| "hypervisor": 'XenServer', | |
| "privateport": 22, | |
| "publicport": 22, | |
| "protocol": 'TCP', | |
| }, | |
| "ostype": 'CentOS 5.5 (64-bit)', | |
| "service_offering": { | |
| "name": "Tiny Instance", | |
| "displaytext": "Tiny Instance", | |
| "cpunumber": 1, | |
| "cpuspeed": 100, | |
| "memory": 256, | |
| }, | |
| } | |
| class TestDeployVmWithMetaData(cloudstackTestCase): | |
| @classmethod | |
| def setUpClass(cls): | |
| cls.testclient = super(TestDeployVmWithMetaData, cls).getClsTestClient() | |
| cls.apiclient = cls.testclient.getApiClient() | |
| cls._cleanup = [] | |
| #cls.services = Services().services | |
| cls.services = cls.testclient.getParsedTestDataConfig() | |
| cls.zone = get_zone(cls.apiclient, cls.testclient.getZoneForTests()) | |
| cls.service_offering = ServiceOffering.create( | |
| cls.apiclient, | |
| cls.services["service_offering"] | |
| ) | |
| cls.template = get_template( | |
| cls.apiclient, | |
| cls.zone.id, | |
| cls.services["ostype"] | |
| ) | |
| @classmethod | |
| def tearDownClass(cls): | |
| try: | |
| cls._cleanup = cls._cleanup[::-1] | |
| cleanup_resources(cls.apiclient, cls._cleanup) | |
| except Exception as e: | |
| raise Exception("Warning: Exception during cleanup : %s" % e) | |
| def setUp(self): | |
| self.apiclient = self.testClient.getApiClient() | |
| self.cleanup = [] | |
| def tearDown(self): | |
| try: | |
| self.cleanup = self.cleanup[::-1] | |
| cleanup_resources(self.apiclient, self.cleanup) | |
| except Exception as e: | |
| raise Exception("Warning: Exception during cleanup : %s" % e) | |
| return | |
| def migrate_VM(self, vm): | |
| """Migrates VM to another host, if available""" | |
| self.debug("+++ Migrating one of the VMs in the created " | |
| "VPC Tier network to another host, if available...") | |
| self.debug("Checking if a host is available for migration...") | |
| hosts = Host.listForMigration(self.apiclient, virtualmachineid=vm.id) | |
| if hosts: | |
| self.assertEqual(isinstance(hosts, list), True, | |
| "List hosts should return a valid list" | |
| ) | |
| host = hosts[0] | |
| self.debug("Migrating VM with ID: " | |
| "%s to Host: %s" % (vm.id, host.id)) | |
| try: | |
| vm.migrate(self.apiclient, hostid=host.id) | |
| except Exception as e: | |
| self.fail("Failed to migrate instance, %s" % e) | |
| self.debug("Migrated VM with ID: " | |
| "%s to Host: %s" % (vm.id, host.id)) | |
| else: | |
| self.debug("No host available for migration. " | |
| "Test requires at-least 2 hosts") | |
| return host | |
| def list_nics(self, vm_id): | |
| list_vm_res = VirtualMachine.list(self.apiclient, id=vm_id) | |
| self.assertEqual(validateList(list_vm_res)[0], PASS, "List vms returned invalid response") | |
| nics = list_vm_res[0].nic | |
| for nic in nics: | |
| if nic.type == "Shared": | |
| nic_res = NIC.list( | |
| self.apiclient, | |
| virtualmachineid=vm_id, | |
| nicid=nic.id | |
| ) | |
| nic_ip = nic_res[0].ipaddress | |
| self.assertIsNotNone(nic_ip, "listNics API response does not have the ip address") | |
| else: | |
| continue | |
| return | |
| @attr(tags=["advanced"], required_hardware='True') | |
| def test_deployVM_verify_metadata_in_VR(self): | |
| """ | |
| 1. Create a network (VR as a provider) | |
| 2. Deploy a VM in the network | |
| 3. Verify VM deployment | |
| 4. From the VM, curl the gateway of the VR to verify the corresponding metadata - hypervisor host name | |
| if the respective Global level and account level flags are set to true | |
| """ | |
| # Update global setting for "global.allow.expose.host.hostname" | |
| Configurations.update(self.apiclient, | |
| name="global.allow.expose.host.hostname", | |
| value="true" | |
| ) | |
| # Update Account level setting | |
| Configurations.update(self.apiclient, | |
| name="account.allow.expose.host.hostname", | |
| value="true" | |
| ) | |
| # Verify that the above mentioned settings are set to true before proceeding | |
| if not is_config_suitable( | |
| apiclient=self.apiclient, | |
| name='global.allow.expose.host.hostname', | |
| value='true'): | |
| self.skipTest('global.allow.expose.host.hostname should be true. skipping') | |
| if not is_config_suitable( | |
| apiclient=self.apiclient, | |
| name='account.allow.expose.host.hostname', | |
| value='true'): | |
| self.skipTest('account.allow.expose.host.hostname should be true. skipping') | |
| self.no_isolate = NetworkOffering.create( | |
| self.apiclient, | |
| self.services["isolated_network_offering"] | |
| ) | |
| self.no_isolate.update(self.apiclient, state='Enabled') | |
| self.isolated_network = Network.create( | |
| self.apiclient, | |
| self.services["network"], | |
| networkofferingid=self.no_isolate.id, | |
| zoneid=self.zone.id, | |
| accountid="admin", | |
| domainid=1 | |
| ) | |
| self.cleanup.append(self.isolated_network) | |
| self.vm = VirtualMachine.create( | |
| self.apiclient, | |
| self.services["virtual_machine"], | |
| templateid=self.template.id, | |
| accountid="admin", | |
| domainid=1, | |
| serviceofferingid=self.service_offering.id, | |
| zoneid=self.zone.id, | |
| networkids=[self.isolated_network.id], | |
| ) | |
| self.assertIsNotNone( | |
| self.vm, | |
| "VM creation failed in the isolated network" | |
| ) | |
| self.cleanup.append(self.vm) | |
| ip_addr = self.vm.ipaddress | |
| self.debug("VM ip address = %s" % ip_addr) | |
| # Verify the retrieved ip address in listNICs API response | |
| self.list_nics(self.vm.id) | |
| vr_res = Router.list( | |
| self.apiclient, | |
| networkid=self.isolated_network.id, | |
| listAll=True | |
| ) | |
| self.assertEqual(validateList(vr_res)[0], PASS, "List Routers returned invalid response") | |
| vr_ip = vr_res[0].guestipaddress | |
| ssh = self.vm.get_ssh_client(ipaddress=ip_addr) | |
| cmd = "curl http://%s/latest/hypervisor-host-name" % vr_ip | |
| res = ssh.execute(cmd) | |
| self.debug("Verifying hypervisor hostname details in the VR") | |
| self.assertEqual( | |
| str(res), | |
| self.vm.hostname, | |
| "Failed to get the hypervisor host name from VR in isolated network" | |
| ) | |
| # Reset configuration values to default values i.e., false | |
| Configurations.update(self.apiclient, | |
| name="global.allow.expose.host.hostname", | |
| value="false" | |
| ) | |
| # Update Account level setting | |
| Configurations.update(self.apiclient, | |
| name="account.allow.expose.host.hostname", | |
| value="false" | |
| ) | |
| return | |
| @attr(tags=["advanced"], required_hardware='True') | |
| def test_deployVM_verify_metadata_in_VR_after_migration(self): | |
| """ | |
| 1. Create a network (VR as a provider) | |
| 2. Deploy a VM in the network | |
| 3. Verify VM deployment | |
| 4. Migrate VM to another host | |
| 4. After migration, from the VM, curl the gateway to verify the corresponding metadata - hypervisor host name | |
| if the respective Global level and account level flags are set to true | |
| """ | |
| # Update global setting for "global.allow.expose.host.hostname" | |
| Configurations.update(self.apiclient, | |
| name="global.allow.expose.host.hostname", | |
| value="true" | |
| ) | |
| # Update Account level setting | |
| Configurations.update(self.apiclient, | |
| name="account.allow.expose.host.hostname", | |
| value="true" | |
| ) | |
| # Verify that the above mentioned settings are set to true before proceeding | |
| if not is_config_suitable( | |
| apiclient=self.apiclient, | |
| name='global.allow.expose.host.hostname', | |
| value='true'): | |
| self.skipTest('global.allow.expose.host.hostname should be true. skipping') | |
| if not is_config_suitable( | |
| apiclient=self.apiclient, | |
| name='account.allow.expose.host.hostname', | |
| value='true'): | |
| self.skipTest('Account level account.allow.expose.host.hostname should be true. skipping') | |
| self.no_isolate = NetworkOffering.create( | |
| self.apiclient, | |
| self.services["isolated_network_offering"] | |
| ) | |
| self.no_isolate.update(self.apiclient, state='Enabled') | |
| self.isolated_network = Network.create( | |
| self.apiclient, | |
| self.services["network"], | |
| networkofferingid=self.no_isolate.id, | |
| zoneid=self.zone.id, | |
| accountid="admin", | |
| domainid=1 | |
| ) | |
| self.cleanup.append(self.isolated_network) | |
| self.vm = VirtualMachine.create( | |
| self.apiclient, | |
| self.services["virtual_machine"], | |
| templateid=self.template.id, | |
| accountid="admin", | |
| domainid=1, | |
| serviceofferingid=self.service_offering.id, | |
| zoneid=self.zone.id, | |
| networkids=[self.isolated_network.id], | |
| ) | |
| self.assertIsNotNone( | |
| self.vm, | |
| "VM creation failed in the isolated network" | |
| ) | |
| host = self.migrate_VM(self.vm) | |
| self.cleanup.append(self.vm) | |
| ip_addr = self.vm.ipaddress | |
| self.debug("VM ip address = %s" % ip_addr) | |
| # Verify the retrieved ip address in listNICs API response | |
| self.list_nics(self.vm.id) | |
| vr_res = Router.list( | |
| self.apiclient, | |
| networkid=self.isolated_network.id, | |
| listAll=True | |
| ) | |
| self.assertEqual(validateList(vr_res)[0], PASS, "List Routers returned invalid response") | |
| vr_ip = vr_res[0].guestipaddress | |
| ssh = self.vm.get_ssh_client(ipaddress=ip_addr) | |
| cmd = "curl http://%s/latest/hypervisor-host-name" % vr_ip | |
| res = ssh.execute(cmd) | |
| self.debug("Verifying hypervisor hostname details in the VR") | |
| self.assertEqual( | |
| str(res), | |
| host.name, | |
| "Failed to get the hypervisor host name from VR in isolated network" | |
| ) | |
| # Reset configuration values to default values i.e., false | |
| Configurations.update(self.apiclient, | |
| name="global.allow.expose.host.hostname", | |
| value="false" | |
| ) | |
| # Update Account level setting | |
| Configurations.update(self.apiclient, | |
| name="account.allow.expose.host.hostname", | |
| value="false" | |
| ) | |
| return |