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

""" Component tests for user data, meta data, ssh keys
    and password reset functionality with
    ConfigDrive
"""

# Import Local Modules
from marvin.cloudstackAPI import (restartVPC)
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.base import (
    Account,
    createVlanIpRange,
    Configurations,
    FireWallRule,
    Host,
    listVlanIpRanges,
    Network,
    NetworkACL,
    NetworkACLList,
    NetworkOffering,
    NetworkServiceProvider,
    PublicIPAddress,
    Router,
    ServiceOffering,
    createSSHKeyPair,
    deleteSSHKeyPair,
    StaticNATRule,
    VirtualMachine,
    VPC,
    VpcOffering,
    Hypervisor, Template)
from marvin.lib.common import (
    get_domain,
    get_zone, get_test_template,
    is_config_suitable)
from marvin.lib.utils import random_gen

# Import System Modules
import base64
import os
import socket
import subprocess
import tempfile
import time
from contextlib import contextmanager
from nose.plugins.attrib import attr

VPC_SERVICES = 'Dhcp,StaticNat,SourceNat,NetworkACL,UserData,Dns'
ISO_SERVICES = 'Dhcp,SourceNat,StaticNat,UserData,Firewall,Dns'

NO_SUCH_FILE = "No such file or directory"


class MySSHKeyPair:
    """Manage SSH Key pairs"""

    def __init__(self, items):
        self.private_key_file = None
        self.__dict__.update(items)

    @classmethod
    def create(cls, apiclient, name=None, account=None,
               domainid=None, projectid=None):
        """Creates SSH keypair"""
        cmd = createSSHKeyPair.createSSHKeyPairCmd()
        cmd.name = name
        if account is not None:
            cmd.account = account
        if domainid is not None:
            cmd.domainid = domainid
        if projectid is not None:
            cmd.projectid = projectid
        return MySSHKeyPair(apiclient.createSSHKeyPair(cmd).__dict__)

    def delete(self, apiclient):
        """Delete SSH key pair"""
        cmd = deleteSSHKeyPair.deleteSSHKeyPairCmd()
        cmd.name = self.name
        cmd.account = self.account
        cmd.domainid = self.domainid
        apiclient.deleteSSHKeyPair(cmd)


class Services:
    """Test Add Remove Network Services
    """

    def __init__(self):
        self.services = {
            "test_templates": {
                "kvm": {
                    "name": "Centos-5.5-sshkey-and-configdrive",
                    "displaytext": "SSHkey and ConfigDrive enabled CentOS",
                    "format": "qcow2",
                    "hypervisor": "kvm",
                    "ostype": "CentOS 5.5 (64-bit)",
                    "url": "http://people.apache.org/~weizhou/centos55-sshkey-configdrive.qcow2.bz2",
                    "requireshvm": "False",
                    "ispublic": "True",
                    "isextractable": "True"
                }
            },
            "vpc_offering_configdrive": {
                "name": 'VPC offering ConfigDrive',
                "displaytext": 'VPC offering ConfigDrive',
                "supportedservices": VPC_SERVICES,
                "serviceProviderList": {
                    "Dhcp": "VpcVirtualRouter",
                    "StaticNat": "VpcVirtualRouter",
                    "SourceNat": "VpcVirtualRouter",
                    "NetworkACL": "VpcVirtualRouter",
                    "UserData": "ConfigDrive",
                    "Dns": "VpcVirtualRouter"
                }
            },
            "vpc_network_offering_configdrive": {
                "name": 'vpc_net_off_marvin_configdrive',
                "displaytext": 'vpc_net_off_marvin_configdrive',
                "guestiptype": 'Isolated',
                "supportedservices": VPC_SERVICES,
                "traffictype": 'GUEST',
                "availability": 'Optional',
                "useVpc": 'on',
                "ispersistent": 'True',
                "serviceProviderList": {
                    "Dhcp": "VpcVirtualRouter",
                    "StaticNat": "VpcVirtualRouter",
                    "SourceNat": "VpcVirtualRouter",
                    "NetworkACL": "VpcVirtualRouter",
                    "UserData": "ConfigDrive",
                    "Dns": "VpcVirtualRouter"
                }
            },
            "isolated_configdrive_network_offering": {
                "name": 'isolated_configdrive_net_off_marvin',
                "displaytext": 'isolated_configdrive_net_off_marvin',
                "guestiptype": 'Isolated',
                "supportedservices": ISO_SERVICES,
                "traffictype": 'GUEST',
                "availability": 'Optional',
                "tags": 'native',
                "serviceProviderList": {
                    "Dhcp": 'VirtualRouter',
                    "StaticNat": 'VirtualRouter',
                    "SourceNat": 'VirtualRouter',
                    "Firewall": 'VirtualRouter',
                    "UserData": 'ConfigDrive',
                    "Dns": 'VirtualRouter'
                }
            },
            "shared_network_config_drive_offering": {
                "name": 'shared_network_config_drive_offering',
                "displaytext": 'shared_network_config_drive_offering',
                "guestiptype": 'shared',
                "supportedservices": 'Dhcp,UserData',
                "traffictype": 'GUEST',
                "specifyVlan": "True",
                "specifyIpRanges": "True",
                "availability": 'Optional',
                "serviceProviderList": {
                    "Dhcp": "VirtualRouter",
                    "UserData": 'ConfigDrive'
                }
            },
            "publiciprange2": {
                "gateway": "10.219.1.1",
                "netmask": "255.255.255.0",
                "startip": "10.219.1.2",
                "endip": "10.219.1.5",
                "forvirtualnetwork": "false"
            },
            "acl": {
                "network_all_1": {
                    "name": "SharedNetwork-All-1",
                    "displaytext": "SharedNetwork-All-1",
                    "vlan": "4001",
                    "gateway": "10.200.100.1",
                    "netmask": "255.255.255.0",
                    "startip": "10.200.100.21",
                    "endip": "10.200.100.100",
                    "acltype": "Domain"
                },
                "network_all_2": {
                    "name": "SharedNetwork2-All-2",
                    "displaytext": "SharedNetwork2-All-2",
                    "vlan": "4002",
                    "gateway": "10.200.200.1",
                    "netmask": "255.255.255.0",
                    "startip": "10.200.200.21",
                    "endip": "10.200.200.100",
                    "acltype": "Domain"
                }
            }
        }


