class TestReadOnlyAccount(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services["virtual_machine"]["zoneid"] = self.zone.id # Create an account with normal domain admin rights self.account_admin = Account.create(self.apiclient, self.services["account"], admin=True, domainid=self.domain.id) # Create an account with readonly domain admin rights self.services["account"]["accounttype"] = 4 self.account_ro_admin = Account.create(self.apiclient, self.services["account"], admin=True, domainid=self.domain.id) regusrkey_cmd = registerUserKeys.registerUserKeysCmd() regusrkey_cmd.id = self.account_admin.user[0].id self.user_admin = self.apiclient.registerUserKeys(regusrkey_cmd) regusrkey_cmd = registerUserKeys.registerUserKeysCmd() regusrkey_cmd.id = self.account_ro_admin.user[0].id self.user_ro_admin = self.apiclient.registerUserKeys(regusrkey_cmd) self.cleanup = [self.account_admin, self.account_ro_admin] return def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return @attr(tags=['advanced']) def test_01_checkApiCallsRoAdmin(self): """Test which API calls are available""" response = None apikey = self.apiclient.connection.apiKey secretkey = self.apiclient.connection.securityKey self.apiclient.connection.apiKey = self.user_admin.apikey self.apiclient.connection.securityKey = self.user_admin.secretkey try: apis_cmd = listApis.listApisCmd() response = self.apiclient.listApis(apis_cmd) except CloudstackAPIException: self.logger.debug("List APIs") except Exception as e: self.logger.debug("Exception %s raised listing API calls " % e) self.assertFalse( all( x.name.startswith(("list", "login", "logout")) for x in response), "List API's contains calls other then list/login/logout") self.apiclient.connection.apiKey = apikey self.apiclient.connection.securityKey = secretkey return @attr(tags=['advanced']) def test_02_checkApiCallsAdmin(self): """Test which API RO calls are available""" response = None apikey = self.apiclient.connection.apiKey secretkey = self.apiclient.connection.securityKey self.apiclient.connection.apiKey = self.user_ro_admin.apikey self.apiclient.connection.securityKey = self.user_ro_admin.secretkey try: apis_cmd = listApis.listApisCmd() response = self.apiclient.listApis(apis_cmd) except CloudstackAPIException: self.logger.debug("List APIs") except Exception as e: self.logger.debug("Exception %s raised listing API calls " % e) self.assertTrue( all( x.name.startswith(("list", "login", "logout")) for x in response), "List API's contains calls other then list/login/logout") self.apiclient.connection.apiKey = apikey self.apiclient.connection.securityKey = secretkey return
class TestDeleteAccount(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template( self.apiclient, self.zone.id ) self.services["virtual_machine"]["zoneid"] = self.zone.id # Create an account, network, VM and IP addresses self.account = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.domain.id ) self.vpc_offering = get_default_vpc_offering(self.apiclient) self.logger.debug("VPC Offering '%s' selected", self.vpc_offering.name) self.network_offering = get_default_network_offering(self.apiclient) self.logger.debug("Network Offering '%s' selected", self.network_offering.name) self.virtual_machine_offering = get_default_virtual_machine_offering(self.apiclient) self.logger.debug("Virtual Machine Offering '%s' selected", self.virtual_machine_offering.name) self.default_allow_acl = get_network_acl(self.apiclient, 'default_allow') self.logger.debug("ACL '%s' selected", self.default_allow_acl.name) self.template = get_template(self.apiclient, self.zone.id) self.logger.debug("Template '%s' selected" % self.template.name) self.vpc1 = VPC.create(self.apiclient, self.services['vpcs']['vpc1'], vpcofferingid=self.vpc_offering.id, zoneid=self.zone.id, domainid=self.domain.id, account=self.account.name) self.logger.debug("VPC '%s' created, CIDR: %s", self.vpc1.name, self.vpc1.cidr) self.network1 = Network.create(self.apiclient, self.services['networks']['network1'], networkofferingid=self.network_offering.id, aclid=self.default_allow_acl.id, vpcid=self.vpc1.id, zoneid=self.zone.id, domainid=self.domain.id, accountid=self.account.name) self.logger.debug("Network '%s' created, CIDR: %s, Gateway: %s", self.network1.name, self.network1.cidr, self.network1.gateway) self.vm1 = VirtualMachine.create(self.apiclient, self.services['vms']['vm1'], templateid=self.template.id, serviceofferingid=self.virtual_machine_offering.id, networkids=[self.network1.id], zoneid=self.zone.id, domainid=self.domain.id, accountid=self.account.name) self.logger.debug("VM '%s' created, Network: %s, IP %s", self.vm1.name, self.network1.name, self.vm1.nic[0].ipaddress) src_nat_ip_addrs = list_public_ip( self.apiclient, account=self.account.name, domainid=self.account.domainid ) try: src_nat_ip_addr = src_nat_ip_addrs[0] except Exception as e: self.fail("SSH failed for VM with IP: %s %s" % (src_nat_ip_addr.ipaddress, e)) self.lb_rule = LoadBalancerRule.create( self.apiclient, self.services["lbrule"], src_nat_ip_addr.id, self.account.name, self.network1.id, self.vpc1.id ) self.lb_rule.assign(self.apiclient, [self.vm1]) self.nat_rule = NATRule.create( self.apiclient, self.vm1, self.services["natrule"], src_nat_ip_addr.id ) self.cleanup = [] return def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return @attr(tags=['advanced']) def test_01_getsecretkey(self): """Test if we can get the secretkey""" userkeys = None userinfo = None try: userkeys = User.registerUserKeys(self.apiclient, self.account.user[0].id) except CloudstackAPIException: self.logger.debug("Registered user keys") except Exception as e: self.logger.debug("Exception %s raised while registering user keys" % e) try: userinfo = User.list(self.apiclient, id=self.account.user[0].id)[0] except CloudstackAPIException: self.logger.debug("Retrieved user") except Exception as e: self.logger.debug("Exception %s raised while retrieving user" % e) self.assertEqual( userkeys.apikey, userinfo.apikey, "API key is different" ) self.assertNotEqual( userkeys.secretkey, userinfo.secretkey, "Secret key is visible" ) return @attr(tags=['advanced']) def test_02_delete_account(self): """Test for delete account""" # Validate the Following # 1. after account.cleanup.interval (global setting) # time all the PF/LB rules should be deleted # 2. verify that list(LoadBalancer/PortForwarding)Rules # API does not return any rules for the account # 3. The domR should have been expunged for this account self.account.delete(self.apiclient) interval = list_configurations( self.apiclient, name='account.cleanup.interval' ) self.assertEqual( isinstance(interval, list), True, "Check if account.cleanup.interval config present" ) # Sleep to ensure that all resources are deleted time.sleep(int(interval[0].value)) # ListLoadBalancerRules should not list # associated rules with deleted account # Unable to find account testuser1 in domain 1 : Exception try: list_lb_rules( self.apiclient, account=self.account.name, domainid=self.account.domainid ) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # ListPortForwardingRules should not # list associated rules with deleted account try: list_nat_rules( self.apiclient, account=self.account.name, domainid=self.account.domainid ) except CloudstackAPIException: self.logger.debug("NATRule is deleted") # Retrieve router for the user account try: routers = list_routers( self.apiclient, account=self.account.name, domainid=self.account.domainid ) self.assertEqual( routers, None, "Check routers are properly deleted." ) except CloudstackAPIException: self.logger.debug("Router is deleted") except Exception as e: raise Exception( "Encountered %s raised while fetching routers for account: %s" % (e, self.account.name)) return
class TestSSVMs(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] self.services = self.testClient.getParsedTestDataConfig() self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services["sleep"] = 2 self.services["timeout"] = 240 # Default value is 120 seconds. That's just too much. self.services["configurableData"]["systemVmDelay"] = 60 return def tearDown(self): try: # Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @attr(tags=['advanced']) def test_01_list_sec_storage_vm(self): self.test_list_svm_vm('secondarystoragevm') @attr(tags=['advanced']) def test_02_list_cpvm_vm(self): self.test_list_svm_vm('consoleproxy') @attr(tags=['advanced']) def test_03_ssvm_internals(self): """Test SSVM Internals""" # Validate the following # 1. The SSVM check script should not return any # WARN|ERROR|FAIL messages # 2. If you are unable to login to the SSVM with the signed key # then test is deemed a failure # 3. There should be only one ""cloud"" process running within the SSVM # 4. If no process is running/multiple process are running # then the test is a failure list_ssvm_response = list_ssvms(self.apiclient, systemvmtype='secondarystoragevm', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_ssvm_response, list), True, "Check list response returns a valid list") ssvm = list_ssvm_response[0] hosts = list_hosts(self.apiclient, id=ssvm.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list response returns a valid list") host = hosts[0] self.logger.debug("Running SSVM check script") try: host.user, host.passwd = get_host_credentials( self.config, host.ipaddress) result = get_process_status( host.ipaddress, 22, host.user, host.passwd, ssvm.linklocalip, "/opt/cosmic/agent/ssvm-check.sh |grep -e ERROR -e WARNING -e FAIL" ) except KeyError: self.skipTest( "Marvin configuration has no host credentials to check router services" ) res = str(result) self.logger.debug("SSVM script output: %s" % res) self.assertEqual(res.count("ERROR"), 1, "Check for Errors in tests") self.assertEqual(res.count("WARNING"), 1, "Check for warnings in tests") # Check status of cosmic-agent service try: host.user, host.passwd = get_host_credentials( self.config, host.ipaddress) result = get_process_status(host.ipaddress, 22, host.user, host.passwd, ssvm.linklocalip, "systemctl status cosmic-agent") except KeyError: self.skipTest( "Marvin configuration has no host credentials to check router services" ) res = str(result) self.logger.debug("cosmic-agent Process status: %s" % res) # cloud.com service (type=secstorage) is running: process id: 2346 self.assertEqual(res.count("active (running)"), 1, "Check cosmic-agent service is running or not") linklocal_ip = None # Check status of cloud service try: linklocal_ip = ssvm.linklocalip host.user, host.passwd = get_host_credentials( self.config, host.ipaddress) result = get_process_status( host.ipaddress, 22, host.user, host.passwd, ssvm.linklocalip, "cat /etc/cosmic/agent/agent.properties | grep eth0ip= | cut -d= -f2" ) except KeyError: self.skipTest( "Marvin configuration has no host credentials to check router services" ) res = result[0] self.logger.debug("Cached Link Local IP: %s" % res) self.assertEqual( linklocal_ip, res, "The cached Link Local should be the same as the current Link Local IP, but they are different! Current ==> %s; Cached ==> %s " % (linklocal_ip, res)) return @attr(tags=['advanced']) def test_04_cpvm_internals(self): """Test CPVM Internals""" # Validate the following # 1. test that telnet access on 8250 is available to # the management server for the CPVM # 2. No telnet access, test FAIL # 3. Service cloud status should report cloud agent status to be # running list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_cpvm_response, list), True, "Check list response returns a valid list") cpvm = list_cpvm_response[0] hosts = list_hosts(self.apiclient, id=cpvm.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list response returns a valid list") host = hosts[0] try: telnetlib.Telnet(str(self.apiclient.connection.mgtSvr), '8250') self.logger.debug("Telnet management server (IP: %s)" % self.apiclient.connection.mgtSvr) except Exception as e: self.fail("Telnet Access failed for %s: %s" % (self.apiclient.connection.mgtSvr, e)) self.logger.debug("Checking cosmic-agent process status") try: host.user, host.passwd = get_host_credentials( self.config, host.ipaddress) result = get_process_status(host.ipaddress, 22, host.user, host.passwd, cpvm.linklocalip, "systemctl status cosmic-agent") except KeyError: self.skipTest( "Marvin configuration has no host credentials to check router services" ) res = str(result) self.logger.debug("cosmic-agent Process status: %s" % res) self.assertEqual(res.count("active (running)"), 1, "Check cosmic-agent service is running or not") linklocal_ip = None # Check status of cosmic-agent service try: linklocal_ip = cpvm.linklocalip host.user, host.passwd = get_host_credentials( self.config, host.ipaddress) result = get_process_status( host.ipaddress, 22, host.user, host.passwd, cpvm.linklocalip, "cat /etc/cosmic/agent/agent.properties | grep eth0ip= | cut -d= -f2" ) except KeyError: self.skipTest( "Marvin configuration has no host credentials to check router services" ) res = result[0] self.logger.debug("Cached Link Local IP: %s" % res) self.assertEqual( linklocal_ip, res, "The cached Link Local should be the same as the current Link Local IP, but they are different! Current ==> %s; Cached ==> %s " % (linklocal_ip, res)) return @attr(tags=['advanced']) def test_05_reboot_ssvm(self): """Test reboot SSVM """ # Validate the following # 1. The SSVM should go to stop and return to Running state # 2. SSVM's public-ip and private-ip must remain the same # before and after reboot # 3. The cloud process should still be running within the SSVM list_ssvm_response = list_ssvms(self.apiclient, systemvmtype='secondarystoragevm', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_ssvm_response, list), True, "Check list response returns a valid list") ssvm_response = list_ssvm_response[0] hosts = list_hosts(self.apiclient, id=ssvm_response.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list response returns a valid list") # Store the public & private IP values before reboot old_public_ip = ssvm_response.publicip old_private_ip = ssvm_response.privateip self.logger.debug("Rebooting SSVM: %s" % ssvm_response.id) cmd = rebootSystemVm.rebootSystemVmCmd() cmd.id = ssvm_response.id self.apiclient.rebootSystemVm(cmd) timeout = self.services["timeout"] while True: list_ssvm_response = list_ssvms(self.apiclient, id=ssvm_response.id) if isinstance(list_ssvm_response, list): if list_ssvm_response[0].state == 'Running': break if timeout == 0: raise Exception("List SSVM call failed!") time.sleep(self.services["sleep"]) timeout = timeout - 1 ssvm_response = list_ssvm_response[0] self.logger.debug("SSVM State: %s" % ssvm_response.state) self.assertEqual('Running', str(ssvm_response.state), "Check whether CPVM is running or not") self.assertEqual( ssvm_response.publicip, old_public_ip, "Check Public IP after reboot with that of before reboot") # Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745 # Wait for the agent to be up self.wait_for_system_vm_agent(ssvm_response.name) # Wait for some time before running diagnostic scripts on SSVM # as it may take some time to start all service properly time.sleep(int(self.services["configurableData"]["systemVmDelay"])) # Call to verify cloud process is running self.test_03_ssvm_internals() return @attr(tags=['advanced']) def test_06_reboot_cpvm(self): """Test reboot CPVM """ # Validate the following # 1. The CPVM should go to stop and return to Running state # 2. CPVM's public-ip and private-ip must remain # the same before and after reboot # 3. the cloud process should still be running within the CPVM list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_cpvm_response, list), True, "Check list response returns a valid list") cpvm_response = list_cpvm_response[0] hosts = list_hosts(self.apiclient, id=cpvm_response.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list response returns a valid list") # Store the public & private IP values before reboot old_public_ip = cpvm_response.publicip old_private_ip = cpvm_response.privateip self.logger.debug("Rebooting CPVM: %s" % cpvm_response.id) cmd = rebootSystemVm.rebootSystemVmCmd() cmd.id = cpvm_response.id self.apiclient.rebootSystemVm(cmd) timeout = self.services["timeout"] while True: list_cpvm_response = list_ssvms(self.apiclient, id=cpvm_response.id) if isinstance(list_cpvm_response, list): if list_cpvm_response[0].state == 'Running': break if timeout == 0: raise Exception("List CPVM call failed!") time.sleep(self.services["sleep"]) timeout = timeout - 1 cpvm_response = list_cpvm_response[0] self.logger.debug("CPVM state: %s" % cpvm_response.state) self.assertEqual('Running', str(cpvm_response.state), "Check whether CPVM is running or not") self.assertEqual( cpvm_response.publicip, old_public_ip, "Check Public IP after reboot with that of before reboot") # Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745 # Wait for the agent to be up self.wait_for_system_vm_agent(cpvm_response.name) # Wait for some time before running diagnostic scripts on SSVM # as it may take some time to start all service properly time.sleep(int(self.services["configurableData"]["systemVmDelay"])) # Call to verify cloud process is running self.test_04_cpvm_internals() return @attr(tags=['advanced']) def test_07_destroy_ssvm(self): """Test destroy SSVM """ # Validate the following # 1. SSVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the # systemVM from what it was before # 3. new SSVM will have a public/private and link-local-ip # 4. cloud process within SSVM must be up and running list_ssvm_response = list_ssvms(self.apiclient, systemvmtype='secondarystoragevm', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_ssvm_response, list), True, "Check list response returns a valid list") ssvm_response = list_ssvm_response[0] old_name = ssvm_response.name self.logger.debug("Destroying SSVM: %s" % ssvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = ssvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_ssvm_response = list_ssvms(self.apiclient, zoneid=self.zone.id, systemvmtype='secondarystoragevm') if isinstance(list_ssvm_response, list): if list_ssvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List SSVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!" ) return time.sleep(self.services["sleep"]) timeout = timeout - 1 ssvm_response = list_ssvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created SSVM self.assertNotEqual(ssvm_response.name, old_name, "Check SSVM new name with name of destroyed SSVM") self.assertEqual(hasattr(ssvm_response, 'privateip'), True, "Check whether SSVM has private IP field") self.assertEqual(hasattr(ssvm_response, 'linklocalip'), True, "Check whether SSVM has link local IP field") self.assertEqual(hasattr(ssvm_response, 'publicip'), True, "Check whether SSVM has public IP field") # Wait for the agent to be up self.wait_for_system_vm_agent(ssvm_response.name) # Wait for some time before running diagnostic scripts on SSVM # as it may take some time to start all service properly time.sleep(int(self.services["configurableData"]["systemVmDelay"])) # Call to verify cloud process is running self.test_03_ssvm_internals() return @attr(tags=['advanced']) def test_08_destroy_cpvm(self): """Test destroy CPVM """ # Validate the following # 1. CPVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the systemVM from # what it was before # 3. new CPVM will have a public/private and link-local-ip # 4. cloud process within CPVM must be up and running list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id) self.assertEqual(isinstance(list_cpvm_response, list), True, "Check list response returns a valid list") cpvm_response = list_cpvm_response[0] old_name = cpvm_response.name self.logger.debug("Destroying CPVM: %s" % cpvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = cpvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id) if isinstance(list_cpvm_response, list): if list_cpvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List CPVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!" ) return time.sleep(self.services["sleep"]) timeout = timeout - 1 cpvm_response = list_cpvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created CPVM self.assertNotEqual(cpvm_response.name, old_name, "Check SSVM new name with name of destroyed CPVM") self.assertEqual(hasattr(cpvm_response, 'privateip'), True, "Check whether CPVM has private IP field") self.assertEqual(hasattr(cpvm_response, 'linklocalip'), True, "Check whether CPVM has link local IP field") self.assertEqual(hasattr(cpvm_response, 'publicip'), True, "Check whether CPVM has public IP field") # Wait for the agent to be up self.wait_for_system_vm_agent(cpvm_response.name) # Wait for some time before running diagnostic scripts on SSVM # as it may take some time to start all service properly time.sleep(int(self.services["configurableData"]["systemVmDelay"])) # Call to verify cloud process is running self.test_04_cpvm_internals() return def wait_for_system_vm_agent(self, vmname): self.logger.debug("Waiting for system VM %s agent to be UP" % vmname) timeout = self.services["timeout"] sleep_interval = self.services["sleep"] while timeout > 0: list_host_response = list_hosts(self.apiclient, name=vmname) if list_host_response and list_host_response[0].state == 'Up': self.debug("System VM %s agent is UP" % vmname) break time.sleep(sleep_interval) timeout = timeout - sleep_interval if timeout <= 0 and list_host_response[0].state != 'Up': self.fail("Timed out waiting for SVM agent to be Up") def test_list_svm_vm(self, svm_type): # Validate the following: # 1. listSystemVM # should return only ONE SVM per zone # 2. The returned SVM should be in Running state # 3. listSystemVM for should list publicip, privateip and link-localip # 4. The gateway programmed on the SVM by listSystemVm should be # the same as the gateway returned by listVlanIpRanges # 5. DNS entries must match those given for the zone list_svm_response = list_ssvms( self.apiclient, systemvmtype=svm_type, state='Running', ) self.assertEqual(isinstance(list_svm_response, list), True, "Check list response returns a valid list") # Verify SSVM response self.assertNotEqual(len(list_svm_response), 0, "Check list System VMs response") list_zones_response = list_zones(self.apiclient) self.assertEqual(isinstance(list_zones_response, list), True, "Check list response returns a valid list") self.logger.debug("Number of zones: %s" % len(list_zones_response)) self.logger.debug("Number of System VMs: %s" % len(list_svm_response)) # Number of Sec storage VMs = No of Zones self.assertEqual(len(list_svm_response), len(list_zones_response), "Check number of System VMs with number of zones") # For each secondary storage VM check private IP, # public IP, link local IP and DNS for svm in list_svm_response: self.logger.debug("SVM state: %s" % svm.state) self.assertEqual(svm.state, 'Running', "Check whether state of System VM is running") self.assertEqual(hasattr(svm, 'privateip'), True, "Check whether System VM has private IP field") self.assertEqual( hasattr(svm, 'linklocalip'), True, "Check whether System VM has link local IP field") self.assertEqual(hasattr(svm, 'publicip'), True, "Check whether System VM has public IP field") # Fetch corresponding ip ranges information from listVlanIpRanges ipranges_response = list_vlan_ipranges(self.apiclient, zoneid=svm.zoneid) self.assertEqual(isinstance(ipranges_response, list), True, "Check list response returns a valid list") iprange = ipranges_response[0] # Execute the following assertion in all zones except basic Zones if not (self.zone.networktype.lower() == 'basic'): self.assertEqual( svm.gateway, iprange.gateway, "Check gateway with that of corresponding ip range") # Fetch corresponding zone information from listZones zone_response = list_zones(self.apiclient, id=svm.zoneid) self.assertEqual(isinstance(zone_response, list), True, "Check list response returns a valid list") self.assertEqual(svm.dns1, zone_response[0].dns1, "Check DNS1 with that of corresponding zone") self.assertEqual(svm.dns2, zone_response[0].dns2, "Check DNS2 with that of corresponding zone") return
class DeployDataCenters(object): """ @Desc : Deploys the Data Center with information provided. Once the Deployment is successful, it will export the DataCenter settings to an obj file ( can be used if wanted to delete the created DC) """ def __init__(self, test_client, cfg): self.__test_client = test_client self.__config = cfg self.__logger = MarvinLog('marvin').get_logger() self.__apiClient = None self.__cleanUp = { } def __persistDcConfig(self): try: ts = strftime("%b_%d_%Y_%H_%M_%S", localtime()) dc_file_path = "dc_entries_" + str(ts) + ".obj" file_to_write = open(dc_file_path, 'w') if file_to_write: pickle.dump(self.__cleanUp, file_to_write) self.__logger.info("=== Data Center Settings are dumped to %s ===" % dc_file_path) except Exception as e: self.__logger.exception("=== Persisting DataCenter config failed: %s ===" % e) def __cleanAndExit(self): try: self.__logger.info("=== deploy dc failed, so cleaning the created entries ===") if not test_data.get("deleteDC", None): self.__logger.info("=== Deploy DC Clean Up flag not set. So, exiting ===") exit(1) self.__logger.info("=== Deploy DC Failed, So Cleaning to Exit ===") remove_dc_obj = DeleteDataCenters(self.__test_client, self.__cleanUp) if remove_dc_obj: if remove_dc_obj.removeDataCenter() == FAILED: self.__logger.error("=== Removing DataCenter Failed ===") else: self.__logger.info("=== Removing DataCenter Successful ===") except Exception as e: self.__logger.exception("=== Clean up failed: %s ===" % e) finally: exit(1) def __addToCleanUp(self, type, id): if type not in self.__cleanUp.keys(): self.__cleanUp[type] = [] self.__cleanUp[type].append(id) if "order" not in self.__cleanUp.keys(): self.__cleanUp["order"] = [] if type not in self.__cleanUp["order"]: self.__cleanUp["order"].append(type) def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): if hosts is None: self.__logger.warn("=== Invalid Hosts Information ===") return failed_cnt = 0 for host in hosts: try: hostcmd = addHost.addHostCmd() hostcmd.clusterid = clusterId hostcmd.hosttags = host.hosttags hostcmd.hypervisor = host.hypervisor hostcmd.password = host.password hostcmd.podid = podId hostcmd.url = host.url hostcmd.username = host.username hostcmd.zoneid = zoneId hostcmd.hypervisor = hypervisor hostcmd.hosttags = hypervisor ret = self.__apiClient.addHost(hostcmd) if ret: self.__logger.info("=== Add Host Successful ===") self.__addToCleanUp("Host", ret[0].id) except Exception as e: failed_cnt += 1 self.__logger.exception("=== Adding Host (%s) Failed: %s ===" % (str(host.url), e)) if failed_cnt == len(hosts): self.__cleanAndExit() def createClusters(self, clusters, zoneId, podId): try: if clusters is None: return for cluster in clusters: clustercmd = addCluster.addClusterCmd() clustercmd.clustername = cluster.clustername clustercmd.clustertype = cluster.clustertype clustercmd.hypervisor = cluster.hypervisor clustercmd.password = cluster.password clustercmd.podid = podId clustercmd.url = cluster.url clustercmd.username = cluster.username clustercmd.zoneid = zoneId clusterresponse = self.__apiClient.addCluster(clustercmd) if clusterresponse[0].id: clusterId = clusterresponse[0].id self.__logger.debug( "Cluster Name : %s Id : %s Created Successfully" % (str(cluster.clustername), str(clusterId))) self.__addToCleanUp("Cluster", clusterId) self.addHosts(cluster.hosts, zoneId, podId, clusterId, cluster.hypervisor) self.waitForHost(zoneId, clusterId) self.createPrimaryStorages(cluster.primaryStorages, zoneId, podId, clusterId) except Exception as e: self.__logger.exception("=== Cluster %s Creation Failed: %s ===" % (str(cluster.clustername), e)) self.__cleanAndExit() def waitForHost(self, zoneId, clusterId): """ Wait for the hosts in the zoneid, clusterid to be up 2 retries with 30s delay """ try: retry, timeout = 2, 30 cmd = listHosts.listHostsCmd() cmd.clusterid, cmd.zoneid = clusterId, zoneId hosts = self.__apiClient.listHosts(cmd) while retry != 0: for host in hosts: if host.state != 'Up': break sleep(timeout) retry -= 1 except Exception as e: self.__logger.exception("=== List Hosts Failed: %s ===" % e) self.__cleanAndExit() def createPrimaryStorages(self, primaryStorages, zoneId, podId=None, clusterId=None): try: if primaryStorages is None: return for primary in primaryStorages: primarycmd = createStoragePool.createStoragePoolCmd() if primary.details: for key, value in vars(primary.details).iteritems(): primarycmd.details.append({ key: value }) primarycmd.name = primary.name primarycmd.tags = primary.tags primarycmd.url = primary.url if primary.scope == 'zone' or clusterId is None: primarycmd.scope = 'zone' primarycmd.hypervisor = primary.hypervisor primarycmd.tags = 'zone' else: primarycmd.podid = podId primarycmd.clusterid = clusterId primarycmd.tags = 'cluster' primarycmd.zoneid = zoneId ret = self.__apiClient.createStoragePool(primarycmd) if ret.id: self.__logger.info("=== Creating Storage Pool Successful ===") self.__addToCleanUp("StoragePool", ret.id) except Exception as e: self.__logger.exception("=== Create Storage Pool Failed: %s ===" % e) self.__cleanAndExit() def createPods(self, pods, zoneId, networkId=None): try: if pods is None: return for pod in pods: createpod = createPod.createPodCmd() createpod.name = pod.name createpod.gateway = pod.gateway createpod.netmask = pod.netmask createpod.startip = pod.startip createpod.endip = pod.endip createpod.zoneid = zoneId createpodResponse = self.__apiClient.createPod(createpod) if createpodResponse.id: podId = createpodResponse.id self.__logger.debug("Pod Name : %s Id : %s Created Successfully" % (str(pod.name), str(podId))) self.__addToCleanUp("Pod", podId) if pod.guestIpRanges is not None and networkId is not None: self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId, podId, networkId) self.createClusters(pod.clusters, zoneId, podId) except Exception as e: self.__logger.exception("=== Pod: %s Creation Failed: %s ===" % (str(pod.name), e)) self.__cleanAndExit() def createVlanIpRanges(self, mode, ipranges, zoneId, podId=None, networkId=None, forvirtualnetwork=None): try: if ipranges is None: return for iprange in ipranges: vlanipcmd = createVlanIpRange.createVlanIpRangeCmd() vlanipcmd.account = iprange.account vlanipcmd.domainid = iprange.domainid vlanipcmd.endip = iprange.endip vlanipcmd.gateway = iprange.gateway vlanipcmd.netmask = iprange.netmask vlanipcmd.networkid = networkId vlanipcmd.podid = podId vlanipcmd.startip = iprange.startip vlanipcmd.zoneid = zoneId vlanipcmd.vlan = iprange.vlan if mode == "Basic": if forvirtualnetwork: vlanipcmd.forvirtualnetwork = "true" else: vlanipcmd.forvirtualnetwork = "false" else: vlanipcmd.forvirtualnetwork = "true" ret = self.__apiClient.createVlanIpRange(vlanipcmd) if ret.id: self.__logger.info("=== Creating Vlan Ip Range Successful ===") self.__addToCleanUp("VlanIpRange", ret.id) except Exception as e: self.__logger.exception("=== Create Vlan Ip Range Failed: %s ===" % e) self.__cleanAndExit() def createSecondaryStorages(self, secondaryStorages, zoneId): try: if secondaryStorages is None: return for secondary in secondaryStorages: secondarycmd = addImageStore.addImageStoreCmd() secondarycmd.url = secondary.url secondarycmd.provider = secondary.provider secondarycmd.details = [] if secondarycmd.provider.lower() in ("smb"): for key, value in vars(secondary.details).iteritems(): secondarycmd.details.append({ 'key': key, 'value': value }) if secondarycmd.provider.lower() in ("nfs", "smb"): secondarycmd.zoneid = zoneId ret = self.__apiClient.addImageStore(secondarycmd) if ret.id: self.__logger.info("=== Add Image Store Successful ===") self.__addToCleanUp("ImageStore", ret.id) except Exception as e: self.__logger.exception("=== Add Image Store Failed: %s ===" % e) self.__cleanAndExit() def createCacheStorages(self, cacheStorages, zoneId): try: if cacheStorages is None: return for cache in cacheStorages: cachecmd = createSecondaryStagingStore.createSecondaryStagingStoreCmd() cachecmd.url = cache.url cachecmd.provider = cache.provider cachecmd.zoneid = zoneId cachecmd.details = [] if cache.details: for key, value in vars(cache.details).iteritems(): cachecmd.details.append({ 'key': key, 'value': value }) ret = self.__apiClient.createSecondaryStagingStore(cachecmd) if ret.id: self.__logger.info("=== Creating Secondary StagingStore Successful ===") self.__addToCleanUp("SecondaryStagingStore", ret.id) except Exception as e: self.__logger.exception("=== Creating Secondary Staging Storage Failed: %s ===" % e) self.__cleanAndExit() def createNetworks(self, networks, zoneId): try: if networks is None: return for network in networks: networkcmd = createNetwork.createNetworkCmd() networkcmd.displaytext = network.displaytext networkcmd.name = network.name networkcmd.networkofferingid = network.networkofferingid networkcmd.zoneid = zoneId ipranges = network.ipranges if ipranges: iprange = ipranges.pop() networkcmd.startip = iprange.startip networkcmd.endip = iprange.endip networkcmd.gateway = iprange.gateway networkcmd.netmask = iprange.netmask networkcmdresponse = self.__apiClient.createNetwork(networkcmd) if networkcmdresponse.id: networkId = networkcmdresponse.id self.__logger.info( "=== Creating Network Name : %s Id : %s Successful ===" % (str(network.name), str(networkId))) self.__addToCleanUp("Network", networkId) return networkId except Exception as e: self.__logger.exception("=== Network : %s Creation Failed: %s ===" % (str(network.name), e)) self.__cleanAndExit() def createPhysicalNetwork(self, net, zoneid): try: phynet = createPhysicalNetwork.createPhysicalNetworkCmd() phynet.zoneid = zoneid phynet.name = net.name phynet.isolationmethods = net.isolationmethods phynetwrk = self.__apiClient.createPhysicalNetwork(phynet) if phynetwrk.id: self.__logger.info("=== Creating Physical Network Name : %s Id : %s Successful ===" % ( str(phynet.name), str(phynetwrk.id))) self.__addToCleanUp("PhysicalNetwork", phynetwrk.id) self.addTrafficTypes(phynetwrk.id, net.traffictypes) return phynetwrk except Exception as e: self.__logger.exception("=== Physical Network Creation Failed: %s ===" % e) self.__cleanAndExit() def updatePhysicalNetwork(self, networkid, state="Enabled", vlan=None): try: upnet = updatePhysicalNetwork.updatePhysicalNetworkCmd() upnet.id = networkid upnet.state = state if vlan: upnet.vlan = vlan ret = self.__apiClient.updatePhysicalNetwork(upnet) return ret except Exception as e: self.__logger.exception("=== Update Physical Network Failed: %s ===" % e) self.__cleanAndExit() def enableProvider(self, provider_id): try: upnetprov = \ updateNetworkServiceProvider.updateNetworkServiceProviderCmd() upnetprov.id = provider_id upnetprov.state = "Enabled" ret = self.__apiClient.updateNetworkServiceProvider(upnetprov) if ret.id: self.__logger.info("=== Update Network Service Provider Successfull ===") except Exception as e: self.__logger.exception("=== Update Network Service Provider Failed: %s ===" % e) self.__cleanAndExit() def configureProviders(self, phynetwrk, providers): """ We will enable the virtualrouter elements for all zones. """ try: for provider in providers: pnetprov = listNetworkServiceProviders.listNetworkServiceProvidersCmd() pnetprov.physicalnetworkid = phynetwrk.id pnetprov.state = "Disabled" pnetprov.name = provider.name pnetprovres = self.__apiClient.listNetworkServiceProviders( pnetprov) if pnetprovres and len(pnetprovres) > 0: if provider.name == 'VirtualRouter' or provider.name == 'VpcVirtualRouter': vrprov = listVirtualRouterElements.listVirtualRouterElementsCmd() vrprov.nspid = pnetprovres[0].id vrprovresponse = self.__apiClient.listVirtualRouterElements(vrprov) vrprovid = vrprovresponse[0].id vrconfig = configureVirtualRouterElement.configureVirtualRouterElementCmd() vrconfig.enabled = "true" vrconfig.id = vrprovid self.__apiClient.configureVirtualRouterElement(vrconfig) self.enableProvider(pnetprovres[0].id) elif provider.name in ['NiciraNvp']: netprov = addNetworkServiceProvider.addNetworkServiceProviderCmd() netprov.name = provider.name netprov.physicalnetworkid = phynetwrk.id result = self.__apiClient.addNetworkServiceProvider( netprov) if result.id: self.__logger.info("=== AddNetworkServiceProvider Successful ===") self.__addToCleanUp("NetworkServiceProvider", result.id) if provider.devices is not None: for device in provider.devices: if provider.name == 'NiciraNvp': cmd = addNiciraNvpDevice.addNiciraNvpDeviceCmd() cmd.hostname = device.hostname cmd.username = device.username cmd.password = device.password cmd.transportzoneuuid = device.transportzoneuuid cmd.physicalnetworkid = phynetwrk.id ret = self.__apiClient.addNiciraNvpDevice(cmd) self.__logger.info("=== Add NiciraNvp Successful ===") self.__addToCleanUp("NiciraNvp", ret.id) else: raise InvalidParameterException( "Device %s doesn't match any know provider type" % device) self.enableProvider(result.id) except Exception as e: self.__logger.exception("=== List Network Service Providers Failed: %s ===" % e) self.__cleanAndExit() def addTrafficTypes(self, physical_network_id, traffictypes): [self.addTrafficType(physical_network_id, traffic_type) for traffic_type in traffictypes] def addTrafficType(self, physical_network_id, traffictype): try: traffic_type = addTrafficType.addTrafficTypeCmd() traffic_type.physicalnetworkid = physical_network_id traffic_type.traffictype = traffictype.typ traffic_type.kvmnetworklabel = traffictype.kvm \ if traffictype.kvm is not None else None traffic_type.xennetworklabel = traffictype.xen \ if traffictype.xen is not None else None traffic_type.simulatorlabel = traffictype.simulator \ if traffictype.simulator is not None else None ret = self.__apiClient.addTrafficType(traffic_type) if ret.id: self.__logger.info("=== Add TrafficType Successful ===") self.__addToCleanUp("TrafficType", ret.id) return ret except Exception as e: self.__logger.exception("=== Add TrafficType Failed: %s ===" % e) self.__cleanAndExit() def enableZone(self, zoneid, allocation_state="Enabled"): try: zoneCmd = updateZone.updateZoneCmd() zoneCmd.id = zoneid zoneCmd.allocationstate = allocation_state ret = self.__apiClient.updateZone(zoneCmd) if ret.id: self.__logger.info("=== Enable Zone Successful ===") return ret except Exception as e: self.__logger.exception("=== Enable Zone Failed: %s ===" % e) self.__cleanAndExit() def updateZoneDetails(self, zoneid, details): try: zoneCmd = updateZone.updateZoneCmd() zoneCmd.id = zoneid zoneCmd.details = details ret = self.__apiClient.updateZone(zoneCmd) if ret.id: self.__logger.info("=== Update Zone Successful ===") return ret except Exception as e: self.__logger.exception("=== Update Zone Failed: %s ===" % e) self.__cleanAndExit() def createZone(self, zone, rec=0): try: zoneresponse = self.__apiClient.createZone(zone) if zoneresponse.id: self.__logger.info("=== Create Zone Successful ===") self.__logger.debug("Zone Name : %s Id : %s " % (str(zone.name), str(zoneresponse.id))) self.__addToCleanUp("Zone", zoneresponse.id) return zoneresponse.id else: self.__logger.exception("=== Zone : %s Creation Failed ===" % str(zone.name)) if not rec: zone.name = zone.name + "_" + random_gen() self.__logger.info("=== Recreating Zone With New Name : %s ===" % zone.name) return self.createZone(zone, 1) except Exception as e: self.__logger.exception("=== Create Zone Failed: %s ===" % e) return FAILED def createZones(self, zones): try: for zone in zones: zonecmd = createZone.createZoneCmd() zonecmd.dns1 = zone.dns1 zonecmd.dns2 = zone.dns2 zonecmd.internaldns1 = zone.internaldns1 zonecmd.internaldns2 = zone.internaldns2 zonecmd.name = zone.name zonecmd.localstorageenabled = zone.localstorageenabled zonecmd.networktype = zone.networktype zonecmd.domain = zone.domain zonecmd.guestcidraddress = zone.guestcidraddress zoneId = self.createZone(zonecmd) if zoneId == FAILED: self.__logger.error("=== Zone: %s Creation Failed. So Exiting ===" % str(zone.name)) self.__cleanAndExit() for pnet in zone.physical_networks: phynetwrk = self.createPhysicalNetwork(pnet, zoneId) self.configureProviders(phynetwrk, pnet.providers) self.updatePhysicalNetwork(phynetwrk.id, "Enabled", vlan=pnet.vlan) if zone.networktype == "Basic": listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd() if len(filter(lambda x: x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0: listnetworkoffering.name = "DefaultSharedNetscalerEIPandELBNetworkOffering" else: listnetworkoffering.name = "DefaultSharedNetworkOfferingWithSGService" if zone.networkofferingname is not None: listnetworkoffering.name = zone.networkofferingname listnetworkofferingresponse = self.__apiClient.listNetworkOfferings(listnetworkoffering) guestntwrk = configGenerator.network() guestntwrk.displaytext = "guestNetworkForBasicZone" guestntwrk.name = "guestNetworkForBasicZone" guestntwrk.zoneid = zoneId guestntwrk.networkofferingid = listnetworkofferingresponse[0].id networkid = self.createNetworks([guestntwrk], zoneId) self.createPods(zone.pods, zoneId, networkid) if self.isEipElbZone(zone): self.createVlanIpRanges(zone.networktype, zone.ipranges, zoneId, forvirtualnetwork=True) isPureAdvancedZone = zone.networktype == "Advanced" if isPureAdvancedZone: self.createPods(zone.pods, zoneId) self.createVlanIpRanges(zone.networktype, zone.ipranges, zoneId) '''Note: Swift needs cache storage first''' self.createCacheStorages(zone.cacheStorages, zoneId) self.createSecondaryStorages(zone.secondaryStorages, zoneId) if zone.primaryStorages: self.createPrimaryStorages(zone.primaryStorages, zoneId) enabled = getattr(zone, 'enabled', 'True') if enabled == 'True' or enabled is None: self.enableZone(zoneId, "Enabled") details = getattr(zone, 'details') if details is not None: det = [d.__dict__ for d in details] self.updateZoneDetails(zoneId, det) return except Exception as e: self.__logger.exception("=== Create Zones Failed: %e ===" % e) def isEipElbZone(self, zone): if zone.networktype == "Basic" and len( filter(lambda x: x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0: return True return False def setClient(self): """ @Name : setClient @Desc : Sets the API Client retrieved from test client """ self.__apiClient = self.__test_client.getApiClient() def updateConfiguration(self, globalCfg): try: if globalCfg is None or self.__apiClient is None: return None for config in globalCfg: updateCfg = updateConfiguration.updateConfigurationCmd() updateCfg.name = config.name updateCfg.value = config.value ret = self.__apiClient.updateConfiguration(updateCfg) if ret.id: self.__logger.info("=== Update Configuration Successfull ===") except Exception as e: self.__logger.exception("=== Update Configuration Failed: %s ===" % e) self.__cleanAndExit() @staticmethod def copyAttributesToCommand(source, command): map(lambda attr: setattr(command, attr, getattr(source, attr, None)), filter(lambda attr: not attr.startswith("__") and attr not in ["required", "isAsync"], dir(command))) def deploy(self): try: self.__logger.info("=== Deploy DC Started ===") ''' Step1 : Set the Client ''' self.setClient() ''' Step2: Update the Configuration ''' self.updateConfiguration(self.__config.globalConfig) ''' Step3 :Deploy the Zone ''' self.createZones(self.__config.zones) ''' Persist the Configuration to an external file post DC creation ''' self.__persistDcConfig() self.__logger.info("=== Deploy DC Successful ===") return SUCCESS except Exception as e: self.__logger.exception("=== Deploy DC Failed: %s ===" % e) self.__cleanAndExit() return FAILED
class DeployDataCenters(object): """ @Desc : Deploys the Data Center with information provided. Once the Deployment is successful, it will export the DataCenter settings to an obj file ( can be used if wanted to delete the created DC) """ def __init__(self, test_client, cfg): self.__test_client = test_client self.__config = cfg self.__logger = MarvinLog('marvin').get_logger() self.__apiClient = None self.__cleanUp = {} def __persistDcConfig(self): try: ts = strftime("%b_%d_%Y_%H_%M_%S", localtime()) dc_file_path = "dc_entries_" + str(ts) + ".obj" file_to_write = open(dc_file_path, 'w') if file_to_write: pickle.dump(self.__cleanUp, file_to_write) self.__logger.info( "=== Data Center Settings are dumped to %s ===" % dc_file_path) except Exception as e: self.__logger.exception( "=== Persisting DataCenter config failed: %s ===" % e) def __cleanAndExit(self): try: self.__logger.info( "=== deploy dc failed, so cleaning the created entries ===") if not test_data.get("deleteDC", None): self.__logger.info( "=== Deploy DC Clean Up flag not set. So, exiting ===") exit(1) self.__logger.info("=== Deploy DC Failed, So Cleaning to Exit ===") remove_dc_obj = DeleteDataCenters(self.__test_client, self.__cleanUp) if remove_dc_obj: if remove_dc_obj.removeDataCenter() == FAILED: self.__logger.error("=== Removing DataCenter Failed ===") else: self.__logger.info( "=== Removing DataCenter Successful ===") except Exception as e: self.__logger.exception("=== Clean up failed: %s ===" % e) finally: exit(1) def __addToCleanUp(self, type, id): if type not in self.__cleanUp.keys(): self.__cleanUp[type] = [] self.__cleanUp[type].append(id) if "order" not in self.__cleanUp.keys(): self.__cleanUp["order"] = [] if type not in self.__cleanUp["order"]: self.__cleanUp["order"].append(type) def addHosts(self, hosts, zoneId, podId, clusterId, hypervisor): if hosts is None: self.__logger.warn("=== Invalid Hosts Information ===") return failed_cnt = 0 for host in hosts: try: hostcmd = addHost.addHostCmd() hostcmd.clusterid = clusterId hostcmd.hosttags = host.hosttags hostcmd.hypervisor = host.hypervisor hostcmd.password = host.password hostcmd.podid = podId hostcmd.url = host.url hostcmd.username = host.username hostcmd.zoneid = zoneId hostcmd.hypervisor = hypervisor ret = self.__apiClient.addHost(hostcmd) if ret: self.__logger.info("=== Add Host Successful ===") self.__addToCleanUp("Host", ret[0].id) except Exception as e: failed_cnt += 1 self.__logger.exception("=== Adding Host (%s) Failed: %s ===" % (str(host.url), e)) if failed_cnt == len(hosts): self.__cleanAndExit() def createClusters(self, clusters, zoneId, podId): try: if clusters is None: return for cluster in clusters: clustercmd = addCluster.addClusterCmd() clustercmd.clustername = cluster.clustername clustercmd.clustertype = cluster.clustertype clustercmd.hypervisor = cluster.hypervisor clustercmd.password = cluster.password clustercmd.podid = podId clustercmd.url = cluster.url clustercmd.username = cluster.username clustercmd.zoneid = zoneId clusterresponse = self.__apiClient.addCluster(clustercmd) if clusterresponse[0].id: clusterId = clusterresponse[0].id self.__logger.debug( "Cluster Name : %s Id : %s Created Successfully" % (str(cluster.clustername), str(clusterId))) self.__addToCleanUp("Cluster", clusterId) self.addHosts(cluster.hosts, zoneId, podId, clusterId, cluster.hypervisor) self.waitForHost(zoneId, clusterId) self.createPrimaryStorages(cluster.primaryStorages, zoneId, podId, clusterId) except Exception as e: self.__logger.exception("=== Cluster %s Creation Failed: %s ===" % (str(cluster.clustername), e)) self.__cleanAndExit() def waitForHost(self, zoneId, clusterId): """ Wait for the hosts in the zoneid, clusterid to be up 2 retries with 30s delay """ try: retry, timeout = 2, 30 cmd = listHosts.listHostsCmd() cmd.clusterid, cmd.zoneid = clusterId, zoneId hosts = self.__apiClient.listHosts(cmd) while retry != 0: for host in hosts: if host.state != 'Up': break sleep(timeout) retry -= 1 except Exception as e: self.__logger.exception("=== List Hosts Failed: %s ===" % e) self.__cleanAndExit() def createPrimaryStorages(self, primaryStorages, zoneId, podId=None, clusterId=None): try: if primaryStorages is None: return for primary in primaryStorages: primarycmd = createStoragePool.createStoragePoolCmd() if primary.details: for key, value in vars(primary.details).iteritems(): primarycmd.details.append({key: value}) primarycmd.name = primary.name primarycmd.tags = primary.tags primarycmd.url = primary.url if primary.scope == 'zone' or clusterId is None: primarycmd.scope = 'zone' primarycmd.hypervisor = primary.hypervisor else: primarycmd.podid = podId primarycmd.clusterid = clusterId primarycmd.zoneid = zoneId ret = self.__apiClient.createStoragePool(primarycmd) if ret.id: self.__logger.info( "=== Creating Storage Pool Successful ===") self.__addToCleanUp("StoragePool", ret.id) except Exception as e: self.__logger.exception("=== Create Storage Pool Failed: %s ===" % e) self.__cleanAndExit() def createPods(self, pods, zoneId, networkId=None): try: if pods is None: return for pod in pods: createpod = createPod.createPodCmd() createpod.name = pod.name createpod.gateway = pod.gateway createpod.netmask = pod.netmask createpod.startip = pod.startip createpod.endip = pod.endip createpod.zoneid = zoneId createpodResponse = self.__apiClient.createPod(createpod) if createpodResponse.id: podId = createpodResponse.id self.__logger.debug( "Pod Name : %s Id : %s Created Successfully" % (str(pod.name), str(podId))) self.__addToCleanUp("Pod", podId) if pod.guestIpRanges is not None and networkId is not None: self.createVlanIpRanges("Basic", pod.guestIpRanges, zoneId, podId, networkId) self.createClusters(pod.clusters, zoneId, podId) except Exception as e: self.__logger.exception("=== Pod: %s Creation Failed: %s ===" % (str(pod.name), e)) self.__cleanAndExit() def createVlanIpRanges(self, mode, ipranges, zoneId, podId=None, networkId=None, forvirtualnetwork=None): try: if ipranges is None: return for iprange in ipranges: vlanipcmd = createVlanIpRange.createVlanIpRangeCmd() vlanipcmd.account = iprange.account vlanipcmd.domainid = iprange.domainid vlanipcmd.endip = iprange.endip vlanipcmd.gateway = iprange.gateway vlanipcmd.netmask = iprange.netmask vlanipcmd.networkid = networkId vlanipcmd.podid = podId vlanipcmd.startip = iprange.startip vlanipcmd.zoneid = zoneId vlanipcmd.vlan = iprange.vlan if mode == "Basic": if forvirtualnetwork: vlanipcmd.forvirtualnetwork = "true" else: vlanipcmd.forvirtualnetwork = "false" else: vlanipcmd.forvirtualnetwork = "true" ret = self.__apiClient.createVlanIpRange(vlanipcmd) if ret.id: self.__logger.info( "=== Creating Vlan Ip Range Successful ===") self.__addToCleanUp("VlanIpRange", ret.id) except Exception as e: self.__logger.exception("=== Create Vlan Ip Range Failed: %s ===" % e) self.__cleanAndExit() def createSecondaryStorages(self, secondaryStorages, zoneId): try: if secondaryStorages is None: return for secondary in secondaryStorages: secondarycmd = addImageStore.addImageStoreCmd() secondarycmd.url = secondary.url secondarycmd.provider = secondary.provider secondarycmd.details = [] if secondarycmd.provider.lower() in ("smb"): for key, value in vars(secondary.details).iteritems(): secondarycmd.details.append({ 'key': key, 'value': value }) if secondarycmd.provider.lower() in ("nfs", "smb"): secondarycmd.zoneid = zoneId ret = self.__apiClient.addImageStore(secondarycmd) if ret.id: self.__logger.info("=== Add Image Store Successful ===") self.__addToCleanUp("ImageStore", ret.id) except Exception as e: self.__logger.exception("=== Add Image Store Failed: %s ===" % e) self.__cleanAndExit() def createCacheStorages(self, cacheStorages, zoneId): try: if cacheStorages is None: return for cache in cacheStorages: cachecmd = createSecondaryStagingStore.createSecondaryStagingStoreCmd( ) cachecmd.url = cache.url cachecmd.provider = cache.provider cachecmd.zoneid = zoneId cachecmd.details = [] if cache.details: for key, value in vars(cache.details).iteritems(): cachecmd.details.append({'key': key, 'value': value}) ret = self.__apiClient.createSecondaryStagingStore(cachecmd) if ret.id: self.__logger.info( "=== Creating Secondary StagingStore Successful ===") self.__addToCleanUp("SecondaryStagingStore", ret.id) except Exception as e: self.__logger.exception( "=== Creating Secondary Staging Storage Failed: %s ===" % e) self.__cleanAndExit() def createNetworks(self, networks, zoneId): try: if networks is None: return for network in networks: networkcmd = createNetwork.createNetworkCmd() networkcmd.displaytext = network.displaytext networkcmd.name = network.name networkcmd.networkofferingid = network.networkofferingid networkcmd.zoneid = zoneId ipranges = network.ipranges if ipranges: iprange = ipranges.pop() networkcmd.startip = iprange.startip networkcmd.endip = iprange.endip networkcmd.gateway = iprange.gateway networkcmd.netmask = iprange.netmask networkcmdresponse = self.__apiClient.createNetwork(networkcmd) if networkcmdresponse.id: networkId = networkcmdresponse.id self.__logger.info( "=== Creating Network Name : %s Id : %s Successful ===" % (str(network.name), str(networkId))) self.__addToCleanUp("Network", networkId) return networkId except Exception as e: self.__logger.exception( "=== Network : %s Creation Failed: %s ===" % (str(network.name), e)) self.__cleanAndExit() def createPhysicalNetwork(self, net, zoneid): try: phynet = createPhysicalNetwork.createPhysicalNetworkCmd() phynet.zoneid = zoneid phynet.name = net.name phynet.isolationmethods = net.isolationmethods phynetwrk = self.__apiClient.createPhysicalNetwork(phynet) if phynetwrk.id: self.__logger.info( "=== Creating Physical Network Name : %s Id : %s Successful ===" % (str(phynet.name), str(phynetwrk.id))) self.__addToCleanUp("PhysicalNetwork", phynetwrk.id) self.addTrafficTypes(phynetwrk.id, net.traffictypes) return phynetwrk except Exception as e: self.__logger.exception( "=== Physical Network Creation Failed: %s ===" % e) self.__cleanAndExit() def updatePhysicalNetwork(self, networkid, state="Enabled", vlan=None): try: upnet = updatePhysicalNetwork.updatePhysicalNetworkCmd() upnet.id = networkid upnet.state = state if vlan: upnet.vlan = vlan ret = self.__apiClient.updatePhysicalNetwork(upnet) return ret except Exception as e: self.__logger.exception( "=== Update Physical Network Failed: %s ===" % e) self.__cleanAndExit() def enableProvider(self, provider_id): try: upnetprov = \ updateNetworkServiceProvider.updateNetworkServiceProviderCmd() upnetprov.id = provider_id upnetprov.state = "Enabled" ret = self.__apiClient.updateNetworkServiceProvider(upnetprov) if ret.id: self.__logger.info( "=== Update Network Service Provider Successfull ===") except Exception as e: self.__logger.exception( "=== Update Network Service Provider Failed: %s ===" % e) self.__cleanAndExit() def configureProviders(self, phynetwrk, providers): """ We will enable the virtualrouter elements for all zones. """ try: for provider in providers: pnetprov = listNetworkServiceProviders.listNetworkServiceProvidersCmd( ) pnetprov.physicalnetworkid = phynetwrk.id pnetprov.state = "Disabled" pnetprov.name = provider.name pnetprovres = self.__apiClient.listNetworkServiceProviders( pnetprov) if pnetprovres and len(pnetprovres) > 0: if provider.name == 'VirtualRouter' or provider.name == 'VpcVirtualRouter': vrprov = listVirtualRouterElements.listVirtualRouterElementsCmd( ) vrprov.nspid = pnetprovres[0].id vrprovresponse = self.__apiClient.listVirtualRouterElements( vrprov) vrprovid = vrprovresponse[0].id vrconfig = configureVirtualRouterElement.configureVirtualRouterElementCmd( ) vrconfig.enabled = "true" vrconfig.id = vrprovid self.__apiClient.configureVirtualRouterElement( vrconfig) self.enableProvider(pnetprovres[0].id) elif provider.name == 'InternalLbVm': internallbprov = listInternalLoadBalancerElements.listInternalLoadBalancerElementsCmd( ) internallbprov.nspid = pnetprovres[0].id internallbresponse = self.__apiClient.listInternalLoadBalancerElements( internallbprov) internallbid = internallbresponse[0].id internallbconfig = configureInternalLoadBalancerElement.configureInternalLoadBalancerElementCmd( ) internallbconfig.enabled = "true" internallbconfig.id = internallbid self.__apiClient.configureInternalLoadBalancerElement( internallbconfig) self.enableProvider(pnetprovres[0].id) elif provider.name == 'SecurityGroupProvider': self.enableProvider(pnetprovres[0].id) elif provider.name in ['NiciraNvp']: netprov = addNetworkServiceProvider.addNetworkServiceProviderCmd( ) netprov.name = provider.name netprov.physicalnetworkid = phynetwrk.id result = self.__apiClient.addNetworkServiceProvider( netprov) if result.id: self.__logger.info( "=== AddNetworkServiceProvider Successful ===") self.__addToCleanUp("NetworkServiceProvider", result.id) if provider.devices is not None: for device in provider.devices: if provider.name == 'NiciraNvp': cmd = addNiciraNvpDevice.addNiciraNvpDeviceCmd( ) cmd.hostname = device.hostname cmd.username = device.username cmd.password = device.password cmd.transportzoneuuid = device.transportzoneuuid cmd.physicalnetworkid = phynetwrk.id ret = self.__apiClient.addNiciraNvpDevice(cmd) self.__logger.info( "=== Add NiciraNvp Successful ===") self.__addToCleanUp("NiciraNvp", ret.id) else: raise InvalidParameterException( "Device %s doesn't match any know provider type" % device) self.enableProvider(result.id) except Exception as e: self.__logger.exception( "=== List Network Service Providers Failed: %s ===" % e) self.__cleanAndExit() def addTrafficTypes(self, physical_network_id, traffictypes): [ self.addTrafficType(physical_network_id, traffic_type) for traffic_type in traffictypes ] def addTrafficType(self, physical_network_id, traffictype): try: traffic_type = addTrafficType.addTrafficTypeCmd() traffic_type.physicalnetworkid = physical_network_id traffic_type.traffictype = traffictype.typ traffic_type.kvmnetworklabel = traffictype.kvm \ if traffictype.kvm is not None else None traffic_type.xennetworklabel = traffictype.xen \ if traffictype.xen is not None else None traffic_type.simulatorlabel = traffictype.simulator \ if traffictype.simulator is not None else None ret = self.__apiClient.addTrafficType(traffic_type) if ret.id: self.__logger.info("=== Add TrafficType Successful ===") self.__addToCleanUp("TrafficType", ret.id) return ret except Exception as e: self.__logger.exception("=== Add TrafficType Failed: %s ===" % e) self.__cleanAndExit() def enableZone(self, zoneid, allocation_state="Enabled"): try: zoneCmd = updateZone.updateZoneCmd() zoneCmd.id = zoneid zoneCmd.allocationstate = allocation_state ret = self.__apiClient.updateZone(zoneCmd) if ret.id: self.__logger.info("=== Enable Zone Successful ===") return ret except Exception as e: self.__logger.exception("=== Enable Zone Failed: %s ===" % e) self.__cleanAndExit() def updateZoneDetails(self, zoneid, details): try: zoneCmd = updateZone.updateZoneCmd() zoneCmd.id = zoneid zoneCmd.details = details ret = self.__apiClient.updateZone(zoneCmd) if ret.id: self.__logger.info("=== Update Zone Successful ===") return ret except Exception as e: self.__logger.exception("=== Update Zone Failed: %s ===" % e) self.__cleanAndExit() def createZone(self, zone, rec=0): try: zoneresponse = self.__apiClient.createZone(zone) if zoneresponse.id: self.__logger.info("=== Create Zone Successful ===") self.__logger.debug("Zone Name : %s Id : %s " % (str(zone.name), str(zoneresponse.id))) self.__addToCleanUp("Zone", zoneresponse.id) return zoneresponse.id else: self.__logger.exception("=== Zone : %s Creation Failed ===" % str(zone.name)) if not rec: zone.name = zone.name + "_" + random_gen() self.__logger.info( "=== Recreating Zone With New Name : %s ===" % zone.name) return self.createZone(zone, 1) except Exception as e: self.__logger.exception("=== Create Zone Failed: %s ===" % e) return FAILED def createZones(self, zones): try: for zone in zones: zonecmd = createZone.createZoneCmd() zonecmd.dns1 = zone.dns1 zonecmd.dns2 = zone.dns2 zonecmd.internaldns1 = zone.internaldns1 zonecmd.internaldns2 = zone.internaldns2 zonecmd.name = zone.name zonecmd.securitygroupenabled = zone.securitygroupenabled zonecmd.localstorageenabled = zone.localstorageenabled zonecmd.networktype = zone.networktype zonecmd.domain = zone.domain if zone.securitygroupenabled != "true": zonecmd.guestcidraddress = zone.guestcidraddress zoneId = self.createZone(zonecmd) if zoneId == FAILED: self.__logger.error( "=== Zone: %s Creation Failed. So Exiting ===" % str(zone.name)) self.__cleanAndExit() for pnet in zone.physical_networks: phynetwrk = self.createPhysicalNetwork(pnet, zoneId) self.configureProviders(phynetwrk, pnet.providers) self.updatePhysicalNetwork(phynetwrk.id, "Enabled", vlan=pnet.vlan) if zone.networktype == "Basic": listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd( ) if len( filter( lambda x: x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0: listnetworkoffering.name = "DefaultSharedNetscalerEIPandELBNetworkOffering" else: listnetworkoffering.name = "DefaultSharedNetworkOfferingWithSGService" if zone.networkofferingname is not None: listnetworkoffering.name = zone.networkofferingname listnetworkofferingresponse = self.__apiClient.listNetworkOfferings( listnetworkoffering) guestntwrk = configGenerator.network() guestntwrk.displaytext = "guestNetworkForBasicZone" guestntwrk.name = "guestNetworkForBasicZone" guestntwrk.zoneid = zoneId guestntwrk.networkofferingid = listnetworkofferingresponse[ 0].id networkid = self.createNetworks([guestntwrk], zoneId) self.createPods(zone.pods, zoneId, networkid) if self.isEipElbZone(zone): self.createVlanIpRanges(zone.networktype, zone.ipranges, zoneId, forvirtualnetwork=True) isPureAdvancedZone = (zone.networktype == "Advanced" and zone.securitygroupenabled != "true") if isPureAdvancedZone: self.createPods(zone.pods, zoneId) self.createVlanIpRanges(zone.networktype, zone.ipranges, zoneId) elif zone.networktype == "Advanced" and zone.securitygroupenabled == "true": listnetworkoffering = listNetworkOfferings.listNetworkOfferingsCmd( ) listnetworkoffering.name = "DefaultSharedNetworkOfferingWithSGService" if zone.networkofferingname is not None: listnetworkoffering.name = zone.networkofferingname listnetworkofferingresponse = self.__apiClient.listNetworkOfferings( listnetworkoffering) networkcmd = createNetwork.createNetworkCmd() networkcmd.displaytext = "Shared SG enabled network" networkcmd.name = "Shared SG enabled network" networkcmd.networkofferingid = listnetworkofferingresponse[ 0].id networkcmd.zoneid = zoneId ipranges = zone.ipranges if ipranges: iprange = ipranges.pop() networkcmd.startip = iprange.startip networkcmd.endip = iprange.endip networkcmd.gateway = iprange.gateway networkcmd.netmask = iprange.netmask networkcmd.vlan = iprange.vlan networkcmdresponse = self.__apiClient.createNetwork( networkcmd) if networkcmdresponse.id: self.__addToCleanUp("Network", networkcmdresponse.id) self.__logger.debug( "create Network Successful. NetworkId : %s " % str(networkcmdresponse.id)) self.createPods(zone.pods, zoneId, networkcmdresponse.id) '''Note: Swift needs cache storage first''' self.createCacheStorages(zone.cacheStorages, zoneId) self.createSecondaryStorages(zone.secondaryStorages, zoneId) if zone.primaryStorages: self.createPrimaryStorages(zone.primaryStorages, zoneId) enabled = getattr(zone, 'enabled', 'True') if enabled == 'True' or enabled is None: self.enableZone(zoneId, "Enabled") details = getattr(zone, 'details') if details is not None: det = [d.__dict__ for d in details] self.updateZoneDetails(zoneId, det) return except Exception as e: self.__logger.exception("=== Create Zones Failed: %e ===" % e) def isEipElbZone(self, zone): if zone.networktype == "Basic" and len( filter(lambda x: x.typ == 'Public', zone.physical_networks[0].traffictypes)) > 0: return True return False def setClient(self): """ @Name : setClient @Desc : Sets the API Client retrieved from test client """ self.__apiClient = self.__test_client.getApiClient() def updateConfiguration(self, globalCfg): try: if globalCfg is None or self.__apiClient is None: return None for config in globalCfg: updateCfg = updateConfiguration.updateConfigurationCmd() updateCfg.name = config.name updateCfg.value = config.value ret = self.__apiClient.updateConfiguration(updateCfg) if ret.id: self.__logger.info( "=== Update Configuration Successfull ===") except Exception as e: self.__logger.exception("=== Update Configuration Failed: %s ===" % e) self.__cleanAndExit() @staticmethod def copyAttributesToCommand(source, command): map( lambda attr: setattr(command, attr, getattr(source, attr, None)), filter( lambda attr: not attr.startswith("__") and attr not in ["required", "isAsync"], dir(command))) def deploy(self): try: self.__logger.info("=== Deploy DC Started ===") ''' Step1 : Set the Client ''' self.setClient() ''' Step2: Update the Configuration ''' self.updateConfiguration(self.__config.globalConfig) ''' Step3 :Deploy the Zone ''' self.createZones(self.__config.zones) ''' Persist the Configuration to an external file post DC creation ''' self.__persistDcConfig() self.__logger.info("=== Deploy DC Successful ===") return SUCCESS except Exception as e: self.__logger.exception("=== Deploy DC Failed: %s ===" % e) self.__cleanAndExit() return FAILED
class TestDeleteAccount(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template(self.apiclient, self.zone.id) self.services["virtual_machine"]["zoneid"] = self.zone.id # Create an account, network, VM and IP addresses self.account = Account.create(self.apiclient, self.services["account"], admin=True, domainid=self.domain.id) self.service_offering = get_default_virtual_machine_offering( self.apiclient) self.vm_1 = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id) src_nat_ip_addrs = list_public_ip(self.apiclient, account=self.account.name, domainid=self.account.domainid) try: src_nat_ip_addr = src_nat_ip_addrs[0] except Exception as e: self.fail("SSH failed for VM with IP: %s %s" % (src_nat_ip_addr.ipaddress, e)) self.lb_rule = LoadBalancerRule.create(self.apiclient, self.services["lbrule"], src_nat_ip_addr.id, self.account.name) self.lb_rule.assign(self.apiclient, [self.vm_1]) self.nat_rule = NATRule.create(self.apiclient, self.vm_1, self.services["natrule"], src_nat_ip_addr.id) self.cleanup = [] return def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) return @attr(tags=['advanced']) def test_01_delete_account(self): """Test for delete account""" # Validate the Following # 1. after account.cleanup.interval (global setting) # time all the PF/LB rules should be deleted # 2. verify that list(LoadBalancer/PortForwarding)Rules # API does not return any rules for the account # 3. The domR should have been expunged for this account self.account.delete(self.apiclient) interval = list_configurations(self.apiclient, name='account.cleanup.interval') self.assertEqual(isinstance(interval, list), True, "Check if account.cleanup.interval config present") # Sleep to ensure that all resources are deleted time.sleep(int(interval[0].value)) # ListLoadBalancerRules should not list # associated rules with deleted account # Unable to find account testuser1 in domain 1 : Exception try: list_lb_rules(self.apiclient, account=self.account.name, domainid=self.account.domainid) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # ListPortForwardingRules should not # list associated rules with deleted account try: list_nat_rules(self.apiclient, account=self.account.name, domainid=self.account.domainid) except CloudstackAPIException: self.logger.debug("NATRule is deleted") # Retrieve router for the user account try: routers = list_routers(self.apiclient, account=self.account.name, domainid=self.account.domainid) self.assertEqual(routers, None, "Check routers are properly deleted.") except CloudstackAPIException: self.logger.debug("Router is deleted") except Exception as e: raise Exception( "Encountered %s raised while fetching routers for account: %s" % (e, self.account.name)) return
class TestScenarioManager: def __init__(self, api_client, scenario_data, test_data, zone, randomizeNames, cleanup): self.api_client = api_client self.scenario_data = scenario_data self.test_data = test_data self.zone = zone self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.dynamic_names = { 'accounts': {}, 'vpcs': {}, 'vms': {}, } self.randomizeNames = randomizeNames self.resources_to_cleanup = [] self.cleanup = cleanup @property def test_data(self): return self.test_data def get_dynamic_name(self, section, name): if name in self.dynamic_names[section]: return self.dynamic_names[section][name] else: return name def setup_infra(self): scenario_data = self.scenario_data['data'] self.deploy_domains(scenario_data['domains']) def deploy_domains(self, domains_data): for domain in domains_data: self.deploy_domain(domain['data']) def deploy_domain(self, domain_data): if domain_data['name'] == 'ROOT': domain_list = Domain.list(api_client=self.api_client, name=domain_data['name']) domain = domain_list[0] else: self.logger.debug('>>> DOMAIN => Creating "%s"...', domain_data['name']) domain = Domain.create( api_client=self.api_client, name=domain_data['name'] + ('-' + random_gen() if self.randomizeNames else '')) self.logger.debug( '>>> DOMAIN => ID: %s => Name: %s => Path: %s => State: %s', domain.id, domain.name, domain.path, domain.state) self.deploy_accounts(domain_data['accounts'], domain) def deploy_accounts(self, accounts_data, domain): for account in accounts_data: self.deploy_account(account['data'], domain) def deploy_account(self, account_data, domain): self.logger.debug('>>> ACCOUNT => Creating "%s"...', account_data['username']) account = None if not self.randomizeNames: account_list = Account.list(api_client=self.api_client, name=account_data['username'], listall=True) if isinstance(account_list, list) and len(account_list) >= 1: if account_list[0].name == account_data['username']: account = account_list[0] self.logger.debug( '>>> ACCOUNT => Loaded from (pre) existing account, ID: %s', account.id) return if not account: account = Account.create(api_client=self.api_client, services=account_data, domainid=domain.uuid, randomizeID=self.randomizeNames) self.resources_to_cleanup.append(account) self.dynamic_names['accounts'][account_data['username']] = account.name self.logger.debug( '>>> ACCOUNT => ID: %s => Name: %s => State: %s => Domain: %s', account.id, account.name, account.state, account.domainid) self.deploy_vpcs(account_data['vpcs'], account) self.deploy_isolatednetworks(account_data['isolatednetworks'], account) self.deploy_vms(account_data['virtualmachines'], account) self.deploy_vpcs_publicipaddresses(account_data['vpcs'], account_data['virtualmachines']) self.deploy_isolatednetworks_publicipaddresses( account_data['isolatednetworks'], account_data['virtualmachines']) self.deploy_privatenetworks(account_data['privatenetworks'], account, domain) self.deploy_vpcs_privategateways(account_data['vpcs']) self.enable_vpcs_localvpngateway(account_data['vpcs']) self.deploy_vpcs_remotevpngateways(account_data['vpcs'], account) def deploy_vpcs(self, vpcs_data, account): for vpc in vpcs_data: self.deploy_vpc(vpc['data'], account) def deploy_vpc(self, vpc_data, account): self.logger.debug('>>> VPC => Creating "%s"...', vpc_data['name']) vpc = VPC.create(api_client=self.api_client, data=vpc_data, zone=self.zone, account=account, randomizeID=self.randomizeNames) self.dynamic_names['vpcs'][vpc_data['name']] = vpc.name self.logger.debug( '>>> VPC => ID: %s => Name: %s => CIDR: %s => State: %s => Offering: %s ' '=> Account: %s => Domain: %s', vpc.id, vpc.name, vpc.cidr, vpc.state, vpc.vpcofferingid, vpc.account, vpc.domainid) self.deploy_acls(vpc_data['acls'], vpc) self.deploy_networks(vpc_data['networks'], vpc) def deploy_acls(self, acls_data, vpc): for acl in acls_data: self.deploy_acl(acl['data'], vpc) def deploy_acl(self, acl_data, vpc): self.logger.debug('>>> ACL => Creating "%s"...', acl_data['name']) acl = NetworkACLList.create(api_client=self.api_client, data=acl_data, vpc=vpc) self.logger.debug('>>> ACL => ID: %s => Name: %s => VPC: %s', acl.id, acl.name, acl.vpcid) self.deploy_rules(acl_data['rules'], acl) def deploy_rules(self, rules_data, acl): for rule in rules_data: self.deploy_rule(rule['data'], acl) def deploy_rule(self, rule_data, acl): self.logger.debug('>>> ACL RULE => Creating...') rule = NetworkACL.create(api_client=self.api_client, data=rule_data, acl=acl) self.logger.debug( '>>> ACL RULE => ID: %s => Number: %s => Action: %s => Traffic Type: %s ' '=> CIDR List: %s => Protocol: %s => Start Port: %s => End Port: %s => ACL: %s', rule.id, rule.number, rule.action, rule.traffictype, rule.cidrlist, rule.protocol.upper(), rule.startport, rule.endport, rule.aclid) def deploy_networks(self, networks_data, vpc): for network in networks_data: self.deploy_network(network['data'], vpc) def deploy_network(self, network_data, vpc): acl = get_network_acl(api_client=self.api_client, name=network_data['aclname'], vpc=vpc) self.logger.debug('>>> TIER => Creating "%s"...', network_data['name']) network = Network.create(self.api_client, data=network_data, vpc=vpc, zone=self.zone, acl=acl) self.logger.debug( '>>> TIER => ID: %s => Name: %s => CIDR: %s => Gateway: %s => Type: %s ' '=> Traffic Type: %s => State: %s => Offering: %s => ACL: %s ' '=> Physical Network: %s => VPC: %s => Domain: %s', network.id, network.name, network.cidr, network.gateway, network.type, network.traffictype, network.state, network.networkofferingid, network.aclid, network.physicalnetworkid, network.vpcid, network.domainid) def deploy_vms(self, vms_data, account): for vm in vms_data: self.deploy_vm(vm['data'], account) def deploy_vm(self, vm_data, account): network_and_ip_list = [] for nic in vm_data['nics']: network = get_network(api_client=self.api_client, name=nic['data']['networkname']) network_and_ip = {'networkid': network.id} if 'guestip' in nic['data']: network_and_ip['ip'] = nic['data']['guestip'] network_and_ip_list.append(network_and_ip) self.logger.debug('>>> VM => Creating "%s"...', vm_data['name']) vm = VirtualMachine.create(self.api_client, data=vm_data, zone=self.zone, account=account, network_and_ip_list=network_and_ip_list) self.dynamic_names['vms'][vm_data['name']] = vm.name self.logger.debug( '>>> VM => ID: %s => Name: %s => IP: %s => State: %s => Offering: %s ' '=> Template: %s => Hypervisor: %s => Domain: %s', vm.id, vm.name, vm.ipaddress, vm.state, vm.serviceofferingid, vm.templateid, vm.hypervisor, vm.domainid) def deploy_vpcs_publicipaddresses(self, vpcs_data, virtualmachines_data): for vpc in vpcs_data: self.deploy_vpc_publicipaddresses(vpc['data'], virtualmachines_data) def deploy_vpc_publicipaddresses(self, vpc_data, virtualmachines_data): vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['name']]) for publicipaddress in vpc_data['publicipaddresses']: self.deploy_publicipaddress(publicipaddress['data'], virtualmachines_data, vpc) def deploy_publicipaddress(self, publicipaddress_data, virtualmachines_data, vpc): self.logger.debug('>>> PUBLIC IP ADDRESS => Creating...') publicipaddress = PublicIPAddress.create(api_client=self.api_client, data=publicipaddress_data, vpc=vpc) ipaddress = publicipaddress.ipaddress self.logger.debug( '>>> PUBLIC IP ADDRESS => ID: %s => IP: %s => State: %s => Source NAT: %s ' '=> Static NAT: %s => ACL: %s => VLAN: %s => Physical Network: %s => Network: %s ' '=> VPC: %s => Domain: %s', ipaddress.id, ipaddress.ipaddress, ipaddress.state, ipaddress.issourcenat, ipaddress.isstaticnat, ipaddress.aclid, ipaddress.vlanid, ipaddress.physicalnetworkid, ipaddress.networkid, ipaddress.vpcid, ipaddress.domainid) self.deploy_portforwards(publicipaddress_data['portforwards'], virtualmachines_data, vpc, publicipaddress) def deploy_portforwards(self, portforwards_data, virtualmachines_data, vpc, publicipaddress): for portforward_data in portforwards_data: for virtualmachine_data in virtualmachines_data: if virtualmachine_data['data']['name'] == portforward_data[ 'data']['virtualmachinename']: for nic_data in virtualmachine_data['data']['nics']: if nic_data['data']['guestip'] == portforward_data[ 'data']['nic']: network = get_network( api_client=self.api_client, name=nic_data['data']['networkname'], vpc=vpc) virtualmachine = get_virtual_machine( api_client=self.api_client, name=self.dynamic_names['vms'][ virtualmachine_data['data']['name']], network=network) self.logger.debug( '>>> PORT FORWARD => Creating...') portforward = NATRule.create( api_client=self.api_client, data=portforward_data['data'], network=network, virtual_machine=virtualmachine, ipaddress=publicipaddress) Tag.create( api_client=self.api_client, resourceType='UserVm', resourceIds=[virtualmachine.id], tags=[{ 'key': 'sship', 'value': publicipaddress.ipaddress.ipaddress }, { 'key': 'sshport', 'value': portforward_data['data']['publicport'] }]) self.logger.debug( '>>> PORT FORWARD => ID: %s => Public Start Port: %s ' '=> Public End Port: %s => Private Start Port: %s ' '=> Private End Port: %s => CIDR List: %s => Protocol: %s ' '=> State: %s => IP: %s => VM: %s', portforward.id, portforward.publicport, portforward.publicendport, portforward.privateport, portforward.privateendport, portforward.cidrlist, portforward.protocol, portforward.state, portforward.ipaddressid, portforward.virtualmachineid) def deploy_privatenetworks(self, privatenetworks_data, account, domain): for privatenetwork in privatenetworks_data: self.deploy_privatenetwork(privatenetwork['data'], account, domain) def deploy_privatenetwork(self, privatenetwork_data, account, domain): self.logger.debug('>>> PRIVATE GATEWAY NETWORK => Creating "%s"...', privatenetwork_data['name']) private_gateways_network = Network.create(api_client=self.api_client, data=privatenetwork_data, zone=self.zone, domain=domain, account=account) self.logger.debug( '>>> PRIVATE GATEWAY NETWORK => ID: %s => Name: %s => CIDR: %s => Type: %s ' '=> Traffic Type: %s => State: %s => Offering: %s => Broadcast Domain Type: %s ' '=> Broadcast URI: %s => Physical Network: %s => Domain: %s', private_gateways_network.id, private_gateways_network.name, private_gateways_network.cidr, private_gateways_network.type, private_gateways_network.traffictype, private_gateways_network.state, private_gateways_network.networkofferingid, private_gateways_network.broadcastdomaintype, private_gateways_network.broadcasturi, private_gateways_network.physicalnetworkid, private_gateways_network.domainid) def deploy_vpcs_privategateways(self, vpcs_data): for vpc in vpcs_data: self.deploy_vpc_privategateways(vpc['data']) def deploy_vpc_privategateways(self, vpc_data): vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['name']]) for privategateway in vpc_data['privategateways']: self.deploy_privategateway(privategateway['data'], vpc) def deploy_privategateway(self, privategateway_data, vpc): self.logger.debug('>>> PRIVATE GATEWAY => Creating "%s"...', privategateway_data['ip']) private_gateway = PrivateGateway.create(api_client=self.api_client, data=privategateway_data, vpc=vpc) self.logger.debug( '>>> PRIVATE GATEWAY => ID: %s => IP: %s => CIDR: %s => State: %s ' '=> Source NAT: %s => ACL: %s => Network: %s => VPC: %s => Domain: %s', private_gateway.id, private_gateway.ipaddress, private_gateway.cidr, private_gateway.state, private_gateway.sourcenatsupported, private_gateway.aclid, private_gateway.networkid, private_gateway.vpcid, private_gateway.domainid) self.deploy_staticroutes(privategateway_data['staticroutes'], vpc) def deploy_staticroutes(self, staticroutes_data, vpc): for staticroute_data in staticroutes_data: self.logger.debug('>>> STATIC ROUTE => Creating...') staticroute = StaticRoute.create(api_client=self.api_client, data=staticroute_data['data'], vpc=vpc) self.logger.debug( '>>> STATIC ROUTE => ID: %s => CIDR: %s => Next Hop: %s => State: %s ' '=> VPC: %s => Domain: %s', staticroute.id, staticroute.cidr, staticroute.nexthop, staticroute.state, staticroute.vpcid, staticroute.domainid) def enable_vpcs_localvpngateway(self, vpcs_data): for vpc_data in vpcs_data: vpc = get_vpc( api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['data']['name']]) if vpc_data['data']['vpnconnections']: self.logger.debug( '>>> VPN LOCAL GATEWAY => Creating on VPC "%s"...', vpc_data['data']['name']) localvpngateway = Vpn.createVpnGateway( api_client=self.api_client, vpc=vpc) self.logger.debug( '>>> VPN LOCAL GATEWAY => ID: %s => IP: %s => VPC: %s => Domain: %s', localvpngateway['id'], localvpngateway['publicip'], localvpngateway['vpcid'], localvpngateway['domainid']) def deploy_vpcs_remotevpngateways(self, vpcs_data, account): for vpc_data in vpcs_data: for vpnconnection_data in vpc_data['data']['vpnconnections']: vpc = get_vpc( api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['data']['name']]) vpc_vpngateway = get_vpngateway(api_client=self.api_client, vpc=vpc) remotevpc = get_vpc( api_client=self.api_client, name=self.dynamic_names['vpcs'][vpnconnection_data]) remotevpc_vpngateway = get_vpngateway( api_client=self.api_client, vpc=remotevpc) self.logger.debug( '>>> VPN CUSTOMER GATEWAY => Creating to VPC "%s"...', vpnconnection_data) vpncustomergateway = VpnCustomerGateway.create( api_client=self.api_client, name="remotegateway_to_" + remotevpc.name, gateway=remotevpc_vpngateway.publicip, cidrlist=remotevpc.cidr, presharedkey='notasecret', ikepolicy='aes128-sha256;modp2048', esppolicy='aes128-sha256;modp2048', account=account.name, domainid=account.domainid) self.logger.debug( '>>> VPN CUSTOMER GATEWAY => ID: %s => Name: %s => CIDR List: %s ' '=> Gateway: %s => Domain: %s', vpncustomergateway.id, vpncustomergateway.name, vpncustomergateway.cidrlist, vpncustomergateway.gateway, vpncustomergateway.domainid) self.logger.debug( '>>> VPN CONNECTION => Creating from VPC "%s" to VPC "%s"...', vpc_data['data']['name'], vpnconnection_data) vpnconnection = Vpn.createVpnConnection( api_client=self.api_client, s2svpngatewayid=vpc_vpngateway.id, s2scustomergatewayid=vpncustomergateway.id) self.logger.debug( '>>> VPN CONNECTION => ID: %s => VPN Local Gateway: %s ' '=> VPN Customer Gateway: %s => State: %s', vpnconnection['id'], vpnconnection['s2svpngatewayid'], vpnconnection['s2scustomergatewayid'], vpnconnection['state']) def deploy_isolatednetworks(self, isolatednetworks_data, account): for isolatednetwork in isolatednetworks_data: self.deploy_isolatednetwork(isolatednetwork['data'], account) def deploy_isolatednetwork(self, isolatednetwork_data, account): self.logger.debug('>>> ISOLATED NETWORK => Creating "%s"...', isolatednetwork_data['name']) isolatednetwork = Network.create(self.api_client, data=isolatednetwork_data, account=account, zone=self.zone) self.logger.debug( '>>> ISOLATED NETWORK => ID: %s => Name: %s => CIDR: %s ' '=> Gateway: %s => Type: %s => Traffic Type: %s => State: %s ' '=> Offering: %s => Physical Network: %s => Domain: %s', isolatednetwork.id, isolatednetwork.name, isolatednetwork.cidr, isolatednetwork.gateway, isolatednetwork.type, isolatednetwork.traffictype, isolatednetwork.state, isolatednetwork.networkofferingid, isolatednetwork.physicalnetworkid, isolatednetwork.domainid) def deploy_isolatednetworks_publicipaddresses(self, isolatednetworks_data, virtualmachines_data): for isolatednetwork in isolatednetworks_data: network = get_network(self.api_client, isolatednetwork['data']['name']) self.deploy_isolatednetwork_egresses(isolatednetwork['data'], network) self.deploy_isolatednetwork_publicipaddresses( isolatednetwork['data'], virtualmachines_data, network) def deploy_isolatednetwork_egresses(self, isolatednetwork_data, network): self.logger.debug('>>> ISOLATED NETWORK EGRESS RULE => Creating...') for egress_data in isolatednetwork_data['egressrules']: egress = EgressFireWallRule.create(self.api_client, network=network, data=egress_data['data']) self.logger.debug( '>>> ISOLATED NETWORK EGRESS RULE => ID: %s => Start Port: %s ' '=> End Port: %s => CIDR: %s => Protocol: %s => State: %s ' '=> Network: %s', egress.id, egress.startport, egress.endport, egress.cidrlist, egress.protocol, egress.state, egress.networkid) def deploy_isolatednetwork_publicipaddresses(self, isolatednetwork_data, virtual_machines, network): for ipaddress in isolatednetwork_data['publicipaddresses']: self.deploy_isolatednetwork_publicipaddress( ipaddress['data'], virtual_machines, network) def deploy_isolatednetwork_publicipaddress(self, ipaddress_data, virtualmachines_data, network): self.logger.debug( '>>> ISOLATED NETWORK PUBLIC IP ADDRESS => Creating...') publicipaddress = PublicIPAddress.create(api_client=self.api_client, data=ipaddress_data, network=network) self.logger.debug( '>>> ISOLATED NETWORK PUBLIC IP ADDRESS => Created! TODO: MISSING FIELDS!' ) self.deploy_firewallrules(ipaddress_data, publicipaddress) self.deploy_portforwards(ipaddress_data['portforwards'], virtualmachines_data, None, publicipaddress) def deploy_firewallrules(self, ipaddress_data, publicipaddress): self.logger.debug( '>>> ISOLATED NETWORK FIREWALL RULE => Creating...') for firewallrule in ipaddress_data['firewallrules']: self.deploy_firewallrule(firewallrule, publicipaddress) def deploy_firewallrule(self, firewallrule, publicipaddress): firewall = FireWallRule.create(self.api_client, data=firewallrule['data'], ipaddress=publicipaddress) self.logger.debug( '>>> ISOLATED NETWORKS FIREWALL RULE => ID: %s => Start Port: %s ' '=> End Port: %s => CIDR: %s => Protocol: %s => State: %s ' '=> Network: %s => IP: %s', firewall.id, firewall.startport, firewall.endport, firewall.cidrlist, firewall.protocol, firewall.state, firewall.networkid, firewall.ipaddress) def get_vpc(self, name): vpc = VPC(get_vpc(api_client=self.api_client, name=name).__dict__, api_client=self.api_client) return vpc def get_virtual_machine(self, vm_name): virtual_machine = VirtualMachine( get_virtual_machine(api_client=self.api_client, name=self.get_dynamic_name('vms', vm_name)).__dict__, []) virtual_machine_tags = Tag.list(api_client=self.api_client, resourceId=[virtual_machine.id], listall=True) for key in virtual_machine_tags: if key.key == 'sshport': virtual_machine.ssh_port = int( key.value.encode('ascii', 'ignore')) if key.key == 'sship': virtual_machine.ssh_ip = key.value.encode('ascii', 'ignore') return virtual_machine def get_network(self, name=None, id=None): return Network( get_network(api_client=self.api_client, name=name, id=id).__dict__) def get_network_acl_list(self, name=None, id=None): return NetworkACLList( get_network_acl(api_client=self.api_client, name=name, id=id).__dict__) def get_default_allow_acl_list(self): return self.get_network_acl_list(name='default_allow') def get_default_deny_acl_list(self): return self.get_network_acl_list(name='default_deny') def deploy_network_acl_list(self, acl_list_name, acl_config, network=None, vpc=None): if network: networkid = network.id if network.vpcid: vpcid = network.vpcid acl_list = NetworkACLList.create(self.api_client, name=acl_list_name, services=[], vpcid=vpcid, vpc=vpc) NetworkACL.create(self.api_client, acl_config, networkid=networkid, aclid=acl_list.id) return acl_list def finalize(self): if self.cleanup: try: self.logger.info( '=== Scenario Manager, Cleaning Up of "%s" Started ===', self.scenario_data['metadata']['name']) cleanup_resources(self.api_client, self.resources_to_cleanup, self.logger) self.logger.info( '=== Scenario Manager, Cleaning Up of "%s" Finished ===', self.scenario_data['metadata']['name']) except: self.logger.exception( 'Oops! Unable to clean up resources of "%s"!', self.scenario_data['metadata']['name']) else: self.logger.info( '=== Scenario Manager, Skipping Cleaning Up of "%s" ===', self.scenario_data['metadata']['name'])
class TestSSVMs(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] self.services = self.testClient.getParsedTestDataConfig() self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services["sleep"] = 5 self.services["timeout"] = 180 return def tearDown(self): try: # Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @attr(tags=['advanced']) def test_01_list_sec_storage_vm(self): self.test_list_svm_vm('secondarystoragevm') @attr(tags=['advanced']) def test_02_list_cpvm_vm(self): self.test_list_svm_vm('consoleproxy') @attr(tags=['advanced']) def test_03_destroy_ssvm(self): """Test destroy SSVM """ # Validate the following # 1. SSVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the # systemVM from what it was before # 3. new SSVM will have a public/private and link-local-ip # 4. cloud process within SSVM must be up and running list_ssvm_response = list_ssvms( self.apiclient, systemvmtype='secondarystoragevm', state='Running', zoneid=self.zone.id ) self.assertEqual( isinstance(list_ssvm_response, list), True, "Check list response returns a valid list" ) ssvm_response = list_ssvm_response[0] old_name = ssvm_response.name self.logger.debug("Destroying SSVM: %s" % ssvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = ssvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_ssvm_response = list_ssvms( self.apiclient, zoneid=self.zone.id, systemvmtype='secondarystoragevm' ) if isinstance(list_ssvm_response, list): if list_ssvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List SSVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!") return time.sleep(self.services["sleep"]) timeout = timeout - 1 ssvm_response = list_ssvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created SSVM self.assertNotEqual( ssvm_response.name, old_name, "Check SSVM new name with name of destroyed SSVM" ) self.assertEqual( hasattr(ssvm_response, 'privateip'), True, "Check whether SSVM has private IP field" ) self.assertEqual( hasattr(ssvm_response, 'linklocalip'), True, "Check whether SSVM has link local IP field" ) self.assertEqual( hasattr(ssvm_response, 'publicip'), True, "Check whether SSVM has public IP field" ) # Wait for the agent to be up self.wait_for_system_vm_agent(ssvm_response.name) return @attr(tags=['advanced']) def test_04_destroy_cpvm(self): """Test destroy CPVM """ # Validate the following # 1. CPVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the systemVM from # what it was before # 3. new CPVM will have a public/private and link-local-ip # 4. cloud process within CPVM must be up and running list_cpvm_response = list_ssvms( self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id ) self.assertEqual( isinstance(list_cpvm_response, list), True, "Check list response returns a valid list" ) cpvm_response = list_cpvm_response[0] old_name = cpvm_response.name self.logger.debug("Destroying CPVM: %s" % cpvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = cpvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_cpvm_response = list_ssvms( self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id ) if isinstance(list_cpvm_response, list): if list_cpvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List CPVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!") return time.sleep(self.services["sleep"]) timeout = timeout - 1 cpvm_response = list_cpvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created CPVM self.assertNotEqual( cpvm_response.name, old_name, "Check SSVM new name with name of destroyed CPVM" ) self.assertEqual( hasattr(cpvm_response, 'privateip'), True, "Check whether CPVM has private IP field" ) self.assertEqual( hasattr(cpvm_response, 'linklocalip'), True, "Check whether CPVM has link local IP field" ) self.assertEqual( hasattr(cpvm_response, 'publicip'), True, "Check whether CPVM has public IP field" ) # Wait for the agent to be up self.wait_for_system_vm_agent(cpvm_response.name) return def wait_for_system_vm_agent(self, vmname): self.logger.debug("Waiting for system VM %s agent to be UP" % vmname) timeout = self.services["timeout"] sleep_interval = self.services["sleep"] while timeout > 0: list_host_response = list_hosts( self.apiclient, name=vmname ) if list_host_response and list_host_response[0].state == 'Up': self.debug("System VM %s agent is UP" % vmname) break time.sleep(sleep_interval) timeout = timeout - sleep_interval if timeout <= 0 and list_host_response[0].state != 'Up': self.logger.debug( "Warning: List CPVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!") return def test_list_svm_vm(self, svm_type): # Validate the following: # 1. listSystemVM # should return only ONE SVM per zone # 2. The returned SVM should be in Running state # 3. listSystemVM for should list publicip, privateip and link-localip # 4. The gateway programmed on the SVM by listSystemVm should be # the same as the gateway returned by listVlanIpRanges # 5. DNS entries must match those given for the zone list_svm_response = list_ssvms( self.apiclient, systemvmtype=svm_type, state='Running', ) self.assertEqual( isinstance(list_svm_response, list), True, "Check list response returns a valid list" ) # Verify SSVM response self.assertNotEqual( len(list_svm_response), 0, "Check list System VMs response" ) list_zones_response = list_zones(self.apiclient) self.assertEqual( isinstance(list_zones_response, list), True, "Check list response returns a valid list" ) self.logger.debug("Number of zones: %s" % len(list_zones_response)) self.logger.debug("Number of System VMs: %s" % len(list_svm_response)) # Number of Sec storage VMs = No of Zones self.assertEqual( len(list_svm_response), len(list_zones_response), "Check number of System VMs with number of zones" ) # For each secondary storage VM check private IP, # public IP, link local IP and DNS for svm in list_svm_response: self.logger.debug("SVM state: %s" % svm.state) self.assertEqual( svm.state, 'Running', "Check whether state of System VM is running" ) self.assertEqual( hasattr(svm, 'privateip'), True, "Check whether System VM has private IP field" ) self.assertEqual( hasattr(svm, 'linklocalip'), True, "Check whether System VM has link local IP field" ) self.assertEqual( hasattr(svm, 'publicip'), True, "Check whether System VM has public IP field" ) # Fetch corresponding ip ranges information from listVlanIpRanges ipranges_response = list_vlan_ipranges( self.apiclient, zoneid=svm.zoneid ) self.assertEqual( isinstance(ipranges_response, list), True, "Check list response returns a valid list" ) iprange = ipranges_response[0] # Execute the following assertion in all zones except basic Zones if not (self.zone.networktype.lower() == 'basic'): self.assertEqual( svm.gateway, iprange.gateway, "Check gateway with that of corresponding ip range" ) # Fetch corresponding zone information from listZones zone_response = list_zones( self.apiclient, id=svm.zoneid ) self.assertEqual( isinstance(zone_response, list), True, "Check list response returns a valid list" ) self.assertEqual( svm.dns1, zone_response[0].dns1, "Check DNS1 with that of corresponding zone" ) self.assertEqual( svm.dns2, zone_response[0].dns2, "Check DNS2 with that of corresponding zone" ) return
class TestReleaseIP(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.services = self.testClient.getParsedTestDataConfig() # Get Zone, Domain and templates self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template(self.apiclient, self.zone.id) self.services["virtual_machine"]["zoneid"] = self.zone.id # Create an account, network, VM, Port forwarding rule, LB rules self.account = Account.create(self.apiclient, self.services["account"], admin=True, domainid=self.domain.id) self.service_offering = get_default_virtual_machine_offering( self.apiclient) self.virtual_machine = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id) self.ip_address = PublicIPAddress.create(self.apiclient, self.account.name, self.zone.id, self.account.domainid) ip_addrs = list_public_ip(self.apiclient, account=self.account.name, domainid=self.account.domainid, issourcenat=False) try: self.ip_addr = ip_addrs[0] except Exception as e: raise Exception( "Failed: During acquiring source NAT for account: %s, :%s" % (self.account.name, e)) self.nat_rule = NATRule.create(self.apiclient, self.virtual_machine, self.services["natrule"], self.ip_addr.id) self.lb_rule = LoadBalancerRule.create(self.apiclient, self.services["lbrule"], self.ip_addr.id, accountid=self.account.name) self.cleanup = [self.virtual_machine, self.account] return def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) @attr(tags=['advanced']) def test_01_release_ip(self): """Test for release public IP address""" self.logger.debug("Deleting Public IP : %s" % self.ip_addr.id) self.ip_address.delete(self.apiclient) retriesCount = 10 isIpAddressDisassociated = False while retriesCount > 0: listResponse = list_public_ip(self.apiclient, id=self.ip_addr.id) if listResponse is None: isIpAddressDisassociated = True break retriesCount -= 1 time.sleep(60) # End while self.assertTrue(isIpAddressDisassociated, "Failed to disassociate IP address") # ListPortForwardingRules should not list # associated rules with Public IP address try: list_nat_rule = list_nat_rules(self.apiclient, id=self.nat_rule.id) self.logger.debug("List NAT Rule response" + str(list_nat_rule)) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # listLoadBalancerRules should not list # associated rules with Public IP address try: list_lb_rule = list_lb_rules(self.apiclient, id=self.lb_rule.id) self.logger.debug("List LB Rule response" + str(list_lb_rule)) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # SSH Attempt though public IP should fail with self.assertRaises(Exception): SshClient(self.ip_addr.ipaddress, self.services["natrule"]["publicport"], self.virtual_machine.username, self.virtual_machine.password, retries=2, delay=0) return
class SshClient(object): """ @Desc : SSH Library for Marvin. Facilitates SSH,SCP services to marvin users @Input: host: Host to connect port: port on host to connect user: Username to be used for connecting passwd: Password for connection retries and delay applies for establishing connection timeout : Applies while executing command """ def __init__(self, host, port, user, password, retries=60, delay=10, key_pair_files=None, timeout=10.0): self.host = None self.port = 22 self.user = user self.passwd = password self.keyPairFiles = key_pair_files self.ssh = SSHClient() self.ssh.set_missing_host_key_policy(AutoAddPolicy()) self.retryCnt = 0 self.delay = 0 self.timeout = 3.0 self.logger = MarvinLog('ssh').get_logger() # Check invalid host value and raise exception # At least host is required for connection if host is not None and host != '': self.host = host if retries is not None and retries > 0: self.retryCnt = retries if delay is not None and delay > 0: self.delay = delay if timeout is not None and timeout > 0: self.timeout = timeout if port is not None and port >= 0: self.port = port if self.create_connection() == FAILED: raise internalError("Connection Failed") def execute(self, command): stdin, stdout, stderr = self.ssh.exec_command(command) output = stdout.readlines() errors = stderr.readlines() results = [] if output is not None and len(output) == 0: if errors is not None and len(errors) > 0: for error in errors: results.append(error.rstrip()) else: for strOut in output: results.append(strOut.rstrip()) self.logger.debug("Executing command via host %s: %s Output: %s" % (str(self.host), command, results)) return results def create_connection(self): """ @Name: createConnection @Desc: Creates an ssh connection for retries mentioned,along with sleep mentioned @Output: SUCCESS on successful connection FAILED If connection through ssh failed """ ret = FAILED while self.retryCnt >= 0: try: self.logger.debug("Trying SSH Connection to host %s on port %s as user %s. RetryCount: %s" % (self.host, str(self.port), self.user, str(self.retryCnt))) if self.keyPairFiles is None: self.ssh.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, timeout=self.timeout) else: self.ssh.connect(hostname=self.host, port=self.port, username=self.user, password=self.passwd, key_filename=self.keyPairFiles, timeout=self.timeout, look_for_keys=False ) self.logger.debug("Connection to host %s on port %s is SUCCESSFUL" % (str(self.host), str(self.port))) ret = SUCCESS break except BadHostKeyException as e: self.logger.debug("Failed to create connection: %s" % e) except AuthenticationException as e: self.logger.debug("Failed to create connection: %s" % e) except SSHException as e: self.logger.debug("Failed to create connection: %s" % e) except socket.error as e: self.logger.debug("Failed to create connection: %s" % e) except Exception as e: self.logger.debug("Failed to create connection: %s" % e) finally: if self.retryCnt == 0 or ret == SUCCESS: break self.retryCnt -= 1 time.sleep(self.delay) return ret def run_command(self, command): """ @Name: runCommand @Desc: Runs a command over ssh and returns the result along with status code @Input: command to execute @Output: 1: status of command executed. SUCCESS : If command execution is successful FAILED : If command execution has failed 2: stdin,stdout,stderr values of command output """ ret = {"status": FAILED, "stdin": None, "stdout": None, "stderr": INVALID_INPUT} if command is None or command == '': return ret try: stdin, stdout, stderr = self.ssh.exec_command(command, timeout=self.timeout) if stdout is not None: status_check = stdout.channel.recv_exit_status() if status_check == 0: ret["status"] = SUCCESS ret["stdout"] = stdout.readlines() if stderr is not None: ret["stderr"] = stderr.readlines() except Exception as e: self.logger.debug("Failed to run command: %s" % e) finally: self.logger.debug("Connection to host %s on port %s is SUCCESSFUL" % (str(self.host), command)) return ret def scp(self, src_file, dest_path): transport = Transport((self.host, int(self.port))) transport.connect(username=self.user, password=self.passwd) sftp = SFTPClient.from_transport(transport) try: sftp.put(src_file, dest_path) except IOError as e: raise e def __del__(self): self.close() def close(self): if self.ssh is not None: self.ssh.close() self.ssh = None
class TestScenarioManager: def __init__(self, api_client, scenario_data, test_data, zone, randomizeNames, cleanup): self.api_client = api_client self.scenario_data = scenario_data self.test_data = test_data self.zone = zone self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.dynamic_names = { 'accounts': {}, 'vpcs': {}, 'vms': {}, } self.randomizeNames = randomizeNames self.resources_to_cleanup = [] self.cleanup = cleanup @property def test_data(self): return self.test_data def get_dynamic_name(self, section, name): if name in self.dynamic_names[section]: return self.dynamic_names[section][name] else: return name def setup_infra(self): scenario_data = self.scenario_data['data'] self.deploy_domains(scenario_data['domains']) def deploy_domains(self, domains_data): for domain in domains_data: self.deploy_domain(domain['data']) def deploy_domain(self, domain_data): if domain_data['name'] == 'ROOT': domain_list = Domain.list( api_client=self.api_client, name=domain_data['name'] ) domain = domain_list[0] else: self.logger.debug('>>> DOMAIN => Creating "%s"...', domain_data['name']) domain = Domain.create( api_client=self.api_client, name=domain_data['name'] + ('-' + random_gen() if self.randomizeNames else '') ) self.logger.debug('>>> DOMAIN => ID: %s => Name: %s => Path: %s => State: %s', domain.id, domain.name, domain.path, domain.state) self.deploy_accounts(domain_data['accounts'], domain) def deploy_accounts(self, accounts_data, domain): for account in accounts_data: self.deploy_account(account['data'], domain) def deploy_account(self, account_data, domain): self.logger.debug('>>> ACCOUNT => Creating "%s"...', account_data['username']) account = None if not self.randomizeNames: account_list = Account.list(api_client=self.api_client, name=account_data['username'], listall=True) if isinstance(account_list, list) and len(account_list) >= 1: if account_list[0].name == account_data['username']: account = account_list[0] self.logger.debug('>>> ACCOUNT => Loaded from (pre) existing account, ID: %s', account.id) return if not account: account = Account.create( api_client=self.api_client, services=account_data, domainid=domain.uuid, randomizeID=self.randomizeNames ) self.resources_to_cleanup.append(account) self.dynamic_names['accounts'][account_data['username']] = account.name self.logger.debug('>>> ACCOUNT => ID: %s => Name: %s => State: %s => Domain: %s', account.id, account.name, account.state, account.domainid) self.deploy_vpcs(account_data['vpcs'], account) self.deploy_isolatednetworks(account_data['isolatednetworks'], account) self.deploy_vms(account_data['virtualmachines'], account) self.deploy_vpcs_publicipaddresses(account_data['vpcs'], account_data['virtualmachines']) self.deploy_isolatednetworks_publicipaddresses(account_data['isolatednetworks'], account_data['virtualmachines']) self.deploy_privatenetworks(account_data['privatenetworks'], account, domain) self.deploy_vpcs_privategateways(account_data['vpcs']) self.enable_vpcs_localvpngateway(account_data['vpcs']) self.deploy_vpcs_remotevpngateways(account_data['vpcs'], account) def deploy_vpcs(self, vpcs_data, account): for vpc in vpcs_data: self.deploy_vpc(vpc['data'], account) def deploy_vpc(self, vpc_data, account): self.logger.debug('>>> VPC => Creating "%s"...', vpc_data['name']) vpc = VPC.create( api_client=self.api_client, data=vpc_data, zone=self.zone, account=account, randomizeID=self.randomizeNames ) self.dynamic_names['vpcs'][vpc_data['name']] = vpc.name self.logger.debug('>>> VPC => ID: %s => Name: %s => CIDR: %s => State: %s => Offering: %s ' '=> Account: %s => Domain: %s', vpc.id, vpc.name, vpc.cidr, vpc.state, vpc.vpcofferingid, vpc.account, vpc.domainid) self.deploy_acls(vpc_data['acls'], vpc) self.deploy_networks(vpc_data['networks'], vpc) def deploy_acls(self, acls_data, vpc): for acl in acls_data: self.deploy_acl(acl['data'], vpc) def deploy_acl(self, acl_data, vpc): self.logger.debug('>>> ACL => Creating "%s"...', acl_data['name']) acl = NetworkACLList.create( api_client=self.api_client, data=acl_data, vpc=vpc ) self.logger.debug('>>> ACL => ID: %s => Name: %s => VPC: %s', acl.id, acl.name, acl.vpcid) self.deploy_rules(acl_data['rules'], acl) def deploy_rules(self, rules_data, acl): for rule in rules_data: self.deploy_rule(rule['data'], acl) def deploy_rule(self, rule_data, acl): self.logger.debug('>>> ACL RULE => Creating...') rule = NetworkACL.create( api_client=self.api_client, data=rule_data, acl=acl ) self.logger.debug('>>> ACL RULE => ID: %s => Number: %s => Action: %s => Traffic Type: %s ' '=> CIDR List: %s => Protocol: %s => Start Port: %s => End Port: %s => ACL: %s', rule.id, rule.number, rule.action, rule.traffictype, rule.cidrlist, rule.protocol.upper(), rule.startport, rule.endport, rule.aclid) def deploy_networks(self, networks_data, vpc): for network in networks_data: self.deploy_network(network['data'], vpc) def deploy_network(self, network_data, vpc): acl = get_network_acl(api_client=self.api_client, name=network_data['aclname'], vpc=vpc) self.logger.debug('>>> TIER => Creating "%s"...', network_data['name']) network = Network.create( self.api_client, data=network_data, vpc=vpc, zone=self.zone, acl=acl ) self.logger.debug('>>> TIER => ID: %s => Name: %s => CIDR: %s => Gateway: %s => Type: %s ' '=> Traffic Type: %s => State: %s => Offering: %s => ACL: %s ' '=> Physical Network: %s => VPC: %s => Domain: %s', network.id, network.name, network.cidr, network.gateway, network.type, network.traffictype, network.state, network.networkofferingid, network.aclid, network.physicalnetworkid, network.vpcid, network.domainid) def deploy_vms(self, vms_data, account): for vm in vms_data: self.deploy_vm(vm['data'], account) def deploy_vm(self, vm_data, account): network_and_ip_list = [] for nic in vm_data['nics']: network = get_network(api_client=self.api_client, name=nic['data']['networkname']) network_and_ip = { 'networkid': network.id } if 'guestip' in nic['data']: network_and_ip['ip'] = nic['data']['guestip'] network_and_ip_list.append(network_and_ip) self.logger.debug('>>> VM => Creating "%s"...', vm_data['name']) vm = VirtualMachine.create( self.api_client, data=vm_data, zone=self.zone, account=account, network_and_ip_list=network_and_ip_list ) self.dynamic_names['vms'][vm_data['name']] = vm.name self.logger.debug('>>> VM => ID: %s => Name: %s => IP: %s => State: %s => Offering: %s ' '=> Template: %s => Hypervisor: %s => Domain: %s', vm.id, vm.name, vm.ipaddress, vm.state, vm.serviceofferingid, vm.templateid, vm.hypervisor, vm.domainid) def deploy_vpcs_publicipaddresses(self, vpcs_data, virtualmachines_data): for vpc in vpcs_data: self.deploy_vpc_publicipaddresses(vpc['data'], virtualmachines_data) def deploy_vpc_publicipaddresses(self, vpc_data, virtualmachines_data): vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['name']]) for publicipaddress in vpc_data['publicipaddresses']: self.deploy_publicipaddress(publicipaddress['data'], virtualmachines_data, vpc) def deploy_publicipaddress(self, publicipaddress_data, virtualmachines_data, vpc): self.logger.debug('>>> PUBLIC IP ADDRESS => Creating...') publicipaddress = PublicIPAddress.create( api_client=self.api_client, data=publicipaddress_data, vpc=vpc ) ipaddress = publicipaddress.ipaddress self.logger.debug('>>> PUBLIC IP ADDRESS => ID: %s => IP: %s => State: %s => Source NAT: %s ' '=> Static NAT: %s => ACL: %s => VLAN: %s => Physical Network: %s => Network: %s ' '=> VPC: %s => Domain: %s', ipaddress.id, ipaddress.ipaddress, ipaddress.state, ipaddress.issourcenat, ipaddress.isstaticnat, ipaddress.aclid, ipaddress.vlanid, ipaddress.physicalnetworkid, ipaddress.networkid, ipaddress.vpcid, ipaddress.domainid) self.deploy_portforwards(publicipaddress_data['portforwards'], virtualmachines_data, vpc, publicipaddress) def deploy_portforwards(self, portforwards_data, virtualmachines_data, vpc, publicipaddress): for portforward_data in portforwards_data: for virtualmachine_data in virtualmachines_data: if virtualmachine_data['data']['name'] == portforward_data['data']['virtualmachinename']: for nic_data in virtualmachine_data['data']['nics']: if nic_data['data']['guestip'] == portforward_data['data']['nic']: network = get_network( api_client=self.api_client, name=nic_data['data']['networkname'], vpc=vpc ) virtualmachine = get_virtual_machine( api_client=self.api_client, name=self.dynamic_names['vms'][virtualmachine_data['data']['name']], network=network ) self.logger.debug('>>> PORT FORWARD => Creating...') portforward = NATRule.create( api_client=self.api_client, data=portforward_data['data'], network=network, virtual_machine=virtualmachine, ipaddress=publicipaddress ) Tag.create( api_client=self.api_client, resourceType='UserVm', resourceIds=[virtualmachine.id], tags=[ { 'key': 'sship', 'value': publicipaddress.ipaddress.ipaddress }, { 'key': 'sshport', 'value': portforward_data['data']['publicport'] } ] ) self.logger.debug('>>> PORT FORWARD => ID: %s => Public Start Port: %s ' '=> Public End Port: %s => Private Start Port: %s ' '=> Private End Port: %s => CIDR List: %s => Protocol: %s ' '=> State: %s => IP: %s => VM: %s', portforward.id, portforward.publicport, portforward.publicendport, portforward.privateport, portforward.privateendport, portforward.cidrlist, portforward.protocol, portforward.state, portforward.ipaddressid, portforward.virtualmachineid) def deploy_privatenetworks(self, privatenetworks_data, account, domain): for privatenetwork in privatenetworks_data: self.deploy_privatenetwork(privatenetwork['data'], account, domain) def deploy_privatenetwork(self, privatenetwork_data, account, domain): self.logger.debug('>>> PRIVATE GATEWAY NETWORK => Creating "%s"...', privatenetwork_data['name']) private_gateways_network = Network.create( api_client=self.api_client, data=privatenetwork_data, zone=self.zone, domain=domain, account=account ) self.logger.debug('>>> PRIVATE GATEWAY NETWORK => ID: %s => Name: %s => CIDR: %s => Type: %s ' '=> Traffic Type: %s => State: %s => Offering: %s => Broadcast Domain Type: %s ' '=> Broadcast URI: %s => Physical Network: %s => Domain: %s', private_gateways_network.id, private_gateways_network.name, private_gateways_network.cidr, private_gateways_network.type, private_gateways_network.traffictype, private_gateways_network.state, private_gateways_network.networkofferingid, private_gateways_network.broadcastdomaintype, private_gateways_network.broadcasturi, private_gateways_network.physicalnetworkid, private_gateways_network.domainid) def deploy_vpcs_privategateways(self, vpcs_data): for vpc in vpcs_data: self.deploy_vpc_privategateways(vpc['data']) def deploy_vpc_privategateways(self, vpc_data): vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['name']]) for privategateway in vpc_data['privategateways']: self.deploy_privategateway(privategateway['data'], vpc) def deploy_privategateway(self, privategateway_data, vpc): self.logger.debug('>>> PRIVATE GATEWAY => Creating "%s"...', privategateway_data['ip']) private_gateway = PrivateGateway.create( api_client=self.api_client, data=privategateway_data, vpc=vpc ) self.logger.debug('>>> PRIVATE GATEWAY => ID: %s => IP: %s => CIDR: %s => State: %s ' '=> Source NAT: %s => ACL: %s => Network: %s => VPC: %s => Domain: %s', private_gateway.id, private_gateway.ipaddress, private_gateway.cidr, private_gateway.state, private_gateway.sourcenatsupported, private_gateway.aclid, private_gateway.networkid, private_gateway.vpcid, private_gateway.domainid) self.deploy_staticroutes(privategateway_data['staticroutes'], vpc) def deploy_staticroutes(self, staticroutes_data, vpc): for staticroute_data in staticroutes_data: self.logger.debug('>>> STATIC ROUTE => Creating...') staticroute = StaticRoute.create( api_client=self.api_client, data=staticroute_data['data'], vpc=vpc ) self.logger.debug('>>> STATIC ROUTE => ID: %s => CIDR: %s => Next Hop: %s => State: %s ' '=> VPC: %s => Domain: %s', staticroute.id, staticroute.cidr, staticroute.nexthop, staticroute.state, staticroute.vpcid, staticroute.domainid) def enable_vpcs_localvpngateway(self, vpcs_data): for vpc_data in vpcs_data: vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['data']['name']]) if vpc_data['data']['vpnconnections']: self.logger.debug('>>> VPN LOCAL GATEWAY => Creating on VPC "%s"...', vpc_data['data']['name']) localvpngateway = Vpn.createVpnGateway(api_client=self.api_client, vpc=vpc) self.logger.debug('>>> VPN LOCAL GATEWAY => ID: %s => IP: %s => VPC: %s => Domain: %s', localvpngateway['id'], localvpngateway['publicip'], localvpngateway['vpcid'], localvpngateway['domainid']) def deploy_vpcs_remotevpngateways(self, vpcs_data, account): for vpc_data in vpcs_data: for vpnconnection_data in vpc_data['data']['vpnconnections']: vpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpc_data['data']['name']]) vpc_vpngateway = get_vpngateway(api_client=self.api_client, vpc=vpc) remotevpc = get_vpc(api_client=self.api_client, name=self.dynamic_names['vpcs'][vpnconnection_data]) remotevpc_vpngateway = get_vpngateway(api_client=self.api_client, vpc=remotevpc) self.logger.debug('>>> VPN CUSTOMER GATEWAY => Creating to VPC "%s"...', vpnconnection_data) vpncustomergateway = VpnCustomerGateway.create( api_client=self.api_client, name="remotegateway_to_" + remotevpc.name, gateway=remotevpc_vpngateway.publicip, cidrlist=remotevpc.cidr, presharedkey='notasecret', ikepolicy='aes128-sha256;modp2048', esppolicy='aes128-sha256;modp2048', account=account.name, domainid=account.domainid ) self.logger.debug('>>> VPN CUSTOMER GATEWAY => ID: %s => Name: %s => CIDR List: %s ' '=> Gateway: %s => Domain: %s', vpncustomergateway.id, vpncustomergateway.name, vpncustomergateway.cidrlist, vpncustomergateway.gateway, vpncustomergateway.domainid) self.logger.debug('>>> VPN CONNECTION => Creating from VPC "%s" to VPC "%s"...', vpc_data['data']['name'], vpnconnection_data) vpnconnection = Vpn.createVpnConnection( api_client=self.api_client, s2svpngatewayid=vpc_vpngateway.id, s2scustomergatewayid=vpncustomergateway.id ) self.logger.debug('>>> VPN CONNECTION => ID: %s => VPN Local Gateway: %s ' '=> VPN Customer Gateway: %s => State: %s', vpnconnection['id'], vpnconnection['s2svpngatewayid'], vpnconnection['s2scustomergatewayid'], vpnconnection['state']) def deploy_isolatednetworks(self, isolatednetworks_data, account): for isolatednetwork in isolatednetworks_data: self.deploy_isolatednetwork(isolatednetwork['data'], account) def deploy_isolatednetwork(self, isolatednetwork_data, account): self.logger.debug('>>> ISOLATED NETWORK => Creating "%s"...', isolatednetwork_data['name']) isolatednetwork = Network.create( self.api_client, data=isolatednetwork_data, account=account, zone=self.zone ) self.logger.debug('>>> ISOLATED NETWORK => ID: %s => Name: %s => CIDR: %s ' '=> Gateway: %s => Type: %s => Traffic Type: %s => State: %s ' '=> Offering: %s => Physical Network: %s => Domain: %s', isolatednetwork.id, isolatednetwork.name, isolatednetwork.cidr, isolatednetwork.gateway, isolatednetwork.type, isolatednetwork.traffictype, isolatednetwork.state, isolatednetwork.networkofferingid, isolatednetwork.physicalnetworkid, isolatednetwork.domainid) def deploy_isolatednetworks_publicipaddresses(self, isolatednetworks_data, virtualmachines_data): for isolatednetwork in isolatednetworks_data: network = get_network(self.api_client, isolatednetwork['data']['name']) self.deploy_isolatednetwork_egresses(isolatednetwork['data'], network) self.deploy_isolatednetwork_publicipaddresses(isolatednetwork['data'], virtualmachines_data, network) def deploy_isolatednetwork_egresses(self, isolatednetwork_data, network): self.logger.debug('>>> ISOLATED NETWORK EGRESS RULE => Creating...') for egress_data in isolatednetwork_data['egressrules']: egress = EgressFireWallRule.create( self.api_client, network=network, data=egress_data['data'] ) self.logger.debug('>>> ISOLATED NETWORK EGRESS RULE => ID: %s => Start Port: %s ' '=> End Port: %s => CIDR: %s => Protocol: %s => State: %s ' '=> Network: %s', egress.id, egress.startport, egress.endport, egress.cidrlist, egress.protocol, egress.state, egress.networkid) def deploy_isolatednetwork_publicipaddresses(self, isolatednetwork_data, virtual_machines, network): for ipaddress in isolatednetwork_data['publicipaddresses']: self.deploy_isolatednetwork_publicipaddress(ipaddress['data'], virtual_machines, network) def deploy_isolatednetwork_publicipaddress(self, ipaddress_data, virtualmachines_data, network): self.logger.debug('>>> ISOLATED NETWORK PUBLIC IP ADDRESS => Creating...') publicipaddress = PublicIPAddress.create( api_client=self.api_client, data=ipaddress_data, network=network ) self.logger.debug('>>> ISOLATED NETWORK PUBLIC IP ADDRESS => Created! TODO: MISSING FIELDS!') self.deploy_firewallrules(ipaddress_data, publicipaddress) self.deploy_portforwards(ipaddress_data['portforwards'], virtualmachines_data, None, publicipaddress) def deploy_firewallrules(self, ipaddress_data, publicipaddress): self.logger.debug('>>> ISOLATED NETWORK FIREWALL RULE => Creating...') for firewallrule in ipaddress_data['firewallrules']: self.deploy_firewallrule(firewallrule, publicipaddress) def deploy_firewallrule(self, firewallrule, publicipaddress): firewall = FireWallRule.create( self.api_client, data=firewallrule['data'], ipaddress=publicipaddress ) self.logger.debug('>>> ISOLATED NETWORKS FIREWALL RULE => ID: %s => Start Port: %s ' '=> End Port: %s => CIDR: %s => Protocol: %s => State: %s ' '=> Network: %s => IP: %s', firewall.id, firewall.startport, firewall.endport, firewall.cidrlist, firewall.protocol, firewall.state, firewall.networkid, firewall.ipaddress) def get_vpc(self, name): vpc = VPC(get_vpc(api_client=self.api_client, name=name).__dict__, api_client=self.api_client) return vpc def get_virtual_machine(self, vm_name): virtual_machine = VirtualMachine(get_virtual_machine( api_client=self.api_client, name=self.get_dynamic_name('vms', vm_name) ).__dict__, []) virtual_machine_tags = Tag.list( api_client=self.api_client, resourceId=[virtual_machine.id], listall=True) for key in virtual_machine_tags: if key.key == 'sshport': virtual_machine.ssh_port = int(key.value.encode('ascii', 'ignore')) if key.key == 'sship': virtual_machine.ssh_ip = key.value.encode('ascii', 'ignore') return virtual_machine def get_network(self, name=None, id=None): return Network(get_network(api_client=self.api_client, name=name, id=id).__dict__) def get_network_acl_list(self, name=None, id=None): return NetworkACLList(get_network_acl(api_client=self.api_client, name=name, id=id).__dict__) def get_default_allow_acl_list(self): return self.get_network_acl_list(name='default_allow') def get_default_deny_acl_list(self): return self.get_network_acl_list(name='default_deny') def deploy_network_acl_list(self, acl_list_name, acl_config, network=None, vpc=None): if network: networkid=network.id if network.vpcid: vpcid=network.vpcid acl_list = NetworkACLList.create(self.api_client, name=acl_list_name, services=[], vpcid=vpcid, vpc=vpc) NetworkACL.create(self.api_client, acl_config, networkid=networkid, aclid=acl_list.id) return acl_list def finalize(self): if self.cleanup: try: self.logger.info('=== Scenario Manager, Cleaning Up of "%s" Started ===', self.scenario_data['metadata']['name']) cleanup_resources(self.api_client, self.resources_to_cleanup, self.logger) self.logger.info('=== Scenario Manager, Cleaning Up of "%s" Finished ===', self.scenario_data['metadata']['name']) except: self.logger.exception('Oops! Unable to clean up resources of "%s"!', self.scenario_data['metadata']['name']) else: self.logger.info('=== Scenario Manager, Skipping Cleaning Up of "%s" ===', self.scenario_data['metadata']['name'])
class TestSSVMs(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.hypervisor = self.testClient.getHypervisorInfo() self.cleanup = [] self.services = self.testClient.getParsedTestDataConfig() self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.services["sleep"] = 5 self.services["timeout"] = 180 return def tearDown(self): try: # Clean up, terminate the created templates cleanup_resources(self.apiclient, self.cleanup) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @attr(tags=['advanced']) def test_01_list_sec_storage_vm(self): self.test_list_svm_vm('secondarystoragevm') @attr(tags=['advanced']) def test_02_list_cpvm_vm(self): self.test_list_svm_vm('consoleproxy') @attr(tags=['advanced']) def test_03_destroy_ssvm(self): """Test destroy SSVM """ # Validate the following # 1. SSVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the # systemVM from what it was before # 3. new SSVM will have a public/private and link-local-ip # 4. cloud process within SSVM must be up and running list_ssvm_response = list_ssvms(self.apiclient, systemvmtype='secondarystoragevm', state='Running', zoneid=self.zone.id) self.assertEqual(isinstance(list_ssvm_response, list), True, "Check list response returns a valid list") ssvm_response = list_ssvm_response[0] old_name = ssvm_response.name self.logger.debug("Destroying SSVM: %s" % ssvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = ssvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_ssvm_response = list_ssvms(self.apiclient, zoneid=self.zone.id, systemvmtype='secondarystoragevm') if isinstance(list_ssvm_response, list): if list_ssvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List SSVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!" ) return time.sleep(self.services["sleep"]) timeout = timeout - 1 ssvm_response = list_ssvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created SSVM self.assertNotEqual(ssvm_response.name, old_name, "Check SSVM new name with name of destroyed SSVM") self.assertEqual(hasattr(ssvm_response, 'privateip'), True, "Check whether SSVM has private IP field") self.assertEqual(hasattr(ssvm_response, 'linklocalip'), True, "Check whether SSVM has link local IP field") self.assertEqual(hasattr(ssvm_response, 'publicip'), True, "Check whether SSVM has public IP field") # Wait for the agent to be up self.wait_for_system_vm_agent(ssvm_response.name) return @attr(tags=['advanced']) def test_04_destroy_cpvm(self): """Test destroy CPVM """ # Validate the following # 1. CPVM should be completely destroyed and a new one will spin up # 2. listSystemVMs will show a different name for the systemVM from # what it was before # 3. new CPVM will have a public/private and link-local-ip # 4. cloud process within CPVM must be up and running list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id) self.assertEqual(isinstance(list_cpvm_response, list), True, "Check list response returns a valid list") cpvm_response = list_cpvm_response[0] old_name = cpvm_response.name self.logger.debug("Destroying CPVM: %s" % cpvm_response.id) cmd = destroySystemVm.destroySystemVmCmd() cmd.id = cpvm_response.id self.apiclient.destroySystemVm(cmd) timeout = self.services["timeout"] while True: list_cpvm_response = list_ssvms(self.apiclient, systemvmtype='consoleproxy', zoneid=self.zone.id) if isinstance(list_cpvm_response, list): if list_cpvm_response[0].state == 'Running': break if timeout == 0: self.logger.debug( "Warning: List CPVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!" ) return time.sleep(self.services["sleep"]) timeout = timeout - 1 cpvm_response = list_cpvm_response[0] # Verify Name, Public IP, Private IP and Link local IP # for newly created CPVM self.assertNotEqual(cpvm_response.name, old_name, "Check SSVM new name with name of destroyed CPVM") self.assertEqual(hasattr(cpvm_response, 'privateip'), True, "Check whether CPVM has private IP field") self.assertEqual(hasattr(cpvm_response, 'linklocalip'), True, "Check whether CPVM has link local IP field") self.assertEqual(hasattr(cpvm_response, 'publicip'), True, "Check whether CPVM has public IP field") # Wait for the agent to be up self.wait_for_system_vm_agent(cpvm_response.name) return def wait_for_system_vm_agent(self, vmname): self.logger.debug("Waiting for system VM %s agent to be UP" % vmname) timeout = self.services["timeout"] sleep_interval = self.services["sleep"] while timeout > 0: list_host_response = list_hosts(self.apiclient, name=vmname) if list_host_response and list_host_response[0].state == 'Up': self.debug("System VM %s agent is UP" % vmname) break time.sleep(sleep_interval) timeout = timeout - sleep_interval if timeout <= 0 and list_host_response[0].state != 'Up': self.logger.debug( "Warning: List CPVM didn't return systemvms in Running state. This is a known issue, ignoring it for now!" ) return def test_list_svm_vm(self, svm_type): # Validate the following: # 1. listSystemVM # should return only ONE SVM per zone # 2. The returned SVM should be in Running state # 3. listSystemVM for should list publicip, privateip and link-localip # 4. The gateway programmed on the SVM by listSystemVm should be # the same as the gateway returned by listVlanIpRanges # 5. DNS entries must match those given for the zone list_svm_response = list_ssvms( self.apiclient, systemvmtype=svm_type, state='Running', ) self.assertEqual(isinstance(list_svm_response, list), True, "Check list response returns a valid list") # Verify SSVM response self.assertNotEqual(len(list_svm_response), 0, "Check list System VMs response") list_zones_response = list_zones(self.apiclient) self.assertEqual(isinstance(list_zones_response, list), True, "Check list response returns a valid list") self.logger.debug("Number of zones: %s" % len(list_zones_response)) self.logger.debug("Number of System VMs: %s" % len(list_svm_response)) # Number of Sec storage VMs = No of Zones self.assertEqual(len(list_svm_response), len(list_zones_response), "Check number of System VMs with number of zones") # For each secondary storage VM check private IP, # public IP, link local IP and DNS for svm in list_svm_response: self.logger.debug("SVM state: %s" % svm.state) self.assertEqual(svm.state, 'Running', "Check whether state of System VM is running") self.assertEqual(hasattr(svm, 'privateip'), True, "Check whether System VM has private IP field") self.assertEqual( hasattr(svm, 'linklocalip'), True, "Check whether System VM has link local IP field") self.assertEqual(hasattr(svm, 'publicip'), True, "Check whether System VM has public IP field") # Fetch corresponding ip ranges information from listVlanIpRanges ipranges_response = list_vlan_ipranges(self.apiclient, zoneid=svm.zoneid) self.assertEqual(isinstance(ipranges_response, list), True, "Check list response returns a valid list") iprange = ipranges_response[0] # Execute the following assertion in all zones except basic Zones if not (self.zone.networktype.lower() == 'basic'): self.assertEqual( svm.gateway, iprange.gateway, "Check gateway with that of corresponding ip range") # Fetch corresponding zone information from listZones zone_response = list_zones(self.apiclient, id=svm.zoneid) self.assertEqual(isinstance(zone_response, list), True, "Check list response returns a valid list") self.assertEqual(svm.dns1, zone_response[0].dns1, "Check DNS1 with that of corresponding zone") self.assertEqual(svm.dns2, zone_response[0].dns2, "Check DNS2 with that of corresponding zone") return
class TestReleaseIP(cloudstackTestCase): def setUp(self): self.logger = MarvinLog(MarvinLog.LOGGER_TEST).get_logger() self.apiclient = self.testClient.getApiClient() self.services = self.testClient.getParsedTestDataConfig() self.vpc_offering = get_default_vpc_offering(self.apiclient) self.network_offering = get_default_network_offering(self.apiclient) # Get Zone, Domain and templates self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) template = get_template( self.apiclient, self.zone.id ) self.services["virtual_machine"]["zoneid"] = self.zone.id # Create an account, network, VM, Port forwarding rule, LB rules self.account = Account.create( self.apiclient, self.services["account"], admin=True, domainid=self.domain.id ) self.service_offering = get_default_virtual_machine_offering(self.apiclient) self.vpc = VPC.create( self.apiclient, self.services["vpc"], vpcofferingid=self.vpc_offering.id, zoneid=self.zone.id, account=self.account.name, domainid=self.account.domainid) ntwk = Network.create( api_client=self.apiclient, services=self.services["network_1"], accountid=self.account.name, domainid=self.domain.id, networkofferingid=self.network_offering.id, zoneid=self.zone.id, vpcid=self.vpc.id ) networkids = [] networkids.append(ntwk.id) self.virtual_machine = VirtualMachine.create( self.apiclient, self.services["virtual_machine"], templateid=template.id, accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, networkids=networkids ) self.ip_address = PublicIPAddress.create( self.apiclient, self.account.name, self.zone.id, self.account.domainid, vpcid=self.vpc.id ) ip_addrs = list_public_ip( self.apiclient, account=self.account.name, domainid=self.account.domainid, issourcenat=False ) try: self.ip_addr = ip_addrs[0] except Exception as e: raise Exception( "Failed: During acquiring source NAT for account: %s, :%s" % (self.account.name, e)) self.nat_rule = NATRule.create( self.apiclient, self.virtual_machine, self.services["natrule"], self.ip_addr.id, networkid=ntwk.id ) self.lb_rule = LoadBalancerRule.create( self.apiclient, self.services["lbrule"], self.ip_addr.id, accountid=self.account.name, networkid=ntwk.id ) self.cleanup = [ self.virtual_machine, self.account ] return def tearDown(self): cleanup_resources(self.apiclient, self.cleanup) @attr(tags=['advanced']) def test_01_release_ip(self): """Test for release public IP address""" self.logger.debug("Deleting Public IP : %s" % self.ip_addr.id) self.ip_address.delete(self.apiclient) retriesCount = 10 isIpAddressDisassociated = False while retriesCount > 0: listResponse = list_public_ip( self.apiclient, id=self.ip_addr.id ) if listResponse is None: isIpAddressDisassociated = True break retriesCount -= 1 time.sleep(60) # End while self.assertTrue( isIpAddressDisassociated, "Failed to disassociate IP address") # ListPortForwardingRules should not list # associated rules with Public IP address try: list_nat_rule = list_nat_rules( self.apiclient, id=self.nat_rule.id ) self.logger.debug("List NAT Rule response" + str(list_nat_rule)) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # listLoadBalancerRules should not list # associated rules with Public IP address try: list_lb_rule = list_lb_rules( self.apiclient, id=self.lb_rule.id ) self.logger.debug("List LB Rule response" + str(list_lb_rule)) except CloudstackAPIException: self.logger.debug("Port Forwarding Rule is deleted") # SSH Attempt though public IP should fail with self.assertRaises(Exception): SshClient( self.ip_addr.ipaddress, self.services["natrule"]["publicport"], self.virtual_machine.username, self.virtual_machine.password, retries=2, delay=0 ) return