Repository: cloudstack Updated Branches: refs/heads/master dc0ba6bd1 -> de173bd89
Add nuagevsp userdata testcase (Cloudstack-9095) & Refactor existing testcases Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/3c8d3d0e Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/3c8d3d0e Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/3c8d3d0e Branch: refs/heads/master Commit: 3c8d3d0ee1288931369650195c8c316508483757 Parents: 359d20e Author: Sowmya <sowmya.neeladh...@nokia.com> Authored: Tue Mar 8 18:13:24 2016 -0800 Committer: Sowmya <sowmya.neeladh...@nokia.com> Committed: Tue Mar 8 18:13:24 2016 -0800 ---------------------------------------------------------------------- test/integration/component/test_nuage_vsp.py | 334 -------- .../plugins/nuagevsp/nuageTestCase.py | 830 +++++++++++++++++++ .../nuagevsp/test_nuage_password_reset.py | 249 ++++++ .../plugins/nuagevsp/test_nuage_vpc_network.py | 98 +++ .../plugins/nuagevsp/test_nuage_vsp.py | 106 +++ tools/marvin/marvin/config/test_data.py | 110 +++ tools/marvin/marvin/lib/base.py | 55 ++ 7 files changed, 1448 insertions(+), 334 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/test/integration/component/test_nuage_vsp.py ---------------------------------------------------------------------- diff --git a/test/integration/component/test_nuage_vsp.py b/test/integration/component/test_nuage_vsp.py deleted file mode 100644 index e7bd10e..0000000 --- a/test/integration/component/test_nuage_vsp.py +++ /dev/null @@ -1,334 +0,0 @@ -# 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 NuageVsp network Plugin -""" -# Import Local Modules -from nose.plugins.attrib import attr -from marvin.cloudstackTestCase import cloudstackTestCase -from marvin.cloudstackAPI import (listPhysicalNetworks, - listNetworkServiceProviders, - addNetworkServiceProvider, - deleteNetworkServiceProvider, - deleteNuageVspDevice, - updateNetworkServiceProvider, - addNuageVspDevice, - destroyVirtualMachine) -from marvin.lib.utils import (cleanup_resources) -from marvin.lib.base import (Account, - VirtualMachine, - ServiceOffering, - NetworkOffering, - Network) -from marvin.lib.common import (get_domain, - get_zone, - get_template) - -import logging -import unittest - - -class Services: - - """Test NuageVsp plugin - """ - - def __init__(self): - print "in __init__" - self.services = { - "account": { - "email": "cloudst...@cloudmonkey.com", - "firstname": "cloudstack", - "lastname": "bob", - "username": "admin", - "password": "password", - }, - "service_offering": { - "name": "Tiny Instance", - "displaytext": "Tiny Instance", - "cpunumber": 1, - "cpuspeed": 100, # in MHz - "memory": 128, # In MBs - }, - "virtual_machine": { - "displayname": "TestVM", - "username": "root", - "password": "password", - "ssh_port": 22, - "hypervisor": 'KVM', - "privateport": 22, - "publicport": 22, - "protocol": 'TCP', - }, - "nuage_vsp_device": { - "hostname": '172.31.222.162', - "username": 'cloudstackuser1', - "password": 'cloudstackuser1', - "port": '8443', - "apiversion": 'v3_2', - "retrycount": '4', - "retryinterval": '60' - }, - # services supported by Nuage for isolated networks. - "network_offering": { - "name": 'nuage_marvin', - "displaytext": 'nuage_marvin', - "guestiptype": 'Isolated', - "supportedservices": - 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', - "traffictype": 'GUEST', - "availability": 'Optional', - "serviceProviderList": { - "UserData": 'VirtualRouter', - "Dhcp": 'NuageVsp', - "Connectivity": 'NuageVsp', - "StaticNat": 'NuageVsp', - "SourceNat": 'NuageVsp', - "Firewall": 'NuageVsp' - }, - "serviceCapabilityList": { - "SourceNat": {"SupportedSourceNatTypes": "perzone"}, - } - }, - "network": { - "name": "nuage", - "displaytext": "nuage", - }, - "ostype": 'CentOS 5.5 (64-bit)', - "sleep": 60, - "timeout": 10 - } - - -class TestNuageVsp(cloudstackTestCase): - - @classmethod - def setUpClass(cls): - print "In setup class" - cls._cleanup = [] - cls.testClient = super(TestNuageVsp, cls).getClsTestClient() - cls.api_client = cls.testClient.getApiClient() - - 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()) - cls.template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - # nuage vsp device brings the Nuage virtual service platform into play - cls.nuage_services = cls.services["nuage_vsp_device"] - try: - - resp = listPhysicalNetworks.listPhysicalNetworksCmd() - print "in cls.setupClass- resp: %s" % resp - resp.zoneid = cls.zone.id - physical_networks = cls.api_client.listPhysicalNetworks(resp) - for pn in physical_networks: - if pn.isolationmethods=='VSP': - physical_network = pn - #if isinstance(physical_networks, list): - # physical_network = physical_networks[1] - resp = listNetworkServiceProviders.listNetworkServiceProvidersCmd() - resp.name = 'NuageVsp' - resp.physicalnetworkid = physical_network.id - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - if not isinstance(nw_service_providers, list): - # create network service provider and add nuage vsp device - resp_add_nsp =\ - addNetworkServiceProvider.addNetworkServiceProviderCmd() - resp_add_nsp.name = 'NuageVsp' - resp_add_nsp.physicalnetworkid = physical_network.id - cls.api_client.addNetworkServiceProvider(resp_add_nsp) - #Get NSP ID - nw_service_providers = cls.api_client.listNetworkServiceProviders( - resp) - cls.debug("NuageVsp NSP ID: %s" % nw_service_providers[0].id) - - resp_add_device = addNuageVspDevice.addNuageVspDeviceCmd() - resp_add_device.physicalnetworkid = physical_network.id - resp_add_device.username = cls.nuage_services["username"] - resp_add_device.password = cls.nuage_services["password"] - resp_add_device.hostname = cls.nuage_services["hostname"] - resp_add_device.port = cls.nuage_services["port"] - resp_add_device.apiversion = cls.nuage_services[ - "apiversion"] - resp_add_device.retrycount = cls.nuage_services[ - "retrycount"] - resp_add_device.retryinterval = cls.nuage_services[ - "retryinterval"] - cls.nuage = cls.api_client.addNuageVspDevice( - resp_add_device) - #Enable NuageVsp NSP - cls.debug("NuageVsp NSP ID : %s" % nw_service_providers[0].id) - resp_up_nsp = \ - updateNetworkServiceProvider.updateNetworkServiceProviderCmd() - resp_up_nsp.id = nw_service_providers[0].id - resp_up_nsp.state = 'Enabled' - cls.api_client.updateNetworkServiceProvider(resp_up_nsp) - - cls.network_offering = NetworkOffering.create( - cls.api_client, - cls.services["network_offering"], - conservemode=True - ) - cls._cleanup.append(cls.network_offering) - - cls.network_offering.update(cls.api_client, state='Enabled') - cls.services["virtual_machine"]["zoneid"] = cls.zone.id - cls.services["virtual_machine"]["template"] = cls.template.id - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls._cleanup.append(cls.service_offering) - except Exception as e: - cls.tearDownClass() - raise unittest.SkipTest("Unable to add VSP device") - return - - @classmethod - def tearDownClass(cls): - try: - cleanup_resources(cls.api_client, cls._cleanup) - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - - def setUp(self): - self.apiclient = self.testClient.getApiClient() - self.dbclient = self.testClient.getDbConnection() - self.account = Account.create( - self.apiclient, - self.services["account"], - admin=True, - domainid=self.domain.id - ) - self.cleanup = [self.account] - return - - - def tearDown(self): - try: - self.debug("Cleaning up the resources") - cleanup_resources(self.apiclient, self.cleanup) - self.debug("Cleanup complete!") - except Exception as e: - raise Exception("Warning: Exception during cleanup : %s" % e) - return - - @attr(tags=["advanced"]) - def test_network_vsp(self): - """Test nuage Network and VM Creation - """ - - self.debug("Creating network with network offering: %s" % - self.network_offering.id) - self.network = Network.create( - self.apiclient, - self.services["network"], - accountid=self.account.name, - domainid=self.account.domainid, - networkofferingid=self.network_offering.id, - zoneid=self.zone.id, - gateway = "10.1.1.1", - netmask = '255.255.255.0' - ) - self.debug("Created network with ID: %s" % self.network.id) - - self.debug("Deploying VM in account: %s" % self.account.name) - - virtual_machine_1 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_1.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" - % virtual_machine_1.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) - - self.debug("Deploying another VM in account: %s" % - self.account.name) - - virtual_machine_2 = VirtualMachine.create( - self.apiclient, - self.services["virtual_machine"], - accountid=self.account.name, - domainid=self.account.domainid, - serviceofferingid=self.service_offering.id, - networkids=[str(self.network.id)] - ) - self.debug("Deployed VM in network: %s" % self.network.id) - list_vm_response = VirtualMachine.list( - self.apiclient, - id=virtual_machine_2.id - ) - - self.debug( - "Verify listVirtualMachines response for virtual machine: %s" - % virtual_machine_2.id - ) - - self.assertEqual( - isinstance(list_vm_response, list), - True, - "Check list response returns a valid list" - ) - vm_response = list_vm_response[0] - - self.assertEqual( - vm_response.state, - "Running", - "VM state should be running after deployment" - ) - - VirtualMachine.delete(virtual_machine_1, self.apiclient, expunge=True) - - # # Deleting a single VM - VirtualMachine.delete(virtual_machine_2, self.apiclient, expunge=True) - - # Delete Network - Network.delete(self.network, self.apiclient) - - return http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/test/integration/plugins/nuagevsp/nuageTestCase.py ---------------------------------------------------------------------- diff --git a/test/integration/plugins/nuagevsp/nuageTestCase.py b/test/integration/plugins/nuagevsp/nuageTestCase.py new file mode 100644 index 0000000..123f2bc --- /dev/null +++ b/test/integration/plugins/nuagevsp/nuageTestCase.py @@ -0,0 +1,830 @@ +# 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. + +""" Custom base class for NuageVsp network Plugin specific Marvin tests +""" +# Import Local Modules +from marvin.cloudstackTestCase import cloudstackTestCase, unittest +from marvin.lib.base import (NetworkServiceProvider, + ServiceOffering, + NetworkOffering, + Network, + Router, + Nuage, + VPC, + VpcOffering, + PublicIPAddress, + VirtualMachine, + StaticNATRule, + NetworkACLList, + NetworkACL, + FireWallRule, + EgressFireWallRule, + Host) +from marvin.lib.common import (get_zone, + get_domain, + get_template, + list_templates, + wait_for_cleanup) +from marvin.lib.utils import cleanup_resources +from marvin.cloudstackAPI import (listPhysicalNetworks, + updateConfiguration, + updateTemplate, + listConfigurations, + listHypervisors, + stopRouter, + startRouter) +# Import nosetests Modules +from nose.plugins.attrib import attr + +# Import System Modules +import socket +import importlib +import logging + + +class nuageTestCase(cloudstackTestCase): + + @classmethod + def setUpClass(cls): + cls.debug("setUpClass nuageTestCase") + + # We want to fail quicker, if it's a failure + socket.setdefaulttimeout(60) + + test_client = super(nuageTestCase, cls).getClsTestClient() + cls.api_client = test_client.getApiClient() + cls.db_client = test_client.getDbConnection() + cls.test_data = test_client.getParsedTestDataConfig() + + # Get Zone, Domain and templates + cls.zone = get_zone(cls.api_client) + cls.domain = get_domain(cls.api_client) + cls.template = get_template(cls.api_client, + cls.zone.id, + cls.test_data["ostype"] + ) + cls.test_data["virtual_machine"]["zoneid"] = cls.zone.id + cls.test_data["virtual_machine"]["template"] = cls.template.id + + # Create service offering + cls.service_offering = ServiceOffering.create(cls.api_client, + cls.test_data["service_offering"] + ) + cls._cleanup = [cls.service_offering] + + # Get configured Nuage Vsp device details + try: + resp = listPhysicalNetworks.listPhysicalNetworksCmd() + resp.zoneid = cls.zone.id + physical_networks = cls.api_client.listPhysicalNetworks(resp) + for pn in physical_networks: + if pn.isolationmethods == 'VSP': + cls.vsp_physical_network = pn + cls.nuage_vsp_device = Nuage.list(cls.api_client, + physicalnetworkid=cls.vsp_physical_network.id + )[0] + pns = cls.config.zones[0].physical_networks + providers = filter(lambda physical_network: 'VSP' in physical_network.isolationmethods, pns)[0].providers + devices = filter(lambda provider: provider.name == 'NuageVsp', providers)[0].devices + cls.nuage_vsp_device.username = devices[0].username + cls.nuage_vsp_device.password = devices[0].password + listConfigurationsCmd = listConfigurations.listConfigurationsCmd() + listConfigurationsCmd.name = "nuagevsp.cms.id" + listConfigurationsCmd.scopename = "global" + cs_config_dict = cls.api_client.listConfigurations(listConfigurationsCmd) + cls.cms_id = str(cs_config_dict[0].value).split(":")[1] + except Exception as e: + cls.tearDownClass() + raise unittest.SkipTest("Warning: Couldn't get configured Nuage Vsp device details: %s" % e) + + # Check if the host hypervisor type is simulator + resp = listHypervisors.listHypervisorsCmd() + resp.zoneid = cls.zone.id + cls.isSimulator = cls.api_client.listHypervisors(resp)[0].name == 'Simulator' + + # VSD is a Python SDK for Nuage Vsp + try: + vspk_module = "vspk." + cls.nuage_vsp_device.apiversion if int(cls.nuage_vsp_device.apiversion[1]) >= 4 \ + else "vspk.vsdk." + cls.nuage_vsp_device.apiversion + vsdk = importlib.import_module(vspk_module) + vspk_utils_module = "vspk.utils" if int(cls.nuage_vsp_device.apiversion[1]) >= 4 \ + else "vspk.vsdk." + cls.nuage_vsp_device.apiversion + ".utils" + vsdk_utils = importlib.import_module(vspk_utils_module) + set_log_level = getattr(vsdk_utils, "set_log_level") + from cms_vspk_wrapper.cms_vspk_wrapper import Cms_vspk_wrapper + except: + raise unittest.SkipTest("vspk (and/or) cms_vspk_wrapper import failure") + + # Configure VSD session + cls._session = vsdk.NUVSDSession(username=cls.nuage_vsp_device.username, + password=cls.nuage_vsp_device.password, + enterprise="csp", api_url="https://%s:%d" % + (cls.nuage_vsp_device.hostname, + cls.nuage_vsp_device.port) + ) + cls._session.start() + + # Configure cms_vspk_wrapper session + cls.log_handler = logging.getLogger("CSLog").handlers[0] + vsd_info = cls.nuage_vsp_device.__dict__ + vsd_info["port"] = str(vsd_info["port"]) + cls.vsd = Cms_vspk_wrapper(vsd_info, cls.log_handler) + + set_log_level(logging.INFO) + + cls.debug("setUpClass nuageTestCase [DONE]") + + def setUp(self): + self.cleanup = [] + return + + @classmethod + def tearDownClass(cls): + try: + # Cleanup resources used + cleanup_resources(cls.api_client, cls._cleanup) + except Exception as e: + cls.debug("Warning: Exception during cleanup : %s" % e) + return + + def tearDown(self): + # Cleanup resources used + self.debug("Cleaning up the resources") + for obj in reversed(self.cleanup): + try: + if isinstance(obj, VirtualMachine): + obj.delete(self.api_client, expunge=True) + else: + obj.delete(self.api_client) + except Exception as e: + self.error("Failed to cleanup %s, got %s" % (obj, e)) + # cleanup_resources(self.api_client, self.cleanup) + self.cleanup = [] + self.debug("Cleanup complete!") + return + + def getConfigurationValue(self, name, scope="global"): + listConfigurationsCmd = listConfigurations.listConfigurationsCmd() + listConfigurationsCmd.name = name + listConfigurationsCmd.scopename = scope + if scope is "zone": + listConfigurationsCmd.zoneid = self.zone.id + return self.api_client.listConfigurations(listConfigurationsCmd) + + def setConfigurationValue(self, name, value, scope="global"): + cmd = updateConfiguration.updateConfigurationCmd() + cmd.name = name + cmd.scopename = scope + if scope is "zone": + cmd.zoneid = self.zone.id + cmd.value = value + self.api_client.updateConfiguration(cmd) + + def updateTemplate(self, value): + self.debug("UPDATE TEMPLATE") + cmd = updateTemplate.updateTemplateCmd() + cmd.id = self.template.id + cmd.passwordenabled = value + self.api_client.updateTemplate(cmd) + list_template_response = list_templates(self.api_client, + templatefilter="all", + id=self.template.id + ) + self.template = list_template_response[0] + + # Creates the vpc offering + def create_VpcOffering(self, vpc_offering, suffix=None): + self.debug('Create VpcOffering') + if suffix: + vpc_offering["name"] = "VPC_OFF-" + str(suffix) + vpc_off = VpcOffering.create(self.api_client, + vpc_offering + ) + # Enable VPC offering + vpc_off.update(self.api_client, state='Enabled') + self.cleanup.append(vpc_off) + self.debug('Created and Enabled VpcOffering') + return vpc_off + + # create_Vpc - Takes the vpc offering as arguments and creates the VPC + def create_Vpc(self, vpc_offering, cidr='10.1.1.1/16', cleanup=True): + self.debug("Creating a VPC network in the account: %s" % self.account.name) + self.test_data["vpc"]["cidr"] = cidr + vpc = VPC.create( + self.api_client, + self.test_data["vpc"], + vpcofferingid=vpc_offering.id, + zoneid=self.zone.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.debug("Created VPC with ID: %s" % vpc.id) + if cleanup: + self.cleanup.append(vpc) + return vpc + + # create_NetworkOffering - Takes the network offering as argument and creates the Network Offering + def create_NetworkOffering(self, net_offering, suffix=None, conserve_mode=False): + self.debug('Create NetworkOffering') + if suffix: + net_offering["name"] = "NET_OFF-" + str(suffix) + nw_off = NetworkOffering.create(self.api_client, + net_offering, + conservemode=conserve_mode + ) + # Enable Network offering + nw_off.update(self.api_client, state='Enabled') + self.cleanup.append(nw_off) + self.debug('Created and Enabled NetworkOffering') + return nw_off + + # create_Network - Takes the network offering as argument and nw_key and creates the network + def create_Network(self, nw_off, nw_key="network", gateway='10.1.1.1', netmask='255.255.255.0', vpc=None, acl_list=None): + if not hasattr(nw_off, "id"): + nw_off = self.create_NetworkOffering(nw_off) + self.debug('Adding Network=%s' % self.test_data[nw_key]) + self.test_data[nw_key]["netmask"] = netmask + obj_network = Network.create(self.api_client, + self.test_data[nw_key], + accountid=self.account.name, + domainid=self.account.domainid, + networkofferingid=nw_off.id, + zoneid=self.zone.id, + gateway=gateway, + vpcid=vpc.id if vpc else self.vpc.id if hasattr(self, "vpc") else None, + aclid=acl_list.id if acl_list else None + ) + self.debug("Created network with ID: %s" % obj_network.id) + self.cleanup.append(obj_network) + return obj_network + + # upgrade_Network - Upgrades the given network + def upgrade_Network(self, nw_off, network): + if not hasattr(nw_off, "id"): + nw_off = self.create_NetworkOffering(nw_off, network.gateway) + self.debug('Update Network=%s' % network) + network.update( + self.api_client, + networkofferingid=nw_off.id, + changecidr=False + ) + self.debug("Updated network with ID: %s" % network.id) + + # delete_Network - Deletes the given network + def delete_Network(self, network): + self.debug('Deleting Network - %s' % network.name) + # Wait for network garbage collection before network deletion + wait_for_cleanup(self.api_client, + ["network.gc.interval", "network.gc.wait"] + ) + network.delete(self.api_client) + if network in self.cleanup: + self.cleanup.remove(network) + self.debug('Deleted Network - %s' % network.name) + + # create_VM_in_Network - Creates a VM in the given network, the vm_key - is the key for the services on the vm. + def create_VM_in_Network(self, network, vm_key="virtual_machine", host_id=None, start_vm=True): + self.debug('Creating VM in network=%s' % network.name) + self.debug('Passed vm_key=%s' % vm_key) + self.test_data[vm_key]["zoneid"] = self.zone.id + self.test_data[vm_key]["template"] = self.template.id + vm = VirtualMachine.create( + self.api_client, + self.test_data[vm_key], + accountid=self.account.name, + domainid=self.account.domainid, + serviceofferingid=self.service_offering.id, + networkids=[str(network.id)], + startvm=start_vm, + hostid=host_id + ) + self.debug('Created VM=%s in network=%s' % (vm.id, network.name)) + self.cleanup.append(vm) + return vm + + # starts the given vm + def start(self, apiclient): + """Start the instance""" + cmd = startVirtualMachine.startVirtualMachineCmd() + cmd.id = self.id + apiclient.startVirtualMachine(cmd) + response = self.getState(apiclient, VirtualMachine.RUNNING) + if response[0] == FAIL: + raise Exception(response[1]) + return + + # stops the given vm + def stop(self, apiclient, forced=None): + """Stop the instance""" + cmd = stopVirtualMachine.stopVirtualMachineCmd() + cmd.id = self.id + if forced: + cmd.forced = forced + apiclient.stopVirtualMachine(cmd) + response = self.getState(apiclient, VirtualMachine.STOPPED) + if response[0] == FAIL: + raise Exception(response[1]) + return + + # delete_VM - Deletes the given VM + def delete_VM(self, vm): + self.debug('Deleting VM - %s' % vm.name) + vm.delete(self.api_client) + # Wait for expunge interval to cleanup VM + wait_for_cleanup(self.api_client, + ["expunge.delay", "expunge.interval"] + ) + if vm in self.cleanup: + self.cleanup.remove(vm) + self.debug('Deleted VM - %s' % vm.name) + + # acquire_Public_IP - Acquires a public IP for the given network + def acquire_Public_IP(self, network, vpc=None): + self.debug("Associating public IP for network: %s" % network.name) + public_ip = PublicIPAddress.create(self.api_client, + accountid=self.account.name, + zoneid=self.zone.id, + domainid=self.account.domainid, + networkid=network.id if vpc is None else None, + vpcid=vpc.id if vpc else self.vpc.id if hasattr(self, "vpc") else None + ) + self.debug("Associated %s with network %s" % (public_ip.ipaddress.ipaddress, + network.id)) + return public_ip + + # create_StaticNatRule_For_VM - Creates static NAT rule for the given network , VM on the given public ip + def create_StaticNatRule_For_VM(self, vm, public_ip, network, vmguestip=None): + self.debug("Enabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + StaticNATRule.enable( + self.api_client, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=vm.id, + networkid=network.id, + vmguestip=vmguestip + ) + self.debug("Static NAT enabled for IP: %s" % + public_ip.ipaddress.ipaddress) + + # delete_StaticNatRule_For_VM - Deletes the static NAT rule for the given VM + def delete_StaticNatRule_For_VM(self, vm, public_ip): + self.debug("Disabling static NAT for IP: %s" % + public_ip.ipaddress.ipaddress) + StaticNATRule.disable( + self.api_client, + ipaddressid=public_ip.ipaddress.id, + virtualmachineid=vm.id + ) + self.debug("Static NAT disabled for IP: %s" % + public_ip.ipaddress.ipaddress) + + # create_firewall_rule - Creates the Ingress firewall rule on the given public ip + def create_firewall_rule(self, public_ip, rule=None): + if not rule: + rule = self.test_data["ingress_rule"] + self.debug("Adding an Ingress Firewall rule to make Guest VMs accessible through Static NAT") + return FireWallRule.create(self.api_client, + ipaddressid=public_ip.ipaddress.id, + protocol=rule["protocol"], + cidrlist=rule["cidrlist"], + startport=rule["startport"], + endport=rule["endport"] + ) + + # create_egress_firewall_rule - Creates the Egress firewall rule on the given public ip + def create_egress_firewall_rule(self, network, rule): + self.debug("Adding an Egress Firewall rule to allow/deny outgoing traffic from Guest VMs") + return EgressFireWallRule.create(self.api_client, + networkid=network.id, + protocol=rule["protocol"], + cidrlist=rule["cidrlist"], + startport=rule["startport"], + endport=rule["endport"] + ) + + # create_network_acl_list - Creates network ACL list in the given VPC + def create_network_acl_list(self, name, description, vpc): + self.debug("Adding NetworkACL list in VPC: %s" % vpc.id) + return NetworkACLList.create(self.api_client, + services={}, + name=name, + description=description, + vpcid=vpc.id + ) + + # create_network_acl_rule - Creates network ACL rule Ingree/Egress in the given network + def create_network_acl_rule(self, rule, traffic_type="Ingress", network=None, acl_list=None): + self.debug("Adding NetworkACL rule: %s" % rule) + return NetworkACL.create(self.api_client, + networkid=network.id if network else None, + services=rule, + traffictype=traffic_type, + aclid=acl_list.id if acl_list else None + ) + + # migrate_vm - Migrates the VM to a different host if available + def migrate_vm(self, vm): + self.debug("Checking if a host is available for migration?") + hosts = Host.listForMigration(self.api_client) + self.assertEqual(isinstance(hosts, list), True, + "List hosts should return a valid list" + ) + # Remove the host of current VM from the hosts list + hosts[:] = [host for host in hosts if host.id != vm.hostid] + if len(hosts) <= 0: + self.skipTest("No host available for migration. Test requires at-least 2 hosts") + host = hosts[0] + self.debug("Migrating VM-ID: %s to Host: %s" % (vm.id, host.id)) + try: + vm.migrate(self.api_client, hostid=host.id) + except Exception as e: + self.fail("Failed to migrate instance, %s" % e) + + # get_network_router - returns the router for the given network + def get_network_router(self, network): + self.debug("Finding the virtual router for network: %s" % network.name) + routers = Router.list(self.api_client, + networkid=network.id, + listall=True + ) + self.assertEqual(isinstance(routers, list), True, + "List routers should return a valid virtual router for network" + ) + return routers[0] + + # stop_network_router - Stops the given network router + def stop_network_router(self, router): + self.debug("Stopping Router with ID: %s" % router.id) + cmd = stopRouter.stopRouterCmd() + cmd.id = router.id + self.api_client.stopRouter(cmd) + + # start_network_router - Starts the given network router + def start_network_router(self, router): + self.debug("Starting Router with ID: %s" % router.id) + cmd = startRouter.startRouterCmd() + cmd.id = router.id + self.api_client.startRouter(cmd) + + # ssh_into_vm - Gets into the shell of the given VM + def ssh_into_vm(self, vm, public_ip): + self.debug("SSH into VM=%s on public_ip=%s" % (vm.name, public_ip.ipaddress.ipaddress)) + ssh_client = vm.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress) + return ssh_client + + # execute_cmd - Executes the given command on the given ssh client + def execute_cmd(self, ssh_client, cmd): + self.debug("EXECUTE SSH COMMAND: " + cmd) + ret_data = "" + out_list = ssh_client.execute(cmd) + if out_list is not None: + ret_data = ' '.join(map(str, out_list)).strip() + self.debug("ssh execute cmd result=" + ret_data) + else: + self.debug("ssh execute cmd result is None") + return ret_data + + # wget_from_server - fetches the index.html file from the given public Ip + def wget_from_server(self, public_ip): + import urllib + self.debug("wget from a http server on public_ip=%s" % public_ip.ipaddress.ipaddress) + wget_file = urllib.urlretrieve("http://%s/index.html" % public_ip.ipaddress.ipaddress, + filename="index.html" + ) + return wget_file + + # validate_NetworkServiceProvider - Validates the Network Service Provider + # in the Nuage VSP Physical Network - matches the given provider name + # against the list of providers fetched + def validate_NetworkServiceProvider(self, provider_name, state=None): + """Validates the Network Service Provider in the Nuage VSP Physical Network""" + self.debug("Check if the Network Service Provider is created successfully ?") + providers = NetworkServiceProvider.list(self.api_client, + name=provider_name, + physicalnetworkid=self.vsp_physical_network.id) + self.assertEqual(isinstance(providers, list), True, + "List Network Service Provider should return a valid list" + ) + self.assertEqual(provider_name, providers[0].name, + "Name of the Network Service Provider should match with the returned list data" + ) + if state: + self.assertEqual(providers[0].state, state, + "Network Service Provider state should be '%s'" % state + ) + self.debug("Network Service Provider creation successfully validated - %s" % provider_name) + + # validate_vpc_offering - Validates the VPC offering, matches the given VPC off name against the list of VPC offerings fetched + def validate_vpc_offering(self, vpc_offering, state=None): + """Validates the VPC offering""" + self.debug("Check if the VPC offering is created successfully ?") + vpc_offs = VpcOffering.list(self.api_client, + id=vpc_offering.id + ) + self.assertEqual(isinstance(vpc_offs, list), True, + "List VPC offering should return a valid list" + ) + self.assertEqual(vpc_offering.name, vpc_offs[0].name, + "Name of the VPC offering should match with the returned list data" + ) + if state: + self.assertEqual(vpc_offs[0].state, state, + "VPC offering state should be '%s'" % state + ) + self.debug("VPC offering creation successfully validated - %s" % vpc_offering.name) + + # validate_vpc - Validates the given VPC matches, the given VPC name against the list of VPCs fetched + def validate_vpc(self, vpc, state=None): + """Validates the VPC""" + self.debug("Check if the VPC is created successfully ?") + vpcs = VPC.list(self.api_client, + id=vpc.id + ) + self.assertEqual(isinstance(vpcs, list), True, + "List VPC should return a valid list" + ) + self.assertEqual(vpc.name, vpcs[0].name, + "Name of the VPC should match with the returned list data" + ) + if state: + self.assertEqual(vpcs[0].state, state, + "VPC state should be '%s'" % state + ) + self.debug("VPC creation successfully validated - %s" % vpc.name) + + # validate_network_offering - Validates the given Network offering + # matches the given network offering name against the list of network + # offerings fetched + def validate_network_offering(self, net_offering, state=None): + """Validates the Network offering""" + self.debug("Check if the Network offering is created successfully ?") + net_offs = NetworkOffering.list(self.api_client, + id=net_offering.id + ) + self.assertEqual(isinstance(net_offs, list), True, + "List Network offering should return a valid list" + ) + self.assertEqual(net_offering.name, net_offs[0].name, + "Name of the Network offering should match with the returned list data" + ) + if state: + self.assertEqual(net_offs[0].state, state, + "Network offering state should be '%s'" % state + ) + self.debug("Network offering creation successfully validated - %s" % net_offering.name) + + # validate_network - Validates the network - matches the given network name against the list of networks fetched + def validate_network(self, network, state=None): + """Validates the network""" + self.debug("Check if the network is created successfully ?") + networks = Network.list(self.api_client, + id=network.id + ) + self.assertEqual(isinstance(networks, list), True, + "List network should return a valid list" + ) + self.assertEqual(network.name, networks[0].name, + "Name of the network should match with with the returned list data" + ) + if state: + self.assertEqual(networks[0].state, state, + "Network state should be '%s'" % state + ) + self.debug("Network creation successfully validated - %s" % network.name) + + # check_router_state - Fetches the list of routers and their states and matches the given router's state + def check_router_state(self, router, state=None): + self.debug("Check if the virtual router is in state - %s" % state) + routers = Router.list(self.api_client, + id=router.id, + listall=True + ) + self.assertEqual(isinstance(routers, list), True, + "List router should return a valid list" + ) + if state: + self.assertEqual(routers[0].state, state, + "Virtual router is not in the expected state" + ) + self.debug("Virtual router is in the expected state - %s" % state) + + # check_vm_state - Fetches the list of VMs and their states and matches the given VM's state + def check_vm_state(self, vm, state=None): + self.debug("Check if the VM instance is in state - %s" % state) + vms = VirtualMachine.list(self.api_client, + id=vm.id, + listall=True + ) + self.assertEqual(isinstance(vms, list), True, + "List virtual machine should return a valid list" + ) + if state: + self.assertEqual(vms[0].state, state, + "Virtual machine is not in the expected state" + ) + self.debug("Virtual machine is in the expected state - %s" % state) + + # validate_Public_IP - Looks if the given public ip is in the allocated state form the list of fetched public IPs + def validate_Public_IP(self, public_ip, network, static_nat=False, vm=None): + """Validates the Public IP""" + self.debug("Check if the Public IP is successfully assigned to the network ?") + public_ips = PublicIPAddress.list(self.api_client, + id=public_ip.ipaddress.id, + networkid=network.id, + isstaticnat=static_nat, + listall=True + ) + self.assertEqual(isinstance(public_ips, list), True, + "List public Ip for network should return a valid list" + ) + self.assertEqual(public_ips[0].ipaddress, public_ip.ipaddress.ipaddress, + "List public Ip for network should list the assigned public Ip address" + ) + self.assertEqual(public_ips[0].state, "Allocated", + "Assigned public Ip is not in the allocated state" + ) + if static_nat and vm: + self.assertEqual(public_ips[0].virtualmachineid, vm.id, + "Static NAT Rule not enabled for the VM using the assigned public Ip" + ) + self.debug("Assigned Public IP is successfully validated - %s" % public_ip.ipaddress.ipaddress) + + # VSD verifications + + def fetch_by_external_id(self, fetcher, *cs_objects): + """ Fetches a child object by external id using the given fetcher, and uuids of the given cloudstack objects. + E.G. + - fetch_by_external_id(vsdk.NUSubnet(id="954de425-b860-410b-be09-c560e7dbb474").vms, cs_vm) + - fetch_by_external_id(session.user.floating_ips, cs_network, cs_public_ip) + :param fetcher: VSPK Fetcher to use to find the child entity + :param cs_objects: Cloudstack objects to take the UUID from. + :return: the VSPK object having the correct externalID + """ + return fetcher.get_first(filter="externalID BEGINSWITH '%s'" % ":".join([o.id for o in cs_objects])) + + # VSD verifications using cms_vspk_wrapper + + def get_externalID(self, object_id): + return object_id + "@" + self.cms_id + + # verify_vsp_network - Fetches the vsd domain, vsd zone and vsd subnet and Verifies the given network/VPC values match the fetched values + def verify_vsp_network(self, domain_id, network, vpc=None): + vsd_enterprise = self.vsd.get_enterprise(name=domain_id) + if vpc: + ext_network_id = self.get_externalID(vpc.id) + else: + ext_network_id = self.get_externalID(network.id) + ext_subnet_id = self.get_externalID(network.id) + vsd_domain = self.vsd.get_domain(externalID=ext_network_id) + vsd_zone = self.vsd.get_zone(externalID=ext_network_id) + vsd_subnet = self.vsd.get_subnet(externalID=ext_subnet_id) + self.debug("SHOW ENTERPRISE DATA FORMAT IN VSD") + self.debug(vsd_enterprise) + self.assertNotEqual(vsd_enterprise, None, + "VSD Enterprise data format should not be a None type" + ) + self.debug("SHOW NETWORK DATA FORMAT IN VSD") + self.debug(vsd_domain) + self.debug(vsd_zone) + self.debug(vsd_subnet) + if vpc: + self.assertEqual(vsd_domain['description'], "VPC_" + vpc.name, + "VSD domain description should match VPC name in CloudStack" + ) + self.assertEqual(vsd_zone['description'], "VPC_" + vpc.name, + "VSD zone description should match VPC name in CloudStack" + ) + else: + self.assertEqual(vsd_domain['description'], network.name, + "VSD domain description should match Isolated Network name in CloudStack" + ) + self.assertEqual(vsd_zone['description'], network.name, + "VSD zone description should match Isolated Network name in CloudStack" + ) + self.assertEqual(vsd_subnet['description'], network.name, + "VSD subnet description should match Isolated Network name in CloudStack" + ) + + # verify_vsp_vm - Fetches the vsd vport, vsd vm and interface and Verifies the given VM values match the fetched values + def verify_vsp_vm(self, vm, stopped=None): + ext_vm_id = self.get_externalID(vm.id) + for nic in vm.nic: + ext_network_id = self.get_externalID(nic.networkid) + ext_nic_id = self.get_externalID(nic.id) + vsd_vport = self.vsd.get_vport(subnet_externalID=ext_network_id, vport_externalID=ext_nic_id) + vsd_vm_interface = self.vsd.get_vm_interface(externalID=ext_nic_id) + self.debug("SHOW VPORT and VM INTERFACE DATA FORMAT IN VSD") + self.debug(vsd_vport) + self.debug(vsd_vm_interface) + self.assertEqual(vsd_vport['active'], True, + "VSD VM vport should be active" + ) + self.assertEqual(vsd_vm_interface['IPAddress'], nic.ipaddress, + "VSD VM interface IP address should match VM's NIC IP address in CloudStack" + ) + vsd_vm = self.vsd.get_vm(externalID=ext_vm_id) + self.debug("SHOW VM DATA FORMAT IN VSD") + self.debug(vsd_vm) + if not self.isSimulator: + if stopped: + self.assertEqual(vsd_vm['status'], "DELETE_PENDING", + "VM state in VSD should be DELETE_PENDING" + ) + else: + self.assertEqual(vsd_vm['status'], vm.state.upper(), + "VM state in VSD should match its state in CloudStack" + ) + # verify_vsp_router - Fetches the vsd router and Verifies the given router status match the fetched status + + def verify_vsp_router(self, router, stopped=None): + ext_router_id = self.get_externalID(router.id) + vsd_router = self.vsd.get_vm(externalID=ext_router_id) + self.debug("SHOW VIRTUAL ROUTER DATA FORMAT IN VSD") + self.debug(vsd_router) + if not self.isSimulator: + if stopped: + self.assertEqual(vsd_router['status'], "DELETE_PENDING", + "Router state in VSD should be DELETE_PENDING" + ) + else: + self.assertEqual(vsd_router['status'], router.state.upper(), + "Router state in VSD should match its state in CloudStack" + ) + + # verify_vsp_floating_ip - Verifies the floating IPs on the given public IP against the VSD FIP + def verify_vsp_floating_ip(self, network, vm, public_ipaddress, vpc=None): + ext_fip_id = self.get_externalID(network.id + ":" + public_ipaddress.id) + vsd_fip = self.vsd.get_floating_ip(externalID=ext_fip_id) + self.debug("SHOW FLOATING IP DATA FORMAT IN VSD") + self.debug(vsd_fip) + self.assertEqual(vsd_fip['address'], public_ipaddress.ipaddress, + "Floating IP address in VSD should match acquired Public IP address in CloudStack" + ) + if vpc: + ext_network_id = self.get_externalID(vpc.id) + else: + ext_network_id = self.get_externalID(network.id) + vsd_domain = self.vsd.get_domain(externalID=ext_network_id) + self.debug("SHOW NETWORK DATA FORMAT IN VSD") + self.debug(vsd_domain) + self.assertEqual(vsd_domain['ID'], vsd_fip['parentID'], + "Floating IP in VSD should be associated with the correct VSD domain, " + "which in turn should correspond to the correct VPC (or) Isolated network in CloudStack" + ) + ext_subnet_id = self.get_externalID(network.id) + vsd_subnet = self.vsd.get_subnet(externalID=ext_subnet_id) + for nic in vm.nic: + if nic.networkname == vsd_subnet['description']: + ext_network_id = self.get_externalID(nic.networkid) + ext_nic_id = self.get_externalID(nic.id) + vsd_vport = self.vsd.get_vport(subnet_externalID=ext_network_id, vport_externalID=ext_nic_id) + self.debug("SHOW VM VPORT DATA FORMAT IN VSD") + self.debug(vsd_vport) + self.assertEqual(vsd_vport['associatedFloatingIPID'], vsd_fip['ID'], + "Floating IP in VSD should be associated to the correct VSD vport, " + "which in turn should correspond to the correct Static NAT enabled VM " + "and Isolated Network in CloudStack" + ) + + # verify_vsp_firewall_rule - Verifies the start port, destination port, + # protocol of the given firewall rule Ingress/Egress against the VSD + # firewall rule + def verify_vsp_firewall_rule(self, firewall_rule, traffic_type="Ingress"): + ext_fw_id = self.get_externalID(firewall_rule.id) + if traffic_type is "Ingress": + vsd_fw_rule = self.vsd.get_egress_acl_entry(externalID=ext_fw_id) + else: + vsd_fw_rule = self.vsd.get_ingress_acl_entry(externalID=ext_fw_id) + self.debug("SHOW ACL ENTRY IN VSD") + self.debug(vsd_fw_rule) + dest_port = str(firewall_rule.startport) + "-" + str(firewall_rule.endport) + self.assertEqual(vsd_fw_rule['destinationPort'], dest_port, + "Destination Port in VSD should match Destination Port in CloudStack" + ) + vsd_protocol = str(vsd_fw_rule['protocol']) + self.debug("vsd protocol " + vsd_protocol) + protocol = "tcp" + if vsd_protocol == 6: + protocol = "tcp" + elif vsd_protocol == 1: + protocol = "icmp" + elif vsd_protocol == 17: + protocol = "udp" + self.assertEqual(protocol, firewall_rule.protocol.lower(), + "Protocol in VSD should match Protocol in CloudStack" + ) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/test/integration/plugins/nuagevsp/test_nuage_password_reset.py ---------------------------------------------------------------------- diff --git a/test/integration/plugins/nuagevsp/test_nuage_password_reset.py b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py new file mode 100644 index 0000000..3e600c2 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py @@ -0,0 +1,249 @@ +# 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. + +""" Component tests for - userdata +""" +# Import Local Modules +from marvin.lib.base import (VirtualMachine, + Account, + PublicIPAddress) +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase +from marvin.cloudstackAPI import (createTemplate, + listVolumes) +import base64 + + +class TestNuagePasswordReset(nuageTestCase): + + @classmethod + def setUpClass(cls): + super(TestNuagePasswordReset, cls).setUpClass() + + return + + def setUp(self): + self.cleanup = [] + self.apiclient = self.testClient.getApiClient() + + self.account = Account.create( + self.apiclient, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + + self.cleanup.append(self.account) + self.remove_vm2 = False + return + + # tearDown() - Cleans up the setup, removes the VMs + def tearDown(self): + self.debug("CLEANUP: TEARDOWN") + self.apiclient = self.testClient.getApiClient() + self.updateTemplate(self.defaultTemplateVal) + self.vm_1.delete(self.apiclient, expunge=True) + if self.remove_vm2: + self.vm_2.delete(self.apiclient, expunge=True) + + try: + cleanup_resources(self.apiclient, self.cleanup) + except Exception as e: + self.debug("Warning: Exception during cleanup : %s" % e) + return + + # create_template - Takes the VM object as the argument to create the template + def create_template(self, vm): + self.debug("CREATE TEMPLATE") + list_volume = list_volumes( + self.apiclient, + virtualmachineid=vm.id, + type='ROOT', + listall=True + ) + if isinstance(list_volume, list): + self.volume = list_volume[0] + else: + raise Exception("Exception: Unable to find root volume for VM: %s" % vm.id) + + self.test_data["template_pr"]["ostype"] = self.test_data["ostype_pr"] + self.pw_enabled_template = Template.create( + self.apiclient, + self.test_data["template_pr"], + self.volume.id, + account=self.account.name, + domainid=self.account.domainid + ) + self.assertEqual(self.pw_enabled_template.passwordenabled, True, "template is not passwordenabled") + self.cleanup.append(self.pw_enabled_template) + + # VM object is passed as an argument and its interface id is returned + def get_vm_interface_id(self, vm): + self.debug("GET VM INTERFACE ID") + nic_ext_id = self.get_externalID(vm.nic[0].id) + vm_interface = self.vsd.get_vm_interface(externalID=nic_ext_id) + vm_interface_id = vm_interface["ID"] + return vm_interface_id + + # VM object is passed as an argument and its userdata URL is returned + def get_userdata_url(self, vm): + self.debug("GET USER DATA URL") + nic = vm.nic[0] + gateway = str(nic.gateway) + self.debug("GATEWAY: " + gateway) + user_data_url = 'curl "http://' + gateway + ':80/latest/user-data"' + return user_data_url + + # Creates and verifies the firewall rule + def create_and_verify_fw(self, vm, public_ip, network): + self.debug("CREATE AND VERIFY FIREWALL RULE") + self.create_StaticNatRule_For_VM(vm, public_ip, network) + + # VSD verification + self.verify_vsp_floating_ip(network, vm, public_ip.ipaddress) + vm_public_ip = public_ip.ipaddress.ipaddress + + fw_rule = self.create_firewall_rule(public_ip, self.test_data["ingress_rule"]) + self.verify_vsp_firewall_rule(fw_rule) + vm_interface_id = self.get_vm_interface_id(vm) + pd = self.vsd.get_vm_interface_policydecisions(id=vm_interface_id) + self.debug(pd) + egressAcls = pd['egressACLs'][0]['entries'] + gotFirewallPolicy = False + for acl in egressAcls: + if acl['destinationPort'] == "22-22": + gotFirewallPolicy = True + break + if not gotFirewallPolicy: + raise ValueError('No firewall policy decision in vm interface') + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_01_UserDataPasswordReset(self): + self.debug("START USER DATA PASSWORD RESET ON VM") + """ + Validate the following: + 1) user data + 2) reset vm password. + + Steps: + 1. Set password enabled to false in the template. + 2. Create an Isolated network - Test Network (10.1.1.1/24). + 3. Deploy VM1 in Test Network + 4. Verify domain,zone subnet, vm. + 5. create public ip , Create Static Nat rule firewall rule and verify + 6. SSH to VM should be successful + 7. verify userdata + 8. check cloud-set-guest-password exist. + 9. if cloud-set-guest-password exist. + 9.1 change template password enabled to true + 9.2 verify that template is password enbalded + 9.3 SSH with new password should be successful + 10. else cloud-set-guest-password does not exist. + 10.1 get the cloud-set-guest-password file + 10.2 stop vm + 10.3 create a new template with password enabled. Verify that template is password enabled. + 10.4 create vm 2 with new template in Test Network + 10.5 Verify vm. + 10.6 create public ip , Create Static Nat rule firewall rule and verify + 10.7 SSH to VM 2 should be successful + 11. Reset VM password (VM_1 if guest password file exist. else it is VM2) + 12 Starting VM and SSH to VM to verify new password + """ + + self.defaultTemplateVal = self.template.passwordenabled + if self.template.passwordenabled: + self.updateTemplate(False) + + self.debug("CREATE AN ISOLATED NETWORK") + self.network_1 = self.create_Network(self.test_data["network_offering_pr"]) + self.cleanup.append(self.network_1) + expUserData = "hello world vm1" + userdata = base64.b64encode(expUserData) + self.test_data["virtual_machine_pr"]["userdata"] = userdata + self.debug("DEPLOY VM 1 IN TEST NETWORK") + # Pass the network and name of the vm type from the testdata with the configuration for the vm + self.vm_1 = self.create_VM_in_Network(self.network_1, "virtual_machine_pr") + + self.vm_1.password = self.test_data["virtual_machine_pr"]["password"] + user_data_cmd = self.get_userdata_url(self.vm_1) + + # VSD verification + self.debug("VERIFY DOMAIN, ZONE, NETWORK , and VM 1") + self.verify_vsp_network(self.domain.id, self.network_1) + self.verify_vsp_vm(self.vm_1) + + self.debug("CREATE PUBLIC IP, STATIC NAT RULE, FLOATING IP, FIREWALL AND VERIFY") + public_ip_1 = self.acquire_Public_IP(self.network_1) + self.create_and_verify_fw(self.vm_1, public_ip_1, self.network_1) + + self.debug("SSH TO VM") + ssh = self.ssh_into_vm(self.vm_1, public_ip_1) + + self.debug("VERIFY USER DATA") + self.debug("Get User Data with command: " + user_data_cmd) + adata = self.execute_cmd(ssh, user_data_cmd) + actUserData = base64.b64decode(adata) + self.debug("Response User Data=" + actUserData + ", Expected=" + expUserData) + self.assertEqual(actUserData, expUserData, "User Data Did Not Match ") + + # check /etc/init.d/cloud-set-quest-password + ls_cmd = "ls /etc/init.d/cloud-set-guest-password" + ls_result = self.execute_cmd(ssh, ls_cmd) + ls_result = ls_result.lower() + self.debug("reponse from ls_cmd: " + ls_result) + if "no such file" in ls_result: + self.debug("NO CLOUD-SET_GUEST_PASSWORD FILE. NEED TO GET ONE") + self.install_cloud_set_guest_password_script(ssh) + self.stop_vm(self.vm_1) + self.create_template(self.vm_1) + self.debug("DEPLOY VM 2 IN TEST NETWORK WITH NEW TEMPLATE") + self.vm_1 = self.create_VM_in_Network(self.network_1, "virtual_machine_pr") + self.remove_vm2 = True + self.debug("STARTING VM_2 ") + startCmd = startVirtualMachine.startVirtualMachineCmd() + startCmd.id = self.vm_2.id + vm_2a = self.apiclient.startVirtualMachine(startCmd) + self.vm_2.password = vm_2a.password.strip() + self.vm_2.nic = vm_2a.nic + self.debug("VM - %s password %s !" % (self.vm_2.name, self.vm_2.password)) + self.assertNotEqual(self.vm_2.password, + self.test_data["virtual_machine_pr"]["password"], + "Password enabled not working. Password same as virtual_machine password " + ) + self.verify_vsp_vm(vm_2a) + self.debug("GET PUBLIC IP, CREATE AND VERIFY FIREWALL RULES") + public_ip_2 = self.acquire_Public_IP(self.network_1) + self.create_and_verify_fw(self.vm_2, public_ip_2, self.network_1) + + ssh = self.ssh_into_vm(self.vm_2, public_ip_2) + vm_test = self.vm_2 + vm_test_public_ip = public_ip_2 + + else: + self.debug("UPDATE TEMPLATE TO PASSWORD ENABLED") + self.updateTemplate(True) + self.assertEqual(self.template.passwordenabled, True, "Template is not password enabled") + vm_test = self.vm_1 + vm_test_public_ip = public_ip_1 + + self.debug("RESETTING VM PASSWORD for VM: %s" % vm_test.name) + vm_test.password = vm_test.resetPassword(self.apiclient) + self.debug("Password reset to: %s" % vm_test.password) + self.debug("STARTING VM AND SSH TO VM TO VERIFY NEW PASSWORD") + vm_test.start(self.apiclient) + self.debug("VM - %s started!" % vm_test.name) + self.ssh_into_vm(vm_test, vm_test_public_ip) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py ---------------------------------------------------------------------- diff --git a/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py new file mode 100644 index 0000000..3fc9c32 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py @@ -0,0 +1,98 @@ +# 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. + +""" Tests for Basic VPC Network Functionality with NuageVsp network Plugin +""" +# Import Local Modules +from marvin.lib.base import Account +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase + + +class TestVpcNetworkNuage(nuageTestCase): + """ Test Basic VPC Network Functionality with NuageVsp network Plugin + """ + + @classmethod + def setUpClass(cls): + super(TestVpcNetworkNuage, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_nuage_vpc_network(self): + """ Test Basic VPC Network Functionality with NuageVsp network Plugin + """ + + # 1. Create Nuage VSP VPC offering, check if it is successfully created and enabled. + # 2. Create a VPC with Nuage VSP VPC offering, check if it is successfully created and enabled. + # 3. Create Nuage Vsp VPC Network offering, check if it is successfully created and enabled. + # 4. Create an ACL list in the created VPC, and add an ACL item to it. + # 5. Create a VPC Network with Nuage Vsp VPC Network offering and the created ACL list, check if it is + # successfully created, is in the "Implemented" state, and is added to the VPC VR. + # 6. Deploy a VM in the created VPC network, check if the VM is successfully deployed and is in the "Running" + # state. + # 7. Verify that the created ACL item is successfully implemented in Nuage Vsp. + + # Creating a VPC offering + self.debug("Creating Nuage VSP VPC offering...") + vpc_offering = self.create_VpcOffering(self.test_data["nuage_vsp_services"]["vpc_offering"]) + self.validate_vpc_offering(vpc_offering, state="Enabled") + + # Creating a VPC + self.debug("Creating a VPC with Nuage VSP VPC offering...") + vpc = self.create_Vpc(vpc_offering, cidr='10.1.0.0/16') + self.validate_vpc(vpc, state="Enabled") + + # Creating a network offering + self.debug("Creating Nuage Vsp VPC Network offering...") + network_offering = self.create_NetworkOffering(self.test_data["nuage_vsp_services"]["vpc_network_offering"]) + self.validate_network_offering(network_offering, state="Enabled") + + # Creating an ACL list + acl_list = self.create_network_acl_list(name="acl", description="acl", vpc=vpc) + + # Creating an ACL item + acl_item = self.create_network_acl_rule(self.test_data["ingress_rule"], acl_list=acl_list) + + # Creating a VPC network in the VPC + self.debug("Creating a VPC network with Nuage Vsp VPC Network offering...") + vpc_network = self.create_Network(network_offering, gateway='10.1.1.1', vpc=vpc, acl_list=acl_list) + self.validate_network(vpc_network, state="Implemented") + vr = self.get_network_router(vpc_network) + self.check_router_state(vr, state="Running") + + # Deploying a VM in the VPC network + vm = self.create_VM_in_Network(vpc_network) + self.check_vm_state(vm, state="Running") + + # VSPK verification + self.verify_vsp_network(self.domain.id, vpc_network, vpc) + self.verify_vsp_router(vr) + self.verify_vsp_vm(vm) + + # VSPK verification for ACL item + self.verify_vsp_firewall_rule(acl_item) http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/test/integration/plugins/nuagevsp/test_nuage_vsp.py ---------------------------------------------------------------------- diff --git a/test/integration/plugins/nuagevsp/test_nuage_vsp.py b/test/integration/plugins/nuagevsp/test_nuage_vsp.py new file mode 100644 index 0000000..a6ec7e1 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_vsp.py @@ -0,0 +1,106 @@ +# 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 NuageVsp network Plugin +""" +# Import Local Modules +from marvin.lib.base import Account +from nose.plugins.attrib import attr +from nuageTestCase import nuageTestCase + + +class TestNuageVsp(nuageTestCase): + """ Test NuageVsp network plugin + """ + + @classmethod + def setUpClass(cls): + super(TestNuageVsp, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_nuage_vsp(self): + """ Test NuageVsp network plugin with basic Isolated Network functionality + """ + + # 1. Verify that the NuageVsp network service provider is successfully created and enabled. + # 2. Create and enable Nuage Vsp Isolated Network offering, check if it is successfully created and enabled. + # 3. Create an Isolated Network with Nuage Vsp Isolated Network offering, check if it is successfully created + # and is in the "Allocated" state. + # 4. Deploy a VM in the created Isolated network, check if the Isolated network state is changed to + # "Implemented", and both the VM & VR are successfully deployed and are in the "Running" state. + # 5. Deploy one more VM in the created Isolated network, check if the VM is successfully deployed and is in the + # "Running" state. + # 6. Delete the created Isolated Network after destroying its VMs, check if the Isolated network is successfully + # deleted. + + self.debug("Validating the NuageVsp network service provider...") + self.validate_NetworkServiceProvider("NuageVsp", state="Enabled") + + # Creating a network offering + self.debug("Creating and enabling Nuage Vsp Isolated Network offering...") + network_offering = self.create_NetworkOffering( + self.test_data["nuage_vsp_services"]["isolated_network_offering"]) + self.validate_network_offering(network_offering, state="Enabled") + + # Creating a network + self.debug("Creating an Isolated Network with Nuage Vsp Isolated Network offering...") + network = self.create_Network(network_offering, gateway='10.1.1.1') + self.validate_network(network, state="Allocated") + + # Deploying a VM in the network + vm_1 = self.create_VM_in_Network(network) + self.validate_network(network, state="Implemented") + vr = self.get_network_router(network) + self.check_router_state(vr, state="Running") + self.check_vm_state(vm_1, state="Running") + + # VSPK verification + self.verify_vsp_network(self.domain.id, network) + self.verify_vsp_router(vr) + self.verify_vsp_vm(vm_1) + + # Deploying one more VM in the network + vm_2 = self.create_VM_in_Network(network) + self.check_vm_state(vm_2, state="Running") + + # VSPK verification + self.verify_vsp_vm(vm_2) + + # Deleting the network + self.debug("Deleting the Isolated Network with Nuage Vsp Isolated Network offering...") + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_Network(network) + with self.assertRaises(Exception): + self.validate_network(network) + self.debug("Isolated Network successfully deleted in CloudStack") + + # VSPK verification + with self.assertRaises(Exception): + self.verify_vsp_network(self.domain.id, network) + self.debug("Isolated Network successfully deleted in VSD") http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/tools/marvin/marvin/config/test_data.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 3d4745d..352f8a2 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -1695,5 +1695,115 @@ test_data = { "ostype": 'CentOS 5.3 (64-bit)', "mode": 'HTTP_DOWNLOAD' } + }, + # Nuage Vsp supported services + "nuage_vsp_services": { + # Services supported by Nuage Vsp for Isolated networks + "isolated_network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": 'NuageVsp', + "StaticNat": 'NuageVsp', + "SourceNat": 'NuageVsp', + "Firewall": 'NuageVsp', + "Connectivity": 'NuageVsp', + "UserData": 'VirtualRouter' + }, + "serviceCapabilityList": { + "SourceNat": {"SupportedSourceNatTypes": "perzone"} + } + }, + # Services supported by Nuage Vsp for VPC networks + "vpc_network_offering": { + "name": 'nuage_vpc_marvin', + "displaytext": 'nuage_vpc_marvin', + "guestiptype": 'Isolated', + "supportedservices": 'Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData', + "traffictype": 'GUEST', + "availability": 'Optional', + "useVpc": 'on', + "ispersistent": 'True', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "StaticNat": "NuageVsp", + "SourceNat": "NuageVsp", + "NetworkACL": "NuageVsp", + "Connectivity": "NuageVsp", + "UserData": "VpcVirtualRouter" + }, + "serviceCapabilityList": { + "SourceNat": {"SupportedSourceNatTypes": "perzone"} + } + }, + # Nuage Vsp supports only pre-defined and custom VPC offerings + "vpc_offering": { + "name": 'Nuage VSP VPC offering', + "displaytext": 'Nuage VSP VPC offering', + "supportedservices": 'Dhcp,StaticNat,SourceNat,NetworkACL,Connectivity,UserData', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "StaticNat": "NuageVsp", + "SourceNat": "NuageVsp", + "NetworkACL": "NuageVsp", + "Connectivity": "NuageVsp", + "UserData": "VpcVirtualRouter" + } } + }, + + #_pr -_ passwordreset - below services used in test_nuage_password_reset + "network_offering_pr": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'Isolated', + "supportedservices": + 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall', + "traffictype": 'GUEST', + "availability": 'Optional', + "serviceProviderList": { + "UserData": 'VirtualRouter', + "Dhcp": 'NuageVsp', + "Connectivity": 'NuageVsp', + "StaticNat": 'NuageVsp', + "SourceNat": 'NuageVsp', + "Firewall": 'NuageVsp' + }, + }, + "network_pr": { + "name": "Test Network", + "displaytext": "Test Network", + "netmask": '255.255.255.0' + }, + "fw_rule_pr": { + "startport": 1, + "endport": 6000, + "cidr": '0.0.0.0/0', + # Any network (For creating FW rule) + "protocol": "TCP" + }, + "virtual_machine_pr": { + "displayname": "Test VM", + "username": "root", + "password": "password", + "ssh_port": 22, + "hypervisor": 'kvm', + # Hypervisor type should be same as + # hypervisor type of cluster + "privateport": 22, + "publicport": 22, + "protocol": 'TCP', + "userdata": "This is sample data", + }, + "template_pr": { + "displaytext": "Cent OS Template", + "name": "Cent OS Template", + "passwordenabled": True, + }, + "ostype_pr": 'CentOS 5.5 (64-bit)', + } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3c8d3d0e/tools/marvin/marvin/lib/base.py ---------------------------------------------------------------------- diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 0be8909..e2f4a2c 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -3957,6 +3957,61 @@ class NetworkServiceProvider: return(apiclient.listNetworkServiceProviders(cmd)) +class Nuage: + """Manage external nuage VSD device""" + + def __init__(self, items): + self.__dict__.update(items) + + @classmethod + def add(cls, apiclient, services, physicalnetworkid, username=None, password=None): + """Add external nuage VSD device to cloudstack""" + + cmd = addNuageVspDevice.addNuageVspDeviceCmd() + cmd.physicalnetworkid = physicalnetworkid + if username: + cmd.username = username + else: + cmd.username = services["username"] + + if password: + cmd.password = password + else: + cmd.password = services["password"] + + cmd.hostname = services["hostname"] + cmd.port = services["port"] + cmd.retrycount = services["retrycount"] + cmd.retryinterval = services["retryinterval"] + cmd.apiversion = services["apiversion"] + + return Nuage(apiclient.addNuageVspDevice(cmd).__dict__) + + def update(self, apiclient, **kwargs): + """Deletes a nuage VSD device from CloudStack""" + + cmd = updateNuageVspDevice.updateNuageVspDeviceCmd() + cmd.physicalnetworkid = self.physicalnetworkid + [setattr(cmd, k, v) for k, v in kwargs.items()] + return apiclient.updateNuageVspDevice(cmd) + + def delete(self, apiclient): + """Deletes a nuage VSD device from CloudStack""" + + cmd = deleteNuageVspDevice.deleteNuageVspDeviceCmd() + cmd.vspdeviceid = self.vspdeviceid + apiclient.deleteNuageVspDevice(cmd) + return + + @classmethod + def list(cls, apiclient, **kwargs): + """List already registered netscaler devices""" + + cmd = listNuageVspDevices.listNuageVspDevicesCmd() + [setattr(cmd, k, v) for k, v in kwargs.items()] + return(apiclient.listNuageVspDevices(cmd)) + + class Router: """Manage router life cycle"""