# 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.

import logging
import random
import SignedAPICall
import time
import XenAPI

from solidfire.factory import ElementFactory

from util import sf_util

# All tests inherit from cloudstackTestCase
from marvin.cloudstackTestCase import cloudstackTestCase

# Import Integration Libraries

# base - contains all resources as entities and defines create, delete, list operations on them
from marvin.lib.base import Account, ServiceOffering, User, Host, StoragePool, VirtualMachine

# common - commonly used methods for all tests are listed here
from marvin.lib.common import get_domain, get_template, get_zone, list_hosts, list_clusters, list_volumes

# utils - utility classes for common cleanup, external library wrappers, etc.
from marvin.lib.utils import cleanup_resources

# Prerequisites:
#  Only one zone
#  Only one pod
#  Only one cluster (two hosts for XenServer / one host for KVM with another added/removed during the tests)
#
# Running the tests:
#  Change the "hypervisor_type" variable to control which hypervisor type to test.
#  If using XenServer, set a breakpoint on each test after the first one. When the breakpoint is hit, reset the added/removed
#   host to a snapshot state and re-start it. Once it's up and running, run the test code.
#  Check that ip_address_of_new_xenserver_host / ip_address_of_new_kvm_host is correct.
#  If using XenServer, verify the "xen_server_master_hostname" variable is correct.
#  If using KVM, verify the "kvm_1_ip_address" variable is correct.


class TestData:
    #constants
    account = "account"
    capacityBytes = "capacitybytes"
    capacityIops = "capacityiops"
    clusterId = "clusterId"
    computeOffering = "computeoffering"
    displayText = "displaytext"
    diskSize = "disksize"
    domainId = "domainId"
    hypervisor = "hypervisor"
    kvm = "kvm"
    mvip = "mvip"
    name = "name"
    newXenServerHost = "newXenServerHost"
    newKvmHost = "newKvmHost"
    newHostDisplayName = "newHostDisplayName"
    password = "password"
    podId = "podid"
    port = "port"
    primaryStorage = "primarystorage"
    primaryStorage2 = "primarystorage2"
    provider = "provider"
    scope = "scope"
    solidFire = "solidfire"
    storageTag = "SolidFire_SAN_1"
    storageTag2 = "SolidFire_Volume_1"
    tags = "tags"
    url = "url"
    user = "user"
    username = "username"
    virtualMachine = "virtualmachine"
    volume_1 = "volume_1"
    xenServer = "xenserver"
    zoneId = "zoneid"

    # modify to control which hypervisor type to test
    hypervisor_type = xenServer
    xen_server_master_hostname = "XenServer-6.5-1"
    kvm_1_ip_address = "192.168.129.84"
    ip_address_of_new_xenserver_host = "192.168.129.243"
    ip_address_of_new_kvm_host = "192.168.129.3"

    def __init__(self):
        self.testdata = {
            TestData.solidFire: {
                TestData.mvip: "192.168.139.112",
                TestData.username: "admin",
                TestData.password: "admin",
                TestData.port: 443,
                TestData.url: "https://192.168.139.112:443"
            },
            TestData.kvm: {
                TestData.username: "root",
                TestData.password: "solidfire"
            },
            TestData.xenServer: {
                TestData.username: "root",
                TestData.password: "solidfire"
            },
            TestData.account: {
                "email": "test@test.com",
                "firstname": "John",
                "lastname": "Doe",
                TestData.username: "test",
                TestData.password: "test"
            },
            TestData.user: {
                "email": "user@test.com",
                "firstname": "Jane",
                "lastname": "Doe",
                TestData.username: "testuser",
                TestData.password: "password"
            },
            TestData.newXenServerHost: {
                TestData.username: "root",
                TestData.password: "solidfire",
                TestData.url: "http://" + TestData.ip_address_of_new_xenserver_host,
                TestData.podId : "1",
                TestData.zoneId: "1"
            },
            TestData.newKvmHost: {
                TestData.username: "root",
                TestData.password: "solidfire",
                TestData.url: "http://" + TestData.ip_address_of_new_kvm_host,
                TestData.podId : "1",
                TestData.zoneId: "1"
            },
            TestData.primaryStorage: {
                TestData.name: "SolidFire-%d" % random.randint(0, 100),
                TestData.scope: "ZONE",
                TestData.url: "MVIP=192.168.139.112;SVIP=10.10.8.112;" +
                       "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                       "clusterDefaultMinIops=10000;clusterDefaultMaxIops=15000;" +
                       "clusterDefaultBurstIopsPercentOfMaxIops=1.5;",
                TestData.provider: "SolidFire",
                TestData.tags: TestData.storageTag,
                TestData.capacityIops: 4500000,
                TestData.capacityBytes: 2251799813685248,
                TestData.hypervisor: "Any"
            },
            TestData.primaryStorage2: {
                TestData.name: "SolidFireShared-%d" % random.randint(0, 100),
                TestData.scope: "CLUSTER",
                TestData.url: "MVIP=192.168.139.112;SVIP=10.10.8.112;" +
                       "clusterAdminUsername=admin;clusterAdminPassword=admin;" +
                       "minIops=5000;maxIops=50000;burstIops=75000",
                TestData.provider: "SolidFireShared",
                TestData.tags: TestData.storageTag2,
                TestData.capacityIops: 5000,
                TestData.capacityBytes: 1099511627776,
                TestData.hypervisor: "XenServer",
                TestData.podId: 1
            },
            TestData.virtualMachine: {
                TestData.name: "TestVM",
                "displayname": "Test VM"
            },
            TestData.computeOffering: {
                TestData.name: "SF_CO_1",
                TestData.displayText: "SF_CO_1 (Min IOPS = 10,000; Max IOPS = 15,000)",
                "cpunumber": 1,
                "cpuspeed": 100,
                "memory": 128,
                "storagetype": "shared",
                "customizediops": False,
                "miniops": "10000",
                "maxiops": "15000",
                "hypervisorsnapshotreserve": 200,
                TestData.tags: TestData.storageTag
            },
            TestData.volume_1: {
                "diskname": "testvolume",
            },
            TestData.newHostDisplayName: "XenServer-6.5-3",
            TestData.zoneId: 1,
            TestData.clusterId: 1,
            TestData.domainId: 1,
            TestData.url: "192.168.129.50"
        }


