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
示例#2
0
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
示例#3
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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'])
示例#8
0
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
示例#9
0
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
示例#10
0
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'])
示例#12
0
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