class ConfigDriveUtils:
    template = None

    class CreateResult:
        def __init__(self, success, offering=None, network=None, vpc=None):
            self.success = success
            self.network = network
            self.offering = offering
            self.vpc = vpc

    class PasswordTest:
        def __init__(self, vm=None, expect_pw=None):
            """
            :param vm: vm
            :param expect_pw: Is a password expected
            """
            self.presence = expect_pw
            self.password = None

            if vm:
                self.password = vm.password
                self.presence = True

            self.test_presence = self.presence is not None

        def __str__(self):
            if self.test_presence:
                return "PasswordTest(presence=%s, password=%s)" % \
                       (self.presence, self.password)
            else:
                return "NoPasswordTest()"

    def __init__(self):
        self.offering = None
        self.vpc = None
        self.vpc_acl_list = None
        self.vpc_acl_rule = None

    @contextmanager
    def stopped_vm(self, vm):
        was_running = (vm.state == VirtualMachine.RUNNING)

        if was_running:
            vm.stop(self.api_client)
            vm.state = VirtualMachine.STOPPED

        yield

        if was_running:
            vm.start(self.api_client)
            vm.state = VirtualMachine.RUNNING
            vm.ssh_client = None

    def update_template(self, **kwargs):
        """Updates value of the guest VM template's password enabled setting
        :param passwordenabled:
        :type passwordenabled: bool
        """
        self.debug("Updating value of guest VM template's password enabled "
                   "setting")
        if not isinstance(self.template, Template):
            self.template = Template(self.template.__dict__)

        Template.update(self.template, self.api_client, **kwargs)
        response = Template.list(self.api_client,
                                 templatefilter="all",
                                 id=self.template.id)
        self.template = Template(response[0].__dict__)
        self.debug("Updated guest VM template")

    def get_userdata_url(self, vm):
        """Returns user data URL for the given VM object"""
        self.debug("Getting user data url")
        nic = vm.nic[0]
        gateway = str(nic.gateway)
        self.debug("Gateway: " + gateway)
        user_data_url = 'curl "http://' + gateway + ':80/latest/user-data"'
        return user_data_url

    def generate_ssh_keys(self):
        """Generates ssh key pair

        Writes the private key into a temp file and returns the file name

        :returns: generated keypair
        :rtype: MySSHKeyPair
        """
        self.keypair = MySSHKeyPair.create(
            self.api_client,
            name=random_gen() + ".pem",
            account=self.account.user[0].account,
            domainid=self.account.domainid)

        self.cleanup.append(self.keypair)
        self.debug("Created keypair with name: %s" % self.keypair.name)
        self.debug("Writing the private key to local file")
        pkfile = tempfile.gettempdir() + os.sep + self.keypair.name
        self.keypair.private_key_file = pkfile
        self.tmp_files.append(pkfile)
        self.debug("File path: %s" % pkfile)
        with open(pkfile, "w+") as f:
            f.write(self.keypair.privatekey)
        os.chmod(pkfile, 0o400)

        return self.keypair

    def validate_acl_rule(self, fw_rule):
        pass

    def validate_vm_networking(self, vm):
        pass

    def validate_network_networking(self, network, vpc):
        pass

    def validate_shared_networking(self, network, vm):
        pass

    def validate_StaticNat_rule_For_VM(self, public_ip, network, vm):
        self.validate_PublicIPAddress(
            public_ip, network, static_nat=True, vm=vm)

    # =========================================================================
    # ---             Config Drive Validation helper methods                ---
    # =========================================================================

    def _mount_config_drive(self, ssh):
        """
        This method is to verify whether configdrive iso
        is attached to vm or not
        Returns mount path if config drive is attached else None
        """
        mountdir = "/root/iso"
        cmd = "blkid -t LABEL='config-2' " \
              "/dev/sr? /dev/hd? /dev/sd? /dev/xvd? -o device"
        tmp_cmd = [
            'bash -c "if [ ! -d {0} ]; then mkdir {0}; fi"'.format(mountdir),
            "umount %s" % mountdir]
        self.debug("Unmounting drive from %s" % mountdir)
        for tcmd in tmp_cmd:
            ssh.execute(tcmd)

        self.debug("Trying to find ConfigDrive device")
        configDrive = ssh.execute(cmd)
        if not configDrive:
            self.warn("ConfigDrive is not attached")
            return None

        res = ssh.execute("mount {} {}".format(str(configDrive[0]), mountdir))
        if str(res).lower().find("mounting read-only") > -1:
            self.debug("ConfigDrive iso is mounted at location %s" % mountdir)
            return mountdir
        else:
            return None

    def _get_config_drive_data(self, ssh, file, name, fail_on_missing=True):
        """Fetches the content of a file on the config drive

        :param ssh: SSH connection to the VM
        :param file: path to the file to fetch
        :param name: description of the file
        :param fail_on_missing:
                 whether the test should fail if the file is missing
        :type ssh: marvin.sshClient.SshClient
        :type file: str
        :type name: str
        :type fail_on_missing: bool
        :returns: the content of the file
        :rtype: str
        """
        cmd = "cat %s" % file
        res = ssh.execute(cmd)
        content = '\n'.join(res)

        if fail_on_missing and NO_SUCH_FILE in content:
            self.debug("{} is not found".format(name))
            self.fail("{} is not found".format(name))

        return content

    def _verify_config_drive_data(self, ssh, file, expected_content, name):
        """Verifies that the file contains the expected content

        :param ssh: SSH connection to the VM
        :param file: path to the file to verify
        :param expected_content:
        :param name:
        :type ssh: marvin.sshClient.SshClient
        :type file: str
        :type expected_content: str
        :type name: str
        """
        actual_content = self._get_config_drive_data(ssh, file, name)

        self.debug("Expected {}: {}".format(name, expected_content))
        self.debug("Actual {}: {}".format(name, actual_content))

        self.assertEqual(expected_content, actual_content,
                         'Userdata found: %s is not equal to expected: %s'
                         % (actual_content, expected_content))

    def _verify_userdata(self, ssh, mount_path, userdata):
        """
        verify Userdata

        :param ssh: SSH connection to the VM
        :param mount_path: mount point of the config drive
        :param userdata: Expected userdata
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        :type userdata: str
        """
        self._verify_config_drive_data(
            ssh,
            mount_path + "/cloudstack/userdata/user_data.txt",
            userdata,
            "userdata (ACS)"
        )

    def _verify_openstack_userdata(self, ssh, mount_path, userdata):
        """
        verify Userdata in Openstack format

        :param ssh: SSH connection to the VM
        :param mount_path: mount point of the config drive
        :param userdata: Expected userdata
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        :type userdata: str
        """
        self._verify_config_drive_data(
            ssh,
            mount_path + "/openstack/latest/user_data",
            userdata,
            "userdata (Openstack)"
        )

    def _verifyPassword(self, ssh, mount_path, password_test):
        """
        Verify Password
        :param ssh: SSH connection to the VM
        :param mount_path: Mount path of the config drive disk
        :param password_test: expected Password behavior
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        :type password_test: ConfigDriveUtils.PasswordTest
        """

        if not password_test.test_presence:
            return

        if password_test.password is not None:
            self.debug("Expected VM password is %s " % password_test.password)

        password_file = mount_path + "/cloudstack/password/vm_password.txt"
        vmpassword = self._get_config_drive_data(ssh, password_file,
                                                 "ConfigDrive password",
                                                 fail_on_missing=False)

        password_found = NO_SUCH_FILE not in vmpassword

        self.assertEqual(password_found, password_test.presence,
                         "Expected is that password is present: %s "
                         " but found is: %s"
                         % (password_test.presence, password_found))

        if password_test.password is not None:
            self.debug("ConfigDrive password is %s " % vmpassword)
            self.debug("Expected Password for vm is %s" %
                       password_test.password)
            self.assertTrue(password_test.password in vmpassword,
                            "Password value test failed, expected %s, was %s" %
                            (password_test.password, vmpassword))

    def _verify_ssh_key(self, ssh, mount_path, ssh_key):
        """
        Verify SSH Key
        :param ssh: SSH connection to the VM
        :param mount_path: Mount path of the config drive disk
        :param ssh_key: expected SSH key
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        :type ssh_key: MySSHKeyPair
        """

        self.debug("Fingerprint of Expected sshkey %s is %s " %
                   (ssh_key.name, ssh_key.fingerprint))
        publicKey_file = mount_path + "/cloudstack/metadata/public-keys.txt"
        cmd = "ssh-keygen -lf %s | cut -f2 -d' '" % publicKey_file
        res = ssh.execute(cmd)
        vmsshkey = str(res[0])

        self.debug("ConfigDrive ssh key is %s " % vmsshkey)

        if NO_SUCH_FILE in vmsshkey:
            self.fail("SSH keyfile is not found")

        self.assertEqual(
            vmsshkey,
            ssh_key.fingerprint,
            "Fingerprint of authorized key does not match ssh key fingerprint"
        )

    def _verify_metadata(self, vm, ssh, mount_path):
        """
        verify metadata files in CloudStack format

        :param vm: the VM
        :param ssh: SSH connection to the VM
        :param mount_path: mount point of the config drive
        :type vm: VirtualMachine
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        """

        metadata_dir = mount_path + "/cloudstack/metadata/"
        vm_files = ["availability-zone.txt",
                    "service-offering.txt",
                    "instance-id.txt",
                    "vm-id.txt",
                    "local-hostname.txt",
                    "local-ipv4.txt",
                    "public-ipv4.txt"]
        # Verify hostname if the appropriate settings are true
        configs = Configurations.list(
            self.api_client,
            name="global.allow.expose.host.hostname",
            listall=True
        )
        exposeHypevisorHostnameGS = configs[0].value

        configs = Configurations.list(
            self.api_client,
            name="account.allow.expose.host.hostname",
            listall=True
        )

        exposeHypevisorHostnameAcc = configs[0].value

        if exposeHypevisorHostnameGS == 'true' and exposeHypevisorHostnameAcc == 'true':
            vm_files.append("hypervisor-host-name.txt")

        configs = Configurations.list(
            self.api_client,
            name="metadata.allow.expose.domain",
            listall=True
        )

        exposeDomain = configs[0].value

        if exposeDomain == 'true':
            vm_files.append("cloud-domain.txt")
            vm_files.append("cloud-domain-id.txt")

        def get_name(vm_file):
            return "{} metadata".format(
                vm_file.split('.'[-1].replace('-', ' '))
            )

        metadata = {vm_file:
                        self._get_config_drive_data(ssh,
                                                    metadata_dir + vm_file,
                                                    get_name(vm_file))
                    for vm_file in vm_files}

        self.assertEqual(
            str(metadata["availability-zone.txt"]),
            self.zone.name,
            "Zone name inside metadata does not match with the zone"
        )
        self.assertEqual(
            str(metadata["local-hostname.txt"]),
            vm.name,
            "vm name inside metadata does not match with the "
            "instance name"
        )
        self.assertEqual(
            str(metadata["vm-id.txt"]),
            vm.id,
            "vm name inside metadata does not match with the "
            "instance name"
        )
        self.assertEqual(
            str(metadata["instance-id.txt"]),
            vm.id,
            "vm name inside metadata does not match with the "
            "instance name"
        )
        self.assertEqual(
            str(metadata["service-offering.txt"]),
            vm.serviceofferingname,
            "Service offering inside metadata does not match "
            "with the instance offering"
        )

        if exposeHypevisorHostnameGS == 'true' and exposeHypevisorHostnameAcc == 'true':
            hostname = vm.hostname

            self.debug("Verifying hypervisor hostname of the VM: %s" % vm.name)
            self.assertEqual(
                str(metadata["hypervisor-host-name.txt"]),
                hostname,
                "Hostname in the metadata file does not match the host "
                "on which the VM is spawned"
            )

        if exposeDomain == 'true':
            self.assertEqual(
                str(metadata["cloud-domain-id.txt"]),
                self.domain.id,
                "Domain name in the metadata file does not match expected"
            )
            self.assertEqual(
                str(metadata["cloud-domain.txt"]),
                self.domain.name,
                "Domain name in the metadata file does not match expected"
            )

        return

    def _verify_openstack_metadata(self, ssh, mount_path):
        """
        verify existence of metadata and user data files
        in OpenStack format

        :param ssh: SSH connection to the VM
        :param mount_path: mount point of the config drive
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        """
        openstackdata_dir = mount_path + "/openstack/latest/"
        openstackdata_files = ["meta_data.json",
                               "vendor_data.json",
                               "network_data.json"]
        for file in openstackdata_files:
            res = ssh.execute("cat %s" % openstackdata_dir + file)
            if NO_SUCH_FILE in res[0]:
                self.fail("{} file not found in vm openstack".format(file))

    def _umount_config_drive(self, ssh, mount_path):
        """unmount config drive inside guest vm

        :param ssh: SSH connection to the VM
        :param mount_path: mount point of the config drive
        :type ssh: marvin.sshClient.SshClient
        :type mount_path: str
        """
        ssh.execute("umount -d %s" % mount_path)
        # Give the VM time to unlock the iso device
        time.sleep(0.5)
        # Verify umount
        result = ssh.execute("ls %s" % mount_path)
        self.assertTrue(len(result) == 0,
                        "After umount directory should be empty "
                        "but contains: %s" % result)

    # =========================================================================
    # ---                    Gherkin style helper methods                   ---
    # =========================================================================

    def given_template_password_enabled_is(self, new_state):
        """Updates value of the guest VM template's password enabled setting
        :param new_state:
        :type new_state: bool
        """
        orig_state = self.template.passwordenabled
        self.debug("Updating guest VM template to password enabled "
                   "from %s to %s" % (orig_state, new_state))
        self.update_template(passwordenabled=new_state)
        self.assertEqual(self.template.passwordenabled, new_state,
                         "Guest VM template is not password enabled")
        return orig_state

    def given_config_drive_provider_is(self, new_state):
        """
        Enables or disables the ConfigDrive Service Provider

        :param new_state: "Enabled" | "Disabled"
        :type new_state: str
        :return: original state
        :rtype: str
        """
        self.debug("Updating Service Provider ConfigDrive to %s" % new_state)
        configdriveprovider = self.get_configdrive_provider()
        orig_state = configdriveprovider.state
        NetworkServiceProvider.update(self.api_client,
                                      configdriveprovider.id,
                                      state=new_state)
        self.validate_NetworkServiceProvider("ConfigDrive", state=new_state)
        return orig_state

    def given_a_network_offering(self, offering_name):
        self.offering = self.create_NetworkOffering(self._get_test_data(
            offering_name))

    def given_a_network_offering_with_configdrive(self):
        self.given_a_network_offering(self.get_network_offering_name())

    def given_a_network_offering_for_vpc_with_configdrive(self):
        self.given_a_network_offering(self.get_network_offering_name_for_vpc())

    def given_a_vpc_with_offering(self, offering_name):
        self.given_config_drive_provider_is("Enabled")
        create_vpc = self.verify_vpc_creation(
            offering_name=offering_name)
        self.assertTrue(create_vpc.success,
                        "Vpc found success = %s, expected success = %s"
                        % (str(create_vpc.success), 'True'))
        self.vpc_acl_list = self.create_NetworkAclList(
            name="acl", description="acl", vpc=create_vpc.vpc)
        self.vpc_acl_rule = self.create_NetworkAclRule(
            self.test_data["ingress_rule"], acl_list=self.vpc_acl_list)

        self.vpc = create_vpc.vpc

    def given_a_vpc(self):
        self.given_a_vpc_with_offering(self.get_vpc_offering_name())

    def when_I_create_a_network_with_that_offering(self, gateway='10.1.1.1'):
        return self.verify_network_creation(
            offering=self.offering,
            gateway=gateway)

    def when_I_create_a_vpc_tier_with_that_offering(self, gateway='10.1.1.1'):
        return self.verify_network_creation(
            offering=self.offering,
            gateway=gateway,
            vpc=self.vpc,
            acl_list=self.vpc_acl_list)

    def when_I_restart_the_vpc_with(self, cleanup=True):
        self.restart_Vpc(self.vpc, cleanup=cleanup)
        self.validate_vpc(self.vpc, state="Enabled")

    def when_I_restart_the_network_with(self, network, cleanup):
        network.restart(self.api_client, cleanup=cleanup)
        self.validate_Network(network, state="Implemented")

    def when_I_deploy_a_vm(self, networks, acl_item=None,
                           vpc=None, keypair=None):

        test_data = self.test_data["virtual_machine_userdata"]

        vm = self.create_VM(
            networks,
            testdata=test_data,
            keypair=keypair)

        # Check VM
        self.check_VM_state(vm, state="Running")
        self.validate_vm_networking(vm)

        if keypair and vm.passwordenabled:
            self._decrypt_password(vm)

        vm.key_pair = self.keypair if keypair else None
        vm.user_data = test_data["userdata"]
        vm.password_test = self.PasswordTest(vm=vm) \
            if vm.passwordenabled \
            else self.PasswordTest(expect_pw=False)

        # Check networks
        network_list = networks \
            if hasattr(networks, "__iter__") \
            else [networks]

        for network in network_list:
            self.validate_Network(network, state="Implemented")
            if network.type == "Shared":
                self.validate_shared_networking(network, self.vpc)
            else:
                self.validate_network_networking(network, self.vpc)

        if self.vpc_acl_rule is not None:
            self.validate_acl_rule(self.vpc_acl_rule)

        return vm

    def when_I_deploy_a_vm_with_keypair_in(self, network):
        return self.when_I_deploy_a_vm(network,
                                       keypair=self.keypair.name)

    def when_I_create_a_static_nat_ip_to(self, vm, network, public_ip=None):
        """
        Creates and verifies (Ingress) firewall rule
        with a Static NAT rule enabled public IP
        :type vm: VirtualMachine
        :type network: Network
        :type public_ip: PublicIPAddress
        :rtype: PublicIPAddress
        """

        if not public_ip:
            public_ip = self.acquire_PublicIPAddress(network, vpc=self.vpc)

        self.debug("Creating and verifying firewall rule")
        self.create_StaticNatRule_For_VM(vm, public_ip, network)

        # Verification

        # self.validate_StaticNat_rule_For_VM(public_ip, network, vm)

        if not self.vpc:
            fw_rule = self.create_FirewallRule(public_ip,
                                               self.test_data["ingress_rule"])
            self.validate_acl_rule(fw_rule)
            self.debug("Successfully created and verified firewall rule")

        self.cleanup.append(public_ip)

        return public_ip

    def then_creating_a_network_with_that_offering_fails(self):
        create_network = self.verify_network_creation(
            offering=self.offering,
            gateway='10.6.6.6')
        self.assertFalse(create_network.success,
                         'Network found success = %s, expected success =%s'
                         % (str(create_network.success), 'False'))

    def then_creating_a_vpc_tier_with_that_offering_fails(self):
        create_network = self.verify_network_creation(
            offering=self.offering,
            gateway='10.6.6.6',
            vpc=self.vpc,
            acl_list=self.vpc_acl_list)
        self.assertFalse(create_network.success,
                         'Create Tier success = %s, expected success =%s'
                         % (str(create_network.success), 'False'))

    def then_the_network_has(self, network_result, state):
        self.validate_Network(network_result.network, state=state)

    def then_the_network_is_successfully_created(self, network):
        self.assertTrue(network.success,
                        'Network found success = %s, expected success = %s'
                        % (str(network.success), 'True'))

    def then_vr_is_as_expected(self, network):
        self.check_Router_state(network=network, state="Running")

    def then_config_drive_is_as_expected(self, vm,
                                         public_ip,
                                         metadata=False,
                                         reconnect=True):
        """Verify Config Drive Content

        :param vm: Virtual Machine
        :param public_ip: public IP
        :param metadata: whether to verify metadata
        :param reconnect: recreate SSH Connection
        :type vm: VirtualMachine
        :type public_ip: PublicIPAddress
        :type metadata: bool
        :type reconnect: bool
        """

        if self.isSimulator:
            self.debug("Simulator Environment: "
                       "Skipping Config Drive content verification")
            return

        self.debug("SSHing into the VM %s" % vm.name)

        ssh = self.ssh_into_VM(vm, public_ip, reconnect=reconnect, keypair=vm.key_pair)

        d = {x.name: x for x in ssh.logger.handlers}
        ssh.logger.handlers = list(d.values())

        mount_path = self._mount_config_drive(ssh)
        self.assertIsNotNone(mount_path,
                             'ConfigdriveIso is not attached to vm')
        if metadata:
            self.debug("Verifying metadata for vm: %s" % vm.name)
            self._verify_metadata(vm, ssh, mount_path)
            self.debug("Verifying openstackdata for vm: %s" % vm.name)
            self._verify_openstack_metadata(ssh, mount_path)

        if hasattr(vm, "user_data") and vm.user_data is not None:
            self.debug("Verifying userdata for vm: %s" % vm.name)
            self._verify_userdata(ssh, mount_path, vm.user_data)
            self._verify_openstack_userdata(ssh, mount_path, vm.user_data)

        if hasattr(vm, "password_test") \
                and vm.password_test is not None \
                and vm.password_test.test_presence:
            self.debug("Verifying password for vm: %s" % vm.name)
            self._verifyPassword(ssh, mount_path, vm.password_test)

        if hasattr(vm, "key_pair") and vm.key_pair is not None:
            self.debug("Verifying sshkey for vm: %s" % vm.name)
            self._verify_ssh_key(ssh, mount_path, vm.key_pair)

        self._umount_config_drive(ssh, mount_path)

    # =========================================================================

    def _get_test_data(self, key):
        return self.test_data[key]

    def get_vpc_offering_name(self):
        return "vpc_offering_configdrive"

    def get_network_offering_name(self):
        return "isolated_configdrive_network_offering"

    def get_network_offering_name_for_vpc(self):
        return "vpc_network_offering_configdrive"

    def get_configdrive_provider(self):
        return NetworkServiceProvider.list(
            self.api_client,
            name="ConfigDrive")[0]

    def verify_network_creation(self, offering=None,
                                offering_name=None,
                                gateway=None,
                                vpc=None, acl_list=None, testdata=None):
        """
        Creates a network

        :param offering: Network Offering
        :type offering: NetworkOffering
        :param offering_name: Offering name
        :type offering_name: Optional[str]
        :param gateway: gateway
        :type gateway: str
        :param vpc: in case of a VPC tier, the parent VPC
        :type vpc: VPC
        :param acl_list: in case of a VPC tier, the acl list
        :type acl_list: NetworkACLList
        :param testdata: Test data
        :type testdata: dict
        :return: Network Creation Result
        :rtype: ConfigDriveUtils.CreateResult
        """
        if offering is None:
            self.debug("Creating network offering...")
            offering = self.create_NetworkOffering(
                self._get_test_data(offering_name))
            self.validate_NetworkOffering(offering, state="Enabled")
        try:
            network = self.create_Network(offering,
                                          gateway=gateway,
                                          vpc=vpc,
                                          acl_list=acl_list,
                                          testdata=testdata)
            return self.CreateResult(True, offering=offering, network=network)
        except Exception as e:
            self.debug("Exception: %s" % e)
            return self.CreateResult(False, offering=offering)

    def verify_vpc_creation(self, offering=None, offering_name=None):
        """
        Creates a VPC

        :param offering: VPC Offering
        :type offering: VpcOffering
        :param offering_name: Offering name
        :type offering_name: Optional[str]
        :return: VPC Creation Result
        :rtype: CreateResult
        """
        if offering is None:
            self.debug("Creating VPC offering...")
            offering = self.create_VpcOffering(
                self._get_test_data(offering_name))
            self.validate_VpcOffering(offering, state="Enabled")
        try:
            vpc = self.create_vpc(offering, cidr='10.1.0.0/16')
            self.validate_vpc(vpc, state="Enabled")
            return self.CreateResult(True, offering=offering, vpc=vpc)
        except Exception as e:
            self.debug("Exception: %s" % e)
            return self.CreateResult(False, offering=offering)

    def _find_nic(self, vm, network):
        vm = VirtualMachine.list(self.api_client, id=vm.id)[0]
        return next(nic for nic in vm.nic if nic.networkid == network.id)

    def get_public_shared_ip(self, vm, network):
        nic = self._find_nic(vm, network)
        return PublicIPAddress({"ipaddress": nic})

    def plug_nic(self, vm, network):
        vm.add_nic(self.api_client, network.id)
        self.debug("Added NIC in VM with ID - %s and network with ID - %s"
                   % (vm.id, network.id))
        vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)

    def unplug_nic(self, vm, network):
        nic = self._find_nic(vm, network)
        vm.remove_nic(self.api_client, nic.id)
        self.debug("Removed NIC with ID - %s in VM with ID - %s and "
                   "network with ID - %s" % (nic.id, vm.id, network.id))

    def update_default_nic(self, vm, network):
        nic = self._find_nic(vm, network)
        vm.update_default_nic(self.api_client, nic.id)
        self.debug("Removed NIC with ID - %s in VM with ID - %s and "
                   "network with ID - %s" % (nic.id, vm.id, network.id))

    def when_I_update_userdata(self, vm, new_user_data):
        """Updates the user data of a VM

        :param public_ip: Public ip of the VM
        :param vm: the Virtual Machine
        :param new_user_data: UserData to set
        :type public_ip: PublicIPAddress
        :type vm: VirtualMachine
        :type new_user_data: str
        :returns: User data in base64 format
        :rtype: str
        """
        self.debug("Updating userdata for VM - %s" % vm.name)
        updated_user_data = base64.encodebytes(new_user_data.encode()).decode()
        with self.stopped_vm(vm):
            vm.update(self.api_client, userdata=updated_user_data)

        vm.user_data = new_user_data
        if vm.state == VirtualMachine.RUNNING:
            vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)

    def update_and_validate_userdata(self, vm, new_user_data, public_ip=None,
                                     **kwargs):
        """Updates the user data of a VM

        :param public_ip: Public ip of the VM
        :param vm: the Virtual Machine
        :param new_user_data: UserData to set
        :type public_ip: PublicIPAddress
        :type vm: VirtualMachine
        :type new_user_data: str
        :returns: User data in base64 format
        :rtype: str
        """

        self.when_I_update_userdata(vm, new_user_data)
        self.then_config_drive_is_as_expected(vm, public_ip, **kwargs)

    def when_I_reset_the_password(self, vm):
        """Resets the password of a VM

        :param vm: the Virtual Machine
        :type vm: VirtualMachine
        :returns: The new password
        :rtype: str
        """

        self.debug("Resetting password for VM - %s" % vm.name)
        with self.stopped_vm(vm):
            vm.password = vm.resetPassword(self.api_client)

        self.debug("Password reset to - %s" % vm.password)
        self.debug("VM - %s password - %s !" %
                   (vm.name, vm.password))

        vm.password_test = ConfigDriveUtils.PasswordTest(vm=vm)

        return vm.password

    def stop_and_start_vm(self, vm):
        self.debug("+++ Verify userdata after stopstartVM - %s" % vm.name)
        with self.stopped_vm(vm):
            pass

        vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)

    def delete_and_recover_vm(self, vm):
        self.debug("+++ Verify userdata after VM recover- %s" % vm.name)
        vm.delete(self.api_client, expunge=False)

        self.debug("Recover VM - %s" % vm.name)
        vm.recover(self.api_client)
        vm.start(self.api_client)
        vm.state = VirtualMachine.RUNNING

        vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)

    def wait_until_done(self, thread_list, name):
        for aThread in thread_list:
            self.debug("[Concurrency]Join %s for vm %s" % (name,
                                                           aThread.get_vm()))
            aThread.join()

    def update_and_validate_sshkeypair(self, vm, public_ip=None):
        """

        :type vm: VirtualMachine
        """

        self.generate_ssh_keys()

        with self.stopped_vm(vm):
            vm_new_ssh = vm.resetSshKey(self.api_client,
                                        keypair=self.keypair.name,
                                        account=self.account.user[0].account,
                                        domainid=self.account.domainid)

        self.debug("Sshkey reset to - %s" % self.keypair.name)

        vm.details = vm_new_ssh.details

        # reset SSH key also removes the password (see https://github.com/apache/cloudstack/pull/4819)
        vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)
        vm.key_pair = self.keypair

        if public_ip:
            self.then_config_drive_is_as_expected(vm, public_ip, metadata=True)

    def _decrypt_password(self, vm):
        """Decrypt VM password

        the new password is available in VM detail,
        named "Encrypted.Password".
        It is encrypted using the SSH Public Key,
        and thus can be decrypted using the SSH Private Key

        :type vm: VirtualMachine
        """
        password_ = vm.details['Encrypted.Password']
        if password_ is not None:
            from base64 import b64decode
            try:
                from Crypto.PublicKey import RSA
                from Crypto.Cipher import PKCS1_v1_5
                with open(self.keypair.private_key_file, "r") as pkfile:
                    key = RSA.importKey(pkfile.read())
                    cipher = PKCS1_v1_5.new(key)
                new_password = cipher.decrypt(b64decode(password_), None)
                if new_password:
                    vm.password = new_password.decode()
                else:
                    self.fail("Failed to decrypt new password")
            except ImportError:
                # No pycrypto, fallback to openssl
                cmd = ["echo " + password_ +
                       " | base64 -d"
                       " | openssl rsautl -decrypt -inkey "
                       + self.keypair.private_key_file
                       + " 2> /dev/null"
                       ]

                new_password = subprocess.check_output(cmd, shell=True)
                self.debug("Decrypted password %s" % new_password)
                if new_password:
                    vm.password = new_password
                else:
                    self.fail("Failed to decrypt new password")

    def add_subnet_to_shared_network_and_verify(self, network, services):
        """verify required nic is present in the VM"""

        self.debug("Going to add new ip range in shared network %s" %
                   network.name)
        cmd = createVlanIpRange.createVlanIpRangeCmd()
        cmd.networkid = network.id
        cmd.gateway = services["gateway"]
        cmd.netmask = services["netmask"]
        cmd.startip = services["startip"]
        cmd.endip = services["endip"]
        cmd.forVirtualNetwork = services["forvirtualnetwork"]
        addedsubnet = self.api_client.createVlanIpRange(cmd)

        self.debug("verify above iprange is successfully added in shared "
                   "network %s or not" % network.name)

        cmd1 = listVlanIpRanges.listVlanIpRangesCmd()
        cmd1.networkid = network.id
        cmd1.id = addedsubnet.vlan.id

        allsubnets = self.api_client.listVlanIpRanges(cmd1)
        self.assertEqual(
            allsubnets[0].id,
            addedsubnet.vlan.id,
            "Check New subnet is successfully added to the shared Network"
        )
        return addedsubnet

    def ssh_into_VM(self, vm, public_ip, reconnect=True, keypair=None):
        pass

    def delete(self, obj, **kwargs):
        if isinstance(obj, VirtualMachine) and "expunge" not in kwargs:
            kwargs["expunge"] = True

        obj.delete(self.api_client, **kwargs)

        if obj in self.cleanup:
            self.cleanup.remove(obj)