class TestAddRemoveHosts(cloudstackTestCase):
    _vag_id_should_be_non_zero_int_err_msg = "The SolidFire VAG ID should be a non-zero integer."
    _sf_account_id_should_be_non_zero_int_err_msg = "The SolidFire account ID should be a non-zero integer."

    @classmethod
    def setUpClass(cls):
        # Set up API client
        testclient = super(TestAddRemoveHosts, cls).getClsTestClient()

        cls.apiClient = testclient.getApiClient()
        cls.configData = testclient.getParsedTestDataConfig()
        cls.dbConnection = testclient.getDbConnection()

        cls.testdata = TestData().testdata

        if TestData.hypervisor_type == TestData.xenServer:
            cls.xs_pool_master_ip = list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name=TestData.xen_server_master_hostname)[0].ipaddress

        cls._connect_to_hypervisor()

        # Set up SolidFire connection
        solidfire = cls.testdata[TestData.solidFire]

        cls.sfe = ElementFactory.create(solidfire[TestData.mvip], solidfire[TestData.username], solidfire[TestData.password])

        # Get Resources from Cloud Infrastructure
        cls.zone = get_zone(cls.apiClient, zone_id=cls.testdata[TestData.zoneId])
        cls.cluster = list_clusters(cls.apiClient)[0]
        cls.template = get_template(cls.apiClient, cls.zone.id, cls.configData["ostype"])
        cls.domain = get_domain(cls.apiClient, cls.testdata[TestData.domainId])

        # Create test account
        cls.account = Account.create(
            cls.apiClient,
            cls.testdata[TestData.account],
            admin=1
        )

        # Set up connection to make customized API calls
        user = User.create(
            cls.apiClient,
            cls.testdata[TestData.user],
            account=cls.account.name,
            domainid=cls.domain.id
        )

        url = cls.testdata[TestData.url]

        api_url = "http://" + url + ":8080/client/api"
        userkeys = User.registerUserKeys(cls.apiClient, user.id)

        cls.cs_api = SignedAPICall.CloudStack(api_url, userkeys.apikey, userkeys.secretkey)

        cls.compute_offering = ServiceOffering.create(
            cls.apiClient,
            cls.testdata[TestData.computeOffering]
        )

        cls._cleanup = [
            cls.compute_offering,
            user,
            cls.account
        ]

    @classmethod
    def tearDownClass(cls):
        try:
            cleanup_resources(cls.apiClient, cls._cleanup)

            sf_util.purge_solidfire_volumes(cls.sfe)
        except Exception as e:
            logging.debug("Exception in tearDownClass(cls): %s" % e)

    def setUp(self):
        self.virtual_machine = None

        self.cleanup = []

    def tearDown(self):
        try:
            if self.virtual_machine is not None:
                self.virtual_machine.delete(self.apiClient, True)

            cleanup_resources(self.apiClient, self.cleanup)
        except Exception as e:
            logging.debug("Exception in tearDown(self): %s" % e)

    def test_add_remove_host_with_solidfire_plugin_1(self):
        primarystorage = self.testdata[TestData.primaryStorage]

        primary_storage = StoragePool.create(
            self.apiClient,
            primarystorage,
            scope=primarystorage[TestData.scope],
            zoneid=self.zone.id,
            provider=primarystorage[TestData.provider],
            tags=primarystorage[TestData.tags],
            capacityiops=primarystorage[TestData.capacityIops],
            capacitybytes=primarystorage[TestData.capacityBytes],
            hypervisor=primarystorage[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage)

        self.virtual_machine = VirtualMachine.create(
            self.apiClient,
            self.testdata[TestData.virtualMachine],
            accountid=self.account.name,
            zoneid=self.zone.id,
            serviceofferingid=self.compute_offering.id,
            templateid=self.template.id,
            domainid=self.domain.id,
            startvm=True
        )

        if TestData.hypervisor_type == TestData.xenServer:
            root_volume = self._get_root_volume(self.virtual_machine)

            sf_iscsi_name = sf_util.get_iqn(self.cs_api, root_volume, self)
            self._perform_add_remove_xenserver_host(primary_storage.id, sf_iscsi_name)
        elif TestData.hypervisor_type == TestData.kvm:
            self._perform_add_remove_kvm_host(primary_storage.id)
        else:
            self.assertTrue(False, "Invalid hypervisor type")

    def test_add_remove_host_with_solidfire_plugin_2(self):
        if TestData.hypervisor_type != TestData.xenServer:
            return

        primarystorage2 = self.testdata[TestData.primaryStorage2]

        primary_storage_2 = StoragePool.create(
            self.apiClient,
            primarystorage2,
            scope=primarystorage2[TestData.scope],
            zoneid=self.zone.id,
            clusterid=self.cluster.id,
            provider=primarystorage2[TestData.provider],
            tags=primarystorage2[TestData.tags],
            capacityiops=primarystorage2[TestData.capacityIops],
            capacitybytes=primarystorage2[TestData.capacityBytes],
            hypervisor=primarystorage2[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage_2)

        sf_iscsi_name = self._get_iqn_2(primary_storage_2)

        self._perform_add_remove_xenserver_host(primary_storage_2.id, sf_iscsi_name)

    def test_add_remove_host_with_solidfire_plugin_3(self):
        if TestData.hypervisor_type != TestData.xenServer:
            return

        primarystorage = self.testdata[TestData.primaryStorage]

        primary_storage = StoragePool.create(
            self.apiClient,
            primarystorage,
            scope=primarystorage[TestData.scope],
            zoneid=self.zone.id,
            provider=primarystorage[TestData.provider],
            tags=primarystorage[TestData.tags],
            capacityiops=primarystorage[TestData.capacityIops],
            capacitybytes=primarystorage[TestData.capacityBytes],
            hypervisor=primarystorage[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage)

        self.virtual_machine = VirtualMachine.create(
            self.apiClient,
            self.testdata[TestData.virtualMachine],
            accountid=self.account.name,
            zoneid=self.zone.id,
            serviceofferingid=self.compute_offering.id,
            templateid=self.template.id,
            domainid=self.domain.id,
            startvm=True
        )

        root_volume = self._get_root_volume(self.virtual_machine)

        sf_iscsi_name = sf_util.get_iqn(self.cs_api, root_volume, self)

        primarystorage2 = self.testdata[TestData.primaryStorage2]

        primary_storage_2 = StoragePool.create(
            self.apiClient,
            primarystorage2,
            scope=primarystorage2[TestData.scope],
            zoneid=self.zone.id,
            clusterid=self.cluster.id,
            provider=primarystorage2[TestData.provider],
            tags=primarystorage2[TestData.tags],
            capacityiops=primarystorage2[TestData.capacityIops],
            capacitybytes=primarystorage2[TestData.capacityBytes],
            hypervisor=primarystorage2[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage_2)

        self._perform_add_remove_xenserver_host(primary_storage.id, sf_iscsi_name)

    def test_add_remove_host_with_solidfire_plugin_4(self):
        if TestData.hypervisor_type != TestData.xenServer:
            return

        primarystorage2 = self.testdata[TestData.primaryStorage2]

        primary_storage_2 = StoragePool.create(
            self.apiClient,
            primarystorage2,
            scope=primarystorage2[TestData.scope],
            zoneid=self.zone.id,
            clusterid=self.cluster.id,
            provider=primarystorage2[TestData.provider],
            tags=primarystorage2[TestData.tags],
            capacityiops=primarystorage2[TestData.capacityIops],
            capacitybytes=primarystorage2[TestData.capacityBytes],
            hypervisor=primarystorage2[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage_2)

        sf_iscsi_name = self._get_iqn_2(primary_storage_2)

        primarystorage = self.testdata[TestData.primaryStorage]

        primary_storage = StoragePool.create(
            self.apiClient,
            primarystorage,
            scope=primarystorage[TestData.scope],
            zoneid=self.zone.id,
            provider=primarystorage[TestData.provider],
            tags=primarystorage[TestData.tags],
            capacityiops=primarystorage[TestData.capacityIops],
            capacitybytes=primarystorage[TestData.capacityBytes],
            hypervisor=primarystorage[TestData.hypervisor]
        )

        self.cleanup.append(primary_storage)

        self.virtual_machine = VirtualMachine.create(
            self.apiClient,
            self.testdata[TestData.virtualMachine],
            accountid=self.account.name,
            zoneid=self.zone.id,
            serviceofferingid=self.compute_offering.id,
            templateid=self.template.id,
            domainid=self.domain.id,
            startvm=True
        )

        self._perform_add_remove_xenserver_host(primary_storage_2.id, sf_iscsi_name)

    def _perform_add_remove_xenserver_host(self, primary_storage_id, sr_name):
        xen_sr = self.xen_session.xenapi.SR.get_by_name_label(sr_name)[0]

        pbds = self.xen_session.xenapi.SR.get_PBDs(xen_sr)

        self._verify_all_pbds_attached(pbds)

        num_pbds = len(pbds)

        sf_vag_id = self._get_sf_vag_id(self.cluster.id, primary_storage_id)

        host_iscsi_iqns = self._get_xenserver_host_iscsi_iqns()

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_orig = len(sf_vag_initiators)

        xen_session = XenAPI.Session("https://" + TestData.ip_address_of_new_xenserver_host)

        xenserver = self.testdata[TestData.xenServer]

        xen_session.xenapi.login_with_password(xenserver[TestData.username], xenserver[TestData.password])

        xen_session.xenapi.pool.join(self.xs_pool_master_ip, xenserver[TestData.username], xenserver[TestData.password])

        time.sleep(60)

        pbds = self.xen_session.xenapi.SR.get_PBDs(xen_sr)

        self.assertEqual(
            len(pbds),
            num_pbds + 1,
            "'len(pbds)' is not equal to 'num_pbds + 1'."
        )

        num_pbds = num_pbds + 1

        num_pbds_not_attached = 0

        for pbd in pbds:
            pbd_record = self.xen_session.xenapi.PBD.get_record(pbd)

            if pbd_record["currently_attached"] == False:
                num_pbds_not_attached = num_pbds_not_attached + 1

        self.assertEqual(
            num_pbds_not_attached,
            1,
            "'num_pbds_not_attached' is not equal to 1."
        )

        host = Host.create(
            self.apiClient,
            self.cluster,
            self.testdata[TestData.newXenServerHost],
            hypervisor="XenServer"
        )

        self.assertTrue(
            isinstance(host, Host),
            "'host' is not a 'Host'."
        )

        pbds = self.xen_session.xenapi.SR.get_PBDs(xen_sr)

        self.assertEqual(
            len(pbds),
            num_pbds,
            "'len(pbds)' is not equal to 'num_pbds'."
        )

        self._verify_all_pbds_attached(pbds)

        host_iscsi_iqns = self._get_xenserver_host_iscsi_iqns()

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_new = len(sf_vag_initiators)

        self.assertEqual(
            sf_vag_initiators_len_new,
            sf_vag_initiators_len_orig + 1,
            "sf_vag_initiators_len_new' != sf_vag_initiators_len_orig + 1"
        )

        host.delete(self.apiClient)

        pbds = self.xen_session.xenapi.SR.get_PBDs(xen_sr)

        self.assertEqual(
            len(pbds),
            num_pbds,
            "'len(pbds)' is not equal to 'num_pbds'."
        )

        self._verify_all_pbds_attached(pbds)

        host_iscsi_iqns = self._get_xenserver_host_iscsi_iqns()

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self.assertEqual(
            len(host_iscsi_iqns) - 1,
            len(sf_vag_initiators),
            "'len(host_iscsi_iqns) - 1' is not equal to 'len(sf_vag_initiators)'."
        )

        host_ref = self.xen_session.xenapi.host.get_by_name_label(self.testdata[TestData.newHostDisplayName])[0]

        self.xen_session.xenapi.pool.eject(host_ref)

        time.sleep(120)

        pbds = self.xen_session.xenapi.SR.get_PBDs(xen_sr)

        self.assertEqual(
            len(pbds),
            num_pbds - 1,
            "'len(pbds)' is not equal to 'num_pbds - 1'."
        )

        self._verify_all_pbds_attached(pbds)

        host_iscsi_iqns = self._get_xenserver_host_iscsi_iqns()

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_new = len(sf_vag_initiators)

        self.assertEqual(
            sf_vag_initiators_len_new,
            sf_vag_initiators_len_orig,
            "sf_vag_initiators_len_new' != sf_vag_initiators_len_orig"
        )

    def _perform_add_remove_kvm_host(self, primary_storage_id):
        sf_vag_id = self._get_sf_vag_id(self.cluster.id, primary_storage_id)

        kvm_login = self.testdata[TestData.kvm]

        kvm_hosts = []

        kvm_hosts.append(TestData.kvm_1_ip_address)

        host_iscsi_iqns = self._get_kvm_host_iscsi_iqns(kvm_hosts, kvm_login[TestData.username], kvm_login[TestData.password])

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_orig = len(sf_vag_initiators)

        host = Host.create(
            self.apiClient,
            self.cluster,
            self.testdata[TestData.newKvmHost],
            hypervisor="KVM"
        )

        self.assertTrue(
            isinstance(host, Host),
            "'host' is not a 'Host'."
        )

        kvm_hosts = []

        kvm_hosts.append(TestData.kvm_1_ip_address)
        kvm_hosts.append(TestData.ip_address_of_new_kvm_host)

        host_iscsi_iqns = self._get_kvm_host_iscsi_iqns(kvm_hosts, kvm_login[TestData.username], kvm_login[TestData.password])

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_new = len(sf_vag_initiators)

        self.assertEqual(
            sf_vag_initiators_len_new,
            sf_vag_initiators_len_orig + 1,
            "sf_vag_initiators_len_new' != sf_vag_initiators_len_orig + 1"
        )

        host.delete(self.apiClient)

        kvm_hosts = []

        kvm_hosts.append(TestData.kvm_1_ip_address)

        host_iscsi_iqns = self._get_kvm_host_iscsi_iqns(kvm_hosts, kvm_login[TestData.username], kvm_login[TestData.password])

        sf_vag = self._get_sf_vag(sf_vag_id)

        sf_vag_initiators = self._get_sf_vag_initiators(sf_vag)

        self._verifyVag(host_iscsi_iqns, sf_vag_initiators)

        sf_vag_initiators_len_new = len(sf_vag_initiators)

        self.assertEqual(
            sf_vag_initiators_len_new,
            sf_vag_initiators_len_orig,
            "sf_vag_initiators_len_new' != sf_vag_initiators_len_orig"
        )

    def _verify_all_pbds_attached(self, pbds):
        for pbd in pbds:
            pbd_record = self.xen_session.xenapi.PBD.get_record(pbd)

            self.assertEqual(
                pbd_record["currently_attached"],
                True,
                "Not all PBDs are currently attached."
            )

    def _get_root_volume(self, vm):
        list_volumes_response = list_volumes(
            self.apiClient,
            virtualmachineid=vm.id,
            listall=True
        )

        self.assertNotEqual(
            list_volumes_response,
            None,
            "'list_volumes_response' should not be equal to 'None'."
        )

        self.assertEqual(
            len(list_volumes_response) > 0,
            True,
            "'len(list_volumes_response)' should be greater than 0."
        )

        for volume in list_volumes_response:
            if volume.type.upper() == "ROOT":
                return volume

        self.assert_(False, "Unable to locate the ROOT volume of the VM with the following ID: " + str(vm.id))

    def _get_iqn_2(self, primary_storage):
        sql_query = "Select path From storage_pool Where uuid = '" + str(primary_storage.id) + "'"

        # make sure you can connect to MySQL: https://teamtreehouse.com/community/cant-connect-remotely-to-mysql-server-with-mysql-workbench
        sql_result = self.dbConnection.execute(sql_query)

        return sql_result[0][0]

    def _get_xenserver_host_iscsi_iqns(self):
        hosts = self.xen_session.xenapi.host.get_all()

        self.assertEqual(
            isinstance(hosts, list),
            True,
            "'hosts' is not a list."
        )

        host_iscsi_iqns = []

        for host in hosts:
            host_iscsi_iqns.append(self._get_xenserver_host_iscsi_iqn(host))

        return host_iscsi_iqns

    def _get_xenserver_host_iscsi_iqn(self, host):
        other_config = self.xen_session.xenapi.host.get_other_config(host)

        return other_config["iscsi_iqn"]

    def _get_kvm_host_iscsi_iqns(self, kvm_ip_addresses, common_username, common_password):
        host_iscsi_iqns = []

        for kvm_ip_address in kvm_ip_addresses:
            host_iscsi_iqn = self._get_kvm_iqn(kvm_ip_address, common_username, common_password)

            host_iscsi_iqns.append(host_iscsi_iqn)

        return host_iscsi_iqns

    def _get_kvm_iqn(self, ip_address, username, password):
        ssh_connection = sf_util.get_ssh_connection(ip_address, username, password)

        searchFor = "InitiatorName="

        stdin, stdout, stderr = ssh_connection.exec_command("sudo grep " + searchFor + " /etc/iscsi/initiatorname.iscsi")

        result = stdout.read()

        ssh_connection.close()

        self.assertFalse(result is None, "Unable to locate the IQN of the KVM host (None)")
        self.assertFalse(len(result.strip()) == 0, "Unable to locate the IQN of the KVM host (Zero-length string)")

        return result[len(searchFor):].strip()

    def _get_sf_vag_id(self, cluster_id, primary_storage_id):
        # Get SF Volume Access Group ID
        sf_vag_id_request = {'clusterid': cluster_id, 'storageid': primary_storage_id}
        sf_vag_id_result = self.cs_api.getSolidFireVolumeAccessGroupId(sf_vag_id_request)
        sf_vag_id = sf_vag_id_result['apisolidfirevolumeaccessgroupid']['solidFireVolumeAccessGroupId']

        self.assertEqual(
            isinstance(sf_vag_id, int),
            True,
            TestAddRemoveHosts._vag_id_should_be_non_zero_int_err_msg
        )

        return sf_vag_id

    def _get_sf_vag(self, sf_vag_id):
        return self.sfe.list_volume_access_groups(sf_vag_id, 1).volume_access_groups[0]

    def _get_sf_vag_initiators(self, sf_vag):
        return sf_vag.initiators

    def _verifyVag(self, host_iscsi_iqns, sf_vag_initiators):
        self.assertEqual(
            isinstance(host_iscsi_iqns, list),
            True,
            "'host_iscsi_iqns' is not a list."
        )

        self.assertEqual(
            isinstance(sf_vag_initiators, list),
            True,
            "'sf_vag_initiators' is not a list."
        )

        self.assertEqual(
            len(host_iscsi_iqns),
            len(sf_vag_initiators),
            "Lists are not the same size."
        )

        for host_iscsi_iqn in host_iscsi_iqns:
            # an error should occur if host_iscsi_iqn is not in sf_vag_initiators
            sf_vag_initiators.index(host_iscsi_iqn)

    @classmethod
    def _connect_to_hypervisor(cls):
        if TestData.hypervisor_type == TestData.kvm:
            pass
        elif TestData.hypervisor_type == TestData.xenServer:
            host_ip = "https://" + \
                  list_hosts(cls.apiClient, clusterid=cls.testdata[TestData.clusterId], name=TestData.xen_server_master_hostname)[0].ipaddress

            cls.xen_session = XenAPI.Session(host_ip)

            xen_server = cls.testdata[TestData.xenServer]

            cls.xen_session.xenapi.login_with_password(xen_server[TestData.username], xen_server[TestData.password])

