def download_systemplates_sec_storage(server, services): """Download System templates on sec storage""" try: # Login to management server ssh = SshClient(server["ipaddress"], server["port"], server["username"], server["password"]) except Exception: raise Exception("SSH access failed for server with IP address: %s" % server["ipaddess"]) # Mount Secondary Storage on Management Server cmds = [ "mkdir -p %s" % services["mnt_dir"], "mount -t nfs %s:/%s %s" % (services["sec_storage"], services["path"], services["mnt_dir"]), "%s -m %s -u %s -h %s -F" % (services["command"], services["mnt_dir"], services["download_url"], services["hypervisor"]) ] for c in cmds: result = ssh.execute(c) res = str(result) # Unmount the Secondary storage ssh.execute("umount %s" % (services["mnt_dir"])) if res.count("Successfully installed system VM template") == 1: return else: raise Exception("Failed to download System Templates on Sec Storage") return
def is_server_ssh_ready(ipaddress, port, username, password, retries=20, retryinterv=30, timeout=10.0, keyPairFileLocation=None): ''' @Name: is_server_ssh_ready @Input: timeout: tcp connection timeout flag, others information need to be added @Output:object for SshClient Name of the function is little misnomer and is not verifying anything as such mentioned ''' try: ssh = SshClient( host=ipaddress, port=port, user=username, passwd=password, keyPairFiles=keyPairFileLocation, retries=retries, delay=retryinterv, timeout=timeout) except Exception as e: raise Exception( "SSH connection has Failed. Waited %ss. Error is %s" % (retries * retryinterv, str(e))) else: return ssh
def get_process_status( hostip, port, username, password, linklocalip, process, hypervisor=None): """Double hop and returns a process status""" # SSH to the machine ssh = SshClient(hostip, port, username, password) if (str(hypervisor).lower() == 'vmware' or str(hypervisor).lower() == 'hyperv'): ssh_command =\ "ssh -i /var/cloudstack/management/" \ ".ssh/id_rsa -ostricthostkeychecking=no " else: ssh_command = "ssh -i ~/.ssh/id_rsa.cloud " \ "-ostricthostkeychecking=no " ssh_command = ssh_command +\ "-oUserKnownHostsFile=/dev/null -p 3922 %s %s" % ( linklocalip, process) # Double hop into router timeout = 5 # Ensure the SSH login is successful while True: res = ssh.execute(ssh_command) if res[0] != "Host key verification failed.": break elif timeout == 0: break time.sleep(5) timeout = timeout - 1 return res
def test_02_pt_deploy_vm_with_startvm_true(self): """ Positive test for stopped VM test path - T1 variant # 1. Deploy VM in the network specifying startvm parameter as True # 2. List VMs and verify that VM is in running state # 3. Verify that router is in running state (Advanced zone) # 4. Add network rules for VM (done in base.py itself) to make # it accessible # 5. Verify that VM is accessible # 6. Destroy and expunge the VM # 7. Wait for network gc time interval and check that router is # in stopped state """ # Create VM in account virtual_machine = VirtualMachine.create( self.userapiclient, self.testdata["small"], templateid=self.defaultTemplateId, accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, networkids=[ self.networkid, ] if self.networkid else None, zoneid=self.zone.id, startvm=True, mode=self.zone.networktype) response = virtual_machine.getState(self.userapiclient, VirtualMachine.RUNNING) self.assertEqual(response[0], PASS, response[1]) if str(self.zone.networktype).lower() == "advanced": response = VerifyRouterState(self.apiclient, self.account.name, self.account.domainid, RUNNING) self.assertTrue(response[0], response[1]) # Check VM accessibility try: SshClient(host=virtual_machine.ssh_ip, port=self.testdata["natrule"]["publicport"], user=virtual_machine.username, passwd=virtual_machine.password) except Exception as e: self.fail("Exception while SSHing to VM: %s" % e) virtual_machine.delete(self.apiclient) if str(self.zone.networktype).lower() == "advanced": # Wait for router to get router in stopped state wait_for_cleanup(self.apiclient, ["network.gc.interval", "network.gc.wait"]) response = VerifyRouterState(self.apiclient, self.account.name, self.account.domainid, STOPPED, retries=10) self.assertTrue(response[0], response[1]) return
def test_releaseIP(self): """Test for release public IP address""" 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_publicIP( 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 ) logger.debug("List NAT Rule response" + str(list_nat_rule)) except CloudstackAPIException: 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 ) logger.debug("List LB Rule response" + str(list_lb_rule)) except CloudstackAPIException: 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
def RestartServers(self): """ Restart management server and usage server """ sshClient = SshClient(self.mgtSvrDetails["mgtSvrIp"], 22, self.mgtSvrDetails["user"], self.mgtSvrDetails["passwd"]) command = "service cloudstack-management restart" sshClient.execute(command) return
def test_releaseIP(self): """Test for release public IP address""" self.debug("Deleting Public IP : %s" % self.ip_addr.id) self.ip_address.delete(self.apiclient) # Sleep to ensure that deleted state is reflected in other calls time.sleep(self.services["sleep"]) # ListPublicIpAddresses should not list deleted Public IP address list_pub_ip_addr_resp = list_publicIP( self.apiclient, id=self.ip_addr.id ) self.debug("List Public IP response" + str(list_pub_ip_addr_resp)) self.assertEqual( list_pub_ip_addr_resp, None, "Check if disassociated IP Address is no longer available" ) # 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.debug("List NAT Rule response" + str(list_nat_rule)) except cloudstackAPIException: self.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.debug("List LB Rule response" + str(list_lb_rule)) except cloudstackAPIException: self.debug("Port Forwarding Rule is deleted") # SSH Attempt though public IP should fail with self.assertRaises(Exception): ssh_2 = SshClient( self.ip_addr.ipaddress, self.services["natrule"]["publicport"], self.virtual_machine.username, self.virtual_machine.password, retries=2, delay=0 ) return
def test_06_reboot_VR_verify_ip_alias(self): """Reboot VR and verify ip alias 1.Deploy guest vm in new cidr 2.Verify ip alias creation 3.Reboot VR 4.Verify ip alias on VR """ list_router_response = list_routers(self.apiclient, zoneid=self.zone.id, listall=True) self.assertEqual(isinstance(list_router_response, list), True, "Check list response returns a valid list") router = list_router_response[0] hosts = list_hosts(self.apiclient, zoneid=router.zoneid, type='Routing', state='Up', id=router.hostid) self.assertEqual(isinstance(hosts, list), True, "Check list host returns a valid list") host = hosts[0] self.debug("Router ID: %s, state: %s" % (router.id, router.state)) self.assertEqual(router.state, 'Running', "Check list router response for router state") port = self.testdata['configurableData']['host']["publicport"] username = self.testdata['configurableData']['host']["username"] password = self.testdata['configurableData']['host']["password"] # SSH to host so that host key is saved in first # attempt SshClient(host.ipaddress, port, username, password) proc = "ip addr show eth0" result = get_process_status(host.ipaddress, port, username, password, router.linklocalip, proc) res = str(result) self.debug("ip alias configuration on VR: %s" % res) self.assertNotEqual( res.find(self.alias_ip) - 1, "ip alias is not created on VR eth0") resp = Router.reboot(self.apiclient, router.id) self.debug("Reboot router api response: %s" % resp) list_router_response = list_routers(self.apiclient, zoneid=self.zone.id, listall=True) self.assertEqual(isinstance(list_router_response, list), True, "Check list response returns a valid list") router = list_router_response[0] self.assertEqual(router.state, 'Running', "Router is not in running state after reboot") result = get_process_status(host.ipaddress, port, username, password, router.linklocalip, proc) res = str(result) self.assertNotEqual(res.find(self.alias_ip), -1, "IP alias not present on VR after VR reboot") return
def test_deploy_vgpu_enabled_vm(self): """Test Deploy Virtual Machine # Validate the following: # 1. Virtual Machine is accessible via SSH # 2. Virtual Machine is vGPU enabled (via SSH) # 3. listVirtualMachines returns accurate information """ if self.hypervisor.lower() not in ["xenserver"]: self.cleanup.append(self.account) self.skipTest("This test case is written specifically\ for XenServer hypervisor") self.virtual_machine = VirtualMachine.create( self.apiclient, self.testdata["small"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.testdata['mode']) self.cleanup.append(self.virtual_machine) list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) self.debug( "Verify listVirtualMachines response for virtual machine: %s" % self.virtual_machine.id) self.assertEqual(isinstance(list_vms, list), True, "List VM response was not a valid list") self.assertNotEqual(len(list_vms), 0, "List VM response was empty") vm = list_vms[0] self.assertEqual(vm.id, self.virtual_machine.id, "Virtual Machine ids do not match") self.assertEqual(vm.name, self.virtual_machine.name, "Virtual Machine names do not match") self.assertEqual(vm.state, "Running", msg="VM is not in Running state") hosts = list_hosts(self.apiclient, id=vm.hostid) hostip = hosts[0].ipaddress try: sshClient = SshClient( host=hostip, port=self.testdata['configurableData']['host']["publicport"], user=self.testdata['configurableData']['host']["username"], passwd=self.testdata['configurableData']['host']["password"]) res = sshClient.execute( "xe vgpu-list vm-name-label=%s params=type-uuid %s" % (vm.instancename)) self.debug("SSH result: %s" % res) except Exception as e: self.fail("SSH Access failed for %s: %s" % (hostip, e)) result = str(res) self.assertEqual(result.count("type-uuid"), 1, "VM is vGPU enabled.") self.cleanup.append(self.account)
def verify_rule_on_host(self, ipaddress, user, password, rule): self.logger.debug("Verifying rule '%s' in host %s" % (rule, ipaddress)) try: ssh = SshClient(ipaddress, 22, user, password) result = ssh.execute("iptables-save |grep \"\\%s\"" % rule) if len(result) == 0 or result[0] != rule: raise Exception("Unable to apply security group rule") except KeyError: self.skipTest( "Provide a marvin config file with host credentials to run %s" % self._testMethodName)
def RestartServer(cls): """Restart management server""" sshClient = SshClient(cls.mgtSvrDetails["mgtSvrIp"], 22, cls.mgtSvrDetails["user"], cls.mgtSvrDetails["passwd"]) command = "service cloudstack-management restart" sshClient.execute(command) return
def setUpClass(cls): cls.testClient = super(TestL2PersistentNetworks, cls).getClsTestClient() cls.api_client = cls.testClient.getApiClient() cls.hypervisor = cls.testClient.getHypervisorInfo() isKVM = cls.hypervisor.lower() in ["kvm"] isOVSEnabled = False hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][ 0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ if isKVM: # Test only if all the hosts use OVS grepCmd = 'grep "network.bridge.type=openvswitch" /etc/cloudstack/agent/agent.properties' hosts = list_hosts(cls.api_client, type='Routing', hypervisor='kvm') for host in hosts: if len( SshClient(host.ipaddress, port=22, user=hostConfig["username"], passwd=hostConfig["password"]).execute( grepCmd)) != 0: isOVSEnabled = True break if isKVM and isOVSEnabled: cls.skipTest( cls, "KVM with OVS doesn't support persistent networks, skipping") # Fill services from the external config file cls.services = cls.testClient.getParsedTestDataConfig() cls.hostConfig = cls.config.__dict__["zones"][0].__dict__["pods"][ 0].__dict__["clusters"][0].__dict__["hosts"][0].__dict__ # Get Zone and templates cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.template = get_template(cls.api_client, cls.zone.id, cls.services["ostype"]) cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["template"] = cls.template.id cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"]) cls.l2_persistent_network_offering = cls.create_network_offering( "nw_off_L2_persistent") cls.isolated_persistent_network_offering = cls.create_network_offering( "nw_off_isolated_persistent") # network will be deleted as part of account cleanup cls._cleanup = [ cls.service_offering, cls.isolated_persistent_network_offering, cls.l2_persistent_network_offering ] return
def get_ssh_client(self, ip, username, password, retries=10): """ Setup ssh client connection and return connection """ try: ssh_client = SshClient(ip, 22, username, password, retries) except Exception as e: raise self.skipTest("Unable to create ssh connection: " % e) self.assertIsNotNone(ssh_client, "Failed to setup ssh connection to ip=%s" % ip) return ssh_client
def ssh_kvm_host(password, ipaddr, instance_name): """Ssh into kvm host and get vm mem details""" mem = [] sshClient = SshClient(ipaddr, 22, "root", password) command = "virsh dominfo %s" % instance_name vm_detail = sshClient.execute(command) max = vm_detail[7].split() min = vm_detail[8].split() mem.append(int(max[2])) mem.append(int(min[2])) return mem
def filecopy(cls,virtual_machine,localfile=None,remotefilelocation=None,permissions="644"): cls.ssh = SshClient( host=virtual_machine.public_ip, port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], user='******', passwd='password') cls.ssh.scp(localfile,remotefilelocation) cls.ssh.runCommand('chmod %s %s' % (permissions,remotefilelocation)) cls.debug("%s file successfully copied to %s " % (localfile, remotefilelocation)) cls.ssh.close()
def vpnClientServicesStart(virtual_machine,vpnclient_services_script): ssh = SshClient( host=virtual_machine.public_ip, port=TestMultipleVPNAccessonVPC.services["virtual_machine"]["ssh_port"], user='******', passwd='password') ssh.execute('%s start >> /tmp/executionoutput.txt' % (vpnclient_services_script)) ssh.execute('echo "VPN Client Services Started" >> /tmp/executionoutput.txt') ssh.close()
def checkHostDown(self, fromHostIp, testHostIp): try: ssh = SshClient(fromHostIp, 22, "root", "password") res = ssh.execute("ping -c 1 %s" % testHostIp) result = str(res) if result.count("100% packet loss") == 1: return True, 1 else: return False, 1 except Exception as e: self.logger.debug("Got exception %s" % e) return False, 1
def restartUsageServer(self): #Restart usage server sshClient = SshClient( self.mgtSvrDetails["mgtSvrIp"], 22, self.mgtSvrDetails["user"], self.mgtSvrDetails["passwd"] ) command = "service cloudstack-usage restart" sshClient.execute(command) return
def test_DeployVm(self): """ Let's start by defining the attributes of our VM that we will be deploying on CloudStack. We will be assuming a single zone is available and is configured and all templates are Ready The hardcoded values are used only for brevity. """ deployVmCmd = deployVirtualMachine.deployVirtualMachineCmd() deployVmCmd.zoneid = self.zone.uuid deployVmCmd.templateid = self.template.uuid #CentOS 5.6 builtin deployVmCmd.serviceofferingid = self.service_offering.uuid deployVmResponse = self.apiClient.deployVirtualMachine(deployVmCmd) self.debug("VM %s was deployed in the job %s" % (deployVmResponse.id, deployVmResponse.jobid)) # At this point our VM is expected to be Running. Let's find out what # listVirtualMachines tells us about VMs in this account listVmCmd = listVirtualMachines.listVirtualMachinesCmd() listVmCmd.id = deployVmResponse.id listVmResponse = self.apiClient.listVirtualMachines(listVmCmd) self.assertNotEqual( len(listVmResponse), 0, "Check if the list API \ returns a non-empty response") vm = listVmResponse[0] self.assertEqual(vm.state, "Running", "Check if VM has reached Running state in CS") hostname = vm.name nattedip = self.setUpNAT(vm.id) self.assertEqual( vm.id, deployVmResponse.id, "Check if the VM returned \ is the same as the one we deployed") self.assertEqual( vm.state, "Running", "Check if VM has reached \ a state of running") # SSH login and compare hostname self.debug("Attempting to SSH into %s over %s of %s" % (nattedip, "22", vm.name)) ssh_client = SshClient(nattedip, "22", "root", "password") stdout = ssh_client.execute("hostname") self.assertEqual( hostname, stdout[0], "cloudstack VM name and hostname \ do not match")
def ssh_xen_host(password, ipaddr, instance_name): """Ssh into xen host and get vm mem details""" mem = [] sshClient = SshClient(ipaddr, 22, "root", password) command = "xe vm-list params=all name-label=%s" % instance_name vm_detail = sshClient.execute(command) max_str = vm_detail[17].split(":") min_str = vm_detail[20].split(":") max = int(max_str[1]) min = int(min_str[1]) mem.append(max) mem.append(min) return mem
def test_deploy_vgpu_enabled_vm(self): """Test Deploy Virtual Machine # Validate the following: # 1. Virtual Machine is accessible via SSH # 2. Virtual Machine is vGPU enabled (via SSH) # 3. listVirtualMachines returns accurate information """ self.virtual_machine = VirtualMachine.create( self.apiclient, self.testdata["vgpu260q"], accountid=self.account.name, domainid=self.account.domainid, serviceofferingid=self.service_offering.id, mode=self.testdata['mode']) list_vms = VirtualMachine.list(self.apiclient, id=self.virtual_machine.id) self.debug( "Verify listVirtualMachines response for virtual machine: %s"\ % self.virtual_machine.id ) self.assertEqual(isinstance(list_vms, list), True, "List VM response was not a valid list") self.assertNotEqual(len(list_vms), 0, "List VM response was empty") vm = list_vms[0] self.assertEqual(vm.id, self.virtual_machine.id, "Virtual Machine ids do not match") self.assertEqual(vm.name, self.virtual_machine.name, "Virtual Machine names do not match") self.assertEqual(vm.state, "Running", msg="VM is not in Running state") hosts = list_hosts(self.apiclient, id=vm.hostid) hostip = hosts[0].ipaddress try: sshClient = SshClient(host=hostip, port=22, user='******', passwd=self.testdata["host_password"]) res = sshClient.execute( "xe vgpu-list vm-name-label=%s params=type-uuid %s" % (vm.instancename)) self.debug("SSH result: %s" % res) except Exception as e: self.fail("SSH Access failed for %s: %s" % \ (hostip, e) ) result = str(res) self.assertEqual(result.count("type-uuid"), 1, "VM is vGPU enabled.")
def test_es_1236_cloudstack_sccs(self): """ @Desc: Test whether cloudstack-sccs is available on management server @Steps: Step1: run cloudstack-sccs on management server Step2: It should return a commit hash """ # Step1: run cloudstack-sccs on management server mgmt_ssh = SshClient(self.apiClient.connection.mgtSvr, 22, self.apiClient.connection.user, self.apiClient.connection.passwd) res = mgmt_ssh.execute("cloudstack-sccs") # Step2: It should return a commit hash return
def setUpClass(self): testClient = super(TestDeployvGPUenabledVM, self).getClsTestClient() self.apiclient = testClient.getApiClient() self.testdata = self.testClient.getParsedTestDataConfig() self._cleanup = [] self.unsupportedHypervisor = False self.noSuitableHost = False # Need to add check whether zone containing the xen hypervisor or not # as well hosts = list_hosts(self.apiclient, hypervisor="XenServer") if hosts is None: # GPU feature is supported only on XenServer.Check listhosts response self.unsupportedHypervisor = True return else: gpuhosts = 0 for ghost in hosts: if ghost.hypervisorversion >= "6.2.0": sshClient = SshClient( host=ghost.ipaddress, port=self.testdata['configurableData']['host'] ["publicport"], user=self.testdata['configurableData']['host'] ["username"], passwd=self.testdata['configurableData']['host'] ["password"]) if ghost.hypervisorversion == "6.2.0": res = sshClient.execute( "xe patch-list uuid=0850b186-4d47-11e3-a720-001b2151a503" ) if len(res) == 0: continue res = sshClient.execute( "xe vgpu-type-list model-name=\"GRID K120Q\"") if len(res) != 0: gpuhosts = gpuhosts + 1 else: continue if gpuhosts == 0: # No XenServer available with GPU Drivers installed self.noSuitableHost = True return self.domain = get_domain(self.apiclient) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) # Creating Account self.account = Account.create(self.apiclient, self.testdata["account"], domainid=self.domain.id) self._cleanup.append(self.account)
def getVirshXML(self, host, instancename): self.assertIsNotNone(host, "Host should not be None") self.assertIsNotNone(instancename, "Instance name should not be None") sshc = SshClient(host=host.ipaddress, port=22, user=self.hostConfig['username'], passwd=self.hostConfig['password']) virsh_cmd = 'virsh dumpxml %s' % instancename xml_res = sshc.execute(virsh_cmd) xml_as_str = ''.join(xml_res) parser = etree.XMLParser(remove_blank_text=True) return ET.fromstring(xml_as_str, parser=parser)
def try_ssh(self, ip_addr, hostnames): try: self.debug("SSH into (Public IP: %s)" % ip_addr) # If Round Robin Algorithm is chosen, # each ssh command should alternate between VMs ssh_1 = SshClient(ip_addr, 22, self.virtual_machine.username, self.virtual_machine.password) hostnames.append(ssh_1.execute("hostname")[0]) self.debug(hostnames) except Exception as e: self.fail("%s: SSH failed for VM with IP Address: %s" % (e, ip_addr)) return hostnames
def get_ssh_client(self, vm, retries): """ Setup ssh client connection and return connection vm requires attributes public_ip, public_port, username, password """ try: ssh_client = SshClient(vm.public_ip, vm.public_port, vm.username, vm.password, retries) except Exception as e: self.fail("Unable to create ssh connection: " % e) self.assertIsNotNone( ssh_client, "Failed to setup ssh connection to vm=%s on public_ip=%s" % (vm.name, vm.public_ip)) return ssh_client
def test_multiple_mgmt_srvr_session_timeout(self): """ @Desc: Check whether mgmt server session times out with in 30s @Steps: Step1: run 'telnet localhot 8250' on the management server and see that it times out with in 30seconds """ # Step1: run cloudstack-sccs on management server mgmt_ssh = SshClient(self.apiClient.connection.mgtSvr, 22, self.apiClient.connection.user, self.apiClient.connection.passwd) res = mgmt_ssh.execute("time telnet localhost 8250") # Step2: It should return a commit hash return
def restartServer(cls): """Restart management server""" sshClient = SshClient(cls.mgtSvrDetails["mgtSvrIp"], 22, cls.mgtSvrDetails["user"], cls.mgtSvrDetails["passwd"]) command = "service cloudstack-management stop" sshClient.execute(command) command = "service cloudstack-management start" sshClient.execute(command) #time.sleep(cls.services["sleep"]) time.sleep(300) return
def _execute_ssh_command(hostip, port, username, password, ssh_command): # SSH to the machine ssh = SshClient(hostip, port, username, password) # Ensure the SSH login is successful while True: res = ssh.execute(ssh_command) if "Connection refused".lower() in res[0].lower(): pass elif res[0] != "Host key verification failed.": break elif timeout == 0: break time.sleep(5) timeout = timeout - 1 return res
def try_ssh(self, ip_addr, hostnames): try: self.debug( "SSH into VM (IPaddress: %s) & NAT Rule (Public IP: %s)" % (self.vm_1.ipaddress, ip_addr)) # If Round Robin Algorithm is chosen, # each ssh command should alternate between VMs ssh_1 = SshClient(ip_addr, self.services['lbrule']["publicport"], self.vm_1.username, self.vm_1.password) hostnames.append(ssh_1.execute("hostname")[0]) self.debug(hostnames) except Exception as e: self.fail("%s: SSH failed for VM with IP Address: %s" % (e, ip_addr)) time.sleep(10) return