class TestConfigDrive(cloudstackTestCase, ConfigDriveUtils):
    """Test user data and password reset functionality
    using configDrive
    """

    def __init__(self, methodName='runTest'):
        super(TestConfigDrive, self).__init__(methodName)
        ConfigDriveUtils.__init__(self)

    @classmethod
    def setUpClass(cls):
        # We want to fail quicker, if it's a failure
        socket.setdefaulttimeout(60)

        test_client = super(TestConfigDrive, cls).getClsTestClient()
        cls.api_client = test_client.getApiClient()
        cls.db_client = test_client.getDbConnection()
        cls.test_data = test_client.getParsedTestDataConfig()
        cls.test_data.update(Services().services)
        cls._cleanup = []

        # Get Zone, Domain and templates
        cls.zone = get_zone(cls.api_client)
        cls.domain = get_domain(cls.api_client)

        cls.hypervisor = cls.testClient.getHypervisorInfo()
        cls.template = get_test_template(cls.api_client,
                                         cls.zone.id,
                                         cls.hypervisor,
                                         cls.test_data["test_templates"])
        cls.test_data["virtual_machine"]["zoneid"] = cls.zone.id
        cls.test_data["virtual_machine"]["template"] = cls.template.id

        # Create service offering
        cls.service_offering = ServiceOffering.create(
            cls.api_client,
            cls.test_data["service_offering"])
        cls._cleanup.append(cls.service_offering)

        hypervisors = Hypervisor.list(cls.api_client, zoneid=cls.zone.id)
        cls.isSimulator = any(h.name == "Simulator" for h in hypervisors)
        return

    def setUp(self):
        # Create an account
        self.cleanup = []
        self.account = Account.create(self.api_client,
                                      self.test_data["account"],
                                      admin=True,
                                      domainid=self.domain.id
                                      )
        self.cleanup.append(self.account)
        self.tmp_files = []
        self.generate_ssh_keys()
        return

    @classmethod
    def tearDownClass(cls):
        super(TestConfigDrive, cls).tearDownClass()

    def tearDown(self):
        super(TestConfigDrive,self).tearDown()

        for tmp_file in self.tmp_files:
            os.remove(tmp_file)
        self.debug("Cleanup complete!")

    # create_StaticNatRule_For_VM - Creates Static NAT rule on the given
    # public IP for the given VM in the given network
    def create_StaticNatRule_For_VM(self, vm, public_ip, network,
                                    vmguestip=None):
        self.debug("Enabling Static NAT rule on public IP - %s for VM with ID "
                   "- %s in network with ID - %s" %
                   (public_ip.ipaddress.ipaddress, vm.id, network.id))
        static_nat_rule = StaticNATRule.enable(
            self.api_client,
            ipaddressid=public_ip.ipaddress.id,
            virtualmachineid=vm.id,
            networkid=network.id,
            vmguestip=vmguestip
        )
        self.debug("Static NAT rule enabled on public IP - %s for VM with ID "
                   "- %s in network with ID - %s" %
                   (public_ip.ipaddress.ipaddress, vm.id, network.id))
        return static_nat_rule

    def create_FirewallRule(self, public_ip, rule=None):
        """Creates an Ingress Firewall Rule on the given public IP
           to allow traffic to a VM in an isolated network
        :param public_ip: Static NAT rule enabled public IP
        :param rule: (optional) Rule to add, defaults to test_data
        :type public_ip: PublicIPAddress
        """
        if not rule:
            rule = self.test_data["ingress_rule"]
        self.debug("Adding an (Ingress) Firewall rule to make Guest VMs "
                   "accessible through Static NAT rule - %s" % rule)
        return FireWallRule.create(self.api_client,
                                   ipaddressid=public_ip.ipaddress.id,
                                   protocol=rule["protocol"],
                                   cidrlist=rule["cidrlist"],
                                   startport=rule["startport"],
                                   endport=rule["endport"]
                                   )

    # validate_NetworkServiceProvider - Validates the given Network Service
    # Provider in the Physical Network, matches the given provider
    # name and state against the list of providers fetched
    def validate_NetworkServiceProvider(self, provider_name, state=None):
        """Validates the Network Service Provider in the Physical
        Network"""
        self.debug("Validating the creation and state of Network Service "
                   "Provider - %s" % provider_name)
        providers = NetworkServiceProvider.list(
            self.api_client,
            name=provider_name
        )
        self.assertEqual(isinstance(providers, list), True,
                         "List Network Service Provider should return a "
                         "valid list"
                         )
        self.assertEqual(provider_name, providers[0].name,
                         "Name of the Network Service Provider should match "
                         "with the returned list data"
                         )
        if state:
            self.assertEqual(providers[0].state, state,
                             "Network Service Provider state should be '%s'" %
                             state
                             )
        self.debug("Successfully validated the creation and state of Network "
                   "Service Provider - %s" % provider_name)

    # validate_PublicIPAddress - Validates if the given public IP address is in
    # the expected state form the list of fetched public IP addresses
    def validate_PublicIPAddress(self, public_ip, network, static_nat=False,
                                 vm=None):
        """Validates the Public IP Address"""
        self.debug("Validating the assignment and state of public IP address "
                   "- %s" % public_ip.ipaddress.ipaddress)
        public_ips = PublicIPAddress.list(self.api_client,
                                          id=public_ip.ipaddress.id,
                                          networkid=network.id,
                                          isstaticnat=static_nat,
                                          listall=True
                                          )
        self.debug("PUBLIC IP = " + public_ips[0])
        self.assertEqual(isinstance(public_ips, list), True,
                         "List public IP for network should return a "
                         "valid list"
                         )
        self.assertEqual(public_ips[0].ipaddress,
                         public_ip.ipaddress.ipaddress,
                         "List public IP for network should list the assigned "
                         "public IP address"
                         )
        self.assertEqual(public_ips[0].state, "Allocated",
                         "Assigned public IP is not in the allocated state"
                         )
        if static_nat and vm:
            self.assertEqual(public_ips[0].virtualmachineid, vm.id,
                             "Static NAT rule is not enabled for the VM on "
                             "the assigned public IP"
                             )
        self.debug("Successfully validated the assignment and state of public "
                   "IP address - %s" % public_ip.ipaddress.ipaddress)

    # create_NetworkOffering - Creates Network offering
    def create_NetworkOffering(self, net_offering, suffix=None,
                               conserve_mode=False):
        self.debug("Creating Network offering")
        if suffix:
            net_offering["name"] = "NET_OFF-" + str(suffix)
        nw_off = NetworkOffering.create(self.api_client,
                                        net_offering,
                                        conservemode=conserve_mode
                                        )
        # Enable Network offering
        nw_off.update(self.api_client, state="Enabled")
        self.debug("Created and Enabled Network offering")
        self.cleanup.append(nw_off)
        return nw_off

    # validate_NetworkOffering - Validates the given Network offering, matches
    # the given network offering name and state against the list of network
    # offerings fetched
    def validate_NetworkOffering(self, net_offering, state=None):
        """Validates the Network offering.
        :param net_offering: Network Offering to validate
        :param state: expected state
        :type net_offering: NetworkOffering
        :type state: str
        """
        self.debug("Validating the creation and state of Network offering - %s"
                   % net_offering.name)
        net_offs = NetworkOffering.list(self.api_client,
                                        id=net_offering.id
                                        )
        self.assertEqual(isinstance(net_offs, list), True,
                         "List Network offering should return a valid list"
                         )
        self.assertEqual(net_offering.name, net_offs[0].name,
                         "Name of the Network offering should match with the "
                         "returned list data"
                         )
        if state:
            self.assertEqual(net_offs[0].state, state,
                             "Network offering state should be '%s'" % state
                             )
        self.debug("Successfully validated the creation and state of Network "
                   "offering - %s" % net_offering.name)

    # create_Network - Creates network with the given Network offering
    def create_Network(self, nw_off, gateway="10.1.1.1",
                       netmask="255.255.255.0", vpc=None, acl_list=None,
                       testdata=None, account=None):
        if not account:
            account = self.account
        self.debug("Creating a network in the account - %s" % account.name)
        if not testdata:
            testdata = self.test_data["network"]
            testdata["name"] = "TestNet-" + gateway + "-" + str(nw_off.name)
            testdata["displaytext"] = "Test Network"
            testdata["gateway"] = gateway
            testdata["netmask"] = netmask
        network = Network.create(self.api_client,
                                 testdata,
                                 accountid=account.name,
                                 domainid=account.domainid,
                                 networkofferingid=nw_off.id,
                                 zoneid=self.zone.id,
                                 vpcid=vpc.id if vpc
                                 else self.vpc.id if self.vpc
                                 else None,
                                 aclid=acl_list.id if acl_list else None
                                 )
        self.debug("Created network with ID - %s" % network.id)
        self.cleanup.append(network)
        return network

    # create_VpcOffering - Creates VPC offering
    def create_VpcOffering(self, vpc_offering, suffix=None):
        self.debug("Creating VPC offering")
        if suffix:
            vpc_offering["name"] = "VPC_OFF-" + str(suffix)
        vpc_off = VpcOffering.create(self.api_client,
                                     vpc_offering
                                     )
        # Enable VPC offering
        vpc_off.update(self.api_client, state="Enabled")
        self.debug("Created and Enabled VPC offering")
        self.cleanup.append(vpc_off)
        return vpc_off

    # create_Vpc - Creates VPC with the given VPC offering
    def create_vpc(self, vpc_offering, cidr='10.1.0.0/16', testdata=None,
                   account=None, networkDomain=None):
        if not account:
            account = self.account
        self.debug("Creating a VPC in the account - %s" % account.name)
        if not testdata:
            testdata = self.test_data["vpc"]
            testdata["name"] = "TestVPC-" + cidr + "-" + str(vpc_offering.name)
            testdata["displaytext"] = "Test VPC"
            testdata["cidr"] = cidr
        vpc = VPC.create(self.api_client,
                         testdata,
                         vpcofferingid=vpc_offering.id,
                         zoneid=self.zone.id,
                         account=account.name,
                         domainid=account.domainid,
                         networkDomain=networkDomain
                         )
        self.debug("Created VPC with ID - %s" % vpc.id)
        self.cleanup.append(vpc)
        return vpc

    # validate_VpcOffering - Validates the given VPC offering, matches the
    # given VPC offering name and state against the list of VPC offerings
    # fetched
    def validate_VpcOffering(self, vpc_offering, state=None):
        """Validates the VPC offering"""
        self.debug("Validating the creation and state of VPC offering - %s" %
                   vpc_offering.name)
        vpc_offs = VpcOffering.list(self.api_client,
                                    id=vpc_offering.id
                                    )
        self.assertEqual(isinstance(vpc_offs, list), True,
                         "List VPC offering should return a valid list"
                         )
        self.assertEqual(vpc_offering.name, vpc_offs[0].name,
                         "Name of the VPC offering should match with the "
                         "returned list data"
                         )
        if state:
            self.assertEqual(vpc_offs[0].state, state,
                             "VPC offering state should be '%s'" % state
                             )
        self.debug("Successfully validated the creation and state of VPC "
                   "offering - %s" % vpc_offering.name)

    # validate_Vpc - Validates the given VPC, matches the given VPC name and
    # state against the list of VPCs fetched
    def validate_vpc(self, vpc, state=None):
        """Validates the VPC"""
        self.debug("Validating the creation and state of VPC - %s" % vpc.name)
        vpcs = VPC.list(self.api_client,
                        id=vpc.id
                        )
        self.assertEqual(isinstance(vpcs, list), True,
                         "List VPC should return a valid list"
                         )
        self.assertEqual(vpc.name, vpcs[0].name,
                         "Name of the VPC should match with the returned "
                         "list data"
                         )
        if state:
            self.assertEqual(vpcs[0].state, state,
                             "VPC state should be '%s'" % state
                             )
        self.debug("Successfully validated the creation and state of VPC - %s"
                   % vpc.name)

    # ssh_into_VM - Gets into the shell of the given VM using its public IP
    def ssh_into_VM(self, vm, public_ip, reconnect=True,
                    negative_test=False, keypair=None):
        self.debug("SSH into VM with ID - %s on public IP address - %s" %
                   (vm.id, public_ip.ipaddress.ipaddress))
        tries = 1 if negative_test else 3
        private_key_file_location = keypair.private_key_file if keypair else None

        def retry_ssh():
            ssh_client = vm.get_ssh_client(
                ipaddress=public_ip.ipaddress.ipaddress,
                reconnect=reconnect,
                keyPairFileLocation=private_key_file_location,
                retries=3 if negative_test else 30
            )
            self.debug("Successful to SSH into VM with ID - %s on "
                       "public IP address - %s" %
                       (vm.id, public_ip.ipaddress.ipaddress))
            return ssh_client

        return retry_ssh()

    # create_VM - Creates VM in the givsen network(s)
    def create_VM(self, network_list, host_id=None, start_vm=True,
                  testdata=None, account=None, keypair=None):
        network_ids = []
        if isinstance(network_list, list):
            for network in network_list:
                network_ids.append(str(network.id))
        else:
            network_ids.append(str(network_list.id))
        if not account:
            account = self.account
        self.debug("Creating VM in network(s) with ID(s) - %s in the "
                   "account - %s" % (network_ids, account.name))
        if not testdata:
            testdata = self.test_data["virtual_machine"]
        vm = VirtualMachine.create(self.api_client,
                                   testdata,
                                   accountid=account.name,
                                   domainid=account.domainid,
                                   serviceofferingid=self.service_offering.id,
                                   templateid=self.template.id,
                                   zoneid=self.zone.id,
                                   networkids=network_ids,
                                   startvm=start_vm,
                                   hostid=host_id,
                                   keypair=keypair
                                   )
        self.debug("Created VM with ID - %s in network(s) with ID(s) - %s"
                   % (vm.id, network_ids))
        self.cleanup.append(vm)
        return vm

    def check_VM_state(self, vm, state=None):
        """Validates the VM state
        Checks if the given VM is in the expected state
        from the list of fetched VMs
        """
        self.debug("Validating the deployment and state of VM - %s" % vm.name)
        vms = VirtualMachine.list(self.api_client,
                                  id=vm.id,
                                  listall=True
                                  )
        self.assertEqual(isinstance(vms, list), True,
                         "List virtual machine should return a valid list"
                         )
        if state:
            self.assertEqual(vms[0].state, state,
                             "Virtual machine is not in the expected state"
                             )
        self.debug("Successfully validated the deployment and state of VM - %s"
                   % vm.name)

    def validate_Network(self, network, state=None):
        """Validates the network
           matches the given network name and state
           against the list of networks fetched
        """
        self.debug("Validating the creation and state of Network - %s" %
                   network.name)
        networks = Network.list(self.api_client,
                                id=network.id
                                )
        self.assertEqual(isinstance(networks, list), True,
                         "List network should return a valid list"
                         )
        self.assertEqual(network.name, networks[0].name,
                         "Name of the network should match with the "
                         "returned list data"
                         )
        if state:
            self.assertEqual(networks[0].state, state,
                             "Network state should be '%s'" % state
                             )
        self.debug("Successfully validated the creation and state of Network "
                   "- %s" % network.name)

    def get_Router(self, network):
        """Returns router for the given network"""
        self.debug("Finding the virtual router for network with ID - %s" %
                   network.id)
        routers = Router.list(self.api_client,
                              networkid=network.id,
                              listall=True
                              )
        self.assertEqual(isinstance(routers, list), True,
                         "List routers should return a valid virtual router "
                         "for network"
                         )
        return routers[0]

    # check_Router_state - Checks if the given router is in the expected state
    # form the list of fetched routers
    def check_Router_state(self, router=None, network=None, state=None):
        """Validates the Router state"""

        if router:
            self.debug("Validating the deployment and state of Router - %s" %
                       router.name)
            routers = Router.list(self.api_client, id=router.id,
                                  listall=True)
        elif network:
            self.debug("Validating the deployment and state of Router "
                       "in network - %s" % network.name)
            routers = Router.list(self.api_client, networkid=network.id,
                                  listall=True)
        else:
            raise AttributeError("Either router or network "
                                 "has to be specified")

        self.assertTrue(isinstance(routers, list),
                        "List router should return a valid list")
        self.assertTrue(len(routers) > 0,
                        "List routers should not return an empty list")

        if state:
            self.assertEqual(routers[0].state, state,
                             "Virtual router is not in the expected state"
                             )
        self.debug("Successfully validated the deployment and state of Router "
                   "- %s" % routers[0].name)

    def acquire_PublicIPAddress(self, network, vpc=None, account=None):
        """Acquires public IP address for the given network/VPC"""
        if not account:
            account = self.account
        self.debug("Associating public IP for network with ID - %s in the "
                   "account - %s" % (network.id, account.name))
        public_ip = PublicIPAddress.create(self.api_client,
                                           accountid=account.name,
                                           domainid=account.domainid,
                                           zoneid=self.zone.id,
                                           networkid=network.id if vpc is None
                                           else None,
                                           vpcid=vpc.id if vpc
                                           else self.vpc.id if self.vpc
                                           else None
                                           )
        self.debug("Associated public IP address - %s with network with ID - "
                   "%s" % (public_ip.ipaddress.ipaddress, network.id))
        self.cleanup.append(public_ip)
        return public_ip

    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.api_client, 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.api_client, hostid=host.id)
                vm.password_test = ConfigDriveUtils.PasswordTest(expect_pw=False)
            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

    # create_NetworkAclList - Creates network ACL list in the given VPC
    def create_NetworkAclList(self, name, description, vpc):
        self.debug("Adding NetworkACL list in VPC with ID - %s" % vpc.id)
        return NetworkACLList.create(self.api_client,
                                     services={},
                                     name=name,
                                     description=description,
                                     vpcid=vpc.id
                                     )

    # create_NetworkAclRule - Creates Ingress/Egress Network ACL rule in the
    # given VPC network/acl list
    def create_NetworkAclRule(self, rule, traffic_type="Ingress", network=None,
                              acl_list=None):
        self.debug("Adding NetworkACL rule - %s" % rule)
        if acl_list:
            return NetworkACL.create(self.api_client,
                                     networkid=network.id if network else None,
                                     services=rule,
                                     traffictype=traffic_type,
                                     aclid=acl_list.id
                                     )
        else:
            return NetworkACL.create(self.api_client,
                                     networkid=network.id if network else None,
                                     services=rule,
                                     traffictype=traffic_type
                                     )

    # restart_Vpc - Restarts the given VPC with/without cleanup
    def restart_Vpc(self, vpc, cleanup=False):
        self.debug("Restarting VPC with ID - %s" % vpc.id)
        cmd = restartVPC.restartVPCCmd()
        cmd.id = vpc.id
        cmd.cleanup = cleanup
        cmd.makeredundant = False
        self.api_client.restartVPC(cmd)
        self.debug("Restarted VPC with ID - %s" % vpc.id)

    @attr(tags=["advanced", "isonw"], required_hardware="true")
    def test_configdrive_isolated_network(self):
        """Test Configdrive as provider for isolated Networks
           to provide userdata and password reset functionality
        """

        # 1. Given ConfigDrive provider is disabled in zone
        #    And a network offering which has
        #      user data provided by ConfigDrive
        #    Then creating an Isolated Network
        #    using that network offering fails

        # 2. Given ConfigDrive provider is enabled in zone
        #    And a network offering which has
        #    * user data provided by ConfigDrive
        #    When I create an Isolated Network using that network offering
        #    Then the network is successfully created,
        #    And is in the "Allocated" state.

        # 3. When I deploy a VM in the created Isolated network with user data,
        #    Then the Isolated network state is changed to "Implemented"
        #    And the VM is successfully deployed and is in the "Running" state
        #    And there is no VR is deployed.
        # 4. And the user data in the ConfigDrive device is as expected
        # 5. And the vm password in the ConfigDrive device is as expected

        # 6. When I stop, reset the password, and start the VM
        # 7. Then I can login into the VM using the new password.
        # 8. And the vm password in the ConfigDrive device is the new one

        # 9. Verify various scenarios and check the data in configdriveIso
        # 10. Delete all the created objects (cleanup).

        self.debug("+++ Scenario: creating an Isolated network with "
                   "config drive fails when config drive provider is "
                   "disabled.")
        self.given_config_drive_provider_is("Disabled")
        self.given_a_network_offering_with_configdrive()
        self.then_creating_a_network_with_that_offering_fails()

        self.debug("+++ Preparation Scenario: "
                   "creating an Isolated networks with "
                   "config drive when config drive provider is "
                   "enabled.")

        self.given_config_drive_provider_is("Enabled")

        create_network1 = self.when_I_create_a_network_with_that_offering()
        self.then_the_network_is_successfully_created(create_network1)
        self.then_the_network_has(create_network1, state="Allocated")

        create_network2 = self.when_I_create_a_network_with_that_offering()
        self.then_the_network_is_successfully_created(create_network2)
        self.then_the_network_has(create_network2, state="Allocated")

        network1 = create_network1.network
        network2 = create_network2.network

        self.given_template_password_enabled_is(True)

        self.debug("+++Deploy VM in the created Isolated network "
                   "with user data provider as configdrive")

        vm1 = self.when_I_deploy_a_vm_with_keypair_in(network1)
        public_ip_1 = \
            self.when_I_create_a_static_nat_ip_to(vm1, network1)

        self.then_vr_is_as_expected(network1)
        self.then_config_drive_is_as_expected(
            vm1, public_ip_1,
            metadata=True)

        self.update_and_validate_userdata(vm1, "helloworld vm1", public_ip_1)
        self.update_and_validate_sshkeypair(vm1, public_ip_1)

        # =====================================================================

        self.debug("Adding a non-default nic to the VM "
                   "making it a multi-nic VM...")
        self.plug_nic(vm1, network2)
        self.then_config_drive_is_as_expected(vm1, public_ip_1,
                                              metadata=True, reconnect=False)

        with self.stopped_vm(vm1):
            self.when_I_reset_the_password(vm1)
            self.when_I_update_userdata(vm1, "hellomultinicvm1")

        self.then_config_drive_is_as_expected(vm1, public_ip_1)

        # =====================================================================
        # Test using network2 as default network
        # =====================================================================

        self.debug("updating non-default nic as the default nic "
                   "of the multi-nic VM and enable staticnat...")
        self.update_default_nic(vm1, network2)

        public_ip_2 = \
            self.when_I_create_a_static_nat_ip_to(vm1, network2)
        self.stop_and_start_vm(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_2, metadata=True)

        self.when_I_reset_the_password(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_2)

        user_data = "hellomultinicvm1again"
        self.update_and_validate_userdata(vm1, user_data, public_ip_2)

        self.debug("Updating the default nic of the multi-nic VM, "
                   "deleting the non-default nic...")
        self.update_default_nic(vm1, network1)
        self.stop_and_start_vm(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        self.delete(public_ip_2)
        self.unplug_nic(vm1, network2)

        # =====================================================================
        # Another Multinic VM
        # =====================================================================
        self.debug("+++ Scenario: "
                   "Reset password and update userdata on a multi nic vm")
        multinicvm1 = self.when_I_deploy_a_vm([network2, network1])
        self.when_I_reset_the_password(multinicvm1)
        public_ip_3 = self.when_I_create_a_static_nat_ip_to(multinicvm1,
                                                            network2)
        self.then_config_drive_is_as_expected(
            multinicvm1, public_ip_3,
            metadata=True)

        user_data2 = "hello multinicvm1"
        self.update_and_validate_userdata(multinicvm1, user_data2, public_ip_3)

        self.delete(multinicvm1, expunge=True)
        self.delete(public_ip_3)
        self.delete(network2)

        # =====================================================================
        # Network restart tests
        # =====================================================================

        self.debug("+++ Scenario: "
                   "verify config drive after restart Isolated network without"
                   " cleanup...")
        self.when_I_reset_the_password(vm1)
        self.when_I_restart_the_network_with(network1, cleanup=False)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after restart Isolated network with"
                   " cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=True)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after reboot")
        vm1.reboot(self.api_client)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
        self.update_and_validate_userdata(vm1, "hello afterboot", public_ip_1)
        self.when_I_reset_the_password(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after migrate")
        host = self.migrate_VM(vm1)
        vm1.hostname = host.name
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
        self.debug("Updating userdata after migrating VM - %s" % vm1.name)
        self.update_and_validate_userdata(vm1, "hello after migrate",
                                          public_ip_1)
        self.when_I_reset_the_password(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after stop/start")
        self.stop_and_start_vm(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)
        self.update_and_validate_userdata(vm1, "hello afterstopstart",
                                          public_ip_1)
        self.when_I_reset_the_password(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after delete/recover")
        self.delete_and_recover_vm(vm1)
        self.then_config_drive_is_as_expected(vm1, public_ip_1,
                                              metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Start VM fails when ConfigDrive provider is disabled")
        self.given_config_drive_provider_is("Disabled")
        with self.assertRaises(Exception):
            self.when_I_update_userdata(vm1, "hi with provider state Disabled")
        self.given_config_drive_provider_is("Enabled")

        self.delete(vm1, expunge=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Update Userdata on a VM that is not password enabled")
        self.given_template_password_enabled_is(False)
        vm1 = self.when_I_deploy_a_vm_with_keypair_in(network1)

        public_ip_1 = \
            self.when_I_create_a_static_nat_ip_to(vm1, network1)

        self.update_and_validate_userdata(vm1,
                                          "This is sample data",
                                          public_ip_1,
                                          metadata=True)

        self.delete(vm1, expunge=True)
        self.delete(network1)

    @attr(tags=["advanced", "vpc"], required_hardware="true")
    def test_configdrive_vpc_network(self):
        """Test Configdrive for VPC Networks
           choose user data with configDrive as service provider
           and test password reset functionality using ConfigDrive
        """

        # 1. Given ConfigDrive provider is disabled in zone
        #    And a network offering for VPC which has
        #      user data provided by ConfigDrive
        #    And a VPC
        #    Then creating an VPC Tier in the VPC
        #    using that network offering fails

        # 2. Given ConfigDrive provider is enabled in zone
        #    And a network offering for VPC which has
        #      user data provided by ConfigDrive
        #    And a VPC
        #    When I create an VPC Tier in the VPC  using that network offering
        #    Then the network is successfully created,
        #    And is in the "Allocated" state.

        # 3. When I deploy a VM in the created VPC tier with user data,
        #    Then the network state is changed to "Implemented"
        #    And the VM is successfully deployed and is in the "Running" state

        # 4. And the user data in the ConfigDrive device is as expected
        # 5. And the vm password in the ConfigDrive device is as expected

        # 6. When I stop, reset the password, and start the VM
        # 7. Then I can login into the VM using the new password.
        # 8. And the vm password in the ConfigDrive device is the new one

        # 9. Verify various scenarios and check the data in configdriveIso
        # 10. Delete all the created objects (cleanup).

        self.debug("+++ Scenario: creating an VPC tier with "
                   "config drive fails when config drive provider is "
                   "disabled.")
        self.given_a_vpc()
        self.given_config_drive_provider_is("Disabled")
        self.given_a_network_offering_for_vpc_with_configdrive()
        self.then_creating_a_vpc_tier_with_that_offering_fails()

        self.debug("+++ Preparation Scenario: "
                   "Create 2 tier with config drive "
                   "when config drive provider is enabled.")

        self.given_config_drive_provider_is("Enabled")

        create_network1 = self.when_I_create_a_vpc_tier_with_that_offering(
            gateway='10.1.1.1')
        self.then_the_network_is_successfully_created(create_network1)
        self.then_the_network_has(create_network1, state="Implemented")

        create_network2 = self.when_I_create_a_vpc_tier_with_that_offering(
            gateway='10.1.2.1')
        self.then_the_network_is_successfully_created(create_network2)
        self.then_the_network_has(create_network2, state="Implemented")

        network1 = create_network1.network
        network2 = create_network2.network

        self.given_template_password_enabled_is(True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Deploy VM in the Tier 1 with user data")
        vm = self.when_I_deploy_a_vm(network1,
                                     keypair=self.keypair.name)
        public_ip_1 = \
            self.when_I_create_a_static_nat_ip_to(vm, network1)
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        self.update_and_validate_userdata(vm, "helloworld vm1",
                                          public_ip_1,
                                          metadata=True)

        self.when_I_reset_the_password(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1)

        self.update_and_validate_sshkeypair(vm, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Restarting the created vpc without cleanup...")
        self.restart_Vpc(self.vpc, cleanup=False)
        self.validate_vpc(self.vpc, state="Enabled")
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("Adding a non-default nic to the VM "
                   "making it a multi-nic VM...")
        self.plug_nic(vm, network2)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        with self.stopped_vm(vm):
            self.when_I_reset_the_password(vm)
            self.when_I_update_userdata(vm, "hellomultinicvm1")

        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        self.unplug_nic(vm, network2)
        self.delete(network2)

        # =====================================================================
        # Network restart tests
        # =====================================================================

        self.debug("+++ Scenario: "
                   "verify config drive after Restart VPC with cleanup...")
        self.when_I_restart_the_vpc_with(cleanup=True)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after Restart VPC without cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=False)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after restart tier with cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=True)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after reboot")
        vm.reboot(self.api_client)
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
        self.update_and_validate_userdata(vm, "hello reboot", public_ip_1)

        self.when_I_reset_the_password(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after migrate")
        host = self.migrate_VM(vm)
        vm.hostname = host.name
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)
        self.update_and_validate_userdata(vm, "hello migrate", public_ip_1)

        self.when_I_reset_the_password(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "update userdata and reset password after stop/start")
        self.stop_and_start_vm(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        self.update_and_validate_userdata(vm, "hello stop/start", public_ip_1)

        self.when_I_reset_the_password(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after delete/recover")
        self.delete_and_recover_vm(vm)
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Verify configdrive when template is not password enabled")
        self.given_config_drive_provider_is("Disabled")
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)
        self.given_config_drive_provider_is("Enabled")

        self.delete(vm, expunge=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Update Userdata on a VM that is not password enabled")

        self.given_template_password_enabled_is(False)

        vm = self.when_I_deploy_a_vm(network1,
                                     keypair=self.keypair.name)
        public_ip_1 = \
            self.when_I_create_a_static_nat_ip_to(vm, network1)
        self.update_and_validate_userdata(vm, "This is sample data",
                                          public_ip_1,
                                          metadata=True)

        self.delete(vm, expunge=True)
        self.delete(network1)

    @attr(tags=["advanced", "shared"], required_hardware="true")
    def test_configdrive_shared_network(self):
        """Test Configdrive as provider for shared Networks
           to provide userdata and password reset functionality
        """

        # 1. When ConfigDrive is disabled as provider in zone
        #    Verify Shared Network creation with a network offering
        #    which has userdata provided by ConfigDrive fails
        # 2. When ConfigDrive is enabled as provider in zone
        #    Create a shared Network with Isolated Network
        #    offering specifying ConfigDrive as serviceProvider
        #    for userdata.
        #    check if it is successfully created and
        #    is in the "Setup" state.
        # 3. Deploy a VM in the created Shared network with user data,
        #    check if the Shared network state is changed to
        #    "Implemented", and the VM is successfully deployed and
        #    is in the "Running" state.
        # 4. Verify that the guest VM's password in the iso.
        # 5. Reset VM password, and start the VM.
        # 6. Verify that the new guest VM template is password enabled by
        #     checking the VM's password (password != "password").
        # 7. Verify various scenarios and check the data in configdriveIso
        # 8. Delete all the created objects (cleanup).

        self.debug("+++Testing configdrive in an shared network fails..."
                   "as provider configdrive is still disabled...")
        self.given_config_drive_provider_is("Disabled")
        shared_test_data = self.test_data["acl"]["network_all_1"]
        shared_network = self.verify_network_creation(
            offering_name="shared_network_config_drive_offering",
            testdata=shared_test_data)
        self.assertFalse(shared_network.success,
                         'Network found success = %s, expected success =%s'
                         % (str(shared_network.success), 'False'))

        self.given_config_drive_provider_is("Enabled")
        shared_network = self.verify_network_creation(
            offering=shared_network.offering, testdata=shared_test_data)
        self.assertTrue(shared_network.success,
                        'Network found success = %s, expected success = %s'
                        % (str(shared_network.success), 'True'))

        self.validate_Network(shared_network.network, state="Setup")

        shared_test_data2 = self.test_data["acl"]["network_all_2"]
        shared_network2 = self.verify_network_creation(
            offering=shared_network.offering,
            testdata=shared_test_data2)
        self.assertTrue(shared_network2.success,
                        'Network found success = %s, expected success = %s'
                        % (str(shared_network2.success), 'True'))

        self.validate_Network(shared_network2.network, state="Setup")

        self.debug("+++Test user data & password reset functionality "
                   "using configdrive in an Isolated network")

        self.given_template_password_enabled_is(True)

        self.generate_ssh_keys()
        self.debug("keypair name %s " % self.keypair.name)

        self.debug("+++Deploy of a VM on a shared network with multiple "
                   "ip ranges, all should have the same value for the "
                   "underlay flag.")
        # Add subnet of different gateway
        self.debug("+++ Adding subnet of different gateway")

        self.add_subnet_to_shared_network_and_verify(shared_network.network,
                                                     self.test_data[
                                                         "publiciprange2"])
        self.test_data["virtual_machine"]["ipaddress"] = \
            self.test_data["acl"]["network_all_1"]["endip"]

        # with self.assertRaises(Exception):
        #         self.create_VM(
        #             [shared_network.network],
        #             testdata=self.test_data["virtual_machine_userdata"])

        self.debug("+++ In a shared network with multiple ip ranges, "
                   "userdata with config drive must be allowed.")

        vm1 = self.create_VM(
            [shared_network.network],
            testdata=self.test_data["virtual_machine_userdata"],
            keypair=self.keypair.name)
        # Check VM
        self.check_VM_state(vm1, state="Running")
        self.check_Router_state(network=shared_network.network,
                                state="Running")

        self.when_I_update_userdata(vm1, "helloworld vm1")

        self.debug("Adding a non-default nic to the VM "
                   "making it a multi-nic VM...")
        self.plug_nic(vm1, shared_network2.network)
        self.when_I_reset_the_password(vm1)

        self.debug("updating non-default nic as the default nic "
                   "of the multi-nic VM...")
        self.update_default_nic(vm1, shared_network2.network)
        self.when_I_reset_the_password(vm1)

        self.when_I_update_userdata(vm1, "hellomultinicvm1")

        self.debug("Updating the default nic of the multi-nic VM, "
                   "deleting the non-default nic...")
        self.update_default_nic(vm1, shared_network.network)
        vm1.stop(self.api_client)
        vm1.start(self.api_client)

        self.unplug_nic(vm1,
                        shared_network2.network)
        self.delete(shared_network2.network)

        self.debug("+++ When template is not password enabled, "
                   "verify configdrive of VM - %s" % vm1.name)
        self.delete(vm1, expunge=True)

        self.given_config_drive_provider_is("Enabled")
        self.given_template_password_enabled_is(False)

        vm1 = self.create_VM(
            [shared_network.network],
            testdata=self.test_data["virtual_machine_userdata"],
            keypair=self.keypair.name)
        self.delete(vm1, expunge=True)
        self.delete(shared_network.network)

    @attr(tags=["advanced", "isonw"], required_hardware="true")
    def test_configdrive_isolated_network_hypervisor_hostname_exposed(self):
        """Test Configdrive as provider for isolated Networks
           to provide userdata and password reset functionality
        """

        # 1. Given a ConfigDrive provider and a network offering
        #    which has userdata provided ConfigDrive, create
        #    an Isolated network using that network offering.
        #    Verify network is successfully created and in the Allocated state
        #    Set the "global.allow.expose.host.hostname" and "account.allow.expose.host.hostname" flags to true
        #    to enable viewing hypevisor host name in the metadata file
        #    Deploy VM in the network created, verify metadata in the configdrive
        #    my mounting the configdrive ISO and verify the respective files
        #
        # 2. Create another Isolated network and plug NIC of the VM to this network
        #    make it the default NIC, verify the metadata file contents.
        #
        # 3. Remove the default NIC, reboot the VM and verify the metadata file contents
        #
        # 4. Restart network without cleanup and verify the metadata file contents
        #
        # 5. Restart the network with cleanup and verify the metadata file contents
        # 6. Migrate the VM to another host and verify the metadata file contents
        # 10. Delete all the created objects (cleanup).

        self.debug("+++ Preparation Scenario: "
                   "creating an Isolated networks with "
                   "config drive when config drive provider is "
                   "enabled.")

        self.given_config_drive_provider_is("Enabled")
        self.given_a_network_offering_with_configdrive()

        create_network1 = self.when_I_create_a_network_with_that_offering()
        self.then_the_network_is_successfully_created(create_network1)
        self.then_the_network_has(create_network1, state="Allocated")

        network1 = create_network1.network

        # Update global setting for "allow.expose.host.hostname"
        Configurations.update(self.api_client,
                              name="global.allow.expose.host.hostname",
                              value="true"
                              )

        # Update Account level setting
        Configurations.update(self.api_client,
                              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.api_client,
                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.api_client,
                name='account.allow.expose.host.hostname',
                value='true'):
            self.skipTest('Account level setting account.allow.expose.host.hostname should be true. skipping')

        self.debug("+++Deploy VM in the created Isolated network "
                   "with user data provider as configdrive")

        self.given_template_password_enabled_is(True)
        vm1 = self.when_I_deploy_a_vm(network1)

        public_ip_1 = self.when_I_create_a_static_nat_ip_to(vm1, network1)

        self.then_vr_is_as_expected(network1)
        self.then_config_drive_is_as_expected(
            vm1, public_ip_1,
            metadata=True)

        # =====================================================================
        # Network restart tests
        # =====================================================================

        self.debug("+++ Scenario: "
                   "verify config drive after restart Isolated network without"
                   " cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=False)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after restart Isolated network with"
                   " cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=True)
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify vm metadata after migrate")
        host = self.migrate_VM(vm1)
        vm1.hostname = host.name
        self.then_config_drive_is_as_expected(vm1, public_ip_1, metadata=True)

        # Reset configuration values to default values i.e., false
        Configurations.update(self.api_client,
                              name="global.allow.expose.host.hostname",
                              value="false"
                              )

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

        self.delete(vm1, expunge=True)
        self.delete(network1)

    @attr(tags=["advanced", "vpc"], required_hardware="true")
    def test_configdrive_vpc_network_verify_metadata(self):
        """Test Configdrive for VPC Networks
           choose user data with configDrive as service provider
           and test vmdata functionality using ConfigDrive
        """

        # 1. Given ConfigDrive provider is enabled in zone
        #    And a network offering for VPC which has
        #      user data provided by ConfigDrive
        #    And a VPC
        #    When I create an VPC Tier in the VPC  using that network offering
        #    Then the network is successfully created,
        #    And is in the "Allocated" state.

        # 2. When I deploy a VM in the created VPC tier with user data,
        #    Then the network state is changed to "Implemented"
        #    And the VM is successfully deployed and is in the "Running" state

        # 3. And the user data in the ConfigDrive device is as expected
        # 4. Verify various scenarios and check the data in configdriveIso
        # 5. Delete all the created objects (cleanup).

        self.debug("+++ Preparation Scenario: "
                   "Create a tier with config drive "
                   "when config drive provider is enabled.")

        self.given_a_vpc()
        self.given_config_drive_provider_is("Enabled")
        self.given_a_network_offering_for_vpc_with_configdrive()
        create_network1 = self.when_I_create_a_vpc_tier_with_that_offering(
            gateway='10.1.1.1')
        self.then_the_network_is_successfully_created(create_network1)
        self.then_the_network_has(create_network1, state="Implemented")

        network1 = create_network1.network

        # Update global setting for "allow.expose.host.hostname"
        Configurations.update(self.api_client,
                              name="global.allow.expose.host.hostname",
                              value="true"
                              )

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

        # Enable domain in metadata
        Configurations.update(self.api_client,
                              name="metadata.allow.expose.domain",
                              value="true"
                              )

        # Verify that the above mentioned settings are set to true before proceeding
        if not is_config_suitable(
                apiclient=self.api_client,
                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.api_client,
                name='account.allow.expose.host.hostname',
                value='true'):
            self.skipTest('Account level setting account.allow.expose.host.hostname should be true. skipping')

        if not is_config_suitable(
                apiclient=self.api_client,
                name='metadata.allow.expose.domain',
                value='true'):
            self.skipTest('metadata.allow.expose.domain should be true. skipping')

        # =====================================================================
        self.debug("+++ Scenario: "
                   "Deploy VM in the Tier 1 with user data")
        self.given_template_password_enabled_is(True)
        vm = self.when_I_deploy_a_vm(network1)
        public_ip_1 = self.when_I_create_a_static_nat_ip_to(vm, network1)

        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        # =====================================================================
        # Network restart tests
        # =====================================================================

        self.debug("+++ Scenario: "
                   "verify config drive after Restart VPC with cleanup...")
        self.when_I_restart_the_vpc_with(cleanup=True)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after Restart VPC without cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=False)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "verify config drive after restart tier with cleanup...")
        self.when_I_restart_the_network_with(network1, cleanup=True)
        self.then_config_drive_is_as_expected(vm, public_ip_1,
                                              metadata=True, reconnect=False)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "validate vm metadata after reboot")
        vm.reboot(self.api_client)
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        # =====================================================================
        self.debug("+++ Scenario: "
                   "validate updated userdata after migrate")
        time.sleep(30)
        host = self.migrate_VM(vm)
        vm.hostname = host.name
        self.then_config_drive_is_as_expected(vm, public_ip_1, metadata=True)

        # Reset configuration values to default values i.e., false
        Configurations.update(self.api_client,
                              name="global.allow.expose.host.hostname",
                              value="false"
                              )

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

        # Disable domain in metadata
        Configurations.update(self.api_client,
                              name="metadata.allow.expose.domain",
                              value="false"
                              )

        self.delete(vm, expunge=True)
        self.delete(network1)
