# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.


# this script will cover VMdeployment  with Userdata tests

from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.base import *
from marvin.lib.utils import (validateList, cleanup_resources)
from marvin.lib.common import *
from nose.plugins.attrib import attr
from marvin.codes import PASS,FAIL

_multiprocess_shared_ = True

class Services:
    def __init__(self):
        self.services = {
            "virtual_machine": {
                "displayname": "TesVM1",
                "username": "root",
                "password": "password",
                "ssh_port": 22,
                "hypervisor": 'XenServer',
                "privateport": 22,
                "publicport": 22,
                "protocol": 'TCP',
                },
            "ostype": 'CentOS 5.5 (64-bit)',
            "service_offering": {
                "name": "Tiny Instance",
                "displaytext": "Tiny Instance",
                "cpunumber": 1,
                "cpuspeed": 100,
                "memory": 256,
                },
            }

class TestDeployVmWithMetaData(cloudstackTestCase):
    @classmethod
    def setUpClass(cls):
        cls.testclient = super(TestDeployVmWithMetaData, cls).getClsTestClient()
        cls.apiclient = cls.testclient.getApiClient()
        cls._cleanup = []
        #cls.services = Services().services
        cls.services = cls.testclient.getParsedTestDataConfig()
        cls.zone = get_zone(cls.apiclient, cls.testclient.getZoneForTests())
        cls.service_offering = ServiceOffering.create(
            cls.apiclient,
            cls.services["service_offering"]
        )

        cls.template = get_template(
            cls.apiclient,
            cls.zone.id,
            cls.services["ostype"]
        )


    @classmethod
    def tearDownClass(cls):
        try:
            cls._cleanup = cls._cleanup[::-1]
            cleanup_resources(cls.apiclient, cls._cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)

    def setUp(self):
        self.apiclient = self.testClient.getApiClient()
        self.cleanup = []

    def tearDown(self):
        try:
            self.cleanup = self.cleanup[::-1]
            cleanup_resources(self.apiclient, self.cleanup)
        except Exception as e:
            raise Exception("Warning: Exception during cleanup : %s" % e)
        return

    def migrate_VM(self, vm):
        """Migrates VM to another host, if available"""
        self.debug("+++ Migrating one of the VMs in the created "
                   "VPC Tier network to another host, if available...")
        self.debug("Checking if a host is available for migration...")
        hosts = Host.listForMigration(self.apiclient, virtualmachineid=vm.id)
        if hosts:
            self.assertEqual(isinstance(hosts, list), True,
                             "List hosts should return a valid list"
                             )
            host = hosts[0]
            self.debug("Migrating VM with ID: "
                       "%s to Host: %s" % (vm.id, host.id))
            try:
                vm.migrate(self.apiclient, hostid=host.id)
            except Exception as e:
                self.fail("Failed to migrate instance, %s" % e)
            self.debug("Migrated VM with ID: "
                       "%s to Host: %s" % (vm.id, host.id))
        else:
            self.debug("No host available for migration. "
                       "Test requires at-least 2 hosts")
        return host

    def list_nics(self, vm_id):
        list_vm_res = VirtualMachine.list(self.apiclient, id=vm_id)
        self.assertEqual(validateList(list_vm_res)[0], PASS, "List vms returned invalid response")
        nics = list_vm_res[0].nic
        for nic in nics:
            if nic.type == "Shared":
                nic_res = NIC.list(
                    self.apiclient,
                    virtualmachineid=vm_id,
                    nicid=nic.id
                )
                nic_ip = nic_res[0].ipaddress
                self.assertIsNotNone(nic_ip, "listNics API response does not have the ip address")
            else:
                continue
        return

    @attr(tags=["advanced"], required_hardware='True')
    def test_deployVM_verify_metadata_in_VR(self):
        """
        1. Create a network (VR as a provider)
        2. Deploy a VM in the network
        3. Verify VM deployment
        4. From the VM, curl the gateway of the VR to verify the corresponding metadata - hypervisor host name
            if the respective Global level and account level flags are set to true
        """
        # Update global setting for "global.allow.expose.host.hostname"
        Configurations.update(self.apiclient,
                              name="global.allow.expose.host.hostname",
                              value="true"
                              )

        # Update Account level setting
        Configurations.update(self.apiclient,
                              name="account.allow.expose.host.hostname",
                              value="true"
                              )

        # Verify that the above mentioned settings are set to true before proceeding
        if not is_config_suitable(
                apiclient=self.apiclient,
                name='global.allow.expose.host.hostname',
                value='true'):
            self.skipTest('global.allow.expose.host.hostname should be true. skipping')

        if not is_config_suitable(
                apiclient=self.apiclient,
                name='account.allow.expose.host.hostname',
                value='true'):
            self.skipTest('account.allow.expose.host.hostname should be true. skipping')

        self.no_isolate = NetworkOffering.create(
            self.apiclient,
            self.services["isolated_network_offering"]
        )
        self.no_isolate.update(self.apiclient, state='Enabled')
        self.isolated_network = Network.create(
            self.apiclient,
            self.services["network"],
            networkofferingid=self.no_isolate.id,
            zoneid=self.zone.id,
            accountid="admin",
            domainid=1
        )
        self.cleanup.append(self.isolated_network)

        self.vm = VirtualMachine.create(
            self.apiclient,
            self.services["virtual_machine"],
            templateid=self.template.id,
            accountid="admin",
            domainid=1,
            serviceofferingid=self.service_offering.id,
            zoneid=self.zone.id,
            networkids=[self.isolated_network.id],
        )
        self.assertIsNotNone(
            self.vm,
            "VM creation failed in the isolated network"
        )
        self.cleanup.append(self.vm)

        ip_addr = self.vm.ipaddress
        self.debug("VM ip address = %s" % ip_addr)

        # Verify the retrieved ip address in listNICs API response
        self.list_nics(self.vm.id)
        vr_res = Router.list(
            self.apiclient,
            networkid=self.isolated_network.id,
            listAll=True
        )
        self.assertEqual(validateList(vr_res)[0], PASS, "List Routers returned invalid response")
        vr_ip = vr_res[0].guestipaddress
        ssh = self.vm.get_ssh_client(ipaddress=ip_addr)
        cmd = "curl http://%s/latest/hypervisor-host-name" % vr_ip
        res = ssh.execute(cmd)
        self.debug("Verifying hypervisor hostname details in the VR")
        self.assertEqual(
            str(res),
            self.vm.hostname,
            "Failed to get the hypervisor host name from VR in isolated network"
        )
        # Reset configuration values to default values i.e., false
        Configurations.update(self.apiclient,
                              name="global.allow.expose.host.hostname",
                              value="false"
                              )

        # Update Account level setting
        Configurations.update(self.apiclient,
                              name="account.allow.expose.host.hostname",
                              value="false"
                              )
        return

    @attr(tags=["advanced"], required_hardware='True')
    def test_deployVM_verify_metadata_in_VR_after_migration(self):
        """
        1. Create a network (VR as a provider)
        2. Deploy a VM in the network
        3. Verify VM deployment
        4. Migrate VM to another host
        4. After migration, from the VM, curl the gateway to verify the corresponding metadata - hypervisor host name
            if the respective Global level and account level flags are set to true
        """
        # Update global setting for "global.allow.expose.host.hostname"
        Configurations.update(self.apiclient,
                              name="global.allow.expose.host.hostname",
                              value="true"
                              )

        # Update Account level setting
        Configurations.update(self.apiclient,
                              name="account.allow.expose.host.hostname",
                              value="true"
                              )

        # Verify that the above mentioned settings are set to true before proceeding
        if not is_config_suitable(
                apiclient=self.apiclient,
                name='global.allow.expose.host.hostname',
                value='true'):
            self.skipTest('global.allow.expose.host.hostname should be true. skipping')

        if not is_config_suitable(
                apiclient=self.apiclient,
                name='account.allow.expose.host.hostname',
                value='true'):
            self.skipTest('Account level account.allow.expose.host.hostname should be true. skipping')

        self.no_isolate = NetworkOffering.create(
            self.apiclient,
            self.services["isolated_network_offering"]
        )
        self.no_isolate.update(self.apiclient, state='Enabled')
        self.isolated_network = Network.create(
            self.apiclient,
            self.services["network"],
            networkofferingid=self.no_isolate.id,
            zoneid=self.zone.id,
            accountid="admin",
            domainid=1
        )
        self.cleanup.append(self.isolated_network)

        self.vm = VirtualMachine.create(
            self.apiclient,
            self.services["virtual_machine"],
            templateid=self.template.id,
            accountid="admin",
            domainid=1,
            serviceofferingid=self.service_offering.id,
            zoneid=self.zone.id,
            networkids=[self.isolated_network.id],
        )
        self.assertIsNotNone(
            self.vm,
            "VM creation failed in the isolated network"
        )

        host = self.migrate_VM(self.vm)

        self.cleanup.append(self.vm)

        ip_addr = self.vm.ipaddress
        self.debug("VM ip address = %s" % ip_addr)

        # Verify the retrieved ip address in listNICs API response
        self.list_nics(self.vm.id)
        vr_res = Router.list(
            self.apiclient,
            networkid=self.isolated_network.id,
            listAll=True
        )
        self.assertEqual(validateList(vr_res)[0], PASS, "List Routers returned invalid response")
        vr_ip = vr_res[0].guestipaddress
        ssh = self.vm.get_ssh_client(ipaddress=ip_addr)
        cmd = "curl http://%s/latest/hypervisor-host-name" % vr_ip
        res = ssh.execute(cmd)
        self.debug("Verifying hypervisor hostname details in the VR")
        self.assertEqual(
            str(res),
            host.name,
            "Failed to get the hypervisor host name from VR in isolated network"
        )
        # Reset configuration values to default values i.e., false
        Configurations.update(self.apiclient,
                              name="global.allow.expose.host.hostname",
                              value="false"
                              )

        # Update Account level setting
        Configurations.update(self.apiclient,
                              name="account.allow.expose.host.hostname",
                              value="false"
                              )

        return

