# -*- coding: utf-8 -*-

##
# Copyright 2016-2017 VMware Inc.
# This file is part of ETSI OSM
# All Rights Reserved.
#
# Licensed 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.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact:  osslegalrouting@vmware.com
##

"""
vimconn_vmware implementation an Abstract class in order to interact with VMware  vCloud Director.
mbayramov@vmware.com
"""
from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar

import vimconn
import os
import shutil
import subprocess
import tempfile
import traceback
import itertools
import requests
import ssl
import atexit

from pyVmomi import vim, vmodl
from pyVim.connect import SmartConnect, Disconnect

from xml.etree import ElementTree as XmlElementTree
from lxml import etree as lxmlElementTree

import yaml
from pyvcloud.vcd.client import BasicLoginCredentials,Client,VcdTaskException
from pyvcloud.vcd.vdc import VDC
from pyvcloud.vcd.org import Org
import re
from pyvcloud.vcd.vapp import VApp
from xml.sax.saxutils import escape
import logging
import json
import time
import uuid
import httplib
#For python3
#import http.client
import hashlib
import socket
import struct
import netaddr
import random

# global variable for vcd connector type
STANDALONE = 'standalone'

# key for flavor dicts
FLAVOR_RAM_KEY = 'ram'
FLAVOR_VCPUS_KEY = 'vcpus'
FLAVOR_DISK_KEY = 'disk'
DEFAULT_IP_PROFILE = {'dhcp_count':50,
                      'dhcp_enabled':True,
                      'ip_version':"IPv4"
                      }
# global variable for wait time
INTERVAL_TIME = 5
MAX_WAIT_TIME = 1800

API_VERSION = '27.0'

__author__ = "Mustafa Bayramov, Arpita Kate, Sachin Bhangare, Prakash Kasar"
__date__ = "$09-Mar-2018 11:09:29$"
__version__ = '0.2'

#     -1: "Could not be created",
#     0: "Unresolved",
#     1: "Resolved",
#     2: "Deployed",
#     3: "Suspended",
#     4: "Powered on",
#     5: "Waiting for user input",
#     6: "Unknown state",
#     7: "Unrecognized state",
#     8: "Powered off",
#     9: "Inconsistent state",
#     10: "Children do not all have the same status",
#     11: "Upload initiated, OVF descriptor pending",
#     12: "Upload initiated, copying contents",
#     13: "Upload initiated , disk contents pending",
#     14: "Upload has been quarantined",
#     15: "Upload quarantine period has expired"

# mapping vCD status to MANO
vcdStatusCode2manoFormat = {4: 'ACTIVE',
                            7: 'PAUSED',
                            3: 'SUSPENDED',
                            8: 'INACTIVE',
                            12: 'BUILD',
                            -1: 'ERROR',
                            14: 'DELETED'}

#
netStatus2manoFormat = {'ACTIVE': 'ACTIVE', 'PAUSED': 'PAUSED', 'INACTIVE': 'INACTIVE', 'BUILD': 'BUILD',
                        'ERROR': 'ERROR', 'DELETED': 'DELETED'
                        }

class vimconnector(vimconn.vimconnector):
    # dict used to store flavor in memory
    flavorlist = {}

    def __init__(self, uuid=None, name=None, tenant_id=None, tenant_name=None,
                 url=None, url_admin=None, user=None, passwd=None, log_level=None, config={}, persistent_info={}):
        """
        Constructor create vmware connector to vCloud director.

        By default construct doesn't validate connection state. So client can create object with None arguments.
        If client specified username , password and host and VDC name.  Connector initialize other missing attributes.

        a) It initialize organization UUID
        b) Initialize tenant_id/vdc ID.   (This information derived from tenant name)

        Args:
            uuid - is organization uuid.
            name - is organization name that must be presented in vCloud director.
            tenant_id - is VDC uuid it must be presented in vCloud director
            tenant_name - is VDC name.
            url - is hostname or ip address of vCloud director
            url_admin - same as above.
            user - is user that administrator for organization. Caller must make sure that
                    username has right privileges.

            password - is password for a user.

            VMware connector also requires PVDC administrative privileges and separate account.
            This variables must be passed via config argument dict contains keys

            dict['admin_username']
            dict['admin_password']
            config - Provide NSX and vCenter information

            Returns:
                Nothing.
        """

        vimconn.vimconnector.__init__(self, uuid, name, tenant_id, tenant_name, url,
                                      url_admin, user, passwd, log_level, config)

        self.logger = logging.getLogger('openmano.vim.vmware')
        self.logger.setLevel(10)
        self.persistent_info = persistent_info

        self.name = name
        self.id = uuid
        self.url = url
        self.url_admin = url_admin
        self.tenant_id = tenant_id
        self.tenant_name = tenant_name
        self.user = user
        self.passwd = passwd
        self.config = config
        self.admin_password = None
        self.admin_user = None
        self.org_name = ""
        self.nsx_manager = None
        self.nsx_user = None
        self.nsx_password = None
        self.availability_zone = None

        # Disable warnings from self-signed certificates.
        requests.packages.urllib3.disable_warnings()

        if tenant_name is not None:
            orgnameandtenant = tenant_name.split(":")
            if len(orgnameandtenant) == 2:
                self.tenant_name = orgnameandtenant[1]
                self.org_name = orgnameandtenant[0]
            else:
                self.tenant_name = tenant_name
        if "orgname" in config:
            self.org_name = config['orgname']

        if log_level:
            self.logger.setLevel(getattr(logging, log_level))

        try:
            self.admin_user = config['admin_username']
            self.admin_password = config['admin_password']
        except KeyError:
            raise vimconn.vimconnException(message="Error admin username or admin password is empty.")

        try:
            self.nsx_manager = config['nsx_manager']
            self.nsx_user = config['nsx_user']
            self.nsx_password = config['nsx_password']
        except KeyError:
            raise vimconn.vimconnException(message="Error: nsx manager or nsx user or nsx password is empty in Config")

        self.vcenter_ip = config.get("vcenter_ip", None)
        self.vcenter_port = config.get("vcenter_port", None)
        self.vcenter_user = config.get("vcenter_user", None)
        self.vcenter_password = config.get("vcenter_password", None)

        #Set availability zone for Affinity rules
        self.availability_zone = self.set_availability_zones()

# ############# Stub code for SRIOV #################
#         try:
#             self.dvs_name = config['dv_switch_name']
#         except KeyError:
#             raise vimconn.vimconnException(message="Error: distributed virtaul switch name is empty in Config")
#
#         self.vlanID_range = config.get("vlanID_range", None)

        self.org_uuid = None
        self.client = None

        if not url:
            raise vimconn.vimconnException('url param can not be NoneType')

        if not self.url_admin:  # try to use normal url
            self.url_admin = self.url

        logging.debug("UUID: {} name: {} tenant_id: {} tenant name {}".format(self.id, self.org_name,
                                                                              self.tenant_id, self.tenant_name))
        logging.debug("vcd url {} vcd username: {} vcd password: {}".format(self.url, self.user, self.passwd))
        logging.debug("vcd admin username {} vcd admin passowrd {}".format(self.admin_user, self.admin_password))

        # initialize organization
        if self.user is not None and self.passwd is not None and self.url:
            self.init_organization()

    def __getitem__(self, index):
        if index == 'name':
            return self.name
        if index == 'tenant_id':
            return self.tenant_id
        if index == 'tenant_name':
            return self.tenant_name
        elif index == 'id':
            return self.id
        elif index == 'org_name':
            return self.org_name
        elif index == 'org_uuid':
            return self.org_uuid
        elif index == 'user':
            return self.user
        elif index == 'passwd':
            return self.passwd
        elif index == 'url':
            return self.url
        elif index == 'url_admin':
            return self.url_admin
        elif index == "config":
            return self.config
        else:
            raise KeyError("Invalid key '%s'" % str(index))

    def __setitem__(self, index, value):
        if index == 'name':
            self.name = value
        if index == 'tenant_id':
            self.tenant_id = value
        if index == 'tenant_name':
            self.tenant_name = value
        elif index == 'id':
            self.id = value
        elif index == 'org_name':
            self.org_name = value
        elif index == 'org_uuid':
            self.org_uuid = value
        elif index == 'user':
            self.user = value
        elif index == 'passwd':
            self.passwd = value
        elif index == 'url':
            self.url = value
        elif index == 'url_admin':
            self.url_admin = value
        else:
            raise KeyError("Invalid key '%s'" % str(index))

    def connect_as_admin(self):
        """ Method connect as pvdc admin user to vCloud director.
            There are certain action that can be done only by provider vdc admin user.
            Organization creation / provider network creation etc.

            Returns:
                The return client object that latter can be used to connect to vcloud director as admin for provider vdc
        """
        self.logger.debug("Logging into vCD {} as admin.".format(self.org_name))

        try:
            host = self.url
            org = 'System'
            client_as_admin = Client(host, verify_ssl_certs=False)
            client_as_admin.set_highest_supported_version()
            client_as_admin.set_credentials(BasicLoginCredentials(self.admin_user, org, self.admin_password))
        except Exception as e:
            raise vimconn.vimconnException(
                  "Can't connect to a vCloud director as: {} with exception {}".format(self.admin_user, e))

        return client_as_admin

    def connect(self):
        """ Method connect as normal user to vCloud director.

            Returns:
                The return client object that latter can be used to connect to vCloud director as admin for VDC
        """
        try:
            self.logger.debug("Logging into vCD {} as {} to datacenter {}.".format(self.org_name,
                                                                                      self.user,
                                                                                      self.org_name))
            host = self.url
            client = Client(host, verify_ssl_certs=False)
            client.set_highest_supported_version()
            client.set_credentials(BasicLoginCredentials(self.user, self.org_name, self.passwd))
        except:
            raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: "
                                                     "{} as user: {}".format(self.org_name, self.user))

        return client

    def init_organization(self):
        """ Method initialize organization UUID and VDC parameters.

            At bare minimum client must provide organization name that present in vCloud director and VDC.

            The VDC - UUID ( tenant_id) will be initialized at the run time if client didn't call constructor.
            The Org - UUID will be initialized at the run time if data center present in vCloud director.

            Returns:
                The return vca object that letter can be used to connect to vcloud direct as admin
        """
        client = self.connect()
        if not client:
            raise vimconn.vimconnConnectionException("Failed to connect vCD.")

        self.client = client
        try:
            if self.org_uuid is None:
                org_list = client.get_org_list()
                for org in org_list.Org:
                    # we set org UUID at the init phase but we can do it only when we have valid credential.
                    if org.get('name') == self.org_name:
                        self.org_uuid = org.get('href').split('/')[-1]
                        self.logger.debug("Setting organization UUID {}".format(self.org_uuid))
                        break
                else:
                    raise vimconn.vimconnException("Vcloud director organization {} not found".format(self.org_name))

                # if well good we require for org details
                org_details_dict = self.get_org(org_uuid=self.org_uuid)

                # we have two case if we want to initialize VDC ID or VDC name at run time
                # tenant_name provided but no tenant id
                if self.tenant_id is None and self.tenant_name is not None and 'vdcs' in org_details_dict:
                    vdcs_dict = org_details_dict['vdcs']
                    for vdc in vdcs_dict:
                        if vdcs_dict[vdc] == self.tenant_name:
                            self.tenant_id = vdc
                            self.logger.debug("Setting vdc uuid {} for organization UUID {}".format(self.tenant_id,
                                                                                                    self.org_name))
                            break
                    else:
                        raise vimconn.vimconnException("Tenant name indicated but not present in vcloud director.")
                    # case two we have tenant_id but we don't have tenant name so we find and set it.
                    if self.tenant_id is not None and self.tenant_name is None and 'vdcs' in org_details_dict:
                        vdcs_dict = org_details_dict['vdcs']
                        for vdc in vdcs_dict:
                            if vdc == self.tenant_id:
                                self.tenant_name = vdcs_dict[vdc]
                                self.logger.debug("Setting vdc uuid {} for organization UUID {}".format(self.tenant_id,
                                                                                                        self.org_name))
                                break
                        else:
                            raise vimconn.vimconnException("Tenant id indicated but not present in vcloud director")
            self.logger.debug("Setting organization uuid {}".format(self.org_uuid))
        except:
            self.logger.debug("Failed initialize organization UUID for org {}".format(self.org_name))
            self.logger.debug(traceback.format_exc())
            self.org_uuid = None

    def new_tenant(self, tenant_name=None, tenant_description=None):
        """ Method adds a new tenant to VIM with this name.
            This action requires access to create VDC action in vCloud director.

            Args:
                tenant_name is tenant_name to be created.
                tenant_description not used for this call

            Return:
                returns the tenant identifier in UUID format.
                If action is failed method will throw vimconn.vimconnException method
            """
        vdc_task = self.create_vdc(vdc_name=tenant_name)
        if vdc_task is not None:
            vdc_uuid, value = vdc_task.popitem()
            self.logger.info("Created new vdc {} and uuid: {}".format(tenant_name, vdc_uuid))
            return vdc_uuid
        else:
            raise vimconn.vimconnException("Failed create tenant {}".format(tenant_name))

    def delete_tenant(self, tenant_id=None):
        """ Delete a tenant from VIM
             Args:
                tenant_id is tenant_id to be deleted.

            Return:
                returns the tenant identifier in UUID format.
                If action is failed method will throw exception
        """
        vca = self.connect_as_admin()
        if not vca:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")

        if tenant_id is not None:
            if vca._session:
                #Get OrgVDC
                url_list = [self.url, '/api/vdc/', tenant_id]
                orgvdc_herf = ''.join(url_list)

                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                                url=orgvdc_herf,
                                                headers=headers)

                if response.status_code != requests.codes.ok:
                    self.logger.debug("delete_tenant():GET REST API call {} failed. "\
                                      "Return status code {}".format(orgvdc_herf,
                                                                     response.status_code))
                    raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id))

                lxmlroot_respond = lxmlElementTree.fromstring(response.content)
                namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
                #For python3
                #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix}
                namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
                vdc_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href']
                vdc_remove_href = vdc_remove_href + '?recursive=true&force=true'

                response = self.perform_request(req_type='DELETE',
                                                url=vdc_remove_href,
                                                headers=headers)

                if response.status_code == 202:
                    time.sleep(5)
                    return tenant_id
                else:
                    self.logger.debug("delete_tenant(): DELETE REST API call {} failed. "\
                                      "Return status code {}".format(vdc_remove_href,
                                                                     response.status_code))
                    raise vimconn.vimconnException("Fail to delete tenant with ID {}".format(tenant_id))
        else:
            self.logger.debug("delete_tenant():Incorrect tenant ID  {}".format(tenant_id))
            raise vimconn.vimconnNotFoundException("Fail to get tenant {}".format(tenant_id))


    def get_tenant_list(self, filter_dict={}):
        """Obtain tenants of VIM
        filter_dict can contain the following keys:
            name: filter by tenant name
            id: filter by tenant uuid/id
            <other VIM specific>
        Returns the tenant list of dictionaries:
            [{'name':'<name>, 'id':'<id>, ...}, ...]

        """
        org_dict = self.get_org(self.org_uuid)
        vdcs_dict = org_dict['vdcs']

        vdclist = []
        try:
            for k in vdcs_dict:
                entry = {'name': vdcs_dict[k], 'id': k}
                # if caller didn't specify dictionary we return all tenants.
                if filter_dict is not None and filter_dict:
                    filtered_entry = entry.copy()
                    filtered_dict = set(entry.keys()) - set(filter_dict)
                    for unwanted_key in filtered_dict: del entry[unwanted_key]
                    if filter_dict == entry:
                        vdclist.append(filtered_entry)
                else:
                    vdclist.append(entry)
        except:
            self.logger.debug("Error in get_tenant_list()")
            self.logger.debug(traceback.format_exc())
            raise vimconn.vimconnException("Incorrect state. {}")

        return vdclist

    def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
        """Adds a tenant network to VIM
        Params:
            'net_name': name of the network
            'net_type': one of:
                'bridge': overlay isolated network
                'data':   underlay E-LAN network for Passthrough and SRIOV interfaces
                'ptp':    underlay E-LINE network for Passthrough and SRIOV interfaces.
            'ip_profile': is a dict containing the IP parameters of the network
                'ip_version': can be "IPv4" or "IPv6" (Currently only IPv4 is implemented)
                'subnet_address': ip_prefix_schema, that is X.X.X.X/Y
                'gateway_address': (Optional) ip_schema, that is X.X.X.X
                'dns_address': (Optional) comma separated list of ip_schema, e.g. X.X.X.X[,X,X,X,X]
                'dhcp_enabled': True or False
                'dhcp_start_address': ip_schema, first IP to grant
                'dhcp_count': number of IPs to grant.
            'shared': if this network can be seen/use by other tenants/organization
            'vlan': in case of a data or ptp net_type, the intended vlan tag to be used for the network
        Returns a tuple with the network identifier and created_items, or raises an exception on error
            created_items can be None or a dictionary where this method can include key-values that will be passed to
            the method delete_network. Can be used to store created segments, created l2gw connections, etc.
            Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
            as not present.
        """

        self.logger.debug("new_network tenant {} net_type {} ip_profile {} shared {}"
                          .format(net_name, net_type, ip_profile, shared))

        created_items = {}
        isshared = 'false'
        if shared:
            isshared = 'true'

# ############# Stub code for SRIOV #################
#         if net_type == "data" or net_type == "ptp":
#             if self.config.get('dv_switch_name') == None:
#                  raise vimconn.vimconnConflictException("You must provide 'dv_switch_name' at config value")
#             network_uuid = self.create_dvPort_group(net_name)

        network_uuid = self.create_network(network_name=net_name, net_type=net_type,
                                           ip_profile=ip_profile, isshared=isshared)
        if network_uuid is not None:
            return network_uuid, created_items
        else:
            raise vimconn.vimconnUnexpectedResponse("Failed create a new network {}".format(net_name))

    def get_vcd_network_list(self):
        """ Method available organization for a logged in tenant

            Returns:
                The return vca object that letter can be used to connect to vcloud direct as admin
        """

        self.logger.debug("get_vcd_network_list(): retrieving network list for vcd {}".format(self.tenant_name))

        if not self.tenant_name:
            raise vimconn.vimconnConnectionException("Tenant name is empty.")

        org, vdc = self.get_vdc_details()
        if vdc is None:
            raise vimconn.vimconnConnectionException("Can't retrieve information for a VDC {}".format(self.tenant_name))

        vdc_uuid = vdc.get('id').split(":")[3]
        if self.client._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                           url=vdc.get('href'),
                                               headers=headers)
        if response.status_code != 200:
            self.logger.error("Failed to get vdc content")
            raise vimconn.vimconnNotFoundException("Failed to get vdc content")
        else:
            content = XmlElementTree.fromstring(response.content)

        network_list = []
        try:
            for item in content:
                if item.tag.split('}')[-1] == 'AvailableNetworks':
                    for net in item:
                        response = self.perform_request(req_type='GET',
                                                   url=net.get('href'),
                                                       headers=headers)

                        if response.status_code != 200:
                            self.logger.error("Failed to get network content")
                            raise vimconn.vimconnNotFoundException("Failed to get network content")
                        else:
                            net_details = XmlElementTree.fromstring(response.content)

                            filter_dict = {}
                            net_uuid = net_details.get('id').split(":")
                            if len(net_uuid) != 4:
                                continue
                            else:
                                net_uuid = net_uuid[3]
                                # create dict entry
                                self.logger.debug("get_vcd_network_list(): Adding network {} "
                                                  "to a list vcd id {} network {}".format(net_uuid,
                                                                                          vdc_uuid,
                                                                                          net_details.get('name')))
                                filter_dict["name"] = net_details.get('name')
                                filter_dict["id"] = net_uuid
                                if [i.text for i in net_details if i.tag.split('}')[-1] == 'IsShared'][0] == 'true':
                                    shared = True
                                else:
                                    shared = False
                                filter_dict["shared"] = shared
                                filter_dict["tenant_id"] = vdc_uuid
                                if int(net_details.get('status')) == 1:
                                    filter_dict["admin_state_up"] = True
                                else:
                                    filter_dict["admin_state_up"] = False
                                filter_dict["status"] = "ACTIVE"
                                filter_dict["type"] = "bridge"
                                network_list.append(filter_dict)
                                self.logger.debug("get_vcd_network_list adding entry {}".format(filter_dict))
        except:
            self.logger.debug("Error in get_vcd_network_list", exc_info=True)
            pass

        self.logger.debug("get_vcd_network_list returning {}".format(network_list))
        return network_list

    def get_network_list(self, filter_dict={}):
        """Obtain tenant networks of VIM
        Filter_dict can be:
            name: network name  OR/AND
            id: network uuid    OR/AND
            shared: boolean     OR/AND
            tenant_id: tenant   OR/AND
            admin_state_up: boolean
            status: 'ACTIVE'

        [{key : value , key : value}]

        Returns the network list of dictionaries:
            [{<the fields at Filter_dict plus some VIM specific>}, ...]
            List can be empty
        """

        self.logger.debug("get_network_list(): retrieving network list for vcd {}".format(self.tenant_name))

        if not self.tenant_name:
            raise vimconn.vimconnConnectionException("Tenant name is empty.")

        org, vdc = self.get_vdc_details()
        if vdc is None:
            raise vimconn.vimconnConnectionException("Can't retrieve information for a VDC {}.".format(self.tenant_name))

        try:
            vdcid = vdc.get('id').split(":")[3]

            if self.client._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                           url=vdc.get('href'),
                                               headers=headers)
            if response.status_code != 200:
                self.logger.error("Failed to get vdc content")
                raise vimconn.vimconnNotFoundException("Failed to get vdc content")
            else:
                content = XmlElementTree.fromstring(response.content)

            network_list = []
            for item in content:
                if item.tag.split('}')[-1] == 'AvailableNetworks':
                    for net in item:
                        response = self.perform_request(req_type='GET',
                                                   url=net.get('href'),
                                                       headers=headers)

                        if response.status_code != 200:
                            self.logger.error("Failed to get network content")
                            raise vimconn.vimconnNotFoundException("Failed to get network content")
                        else:
                            net_details = XmlElementTree.fromstring(response.content)

                            filter_entry = {}
                            net_uuid = net_details.get('id').split(":")
                            if len(net_uuid) != 4:
                                continue
                            else:
                                net_uuid = net_uuid[3]
                                # create dict entry
                                self.logger.debug("get_network_list(): Adding net {}"
                                                  " to a list vcd id {} network {}".format(net_uuid,
                                                                                           vdcid,
                                                                                           net_details.get('name')))
                                filter_entry["name"] = net_details.get('name')
                                filter_entry["id"] = net_uuid
                                if [i.text for i in net_details if i.tag.split('}')[-1] == 'IsShared'][0] == 'true':
                                    shared = True
                                else:
                                    shared = False
                                filter_entry["shared"] = shared
                                filter_entry["tenant_id"] = vdcid
                                if int(net_details.get('status')) == 1:
                                    filter_entry["admin_state_up"] = True
                                else:
                                    filter_entry["admin_state_up"] = False
                                filter_entry["status"] = "ACTIVE"
                                filter_entry["type"] = "bridge"
                                filtered_entry = filter_entry.copy()

                                if filter_dict is not None and filter_dict:
                                    # we remove all the key : value we don't care and match only
                                    # respected field
                                    filtered_dict = set(filter_entry.keys()) - set(filter_dict)
                                    for unwanted_key in filtered_dict: del filter_entry[unwanted_key]
                                    if filter_dict == filter_entry:
                                        network_list.append(filtered_entry)
                                else:
                                    network_list.append(filtered_entry)
        except Exception as e:
            self.logger.debug("Error in get_network_list",exc_info=True)
            if isinstance(e, vimconn.vimconnException):
                raise
            else:
                raise vimconn.vimconnNotFoundException("Failed : Networks list not found {} ".format(e))

        self.logger.debug("Returning {}".format(network_list))
        return network_list

    def get_network(self, net_id):
        """Method obtains network details of net_id VIM network
           Return a dict with  the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]"""

        try:
            org, vdc = self.get_vdc_details()
            vdc_id = vdc.get('id').split(":")[3]
            if self.client._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                           url=vdc.get('href'),
                                               headers=headers)
            if response.status_code != 200:
                self.logger.error("Failed to get vdc content")
                raise vimconn.vimconnNotFoundException("Failed to get vdc content")
            else:
                content = XmlElementTree.fromstring(response.content)

            filter_dict = {}

            for item in content:
                if item.tag.split('}')[-1] == 'AvailableNetworks':
                    for net in item:
                        response = self.perform_request(req_type='GET',
                                                   url=net.get('href'),
                                                       headers=headers)

                        if response.status_code != 200:
                            self.logger.error("Failed to get network content")
                            raise vimconn.vimconnNotFoundException("Failed to get network content")
                        else:
                            net_details = XmlElementTree.fromstring(response.content)

                            vdc_network_id = net_details.get('id').split(":")
                            if len(vdc_network_id) == 4 and vdc_network_id[3] == net_id:
                                filter_dict["name"] = net_details.get('name')
                                filter_dict["id"] = vdc_network_id[3]
                                if [i.text for i in net_details if i.tag.split('}')[-1] == 'IsShared'][0] == 'true':
                                    shared = True
                                else:
                                    shared = False
                                filter_dict["shared"] = shared
                                filter_dict["tenant_id"] = vdc_id
                                if int(net_details.get('status')) == 1:
                                    filter_dict["admin_state_up"] = True
                                else:
                                    filter_dict["admin_state_up"] = False
                                filter_dict["status"] = "ACTIVE"
                                filter_dict["type"] = "bridge"
                                self.logger.debug("Returning {}".format(filter_dict))
                                return filter_dict
                    else:
                        raise vimconn.vimconnNotFoundException("Network {} not found".format(net_id))
        except Exception as e:
            self.logger.debug("Error in get_network")
            self.logger.debug(traceback.format_exc())
            if isinstance(e, vimconn.vimconnException):
                raise
            else:
                raise vimconn.vimconnNotFoundException("Failed : Network not found {} ".format(e))

        return filter_dict

    def delete_network(self, net_id, created_items=None):
        """
        Removes a tenant network from VIM and its associated elements
        :param net_id: VIM identifier of the network, provided by method new_network
        :param created_items: dictionary with extra items to be deleted. provided by method new_network
        Returns the network identifier or raises an exception upon error or when network is not found
        """

        # ############# Stub code for SRIOV #################
#         dvport_group = self.get_dvport_group(net_id)
#         if dvport_group:
#             #delete portgroup
#             status = self.destroy_dvport_group(net_id)
#             if status:
#                 # Remove vlanID from persistent info
#                 if net_id in self.persistent_info["used_vlanIDs"]:
#                     del self.persistent_info["used_vlanIDs"][net_id]
#
#                 return net_id

        vcd_network = self.get_vcd_network(network_uuid=net_id)
        if vcd_network is not None and vcd_network:
            if self.delete_network_action(network_uuid=net_id):
                return net_id
        else:
            raise vimconn.vimconnNotFoundException("Network {} not found".format(net_id))

    def refresh_nets_status(self, net_list):
        """Get the status of the networks
           Params: the list of network identifiers
           Returns a dictionary with:
                net_id:         #VIM id of this network
                    status:     #Mandatory. Text with one of:
                                #  DELETED (not found at vim)
                                #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
                                #  OTHER (Vim reported other status not understood)
                                #  ERROR (VIM indicates an ERROR status)
                                #  ACTIVE, INACTIVE, DOWN (admin down),
                                #  BUILD (on building process)
                                #
                    error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
                    vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)

        """

        dict_entry = {}
        try:
            for net in net_list:
                errormsg = ''
                vcd_network = self.get_vcd_network(network_uuid=net)
                if vcd_network is not None and vcd_network:
                    if vcd_network['status'] == '1':
                        status = 'ACTIVE'
                    else:
                        status = 'DOWN'
                else:
                    status = 'DELETED'
                    errormsg = 'Network not found.'

                dict_entry[net] = {'status': status, 'error_msg': errormsg,
                                   'vim_info': yaml.safe_dump(vcd_network)}
        except:
            self.logger.debug("Error in refresh_nets_status")
            self.logger.debug(traceback.format_exc())

        return dict_entry

    def get_flavor(self, flavor_id):
        """Obtain flavor details from the  VIM
            Returns the flavor dict details {'id':<>, 'name':<>, other vim specific } #TODO to concrete
        """
        if flavor_id not in vimconnector.flavorlist:
            raise vimconn.vimconnNotFoundException("Flavor not found.")
        return vimconnector.flavorlist[flavor_id]

    def new_flavor(self, flavor_data):
        """Adds a tenant flavor to VIM
            flavor_data contains a dictionary with information, keys:
                name: flavor name
                ram: memory (cloud type) in MBytes
                vpcus: cpus (cloud type)
                extended: EPA parameters
                  - numas: #items requested in same NUMA
                        memory: number of 1G huge pages memory
                        paired-threads|cores|threads: number of paired hyperthreads, complete cores OR individual threads
                        interfaces: # passthrough(PT) or SRIOV interfaces attached to this numa
                          - name: interface name
                            dedicated: yes|no|yes:sriov;  for PT, SRIOV or only one SRIOV for the physical NIC
                            bandwidth: X Gbps; requested guarantee bandwidth
                            vpci: requested virtual PCI address
                disk: disk size
                is_public:
                 #TODO to concrete
        Returns the flavor identifier"""

        # generate a new uuid put to internal dict and return it.
        self.logger.debug("Creating new flavor - flavor_data: {}".format(flavor_data))
        new_flavor=flavor_data
        ram = flavor_data.get(FLAVOR_RAM_KEY, 1024)
        cpu = flavor_data.get(FLAVOR_VCPUS_KEY, 1)
        disk = flavor_data.get(FLAVOR_DISK_KEY, 0)

        if not isinstance(ram, int):
            raise vimconn.vimconnException("Non-integer value for ram")
        elif not isinstance(cpu, int):
            raise vimconn.vimconnException("Non-integer value for cpu")
        elif not isinstance(disk, int):
            raise vimconn.vimconnException("Non-integer value for disk")

        extended_flv = flavor_data.get("extended")
        if extended_flv:
            numas=extended_flv.get("numas")
            if numas:
                for numa in numas:
                    #overwrite ram and vcpus
                    if 'memory' in numa:
                        ram = numa['memory']*1024
                    if 'paired-threads' in numa:
                        cpu = numa['paired-threads']*2
                    elif 'cores' in numa:
                        cpu = numa['cores']
                    elif 'threads' in numa:
                        cpu = numa['threads']

        new_flavor[FLAVOR_RAM_KEY] = ram
        new_flavor[FLAVOR_VCPUS_KEY] = cpu
        new_flavor[FLAVOR_DISK_KEY] = disk
        # generate a new uuid put to internal dict and return it.
        flavor_id = uuid.uuid4()
        vimconnector.flavorlist[str(flavor_id)] = new_flavor
        self.logger.debug("Created flavor - {} : {}".format(flavor_id, new_flavor))

        return str(flavor_id)

    def delete_flavor(self, flavor_id):
        """Deletes a tenant flavor from VIM identify by its id

           Returns the used id or raise an exception
        """
        if flavor_id not in vimconnector.flavorlist:
            raise vimconn.vimconnNotFoundException("Flavor not found.")

        vimconnector.flavorlist.pop(flavor_id, None)
        return flavor_id

    def new_image(self, image_dict):
        """
        Adds a tenant image to VIM
        Returns:
            200, image-id        if the image is created
            <0, message          if there is an error
        """

        return self.get_image_id_from_path(image_dict['location'])

    def delete_image(self, image_id):
        """
            Deletes a tenant image from VIM
            Args:
                image_id is ID of Image to be deleted
            Return:
                returns the image identifier in UUID format or raises an exception on error
        """
        conn = self.connect_as_admin()
        if not conn:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")
        # Get Catalog details
        url_list = [self.url, '/api/catalog/', image_id]
        catalog_herf = ''.join(url_list)

        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                  'x-vcloud-authorization': conn._session.headers['x-vcloud-authorization']}

        response = self.perform_request(req_type='GET',
                                        url=catalog_herf,
                                        headers=headers)

        if response.status_code != requests.codes.ok:
            self.logger.debug("delete_image():GET REST API call {} failed. "\
                              "Return status code {}".format(catalog_herf,
                                                             response.status_code))
            raise vimconn.vimconnNotFoundException("Fail to get image {}".format(image_id))

        lxmlroot_respond = lxmlElementTree.fromstring(response.content)
        namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
        #For python3
        #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix}
        namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"

        catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems",namespaces)
        catalogItems = catalogItems_section.iterfind("xmlns:CatalogItem",namespaces)
        for catalogItem in catalogItems:
            catalogItem_href = catalogItem.attrib['href']

            response = self.perform_request(req_type='GET',
                                        url=catalogItem_href,
                                        headers=headers)

            if response.status_code != requests.codes.ok:
                self.logger.debug("delete_image():GET REST API call {} failed. "\
                                  "Return status code {}".format(catalog_herf,
                                                                 response.status_code))
                raise vimconn.vimconnNotFoundException("Fail to get catalogItem {} for catalog {}".format(
                                                                                    catalogItem,
                                                                                    image_id))

            lxmlroot_respond = lxmlElementTree.fromstring(response.content)
            namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
            #For python3
            #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix}
            namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
            catalogitem_remove_href = lxmlroot_respond.find("xmlns:Link[@rel='remove']",namespaces).attrib['href']

            #Remove catalogItem
            response = self.perform_request(req_type='DELETE',
                                        url=catalogitem_remove_href,
                                        headers=headers)
            if response.status_code == requests.codes.no_content:
                self.logger.debug("Deleted Catalog item {}".format(catalogItem))
            else:
                raise vimconn.vimconnException("Fail to delete Catalog Item {}".format(catalogItem))

        #Remove catalog
        url_list = [self.url, '/api/admin/catalog/', image_id]
        catalog_remove_herf = ''.join(url_list)
        response = self.perform_request(req_type='DELETE',
                                        url=catalog_remove_herf,
                                        headers=headers)

        if response.status_code == requests.codes.no_content:
            self.logger.debug("Deleted Catalog {}".format(image_id))
            return image_id
        else:
            raise vimconn.vimconnException("Fail to delete Catalog {}".format(image_id))


    def catalog_exists(self, catalog_name, catalogs):
        """

        :param catalog_name:
        :param catalogs:
        :return:
        """
        for catalog in catalogs:
            if catalog['name'] == catalog_name:
                return catalog['id']

    def create_vimcatalog(self, vca=None, catalog_name=None):
        """ Create new catalog entry in vCloud director.

            Args
                vca:  vCloud director.
                catalog_name catalog that client wish to create.   Note no validation done for a name.
                Client must make sure that provide valid string representation.

             Returns catalog id if catalog created else None.

        """
        try:
            lxml_catalog_element = vca.create_catalog(catalog_name, catalog_name)
            if lxml_catalog_element:
                id_attr_value = lxml_catalog_element.get('id')  # 'urn:vcloud:catalog:7490d561-d384-4dac-8229-3575fd1fc7b4'
                return id_attr_value.split(':')[-1]
            catalogs = vca.list_catalogs()
        except Exception as ex:
            self.logger.error(
                'create_vimcatalog(): Creation of catalog "{}" failed with error: {}'.format(catalog_name, ex))
            raise
        return self.catalog_exists(catalog_name, catalogs)

    # noinspection PyIncorrectDocstring
    def upload_ovf(self, vca=None, catalog_name=None, image_name=None, media_file_name=None,
                   description='', progress=False, chunk_bytes=128 * 1024):
        """
        Uploads a OVF file to a vCloud catalog

        :param chunk_bytes:
        :param progress:
        :param description:
        :param image_name:
        :param vca:
        :param catalog_name: (str): The name of the catalog to upload the media.
        :param media_file_name: (str): The name of the local media file to upload.
        :return: (bool) True if the media file was successfully uploaded, false otherwise.
        """
        os.path.isfile(media_file_name)
        statinfo = os.stat(media_file_name)

        #  find a catalog entry where we upload OVF.
        #  create vApp Template and check the status if vCD able to read OVF it will respond with appropirate
        #  status change.
        #  if VCD can parse OVF we upload VMDK file
        try:
            for catalog in vca.list_catalogs():
                if catalog_name != catalog['name']:
                    continue
                catalog_href = "{}/api/catalog/{}/action/upload".format(self.url, catalog['id'])
                data = """
                <UploadVAppTemplateParams name="{}" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"><Description>{} vApp Template</Description></UploadVAppTemplateParams>
                """.format(catalog_name, description)

                if self.client:
                    headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                    headers['Content-Type'] = 'application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml'

                response = self.perform_request(req_type='POST',
                                                url=catalog_href,
                                                headers=headers,
                                                data=data)

                if response.status_code == requests.codes.created:
                    catalogItem = XmlElementTree.fromstring(response.content)
                    entity = [child for child in catalogItem if
                              child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0]
                    href = entity.get('href')
                    template = href

                    response = self.perform_request(req_type='GET',
                                                    url=href,
                                                    headers=headers)

                    if response.status_code == requests.codes.ok:
                        headers['Content-Type'] = 'Content-Type text/xml'
                        result = re.search('rel="upload:default"\shref="(.*?\/descriptor.ovf)"',response.content)
                        if result:
                            transfer_href = result.group(1)

                        response = self.perform_request(req_type='PUT',
                                                    url=transfer_href,
                                                    headers=headers,
                                                    data=open(media_file_name, 'rb'))
                        if response.status_code != requests.codes.ok:
                            self.logger.debug(
                                "Failed create vApp template for catalog name {} and image {}".format(catalog_name,
                                                                                                      media_file_name))
                            return False

                    # TODO fix this with aync block
                    time.sleep(5)

                    self.logger.debug("vApp template for catalog name {} and image {}".format(catalog_name, media_file_name))

                    # uploading VMDK file
                    # check status of OVF upload and upload remaining files.
                    response = self.perform_request(req_type='GET',
                                                    url=template,
                                                    headers=headers)

                    if response.status_code == requests.codes.ok:
                        result = re.search('rel="upload:default"\s*href="(.*?vmdk)"',response.content)
                        if result:
                            link_href = result.group(1)
                        # we skip ovf since it already uploaded.
                        if 'ovf' in link_href:
                            continue
                        # The OVF file and VMDK must be in a same directory
                        head, tail = os.path.split(media_file_name)
                        file_vmdk = head + '/' + link_href.split("/")[-1]
                        if not os.path.isfile(file_vmdk):
                            return False
                        statinfo = os.stat(file_vmdk)
                        if statinfo.st_size == 0:
                            return False
                        hrefvmdk = link_href

                        if progress:
                            widgets = ['Uploading file: ', Percentage(), ' ', Bar(), ' ', ETA(), ' ',
                                           FileTransferSpeed()]
                            progress_bar = ProgressBar(widgets=widgets, maxval=statinfo.st_size).start()

                        bytes_transferred = 0
                        f = open(file_vmdk, 'rb')
                        while bytes_transferred < statinfo.st_size:
                            my_bytes = f.read(chunk_bytes)
                            if len(my_bytes) <= chunk_bytes:
                                headers['Content-Range'] = 'bytes %s-%s/%s' % (
                                    bytes_transferred, len(my_bytes) - 1, statinfo.st_size)
                                headers['Content-Length'] = str(len(my_bytes))
                                response = requests.put(url=hrefvmdk,
                                                         headers=headers,
                                                         data=my_bytes,
                                                         verify=False)
                                if response.status_code == requests.codes.ok:
                                    bytes_transferred += len(my_bytes)
                                    if progress:
                                        progress_bar.update(bytes_transferred)
                                else:
                                    self.logger.debug(
                                        'file upload failed with error: [%s] %s' % (response.status_code,
                                                                                        response.content))

                                    f.close()
                                    return False
                        f.close()
                        if progress:
                            progress_bar.finish()
                            time.sleep(10)
                    return True
                else:
                    self.logger.debug("Failed retrieve vApp template for catalog name {} for OVF {}".
                                      format(catalog_name, media_file_name))
                    return False
        except Exception as exp:
            self.logger.debug("Failed while uploading OVF to catalog {} for OVF file {} with Exception {}"
                .format(catalog_name,media_file_name, exp))
            raise vimconn.vimconnException(
                "Failed while uploading OVF to catalog {} for OVF file {} with Exception {}"
                .format(catalog_name,media_file_name, exp))

        self.logger.debug("Failed retrieve catalog name {} for OVF file {}".format(catalog_name, media_file_name))
        return False

    def upload_vimimage(self, vca=None, catalog_name=None, media_name=None, medial_file_name=None, progress=False):
        """Upload media file"""
        # TODO add named parameters for readability

        return self.upload_ovf(vca=vca, catalog_name=catalog_name, image_name=media_name.split(".")[0],
                               media_file_name=medial_file_name, description='medial_file_name', progress=progress)

    def validate_uuid4(self, uuid_string=None):
        """  Method validate correct format of UUID.

        Return: true if string represent valid uuid
        """
        try:
            val = uuid.UUID(uuid_string, version=4)
        except ValueError:
            return False
        return True

    def get_catalogid(self, catalog_name=None, catalogs=None):
        """  Method check catalog and return catalog ID in UUID format.

        Args
            catalog_name: catalog name as string
            catalogs:  list of catalogs.

        Return: catalogs uuid
        """

        for catalog in catalogs:
            if catalog['name'] == catalog_name:
                catalog_id = catalog['id']
                return catalog_id
        return None

    def get_catalogbyid(self, catalog_uuid=None, catalogs=None):
        """  Method check catalog and return catalog name lookup done by catalog UUID.

        Args
            catalog_name: catalog name as string
            catalogs:  list of catalogs.

        Return: catalogs name or None
        """

        if not self.validate_uuid4(uuid_string=catalog_uuid):
            return None

        for catalog in catalogs:
            catalog_id = catalog.get('id')
            if catalog_id == catalog_uuid:
                return catalog.get('name')
        return None

    def get_catalog_obj(self, catalog_uuid=None, catalogs=None):
        """  Method check catalog and return catalog name lookup done by catalog UUID.

        Args
            catalog_name: catalog name as string
            catalogs:  list of catalogs.

        Return: catalogs name or None
        """

        if not self.validate_uuid4(uuid_string=catalog_uuid):
            return None

        for catalog in catalogs:
            catalog_id = catalog.get('id')
            if catalog_id == catalog_uuid:
                return catalog
        return None

    def get_image_id_from_path(self, path=None, progress=False):
        """  Method upload OVF image to vCloud director.

        Each OVF image represented as single catalog entry in vcloud director.
        The method check for existing catalog entry.  The check done by file name without file extension.

        if given catalog name already present method will respond with existing catalog uuid otherwise
        it will create new catalog entry and upload OVF file to newly created catalog.

        If method can't create catalog entry or upload a file it will throw exception.

        Method accept boolean flag progress that will output progress bar. It useful method
        for standalone upload use case. In case to test large file upload.

        Args
            path: - valid path to OVF file.
            progress - boolean progress bar show progress bar.

        Return: if image uploaded correct method will provide image catalog UUID.
        """

        if not path:
            raise vimconn.vimconnException("Image path can't be None.")

        if not os.path.isfile(path):
            raise vimconn.vimconnException("Can't read file. File not found.")

        if not os.access(path, os.R_OK):
            raise vimconn.vimconnException("Can't read file. Check file permission to read.")

        self.logger.debug("get_image_id_from_path() client requesting {} ".format(path))

        dirpath, filename = os.path.split(path)
        flname, file_extension = os.path.splitext(path)
        if file_extension != '.ovf':
            self.logger.debug("Wrong file extension {} connector support only OVF container.".format(file_extension))
            raise vimconn.vimconnException("Wrong container.  vCloud director supports only OVF.")

        catalog_name = os.path.splitext(filename)[0]
        catalog_md5_name = hashlib.md5(path).hexdigest()
        self.logger.debug("File name {} Catalog Name {} file path {} "
                          "vdc catalog name {}".format(filename, catalog_name, path, catalog_md5_name))

        try:
            org,vdc = self.get_vdc_details()
            catalogs = org.list_catalogs()
        except Exception as exp:
            self.logger.debug("Failed get catalogs() with Exception {} ".format(exp))
            raise vimconn.vimconnException("Failed get catalogs() with Exception {} ".format(exp))

        if len(catalogs) == 0:
            self.logger.info("Creating a new catalog entry {} in vcloud director".format(catalog_name))
            if self.create_vimcatalog(org, catalog_md5_name) is None:
                raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))

            result = self.upload_vimimage(vca=org, catalog_name=catalog_md5_name,
                                          media_name=filename, medial_file_name=path, progress=progress)
            if not result:
                raise vimconn.vimconnException("Failed create vApp template for catalog {} ".format(catalog_name))
            return self.get_catalogid(catalog_name, catalogs)
        else:
            for catalog in catalogs:
                # search for existing catalog if we find same name we return ID
                # TODO optimize this
                if catalog['name'] == catalog_md5_name:
                    self.logger.debug("Found existing catalog entry for {} "
                                      "catalog id {}".format(catalog_name,
                                                             self.get_catalogid(catalog_md5_name, catalogs)))
                    return self.get_catalogid(catalog_md5_name, catalogs)

        # if we didn't find existing catalog we create a new one and upload image.
        self.logger.debug("Creating new catalog entry {} - {}".format(catalog_name, catalog_md5_name))
        if self.create_vimcatalog(org, catalog_md5_name) is None:
            raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))

        result = self.upload_vimimage(vca=org, catalog_name=catalog_md5_name,
                                      media_name=filename, medial_file_name=path, progress=progress)
        if not result:
            raise vimconn.vimconnException("Failed create vApp template for catalog {} ".format(catalog_md5_name))

        return self.get_catalogid(catalog_md5_name, org.list_catalogs())

    def get_image_list(self, filter_dict={}):
        '''Obtain tenant images from VIM
        Filter_dict can be:
            name: image name
            id: image uuid
            checksum: image checksum
            location: image path
        Returns the image list of dictionaries:
            [{<the fields at Filter_dict plus some VIM specific>}, ...]
            List can be empty
        '''

        try:
            org, vdc = self.get_vdc_details()
            image_list = []
            catalogs = org.list_catalogs()
            if len(catalogs) == 0:
                return image_list
            else:
                for catalog in catalogs:
                    catalog_uuid = catalog.get('id')
                    name = catalog.get('name')
                    filtered_dict = {}
                    if filter_dict.get("name") and filter_dict["name"] != name:
                        continue
                    if filter_dict.get("id") and filter_dict["id"] != catalog_uuid:
                        continue
                    filtered_dict ["name"] = name
                    filtered_dict ["id"] = catalog_uuid
                    image_list.append(filtered_dict)

                self.logger.debug("List of already created catalog items: {}".format(image_list))
                return image_list
        except Exception as exp:
            raise vimconn.vimconnException("Exception occured while retriving catalog items {}".format(exp))

    def get_vappid(self, vdc=None, vapp_name=None):
        """ Method takes vdc object and vApp name and returns vapp uuid or None

        Args:
            vdc: The VDC object.
            vapp_name: is application vappp name identifier

        Returns:
                The return vApp name otherwise None
        """
        if vdc is None or vapp_name is None:
            return None
        # UUID has following format https://host/api/vApp/vapp-30da58a3-e7c7-4d09-8f68-d4c8201169cf
        try:
            refs = filter(lambda ref: ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml',
                          vdc.ResourceEntities.ResourceEntity)
            #For python3
            #refs = [ref for ref in vdc.ResourceEntities.ResourceEntity\
            #         if ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml']
            if len(refs) == 1:
                return refs[0].href.split("vapp")[1][1:]
        except Exception as e:
            self.logger.exception(e)
            return False
        return None

    def check_vapp(self, vdc=None, vapp_uuid=None):
        """ Method Method returns True or False if vapp deployed in vCloud director

            Args:
                vca: Connector to VCA
                vdc: The VDC object.
                vappid: vappid is application identifier

            Returns:
                The return True if vApp deployed
                :param vdc:
                :param vapp_uuid:
        """
        try:
            refs = filter(lambda ref:
                          ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml',
                          vdc.ResourceEntities.ResourceEntity)
            #For python3
            #refs = [ref for ref in vdc.ResourceEntities.ResourceEntity\
            #         if ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml']
            for ref in refs:
                vappid = ref.href.split("vapp")[1][1:]
                # find vapp with respected vapp uuid
                if vappid == vapp_uuid:
                    return True
        except Exception as e:
            self.logger.exception(e)
            return False
        return False

    def get_namebyvappid(self, vapp_uuid=None):
        """Method returns vApp name from vCD and lookup done by vapp_id.

        Args:
            vapp_uuid: vappid is application identifier

        Returns:
            The return vApp name otherwise None
        """
        try:
            if self.client and vapp_uuid:
                vapp_call = "{}/api/vApp/vapp-{}".format(self.url, vapp_uuid)
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                     'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

                response = self.perform_request(req_type='GET',
                                                url=vapp_call,
                                                headers=headers)
                #Retry login if session expired & retry sending request
                if response.status_code == 403:
                    response = self.retry_rest('GET', vapp_call)

                tree = XmlElementTree.fromstring(response.content)
                return tree.attrib['name']
        except Exception as e:
            self.logger.exception(e)
            return None
        return None

    def new_vminstance(self, name=None, description="", start=False, image_id=None, flavor_id=None, net_list=[],
                       cloud_config=None, disk_list=None, availability_zone_index=None, availability_zone_list=None):
        """Adds a VM instance to VIM
        Params:
            'start': (boolean) indicates if VM must start or created in pause mode.
            'image_id','flavor_id': image and flavor VIM id to use for the VM
            'net_list': list of interfaces, each one is a dictionary with:
                'name': (optional) name for the interface.
                'net_id': VIM network id where this interface must be connect to. Mandatory for type==virtual
                'vpci': (optional) virtual vPCI address to assign at the VM. Can be ignored depending on VIM capabilities
                'model': (optional and only have sense for type==virtual) interface model: virtio, e1000, ...
                'mac_address': (optional) mac address to assign to this interface
                #TODO: CHECK if an optional 'vlan' parameter is needed for VIMs when type if VF and net_id is not provided,
                    the VLAN tag to be used. In case net_id is provided, the internal network vlan is used for tagging VF
                'type': (mandatory) can be one of:
                    'virtual', in this case always connected to a network of type 'net_type=bridge'
                     'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
                           can created unconnected
                     'SR-IOV' or 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
                     'VFnotShared'(SRIOV without VLAN tag) same as PF for network connectivity. VF where no other VFs
                            are allocated on the same physical NIC
                'bw': (optional) only for PF/VF/VFnotShared. Minimal Bandwidth required for the interface in GBPS
                'port_security': (optional) If False it must avoid any traffic filtering at this interface. If missing
                                or True, it must apply the default VIM behaviour
                After execution the method will add the key:
                'vim_id': must be filled/added by this method with the VIM identifier generated by the VIM for this
                        interface. 'net_list' is modified
            'cloud_config': (optional) dictionary with:
                'key-pairs': (optional) list of strings with the public key to be inserted to the default user
                'users': (optional) list of users to be inserted, each item is a dict with:
                    'name': (mandatory) user name,
                    'key-pairs': (optional) list of strings with the public key to be inserted to the user
                'user-data': (optional) can be a string with the text script to be passed directly to cloud-init,
                    or a list of strings, each one contains a script to be passed, usually with a MIMEmultipart file
                'config-files': (optional). List of files to be transferred. Each item is a dict with:
                    'dest': (mandatory) string with the destination absolute path
                    'encoding': (optional, by default text). Can be one of:
                        'b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64'
                    'content' (mandatory): string with the content of the file
                    'permissions': (optional) string with file permissions, typically octal notation '0644'
                    'owner': (optional) file owner, string with the format 'owner:group'
                'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk)
            'disk_list': (optional) list with additional disks to the VM. Each item is a dict with:
                'image_id': (optional). VIM id of an existing image. If not provided an empty disk must be mounted
                'size': (mandatory) string with the size of the disk in GB
            availability_zone_index: Index of availability_zone_list to use for this this VM. None if not AV required
            availability_zone_list: list of availability zones given by user in the VNFD descriptor.  Ignore if
                availability_zone_index is None
        Returns a tuple with the instance identifier and created_items or raises an exception on error
            created_items can be None or a dictionary where this method can include key-values that will be passed to
            the method delete_vminstance and action_vminstance. Can be used to store created ports, volumes, etc.
            Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
            as not present.
        """
        self.logger.info("Creating new instance for entry {}".format(name))
        self.logger.debug("desc {} boot {} image_id: {} flavor_id: {} net_list: {} cloud_config {} disk_list {} "\
                          "availability_zone_index {} availability_zone_list {}"\
                          .format(description, start, image_id, flavor_id, net_list, cloud_config, disk_list,\
                                  availability_zone_index, availability_zone_list))

        #new vm name = vmname + tenant_id + uuid
        new_vm_name = [name, '-', str(uuid.uuid4())]
        vmname_andid = ''.join(new_vm_name)

        for net in net_list:
            if net['type'] == "PCI-PASSTHROUGH":
                raise vimconn.vimconnNotSupportedException(
                      "Current vCD version does not support type : {}".format(net['type']))

        if len(net_list) > 10:
            raise vimconn.vimconnNotSupportedException(
                      "The VM hardware versions 7 and above support upto 10 NICs only")

        # if vm already deployed we return existing uuid
        # we check for presence of VDC, Catalog entry and Flavor.
        org, vdc = self.get_vdc_details()
        if vdc is None:
            raise vimconn.vimconnNotFoundException(
                "new_vminstance(): Failed create vApp {}: (Failed retrieve VDC information)".format(name))
        catalogs = org.list_catalogs()
        if catalogs is None:
            #Retry once, if failed by refreshing token
            self.get_token()
            org = Org(self.client, resource=self.client.get_org())
            catalogs = org.list_catalogs()
        if catalogs is None:
            raise vimconn.vimconnNotFoundException(
                "new_vminstance(): Failed create vApp {}: (Failed retrieve catalogs list)".format(name))

        catalog_hash_name = self.get_catalogbyid(catalog_uuid=image_id, catalogs=catalogs)
        if catalog_hash_name:
            self.logger.info("Found catalog entry {} for image id {}".format(catalog_hash_name, image_id))
        else:
            raise vimconn.vimconnNotFoundException("new_vminstance(): Failed create vApp {}: "
                                                   "(Failed retrieve catalog information {})".format(name, image_id))

        # Set vCPU and Memory based on flavor.
        vm_cpus = None
        vm_memory = None
        vm_disk = None
        numas = None

        if flavor_id is not None:
            if flavor_id not in vimconnector.flavorlist:
                raise vimconn.vimconnNotFoundException("new_vminstance(): Failed create vApp {}: "
                                                       "Failed retrieve flavor information "
                                                       "flavor id {}".format(name, flavor_id))
            else:
                try:
                    flavor = vimconnector.flavorlist[flavor_id]
                    vm_cpus = flavor[FLAVOR_VCPUS_KEY]
                    vm_memory = flavor[FLAVOR_RAM_KEY]
                    vm_disk = flavor[FLAVOR_DISK_KEY]
                    extended = flavor.get("extended", None)
                    if extended:
                        numas=extended.get("numas", None)

                except Exception as exp:
                    raise vimconn.vimconnException("Corrupted flavor. {}.Exception: {}".format(flavor_id, exp))

        # image upload creates template name as catalog name space Template.
        templateName = self.get_catalogbyid(catalog_uuid=image_id, catalogs=catalogs)
        power_on = 'false'
        if start:
            power_on = 'true'

        # client must provide at least one entry in net_list if not we report error
        #If net type is mgmt, then configure it as primary net & use its NIC index as primary NIC
        #If no mgmt, then the 1st NN in netlist is considered as primary net. 
        primary_net = None
        primary_netname = None
        primary_net_href = None
        network_mode = 'bridged'
        if net_list is not None and len(net_list) > 0:
            for net in net_list:
                if 'use' in net and net['use'] == 'mgmt' and not primary_net:
                    primary_net = net
            if primary_net is None:
                primary_net = net_list[0]

            try:
                primary_net_id = primary_net['net_id']
                url_list = [self.url, '/api/network/', primary_net_id]
                primary_net_href = ''.join(url_list) 
                network_dict = self.get_vcd_network(network_uuid=primary_net_id)
                if 'name' in network_dict:
                    primary_netname = network_dict['name']

            except KeyError:
                raise vimconn.vimconnException("Corrupted flavor. {}".format(primary_net))
        else:
            raise vimconn.vimconnUnexpectedResponse("new_vminstance(): Failed network list is empty.".format(name))

        # use: 'data', 'bridge', 'mgmt'
        # create vApp.  Set vcpu and ram based on flavor id.
        try:
            vdc_obj = VDC(self.client, resource=org.get_vdc(self.tenant_name))
            if not vdc_obj:
                raise vimconn.vimconnNotFoundException("new_vminstance(): Failed to get VDC object")

            for retry in (1,2):
                items = org.get_catalog_item(catalog_hash_name, catalog_hash_name)
                catalog_items = [items.attrib]

                if len(catalog_items) == 1:
                    if self.client:
                        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

                    response = self.perform_request(req_type='GET',
                                                url=catalog_items[0].get('href'),
                                                headers=headers)
                    catalogItem = XmlElementTree.fromstring(response.content)
                    entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0]
                    vapp_tempalte_href = entity.get("href")

                response = self.perform_request(req_type='GET',
                                                    url=vapp_tempalte_href,
                                                    headers=headers)
                if response.status_code != requests.codes.ok:
                    self.logger.debug("REST API call {} failed. Return status code {}".format(vapp_tempalte_href,
                                                                                           response.status_code))
                else:
                    result = (response.content).replace("\n"," ")

                vapp_template_tree = XmlElementTree.fromstring(response.content)
                children_element = [child for child in vapp_template_tree if 'Children' in child.tag][0]
                vm_element = [child for child in children_element if 'Vm' in child.tag][0]
                vm_name = vm_element.get('name')
                vm_id = vm_element.get('id')
                vm_href = vm_element.get('href')

                cpus = re.search('<rasd:Description>Number of Virtual CPUs</.*?>(\d+)</rasd:VirtualQuantity>',result).group(1)
                memory_mb = re.search('<rasd:Description>Memory Size</.*?>(\d+)</rasd:VirtualQuantity>',result).group(1)
                cores = re.search('<vmw:CoresPerSocket ovf:required.*?>(\d+)</vmw:CoresPerSocket>',result).group(1)

                headers['Content-Type'] = 'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'
                vdc_id = vdc.get('id').split(':')[-1]
                instantiate_vapp_href = "{}/api/vdc/{}/action/instantiateVAppTemplate".format(self.url,
                                                                                                vdc_id)
                data = """<?xml version="1.0" encoding="UTF-8"?>
                <InstantiateVAppTemplateParams
                xmlns="http://www.vmware.com/vcloud/v1.5"
                name="{}"
                deploy="false"
                powerOn="false"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1">
                <Description>Vapp instantiation</Description>
                <InstantiationParams>
                     <NetworkConfigSection>
                         <ovf:Info>Configuration parameters for logical networks</ovf:Info>
                         <NetworkConfig networkName="{}">
                             <Configuration>
                                 <ParentNetwork href="{}" />
                                 <FenceMode>bridged</FenceMode>
                             </Configuration>
                         </NetworkConfig>
                     </NetworkConfigSection>
                <LeaseSettingsSection
                type="application/vnd.vmware.vcloud.leaseSettingsSection+xml">
                <ovf:Info>Lease Settings</ovf:Info>
                <StorageLeaseInSeconds>172800</StorageLeaseInSeconds>
                <StorageLeaseExpiration>2014-04-25T08:08:16.438-07:00</StorageLeaseExpiration>
                </LeaseSettingsSection>
                </InstantiationParams>
                <Source href="{}"/>
                <SourcedItem>
                <Source href="{}" id="{}" name="{}"
                type="application/vnd.vmware.vcloud.vm+xml"/>
                <VmGeneralParams>
                    <NeedsCustomization>false</NeedsCustomization>
                </VmGeneralParams>
                <InstantiationParams>
                      <NetworkConnectionSection>
                      <ovf:Info>Specifies the available VM network connections</ovf:Info>
                      <NetworkConnection network="{}">
                      <NetworkConnectionIndex>0</NetworkConnectionIndex>
                      <IsConnected>true</IsConnected>
                      <IpAddressAllocationMode>DHCP</IpAddressAllocationMode>
                      </NetworkConnection>
                      </NetworkConnectionSection><ovf:VirtualHardwareSection>
                      <ovf:Info>Virtual hardware requirements</ovf:Info>
                      <ovf:Item xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
                      xmlns:vmw="http://www.vmware.com/schema/ovf">
                      <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
                      <rasd:Description>Number of Virtual CPUs</rasd:Description>
                      <rasd:ElementName xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">{cpu} virtual CPU(s)</rasd:ElementName>
                      <rasd:InstanceID>4</rasd:InstanceID>
                      <rasd:Reservation>0</rasd:Reservation>
                      <rasd:ResourceType>3</rasd:ResourceType>
                      <rasd:VirtualQuantity xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="int">{cpu}</rasd:VirtualQuantity>
                      <rasd:Weight>0</rasd:Weight>
                      <vmw:CoresPerSocket ovf:required="false">{core}</vmw:CoresPerSocket>
                      </ovf:Item><ovf:Item xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData">
                      <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
                      <rasd:Description>Memory Size</rasd:Description>
                      <rasd:ElementName xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="str">{memory} MB of memory</rasd:ElementName>
                      <rasd:InstanceID>5</rasd:InstanceID>
                      <rasd:Reservation>0</rasd:Reservation>
                      <rasd:ResourceType>4</rasd:ResourceType>
                      <rasd:VirtualQuantity xmlns:py="http://codespeak.net/lxml/objectify/pytype" py:pytype="int">{memory}</rasd:VirtualQuantity>
                      <rasd:Weight>0</rasd:Weight>
                      </ovf:Item>
                </ovf:VirtualHardwareSection>
                </InstantiationParams>
                </SourcedItem>
                <AllEULAsAccepted>false</AllEULAsAccepted>
                </InstantiateVAppTemplateParams>""".format(vmname_andid,
                                                        primary_netname,
                                                        primary_net_href,
                                                     vapp_tempalte_href,
                                                                vm_href,
                                                                  vm_id,
                                                                vm_name,
                                                        primary_netname,
                                                               cpu=cpus,
                                                             core=cores,
                                                       memory=memory_mb)

                response = self.perform_request(req_type='POST',
                                                url=instantiate_vapp_href,
                                                headers=headers,
                                                data=data)

                if response.status_code != 201:
                    self.logger.error("REST call {} failed reason : {}"\
                         "status code : {}".format(instantiate_vapp_href,
                                                        response.content,
                                                   response.status_code))
                    raise vimconn.vimconnException("new_vminstance(): Failed to create"\
                                                        "vAapp {}".format(vmname_andid))
                else:
                    vapptask = self.get_task_from_response(response.content)

                if vapptask is None and retry==1:
                    self.get_token() # Retry getting token
                    continue
                else:
                    break

            if vapptask is None or vapptask is False:
                raise vimconn.vimconnUnexpectedResponse(
                    "new_vminstance(): failed to create vApp {}".format(vmname_andid))

            # wait for task to complete
            result = self.client.get_task_monitor().wait_for_success(task=vapptask)

            if result.get('status') == 'success':
                self.logger.debug("new_vminstance(): Sucessfully created Vapp {}".format(vmname_andid))
            else:
                raise vimconn.vimconnUnexpectedResponse(
                    "new_vminstance(): failed to create vApp {}".format(vmname_andid))

        except Exception as exp:
            raise vimconn.vimconnUnexpectedResponse(
                "new_vminstance(): failed to create vApp {} with Exception:{}".format(vmname_andid, exp))

        # we should have now vapp in undeployed state.
        try:
            vdc_obj = VDC(self.client, href=vdc.get('href'))
            vapp_resource = vdc_obj.get_vapp(vmname_andid)
            vapp_uuid = vapp_resource.get('id').split(':')[-1]
            vapp = VApp(self.client, resource=vapp_resource)

        except Exception as exp:
            raise vimconn.vimconnUnexpectedResponse(
                    "new_vminstance(): Failed to retrieve vApp {} after creation: Exception:{}"
                    .format(vmname_andid, exp))

        if vapp_uuid is None:
            raise vimconn.vimconnUnexpectedResponse(
                "new_vminstance(): Failed to retrieve vApp {} after creation".format(
                                                                            vmname_andid))

        #Add PCI passthrough/SRIOV configrations
        vm_obj = None
        pci_devices_info = []
        reserve_memory = False

        for net in net_list:
            if net["type"] == "PF" or net["type"] == "PCI-PASSTHROUGH":
                pci_devices_info.append(net)
            elif (net["type"] == "VF" or net["type"] == "SR-IOV" or net["type"] == "VFnotShared") and 'net_id'in net:
                reserve_memory = True

        #Add PCI
        if len(pci_devices_info) > 0:
            self.logger.info("Need to add PCI devices {} into VM {}".format(pci_devices_info,
                                                                        vmname_andid ))
            PCI_devices_status, vm_obj, vcenter_conect = self.add_pci_devices(vapp_uuid,
                                                                            pci_devices_info,
                                                                            vmname_andid)
            if PCI_devices_status:
                self.logger.info("Added PCI devives {} to VM {}".format(
                                                            pci_devices_info,
                                                            vmname_andid)
                                 )
                reserve_memory = True
            else:
                self.logger.info("Fail to add PCI devives {} to VM {}".format(
                                                            pci_devices_info,
                                                            vmname_andid)
                                 )

        # Modify vm disk
        if vm_disk:
            #Assuming there is only one disk in ovf and fast provisioning in organization vDC is disabled
            result = self.modify_vm_disk(vapp_uuid, vm_disk)
            if result :
                self.logger.debug("Modified Disk size of VM {} ".format(vmname_andid))

        #Add new or existing disks to vApp
        if disk_list:
            added_existing_disk = False
            for disk in disk_list:
                if 'device_type' in disk and disk['device_type'] == 'cdrom':
                    image_id = disk['image_id']
                    # Adding CD-ROM to VM
                    # will revisit code once specification ready to support this feature
                    self.insert_media_to_vm(vapp, image_id)
                elif "image_id" in disk and disk["image_id"] is not None:
                    self.logger.debug("Adding existing disk from image {} to vm {} ".format(
                                                                    disk["image_id"] , vapp_uuid))
                    self.add_existing_disk(catalogs=catalogs,
                                           image_id=disk["image_id"],
                                           size = disk["size"],
                                           template_name=templateName,
                                           vapp_uuid=vapp_uuid
                                           )
                    added_existing_disk = True
                else:
                    #Wait till added existing disk gets reflected into vCD database/API
                    if added_existing_disk:
                        time.sleep(5)
                        added_existing_disk = False
                    self.add_new_disk(vapp_uuid, disk['size'])

        if numas:
            # Assigning numa affinity setting
            for numa in numas:
                if 'paired-threads-id' in numa:
                    paired_threads_id = numa['paired-threads-id']
                    self.set_numa_affinity(vapp_uuid, paired_threads_id)

        # add NICs & connect to networks in netlist
        try:
            vdc_obj = VDC(self.client, href=vdc.get('href'))
            vapp_resource = vdc_obj.get_vapp(vmname_andid)
            vapp = VApp(self.client, resource=vapp_resource)
            vapp_id = vapp_resource.get('id').split(':')[-1]

            self.logger.info("Removing primary NIC: ")
            # First remove all NICs so that NIC properties can be adjusted as needed
            self.remove_primary_network_adapter_from_all_vms(vapp)

            self.logger.info("Request to connect VM to a network: {}".format(net_list))
            primary_nic_index = 0
            nicIndex = 0
            for net in net_list:
                # openmano uses network id in UUID format.
                # vCloud Director need a name so we do reverse operation from provided UUID we lookup a name
                # [{'use': 'bridge', 'net_id': '527d4bf7-566a-41e7-a9e7-ca3cdd9cef4f', 'type': 'virtual',
                #   'vpci': '0000:00:11.0', 'name': 'eth0'}]

                if 'net_id' not in net:
                    continue

                #Using net_id as a vim_id i.e. vim interface id, as do not have saperate vim interface id
                #Same will be returned in refresh_vms_status() as vim_interface_id
                net['vim_id'] = net['net_id']  # Provide the same VIM identifier as the VIM network

                interface_net_id = net['net_id']
                interface_net_name = self.get_network_name_by_id(network_uuid=interface_net_id)
                interface_network_mode = net['use']

                if interface_network_mode == 'mgmt':
                    primary_nic_index = nicIndex

                """- POOL (A static IP address is allocated automatically from a pool of addresses.)
                                  - DHCP (The IP address is obtained from a DHCP service.)
                                  - MANUAL (The IP address is assigned manually in the IpAddress element.)
                                  - NONE (No IP addressing mode specified.)"""

                if primary_netname is not None:
                    self.logger.debug("new_vminstance(): Filtering by net name {}".format(interface_net_name))
                    nets = filter(lambda n: n.get('name') == interface_net_name, self.get_network_list())
                    #For python3
                    #nets = [n for n in self.get_network_list() if n.get('name') == interface_net_name]
                    if len(nets) == 1:
                        self.logger.info("new_vminstance(): Found requested network: {}".format(nets[0].get('name')))

                        if interface_net_name != primary_netname:
                            # connect network to VM - with all DHCP by default
                            self.logger.info("new_vminstance(): Attaching net {} to vapp".format(interface_net_name))
                            self.connect_vapp_to_org_vdc_network(vapp_id, nets[0].get('name'))

                        type_list = ('PF', 'PCI-PASSTHROUGH', 'VFnotShared')
                        nic_type = 'VMXNET3'
                        if 'type' in net and net['type'] not in type_list:
                            # fetching nic type from vnf
                            if 'model' in net:
                                if net['model'] is not None:
                                    if net['model'].lower() == 'paravirt' or net['model'].lower() == 'virtio':
                                        nic_type = 'VMXNET3'
                                else:
                                    nic_type = net['model']

                                self.logger.info("new_vminstance(): adding network adapter "\
                                                          "to a network {}".format(nets[0].get('name')))
                                self.add_network_adapter_to_vms(vapp, nets[0].get('name'),
                                                                primary_nic_index,
                                                                nicIndex,
                                                                net,
                                                                nic_type=nic_type)
                            else:
                                self.logger.info("new_vminstance(): adding network adapter "\
                                                         "to a network {}".format(nets[0].get('name')))
                                if net['type'] in ['SR-IOV', 'VF']:
                                    nic_type = net['type']
                                self.add_network_adapter_to_vms(vapp, nets[0].get('name'),
                                                                primary_nic_index,
                                                                nicIndex,
                                                                net,
                                                                nic_type=nic_type)
                nicIndex += 1

            # cloud-init for ssh-key injection
            if cloud_config:
                # Create a catalog which will be carrying the config drive ISO
                # This catalog is deleted during vApp deletion. The catalog name carries
                # vApp UUID and thats how it gets identified during its deletion.
                config_drive_catalog_name = 'cfg_drv-' + vapp_uuid
                self.logger.info('new_vminstance(): Creating catalog "{}" to carry config drive ISO'.format(
                    config_drive_catalog_name))
                config_drive_catalog_id = self.create_vimcatalog(org, config_drive_catalog_name)
                if config_drive_catalog_id is None:
                    error_msg = "new_vminstance(): Failed to create new catalog '{}' to carry the config drive " \
                                "ISO".format(config_drive_catalog_name)
                    raise Exception(error_msg)

                # Create config-drive ISO
                _, userdata = self._create_user_data(cloud_config)
                # self.logger.debug('new_vminstance(): The userdata for cloud-init: {}'.format(userdata))
                iso_path = self.create_config_drive_iso(userdata)
                self.logger.debug('new_vminstance(): The ISO is successfully created. Path: {}'.format(iso_path))

                self.logger.info('new_vminstance(): uploading iso to catalog {}'.format(config_drive_catalog_name))
                self.upload_iso_to_catalog(config_drive_catalog_id, iso_path)
                # Attach the config-drive ISO to the VM
                self.logger.info('new_vminstance(): Attaching the config-drive ISO to the VM')
                # The ISO remains in INVALID_STATE right after the PUT request (its a blocking call though)
                time.sleep(5)
                self.insert_media_to_vm(vapp, config_drive_catalog_id)
                shutil.rmtree(os.path.dirname(iso_path), ignore_errors=True)

            # If VM has PCI devices or SRIOV reserve memory for VM
            if reserve_memory:
                self.reserve_memory_for_all_vms(vapp, memory_mb)

            self.logger.debug("new_vminstance(): starting power on vApp {} ".format(vmname_andid))

            poweron_task = self.power_on_vapp(vapp_id, vmname_andid)
            result = self.client.get_task_monitor().wait_for_success(task=poweron_task)
            if result.get('status') == 'success':
                self.logger.info("new_vminstance(): Successfully power on "\
                                             "vApp {}".format(vmname_andid))
            else:
                self.logger.error("new_vminstance(): failed to power on vApp "\
                                                     "{}".format(vmname_andid))

        except Exception as exp:
            try:
                self.delete_vminstance(vapp_uuid)
            except Exception as exp2:
                self.logger.error("new_vminstance rollback fail {}".format(exp2))
            # it might be a case if specific mandatory entry in dict is empty or some other pyVcloud exception
            self.logger.error("new_vminstance(): Failed create new vm instance {} with exception {}"
                              .format(name, exp))
            raise vimconn.vimconnException("new_vminstance(): Failed create new vm instance {} with exception {}"
                                           .format(name, exp))

        # check if vApp deployed and if that the case return vApp UUID otherwise -1
        wait_time = 0
        vapp_uuid = None
        while wait_time <= MAX_WAIT_TIME:
            try:
                vapp_resource = vdc_obj.get_vapp(vmname_andid)
                vapp = VApp(self.client, resource=vapp_resource)
            except Exception as exp:
                raise vimconn.vimconnUnexpectedResponse(
                        "new_vminstance(): Failed to retrieve vApp {} after creation: Exception:{}"
                        .format(vmname_andid, exp))

            #if vapp and vapp.me.deployed:
            if vapp and vapp_resource.get('deployed') == 'true':
                vapp_uuid = vapp_resource.get('id').split(':')[-1]
                break
            else:
                self.logger.debug("new_vminstance(): Wait for vApp {} to deploy".format(name))
                time.sleep(INTERVAL_TIME)

            wait_time +=INTERVAL_TIME

        #SET Affinity Rule for VM
        #Pre-requisites: User has created Hosh Groups in vCenter with respective Hosts to be used
        #While creating VIM account user has to pass the Host Group names in availability_zone list
        #"availability_zone" is a  part of VIM "config" parameters
        #For example, in VIM config: "availability_zone":["HG_170","HG_174","HG_175"]
        #Host groups are referred as availability zones
        #With following procedure, deployed VM will be added into a VM group.
        #Then A VM to Host Affinity rule will be created using the VM group & Host group.
        if(availability_zone_list):
            self.logger.debug("Existing Host Groups in VIM {}".format(self.config.get('availability_zone')))
            #Admin access required for creating Affinity rules
            client = self.connect_as_admin()
            if not client:
                raise vimconn.vimconnConnectionException("Failed to connect vCD as admin")
            else:
                self.client = client
            if self.client:
                headers = {'Accept':'application/*+xml;version=27.0',
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            #Step1: Get provider vdc details from organization
            pvdc_href = self.get_pvdc_for_org(self.tenant_name, headers)
            if pvdc_href is not None:
            #Step2: Found required pvdc, now get resource pool information
                respool_href = self.get_resource_pool_details(pvdc_href, headers)
                if respool_href is None:
                    #Raise error if respool_href not found
                    msg = "new_vminstance():Error in finding resource pool details in pvdc {}"\
                           .format(pvdc_href)
                    self.log_message(msg)

            #Step3: Verify requested availability zone(hostGroup) is present in vCD
            # get availability Zone
            vm_az = self.get_vm_availability_zone(availability_zone_index, availability_zone_list)
            # check if provided av zone(hostGroup) is present in vCD VIM
            status = self.check_availibility_zone(vm_az, respool_href, headers)
            if status is False:
                msg = "new_vminstance(): Error in finding availability zone(Host Group): {} in "\
                       "resource pool {} status: {}".format(vm_az,respool_href,status)
                self.log_message(msg)
            else:
                self.logger.debug ("new_vminstance(): Availability zone {} found in VIM".format(vm_az))

            #Step4: Find VM group references to create vm group
            vmgrp_href = self.find_vmgroup_reference(respool_href, headers)
            if vmgrp_href == None:
                msg = "new_vminstance(): No reference to VmGroup found in resource pool"
                self.log_message(msg)

            #Step5: Create a VmGroup with name az_VmGroup
            vmgrp_name = vm_az + "_" + name #Formed VM Group name = Host Group name + VM name
            status = self.create_vmgroup(vmgrp_name, vmgrp_href, headers)
            if status is not True:
                msg = "new_vminstance(): Error in creating VM group {}".format(vmgrp_name)
                self.log_message(msg)

            #VM Group url to add vms to vm group
            vmgrpname_url = self.url + "/api/admin/extension/vmGroup/name/"+ vmgrp_name

            #Step6: Add VM to VM Group
            #Find VM uuid from vapp_uuid
            vm_details = self.get_vapp_details_rest(vapp_uuid)
            vm_uuid = vm_details['vmuuid']

            status = self.add_vm_to_vmgroup(vm_uuid, vmgrpname_url, vmgrp_name, headers)
            if status is not True:
                msg = "new_vminstance(): Error in adding VM to VM group {}".format(vmgrp_name)
                self.log_message(msg)

            #Step7: Create VM to Host affinity rule
            addrule_href = self.get_add_rule_reference (respool_href, headers)
            if addrule_href is None:
                msg = "new_vminstance(): Error in finding href to add rule in resource pool: {}"\
                      .format(respool_href)
                self.log_message(msg)

            status = self.create_vm_to_host_affinity_rule(addrule_href, vmgrp_name, vm_az, "Affinity",  headers)
            if status is False:
                msg = "new_vminstance(): Error in creating affinity rule for VM {} in Host group {}"\
                      .format(name, vm_az)
                self.log_message(msg)
            else:
                self.logger.debug("new_vminstance(): Affinity rule created successfully. Added {} in Host group {}"\
                                    .format(name, vm_az))
            #Reset token to a normal user to perform other operations
            self.get_token()

        if vapp_uuid is not None:
            return vapp_uuid, None
        else:
            raise vimconn.vimconnUnexpectedResponse("new_vminstance(): Failed create new vm instance {}".format(name))

    def create_config_drive_iso(self, user_data):
        tmpdir = tempfile.mkdtemp()
        iso_path = os.path.join(tmpdir, 'ConfigDrive.iso')
        latest_dir = os.path.join(tmpdir, 'openstack', 'latest')
        os.makedirs(latest_dir)
        with open(os.path.join(latest_dir, 'meta_data.json'), 'w') as meta_file_obj, \
                open(os.path.join(latest_dir, 'user_data'), 'w') as userdata_file_obj:
            userdata_file_obj.write(user_data)
            meta_file_obj.write(json.dumps({"availability_zone": "nova",
                                            "launch_index": 0,
                                            "name": "ConfigDrive",
                                            "uuid": str(uuid.uuid4())}
                                           )
                                )
        genisoimage_cmd = 'genisoimage -J -r -V config-2 -o {iso_path} {source_dir_path}'.format(
            iso_path=iso_path, source_dir_path=tmpdir)
        self.logger.info('create_config_drive_iso(): Creating ISO by running command "{}"'.format(genisoimage_cmd))
        try:
            FNULL = open(os.devnull, 'w')
            subprocess.check_call(genisoimage_cmd, shell=True, stdout=FNULL)
        except subprocess.CalledProcessError as e:
            shutil.rmtree(tmpdir, ignore_errors=True)
            error_msg = 'create_config_drive_iso(): Exception while running genisoimage command: {}'.format(e)
            self.logger.error(error_msg)
            raise Exception(error_msg)
        return iso_path

    def upload_iso_to_catalog(self, catalog_id, iso_file_path):
        if not os.path.isfile(iso_file_path):
            error_msg = "upload_iso_to_catalog(): Given iso file is not present. Given path: {}".format(iso_file_path)
            self.logger.error(error_msg)
            raise Exception(error_msg)
        iso_file_stat = os.stat(iso_file_path)
        xml_media_elem = '''<?xml version="1.0" encoding="UTF-8"?>
                            <Media
                                xmlns="http://www.vmware.com/vcloud/v1.5"
                                name="{iso_name}"
                                size="{iso_size}"
                                imageType="iso">
                                <Description>ISO image for config-drive</Description>
                            </Media>'''.format(iso_name=os.path.basename(iso_file_path), iso_size=iso_file_stat.st_size)
        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                   'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
        headers['Content-Type'] = 'application/vnd.vmware.vcloud.media+xml'
        catalog_href = self.url + '/api/catalog/' + catalog_id + '/action/upload'
        response = self.perform_request(req_type='POST', url=catalog_href, headers=headers, data=xml_media_elem)

        if response.status_code != 201:
            error_msg = "upload_iso_to_catalog(): Failed to POST an action/upload request to {}".format(catalog_href)
            self.logger.error(error_msg)
            raise Exception(error_msg)

        catalogItem = XmlElementTree.fromstring(response.content)
        entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.media+xml"][0]
        entity_href = entity.get('href')

        response = self.perform_request(req_type='GET', url=entity_href, headers=headers)
        if response.status_code != 200:
            raise Exception("upload_iso_to_catalog(): Failed to GET entity href {}".format(entity_href))

        match = re.search(r'<Files>\s+?<File.+?href="(.+?)"/>\s+?</File>\s+?</Files>', response.text, re.DOTALL)
        if match:
            media_upload_href = match.group(1)
        else:
            raise Exception('Could not parse the upload URL for the media file from the last response')
        upload_iso_task = self.get_task_from_response(response.content)
        headers['Content-Type'] = 'application/octet-stream'
        response = self.perform_request(req_type='PUT',
                                        url=media_upload_href,
                                        headers=headers,
                                        data=open(iso_file_path, 'rb'))

        if response.status_code != 200:
            raise Exception('PUT request to "{}" failed'.format(media_upload_href))
        result = self.client.get_task_monitor().wait_for_success(task=upload_iso_task)
        if result.get('status') != 'success':
            raise Exception('The upload iso task failed with status {}'.format(result.get('status')))

    def get_vcd_availibility_zones(self,respool_href, headers):
        """ Method to find presence of av zone is VIM resource pool

            Args:
                respool_href - resource pool href
                headers - header information

            Returns:
               vcd_az - list of azone present in vCD
        """
        vcd_az = []
        url=respool_href
        resp = self.perform_request(req_type='GET',url=respool_href, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(url, resp.status_code))
        else:
        #Get the href to hostGroups and find provided hostGroup is present in it
            resp_xml = XmlElementTree.fromstring(resp.content)
            for child in resp_xml:
                if 'VMWProviderVdcResourcePool' in child.tag:
                    for schild in child:
                        if 'Link' in schild.tag:
                            if schild.attrib.get('type') == "application/vnd.vmware.admin.vmwHostGroupsType+xml":
                                hostGroup = schild.attrib.get('href')
                                hg_resp = self.perform_request(req_type='GET',url=hostGroup, headers=headers)
                                if hg_resp.status_code != requests.codes.ok:
                                    self.logger.debug ("REST API call {} failed. Return status code {}".format(hostGroup, hg_resp.status_code))
                                else:
                                    hg_resp_xml =  XmlElementTree.fromstring(hg_resp.content)
                                    for hostGroup in hg_resp_xml:
                                        if 'HostGroup' in hostGroup.tag:
                                            #append host group name to the list
                                            vcd_az.append(hostGroup.attrib.get("name"))
        return vcd_az


    def set_availability_zones(self):
        """
        Set vim availability zone
        """

        vim_availability_zones = None
        availability_zone = None
        if 'availability_zone' in self.config:
            vim_availability_zones = self.config.get('availability_zone')
        if isinstance(vim_availability_zones, str):
            availability_zone = [vim_availability_zones]
        elif isinstance(vim_availability_zones, list):
            availability_zone = vim_availability_zones
        else:
            return availability_zone

        return availability_zone


    def get_vm_availability_zone(self, availability_zone_index, availability_zone_list):
        """
        Return the availability zone to be used by the created VM.
        returns: The VIM availability zone to be used or None
        """
        if availability_zone_index is None:
            if not self.config.get('availability_zone'):
                return None
            elif isinstance(self.config.get('availability_zone'), str):
                return self.config['availability_zone']
            else:
                return self.config['availability_zone'][0]

        vim_availability_zones = self.availability_zone

        # check if VIM offer enough availability zones describe in the VNFD
        if vim_availability_zones and len(availability_zone_list) <= len(vim_availability_zones):
            # check if all the names of NFV AV match VIM AV names
            match_by_index = False
            for av in availability_zone_list:
                if av not in vim_availability_zones:
                    match_by_index = True
                    break
            if match_by_index:
                self.logger.debug("Required Availability zone or Host Group not found in VIM config")
                self.logger.debug("Input Availability zone list: {}".format(availability_zone_list))
                self.logger.debug("VIM configured Availability zones: {}".format(vim_availability_zones))
                self.logger.debug("VIM Availability zones will be used by index")
                return vim_availability_zones[availability_zone_index]
            else:
                return availability_zone_list[availability_zone_index]
        else:
            raise vimconn.vimconnConflictException("No enough availability zones at VIM for this deployment")


    def create_vm_to_host_affinity_rule(self, addrule_href, vmgrpname, hostgrpname, polarity, headers):
        """ Method to create VM to Host Affinity rule in vCD

        Args:
            addrule_href - href to make a POST request
            vmgrpname - name of the VM group created
            hostgrpnmae - name of the host group created earlier
            polarity - Affinity or Anti-affinity (default: Affinity)
            headers - headers to make REST call

        Returns:
            True- if rule is created
            False- Failed to create rule due to some error

        """
        task_status = False
        rule_name = polarity + "_" + vmgrpname
        payload = """<?xml version="1.0" encoding="UTF-8"?>
                     <vmext:VMWVmHostAffinityRule
                       xmlns:vmext="http://www.vmware.com/vcloud/extension/v1.5"
                       xmlns:vcloud="http://www.vmware.com/vcloud/v1.5"
                       type="application/vnd.vmware.admin.vmwVmHostAffinityRule+xml">
                       <vcloud:Name>{}</vcloud:Name>
                       <vcloud:IsEnabled>true</vcloud:IsEnabled>
                       <vcloud:IsMandatory>true</vcloud:IsMandatory>
                       <vcloud:Polarity>{}</vcloud:Polarity>
                       <vmext:HostGroupName>{}</vmext:HostGroupName>
                       <vmext:VmGroupName>{}</vmext:VmGroupName>
                     </vmext:VMWVmHostAffinityRule>""".format(rule_name, polarity, hostgrpname, vmgrpname)

        resp = self.perform_request(req_type='POST',url=addrule_href, headers=headers, data=payload)

        if resp.status_code != requests.codes.accepted:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(addrule_href, resp.status_code))
            task_status = False
            return task_status
        else:
            affinity_task = self.get_task_from_response(resp.content)
            self.logger.debug ("affinity_task: {}".format(affinity_task))
            if affinity_task is None or affinity_task is False:
                raise vimconn.vimconnUnexpectedResponse("failed to find affinity task")
            # wait for task to complete
            result = self.client.get_task_monitor().wait_for_success(task=affinity_task)
            if result.get('status') == 'success':
                self.logger.debug("Successfully created affinity rule {}".format(rule_name))
                return True
            else:
                raise vimconn.vimconnUnexpectedResponse(
                      "failed to create affinity rule {}".format(rule_name))


    def get_add_rule_reference (self, respool_href, headers):
        """ This method finds href to add vm to host affinity rule to vCD

        Args:
            respool_href- href to resource pool
            headers- header information to make REST call

        Returns:
            None - if no valid href to add rule found or
            addrule_href - href to add vm to host affinity rule of resource pool
        """
        addrule_href = None
        resp = self.perform_request(req_type='GET',url=respool_href, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(respool_href, resp.status_code))
        else:

            resp_xml = XmlElementTree.fromstring(resp.content)
            for child in resp_xml:
                if 'VMWProviderVdcResourcePool' in child.tag:
                    for schild in child:
                        if 'Link' in schild.tag:
                            if schild.attrib.get('type') == "application/vnd.vmware.admin.vmwVmHostAffinityRule+xml" and \
                                schild.attrib.get('rel') == "add":
                                addrule_href = schild.attrib.get('href')
                                break

        return addrule_href


    def add_vm_to_vmgroup(self, vm_uuid, vmGroupNameURL, vmGroup_name, headers):
        """ Method to add deployed VM to newly created VM Group.
            This is required to create VM to Host affinity in vCD

        Args:
            vm_uuid- newly created vm uuid
            vmGroupNameURL- URL to VM Group name
            vmGroup_name- Name of VM group created
            headers- Headers for REST request

        Returns:
            True- if VM added to VM group successfully
            False- if any error encounter
        """

        addvm_resp = self.perform_request(req_type='GET',url=vmGroupNameURL, headers=headers)#, data=payload)

        if addvm_resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call to get VM Group Name url {} failed. Return status code {}"\
                               .format(vmGroupNameURL, addvm_resp.status_code))
            return False
        else:
            resp_xml = XmlElementTree.fromstring(addvm_resp.content)
            for child in resp_xml:
                if child.tag.split('}')[1] == 'Link':
                    if child.attrib.get("rel") == "addVms":
                        addvmtogrpURL =  child.attrib.get("href")

        #Get vm details
        url_list = [self.url, '/api/vApp/vm-',vm_uuid]
        vmdetailsURL = ''.join(url_list)

        resp = self.perform_request(req_type='GET',url=vmdetailsURL, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(vmdetailsURL, resp.status_code))
            return False

        #Parse VM details
        resp_xml = XmlElementTree.fromstring(resp.content)
        if resp_xml.tag.split('}')[1] == "Vm":
            vm_id = resp_xml.attrib.get("id")
            vm_name = resp_xml.attrib.get("name")
            vm_href = resp_xml.attrib.get("href")
            #print vm_id, vm_name, vm_href
        #Add VM into VMgroup
        payload = """<?xml version="1.0" encoding="UTF-8"?>\
                   <ns2:Vms xmlns:ns2="http://www.vmware.com/vcloud/v1.5" \
                    xmlns="http://www.vmware.com/vcloud/versions" \
                    xmlns:ns3="http://schemas.dmtf.org/ovf/envelope/1" \
                    xmlns:ns4="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" \
                    xmlns:ns5="http://schemas.dmtf.org/wbem/wscim/1/common" \
                    xmlns:ns6="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" \
                    xmlns:ns7="http://www.vmware.com/schema/ovf" \
                    xmlns:ns8="http://schemas.dmtf.org/ovf/environment/1" \
                    xmlns:ns9="http://www.vmware.com/vcloud/extension/v1.5">\
                    <ns2:VmReference href="{}" id="{}" name="{}" \
                    type="application/vnd.vmware.vcloud.vm+xml" />\
                   </ns2:Vms>""".format(vm_href, vm_id, vm_name)

        addvmtogrp_resp = self.perform_request(req_type='POST',url=addvmtogrpURL, headers=headers, data=payload)

        if addvmtogrp_resp.status_code != requests.codes.accepted:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(addvmtogrpURL, addvmtogrp_resp.status_code))
            return False
        else:
            self.logger.debug ("Done adding VM {} to VMgroup {}".format(vm_name, vmGroup_name))
            return True


    def create_vmgroup(self, vmgroup_name, vmgroup_href, headers):
        """Method to create a VM group in vCD

           Args:
              vmgroup_name : Name of VM group to be created
              vmgroup_href : href for vmgroup
              headers- Headers for REST request
        """
        #POST to add URL with required data
        vmgroup_status = False
        payload = """<VMWVmGroup xmlns="http://www.vmware.com/vcloud/extension/v1.5" \
                       xmlns:vcloud_v1.5="http://www.vmware.com/vcloud/v1.5" name="{}">\
                   <vmCount>1</vmCount>\
                   </VMWVmGroup>""".format(vmgroup_name)
        resp = self.perform_request(req_type='POST',url=vmgroup_href, headers=headers, data=payload)

        if resp.status_code != requests.codes.accepted:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(vmgroup_href, resp.status_code))
            return vmgroup_status
        else:
            vmgroup_task = self.get_task_from_response(resp.content)
            if vmgroup_task is None or vmgroup_task is False:
                raise vimconn.vimconnUnexpectedResponse(
                    "create_vmgroup(): failed to create VM group {}".format(vmgroup_name))

            # wait for task to complete
            result = self.client.get_task_monitor().wait_for_success(task=vmgroup_task)

            if result.get('status') == 'success':
                self.logger.debug("create_vmgroup(): Successfully created VM group {}".format(vmgroup_name))
                #time.sleep(10)
                vmgroup_status = True
                return vmgroup_status
            else:
                raise vimconn.vimconnUnexpectedResponse(\
                        "create_vmgroup(): failed to create VM group {}".format(vmgroup_name))


    def find_vmgroup_reference(self, url, headers):
        """ Method to create a new VMGroup which is required to add created VM
            Args:
               url- resource pool href
               headers- header information

            Returns:
               returns href to VM group to create VM group
        """
        #Perform GET on resource pool to find 'add' link to create VMGroup
        #https://vcd-ip/api/admin/extension/providervdc/<providervdc id>/resourcePools
        vmgrp_href = None
        resp = self.perform_request(req_type='GET',url=url, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(url, resp.status_code))
        else:
            #Get the href to add vmGroup to vCD
            resp_xml = XmlElementTree.fromstring(resp.content)
            for child in resp_xml:
                if 'VMWProviderVdcResourcePool' in child.tag:
                    for schild in child:
                        if 'Link' in schild.tag:
                            #Find href with type VMGroup and rel with add
                            if schild.attrib.get('type') == "application/vnd.vmware.admin.vmwVmGroupType+xml"\
                                and schild.attrib.get('rel') == "add":
                                vmgrp_href = schild.attrib.get('href')
                                return vmgrp_href


    def check_availibility_zone(self, az, respool_href, headers):
        """ Method to verify requested av zone is present or not in provided
            resource pool

            Args:
                az - name of hostgroup (availibility_zone)
                respool_href - Resource Pool href
                headers - Headers to make REST call
            Returns:
                az_found - True if availibility_zone is found else False
        """
        az_found = False
        headers['Accept']='application/*+xml;version=27.0'
        resp = self.perform_request(req_type='GET',url=respool_href, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}".format(respool_href, resp.status_code))
        else:
        #Get the href to hostGroups and find provided hostGroup is present in it
            resp_xml = XmlElementTree.fromstring(resp.content)

            for child in resp_xml:
                if 'VMWProviderVdcResourcePool' in child.tag:
                    for schild in child:
                        if 'Link' in schild.tag:
                            if schild.attrib.get('type') == "application/vnd.vmware.admin.vmwHostGroupsType+xml":
                                hostGroup_href = schild.attrib.get('href')
                                hg_resp = self.perform_request(req_type='GET',url=hostGroup_href, headers=headers)
                                if hg_resp.status_code != requests.codes.ok:
                                    self.logger.debug ("REST API call {} failed. Return status code {}".format(hostGroup_href, hg_resp.status_code))
                                else:
                                    hg_resp_xml = XmlElementTree.fromstring(hg_resp.content)
                                    for hostGroup in hg_resp_xml:
                                        if 'HostGroup' in hostGroup.tag:
                                            if hostGroup.attrib.get("name") == az:
                                                az_found = True
                                                break
        return az_found


    def get_pvdc_for_org(self, org_vdc, headers):
        """ This method gets provider vdc references from organisation

            Args:
               org_vdc - name of the organisation VDC to find pvdc
               headers - headers to make REST call

            Returns:
               None - if no pvdc href found else
               pvdc_href - href to pvdc
        """

        #Get provider VDC references from vCD
        pvdc_href = None
        #url = '<vcd url>/api/admin/extension/providerVdcReferences'
        url_list = [self.url, '/api/admin/extension/providerVdcReferences']
        url = ''.join(url_list)

        response = self.perform_request(req_type='GET',url=url, headers=headers)
        if response.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}"\
                               .format(url, response.status_code))
        else:
            xmlroot_response = XmlElementTree.fromstring(response.content)
            for child in xmlroot_response:
                if 'ProviderVdcReference' in child.tag:
                    pvdc_href = child.attrib.get('href')
                    #Get vdcReferences to find org
                    pvdc_resp = self.perform_request(req_type='GET',url=pvdc_href, headers=headers)
                    if pvdc_resp.status_code != requests.codes.ok:
                        raise vimconn.vimconnException("REST API call {} failed. "\
                                                       "Return status code {}"\
                                                       .format(url, pvdc_resp.status_code))

                    pvdc_resp_xml = XmlElementTree.fromstring(pvdc_resp.content)
                    for child in pvdc_resp_xml:
                        if 'Link' in child.tag:
                            if child.attrib.get('type') == "application/vnd.vmware.admin.vdcReferences+xml":
                                vdc_href = child.attrib.get('href')

                                #Check if provided org is present in vdc
                                vdc_resp = self.perform_request(req_type='GET',
                                                                url=vdc_href,
                                                                headers=headers)
                                if vdc_resp.status_code != requests.codes.ok:
                                    raise vimconn.vimconnException("REST API call {} failed. "\
                                                                   "Return status code {}"\
                                                                   .format(url, vdc_resp.status_code))
                                vdc_resp_xml = XmlElementTree.fromstring(vdc_resp.content)
                                for child in vdc_resp_xml:
                                    if 'VdcReference' in child.tag:
                                        if child.attrib.get('name') == org_vdc:
                                            return pvdc_href


    def get_resource_pool_details(self, pvdc_href, headers):
        """ Method to get resource pool information.
            Host groups are property of resource group.
            To get host groups, we need to GET details of resource pool.

            Args:
                pvdc_href: href to pvdc details
                headers: headers

            Returns:
                respool_href - Returns href link reference to resource pool
        """
        respool_href = None
        resp = self.perform_request(req_type='GET',url=pvdc_href, headers=headers)

        if resp.status_code != requests.codes.ok:
            self.logger.debug ("REST API call {} failed. Return status code {}"\
                               .format(pvdc_href, resp.status_code))
        else:
            respool_resp_xml = XmlElementTree.fromstring(resp.content)
            for child in respool_resp_xml:
                if 'Link' in child.tag:
                    if child.attrib.get('type') == "application/vnd.vmware.admin.vmwProviderVdcResourcePoolSet+xml":
                        respool_href = child.attrib.get("href")
                        break
        return respool_href


    def log_message(self, msg):
        """
            Method to log error messages related to Affinity rule creation
            in new_vminstance & raise Exception
                Args :
                    msg - Error message to be logged

        """
        #get token to connect vCD as a normal user
        self.get_token()
        self.logger.debug(msg)
        raise vimconn.vimconnException(msg)


    ##
    ##
    ##  based on current discussion
    ##
    ##
    ##  server:
    #   created: '2016-09-08T11:51:58'
    #   description: simple-instance.linux1.1
    #   flavor: ddc6776e-75a9-11e6-ad5f-0800273e724c
    #   hostId: e836c036-74e7-11e6-b249-0800273e724c
    #   image: dde30fe6-75a9-11e6-ad5f-0800273e724c
    #   status: ACTIVE
    #   error_msg:
    #   interfaces: …
    #
    def get_vminstance(self, vim_vm_uuid=None):
        """Returns the VM instance information from VIM"""

        self.logger.debug("Client requesting vm instance {} ".format(vim_vm_uuid))

        org, vdc = self.get_vdc_details()
        if vdc is None:
            raise vimconn.vimconnConnectionException(
                "Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))

        vm_info_dict = self.get_vapp_details_rest(vapp_uuid=vim_vm_uuid)
        if not vm_info_dict:
            self.logger.debug("get_vminstance(): Failed to get vApp name by UUID {}".format(vim_vm_uuid))
            raise vimconn.vimconnNotFoundException("Failed to get vApp name by UUID {}".format(vim_vm_uuid))

        status_key = vm_info_dict['status']
        error = ''
        try:
            vm_dict = {'created': vm_info_dict['created'],
                       'description': vm_info_dict['name'],
                       'status': vcdStatusCode2manoFormat[int(status_key)],
                       'hostId': vm_info_dict['vmuuid'],
                       'error_msg': error,
                       'vim_info': yaml.safe_dump(vm_info_dict), 'interfaces': []}

            if 'interfaces' in vm_info_dict:
                vm_dict['interfaces'] = vm_info_dict['interfaces']
            else:
                vm_dict['interfaces'] = []
        except KeyError:
            vm_dict = {'created': '',
                       'description': '',
                       'status': vcdStatusCode2manoFormat[int(-1)],
                       'hostId': vm_info_dict['vmuuid'],
                       'error_msg': "Inconsistency state",
                       'vim_info': yaml.safe_dump(vm_info_dict), 'interfaces': []}

        return vm_dict

    def delete_vminstance(self, vm__vim_uuid, created_items=None):
        """Method poweroff and remove VM instance from vcloud director network.

        Args:
            vm__vim_uuid: VM UUID

        Returns:
            Returns the instance identifier
        """

        self.logger.debug("Client requesting delete vm instance {} ".format(vm__vim_uuid))

        org, vdc = self.get_vdc_details()
        vdc_obj = VDC(self.client, href=vdc.get('href'))
        if vdc_obj is None:
            self.logger.debug("delete_vminstance(): Failed to get a reference of VDC for a tenant {}".format(
                self.tenant_name))
            raise vimconn.vimconnException(
                "delete_vminstance(): Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))

        try:
            vapp_name = self.get_namebyvappid(vm__vim_uuid)
            if vapp_name is None:
                self.logger.debug("delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid))
                return -1, "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)
            self.logger.info("Deleting vApp {} and UUID {}".format(vapp_name, vm__vim_uuid))
            vapp_resource = vdc_obj.get_vapp(vapp_name)
            vapp = VApp(self.client, resource=vapp_resource)

            # Delete vApp and wait for status change if task executed and vApp is None.

            if vapp:
                if vapp_resource.get('deployed') == 'true':
                    self.logger.info("Powering off vApp {}".format(vapp_name))
                    #Power off vApp
                    powered_off = False
                    wait_time = 0
                    while wait_time <= MAX_WAIT_TIME:
                        power_off_task = vapp.power_off()
                        result = self.client.get_task_monitor().wait_for_success(task=power_off_task)

                        if result.get('status') == 'success':
                            powered_off = True
                            break
                        else:
                            self.logger.info("Wait for vApp {} to power off".format(vapp_name))
                            time.sleep(INTERVAL_TIME)

                        wait_time +=INTERVAL_TIME
                    if not powered_off:
                        self.logger.debug("delete_vminstance(): Failed to power off VM instance {} ".format(vm__vim_uuid))
                    else:
                        self.logger.info("delete_vminstance(): Powered off VM instance {} ".format(vm__vim_uuid))

                    #Undeploy vApp
                    self.logger.info("Undeploy vApp {}".format(vapp_name))
                    wait_time = 0
                    undeployed = False
                    while wait_time <= MAX_WAIT_TIME:
                        vapp = VApp(self.client, resource=vapp_resource)
                        if not vapp:
                            self.logger.debug("delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid))
                            return -1, "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)
                        undeploy_task = vapp.undeploy()

                        result = self.client.get_task_monitor().wait_for_success(task=undeploy_task)
                        if result.get('status') == 'success':
                            undeployed = True
                            break
                        else:
                            self.logger.debug("Wait for vApp {} to undeploy".format(vapp_name))
                            time.sleep(INTERVAL_TIME)

                        wait_time +=INTERVAL_TIME

                    if not undeployed:
                        self.logger.debug("delete_vminstance(): Failed to undeploy vApp {} ".format(vm__vim_uuid))

                # delete vapp
                self.logger.info("Start deletion of vApp {} ".format(vapp_name))

                if vapp is not None:
                    wait_time = 0
                    result = False

                    while wait_time <= MAX_WAIT_TIME:
                        vapp = VApp(self.client, resource=vapp_resource)
                        if not vapp:
                            self.logger.debug("delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid))
                            return -1, "delete_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid)

                        delete_task = vdc_obj.delete_vapp(vapp.name, force=True)

                        result = self.client.get_task_monitor().wait_for_success(task=delete_task)
                        if result.get('status') == 'success':
                            break
                        else:
                            self.logger.debug("Wait for vApp {} to delete".format(vapp_name))
                            time.sleep(INTERVAL_TIME)

                        wait_time +=INTERVAL_TIME

                    if result is None:
                        self.logger.debug("delete_vminstance(): Failed delete uuid {} ".format(vm__vim_uuid))
                    else:
                        self.logger.info("Deleted vm instance {} sccessfully".format(vm__vim_uuid))
                        config_drive_catalog_name, config_drive_catalog_id = 'cfg_drv-' + vm__vim_uuid, None
                        catalog_list = self.get_image_list()
                        try:
                            config_drive_catalog_id = [catalog_['id'] for catalog_ in catalog_list
                                                       if catalog_['name'] == config_drive_catalog_name][0]
                        except IndexError:
                            pass
                        if config_drive_catalog_id:
                            self.logger.debug('delete_vminstance(): Found a config drive catalog {} matching '
                                              'vapp_name"{}". Deleting it.'.format(config_drive_catalog_id, vapp_name))
                            self.delete_image(config_drive_catalog_id)
                        return vm__vim_uuid
        except:
            self.logger.debug(traceback.format_exc())
            raise vimconn.vimconnException("delete_vminstance(): Failed delete vm instance {}".format(vm__vim_uuid))


    def refresh_vms_status(self, vm_list):
        """Get the status of the virtual machines and their interfaces/ports
           Params: the list of VM identifiers
           Returns a dictionary with:
                vm_id:          #VIM id of this Virtual Machine
                    status:     #Mandatory. Text with one of:
                                #  DELETED (not found at vim)
                                #  VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
                                #  OTHER (Vim reported other status not understood)
                                #  ERROR (VIM indicates an ERROR status)
                                #  ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
                                #  CREATING (on building process), ERROR
                                #  ACTIVE:NoMgmtIP (Active but any of its interface has an IP address
                                #
                    error_msg:  #Text with VIM error message, if any. Or the VIM connection ERROR
                    vim_info:   #Text with plain information obtained from vim (yaml.safe_dump)
                    interfaces:
                     -  vim_info:         #Text with plain information obtained from vim (yaml.safe_dump)
                        mac_address:      #Text format XX:XX:XX:XX:XX:XX
                        vim_net_id:       #network id where this interface is connected
                        vim_interface_id: #interface/port VIM id
                        ip_address:       #null, or text with IPv4, IPv6 address
        """

        self.logger.debug("Client requesting refresh vm status for {} ".format(vm_list))

        org,vdc = self.get_vdc_details()
        if vdc is None:
            raise vimconn.vimconnException("Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))

        vms_dict = {}
        nsx_edge_list = []
        for vmuuid in vm_list:
            vapp_name = self.get_namebyvappid(vmuuid)
            if vapp_name is not None:

                try:
                    vm_pci_details = self.get_vm_pci_details(vmuuid)
                    vdc_obj = VDC(self.client, href=vdc.get('href'))
                    vapp_resource = vdc_obj.get_vapp(vapp_name)
                    the_vapp = VApp(self.client, resource=vapp_resource)

                    vm_details = {}
                    for vm in the_vapp.get_all_vms():
                        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                        response = self.perform_request(req_type='GET',
                                                        url=vm.get('href'),
                                                        headers=headers)

                        if response.status_code != 200:
                            self.logger.error("refresh_vms_status : REST call {} failed reason : {}"\
                                                            "status code : {}".format(vm.get('href'),
                                                                                    response.content,
                                                                               response.status_code))
                            raise vimconn.vimconnException("refresh_vms_status : Failed to get "\
                                                                         "VM details")
                        xmlroot = XmlElementTree.fromstring(response.content)

                        
                        result = response.content.replace("\n"," ")
                        hdd_match = re.search('vcloud:capacity="(\d+)"\svcloud:storageProfileOverrideVmDefault=',result)
                        if hdd_match:
                            hdd_mb = hdd_match.group(1)
                            vm_details['hdd_mb'] = int(hdd_mb) if hdd_mb else None
                        cpus_match = re.search('<rasd:Description>Number of Virtual CPUs</.*?>(\d+)</rasd:VirtualQuantity>',result)
                        if cpus_match:
                            cpus = cpus_match.group(1)
                            vm_details['cpus'] = int(cpus) if cpus else None
                        memory_mb = re.search('<rasd:Description>Memory Size</.*?>(\d+)</rasd:VirtualQuantity>',result).group(1)
                        vm_details['memory_mb'] = int(memory_mb) if memory_mb else None
                        vm_details['status'] = vcdStatusCode2manoFormat[int(xmlroot.get('status'))]
                        vm_details['id'] = xmlroot.get('id')
                        vm_details['name'] = xmlroot.get('name')
                        vm_info = [vm_details]
                        if vm_pci_details:
                            vm_info[0].update(vm_pci_details)

                        vm_dict = {'status': vcdStatusCode2manoFormat[int(vapp_resource.get('status'))],
                                   'error_msg': vcdStatusCode2manoFormat[int(vapp_resource.get('status'))],
                                   'vim_info': yaml.safe_dump(vm_info), 'interfaces': []}

                        # get networks
                        vm_ip = None
                        vm_mac = None
                        networks = re.findall('<NetworkConnection needsCustomization=.*?</NetworkConnection>',result)
                        for network in networks:
                            mac_s = re.search('<MACAddress>(.*?)</MACAddress>',network)
                            vm_mac = mac_s.group(1) if mac_s else None
                            ip_s = re.search('<IpAddress>(.*?)</IpAddress>',network)
                            vm_ip = ip_s.group(1) if ip_s else None

                            if vm_ip is None:
                                if not nsx_edge_list:
                                    nsx_edge_list = self.get_edge_details()
                                    if nsx_edge_list is None:
                                        raise vimconn.vimconnException("refresh_vms_status:"\
                                                                       "Failed to get edge details from NSX Manager")
                                if vm_mac is not None:
                                    vm_ip = self.get_ipaddr_from_NSXedge(nsx_edge_list, vm_mac)

                            net_s = re.search('network="(.*?)"',network)
                            network_name = net_s.group(1) if net_s else None

                            vm_net_id = self.get_network_id_by_name(network_name)
                            interface = {"mac_address": vm_mac,
                                         "vim_net_id": vm_net_id,
                                         "vim_interface_id": vm_net_id,
                                         "ip_address": vm_ip}

                            vm_dict["interfaces"].append(interface)

                    # add a vm to vm dict
                    vms_dict.setdefault(vmuuid, vm_dict)
                    self.logger.debug("refresh_vms_status : vm info {}".format(vm_dict))
                except Exception as exp:
                    self.logger.debug("Error in response {}".format(exp))
                    self.logger.debug(traceback.format_exc())

        return vms_dict


    def get_edge_details(self):
        """Get the NSX edge list from NSX Manager
           Returns list of NSX edges
        """
        edge_list = []
        rheaders = {'Content-Type': 'application/xml'}
        nsx_api_url = '/api/4.0/edges'

        self.logger.debug("Get edge details from NSX Manager {} {}".format(self.nsx_manager, nsx_api_url))

        try:
            resp = requests.get(self.nsx_manager + nsx_api_url,
                                auth = (self.nsx_user, self.nsx_password),
                                verify = False, headers = rheaders)
            if resp.status_code == requests.codes.ok:
                paged_Edge_List = XmlElementTree.fromstring(resp.text)
                for edge_pages in paged_Edge_List:
                    if edge_pages.tag == 'edgePage':
                        for edge_summary in edge_pages:
                            if edge_summary.tag == 'pagingInfo':
                                for element in edge_summary:
                                    if element.tag == 'totalCount' and element.text == '0':
                                        raise vimconn.vimconnException("get_edge_details: No NSX edges details found: {}"
                                                                       .format(self.nsx_manager))

                            if edge_summary.tag == 'edgeSummary':
                                for element in edge_summary:
                                    if element.tag == 'id':
                                        edge_list.append(element.text)
                    else:
                        raise vimconn.vimconnException("get_edge_details: No NSX edge details found: {}"
                                                       .format(self.nsx_manager))

                if not edge_list:
                    raise vimconn.vimconnException("get_edge_details: "\
                                                   "No NSX edge details found: {}"
                                                   .format(self.nsx_manager))
                else:
                    self.logger.debug("get_edge_details: Found NSX edges {}".format(edge_list))
                    return edge_list
            else:
                self.logger.debug("get_edge_details: "
                                  "Failed to get NSX edge details from NSX Manager: {}"
                                  .format(resp.content))
                return None

        except Exception as exp:
            self.logger.debug("get_edge_details: "\
                              "Failed to get NSX edge details from NSX Manager: {}"
                              .format(exp))
            raise vimconn.vimconnException("get_edge_details: "\
                                           "Failed to get NSX edge details from NSX Manager: {}"
                                           .format(exp))


    def get_ipaddr_from_NSXedge(self, nsx_edges, mac_address):
        """Get IP address details from NSX edges, using the MAC address
           PARAMS: nsx_edges : List of NSX edges
                   mac_address : Find IP address corresponding to this MAC address
           Returns: IP address corrresponding to the provided MAC address
        """

        ip_addr = None
        rheaders = {'Content-Type': 'application/xml'}

        self.logger.debug("get_ipaddr_from_NSXedge: Finding IP addr from NSX edge")

        try:
            for edge in nsx_edges:
                nsx_api_url = '/api/4.0/edges/'+ edge +'/dhcp/leaseInfo'

                resp = requests.get(self.nsx_manager + nsx_api_url,
                                    auth = (self.nsx_user, self.nsx_password),
                                    verify = False, headers = rheaders)

                if resp.status_code == requests.codes.ok:
                    dhcp_leases = XmlElementTree.fromstring(resp.text)
                    for child in dhcp_leases:
                        if child.tag == 'dhcpLeaseInfo':
                            dhcpLeaseInfo = child
                            for leaseInfo in dhcpLeaseInfo:
                                for elem in leaseInfo:
                                    if (elem.tag)=='macAddress':
                                        edge_mac_addr = elem.text
                                    if (elem.tag)=='ipAddress':
                                        ip_addr = elem.text
                                if edge_mac_addr is not None:
                                    if edge_mac_addr == mac_address:
                                        self.logger.debug("Found ip addr {} for mac {} at NSX edge {}"
                                                          .format(ip_addr, mac_address,edge))
                                        return ip_addr
                else:
                    self.logger.debug("get_ipaddr_from_NSXedge: "\
                                      "Error occurred while getting DHCP lease info from NSX Manager: {}"
                                      .format(resp.content))

            self.logger.debug("get_ipaddr_from_NSXedge: No IP addr found in any NSX edge")
            return None

        except XmlElementTree.ParseError as Err:
            self.logger.debug("ParseError in response from NSX Manager {}".format(Err.message), exc_info=True)


    def action_vminstance(self, vm__vim_uuid=None, action_dict=None, created_items={}):
        """Send and action over a VM instance from VIM
        Returns the vm_id if the action was successfully sent to the VIM"""

        self.logger.debug("Received action for vm {} and action dict {}".format(vm__vim_uuid, action_dict))
        if vm__vim_uuid is None or action_dict is None:
            raise vimconn.vimconnException("Invalid request. VM id or action is None.")

        org, vdc = self.get_vdc_details()
        if vdc is None:
            raise  vimconn.vimconnException("Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))

        vapp_name = self.get_namebyvappid(vm__vim_uuid)
        if vapp_name is None:
            self.logger.debug("action_vminstance(): Failed to get vm by given {} vm uuid".format(vm__vim_uuid))
            raise vimconn.vimconnException("Failed to get vm by given {} vm uuid".format(vm__vim_uuid))
        else:
            self.logger.info("Action_vminstance vApp {} and UUID {}".format(vapp_name, vm__vim_uuid))

        try:
            vdc_obj = VDC(self.client, href=vdc.get('href'))
            vapp_resource = vdc_obj.get_vapp(vapp_name)
            vapp = VApp(self.client, resource=vapp_resource)
            if "start" in action_dict:
                self.logger.info("action_vminstance: Power on vApp: {}".format(vapp_name))
                poweron_task = self.power_on_vapp(vm__vim_uuid, vapp_name)
                result = self.client.get_task_monitor().wait_for_success(task=poweron_task)
                self.instance_actions_result("start", result, vapp_name)
            elif "rebuild" in action_dict:
                self.logger.info("action_vminstance: Rebuild vApp: {}".format(vapp_name))
                rebuild_task = vapp.deploy(power_on=True)
                result = self.client.get_task_monitor().wait_for_success(task=rebuild_task)
                self.instance_actions_result("rebuild", result, vapp_name)
            elif "pause" in action_dict:
                self.logger.info("action_vminstance: pause vApp: {}".format(vapp_name))
                pause_task = vapp.undeploy(action='suspend')
                result = self.client.get_task_monitor().wait_for_success(task=pause_task)
                self.instance_actions_result("pause", result, vapp_name)
            elif "resume" in action_dict:
                self.logger.info("action_vminstance: resume vApp: {}".format(vapp_name))
                poweron_task = self.power_on_vapp(vm__vim_uuid, vapp_name)
                result = self.client.get_task_monitor().wait_for_success(task=poweron_task)
                self.instance_actions_result("resume", result, vapp_name)
            elif "shutoff" in action_dict or "shutdown" in action_dict:
                action_name , value = action_dict.items()[0]
                #For python3
                #action_name , value = list(action_dict.items())[0]
                self.logger.info("action_vminstance: {} vApp: {}".format(action_name, vapp_name))
                shutdown_task = vapp.shutdown()
                result = self.client.get_task_monitor().wait_for_success(task=shutdown_task)
                if action_name == "shutdown":
                    self.instance_actions_result("shutdown", result, vapp_name)
                else:
                    self.instance_actions_result("shutoff", result, vapp_name)
            elif "forceOff" in action_dict:
                result = vapp.undeploy(action='powerOff')
                self.instance_actions_result("forceOff", result, vapp_name)
            elif "reboot" in action_dict:
                self.logger.info("action_vminstance: reboot vApp: {}".format(vapp_name))
                reboot_task = vapp.reboot()
                self.client.get_task_monitor().wait_for_success(task=reboot_task)
            else:
                raise vimconn.vimconnException("action_vminstance: Invalid action {} or action is None.".format(action_dict))
            return vm__vim_uuid
        except Exception as exp :
            self.logger.debug("action_vminstance: Failed with Exception {}".format(exp))
            raise vimconn.vimconnException("action_vminstance: Failed with Exception {}".format(exp))

    def instance_actions_result(self, action, result, vapp_name):
        if result.get('status') == 'success':
            self.logger.info("action_vminstance: Sucessfully {} the vApp: {}".format(action, vapp_name))
        else:
            self.logger.error("action_vminstance: Failed to {} vApp: {}".format(action, vapp_name))

    def get_vminstance_console(self, vm_id, console_type="novnc"):
        """
        Get a console for the virtual machine
        Params:
            vm_id: uuid of the VM
            console_type, can be:
                "novnc" (by default), "xvpvnc" for VNC types,
                "rdp-html5" for RDP types, "spice-html5" for SPICE types
        Returns dict with the console parameters:
                protocol: ssh, ftp, http, https, ...
                server:   usually ip address
                port:     the http, ssh, ... port
                suffix:   extra text, e.g. the http path and query string
        """
        console_dict = {}

        if console_type==None or console_type=='novnc':

            url_rest_call = "{}/api/vApp/vm-{}/screen/action/acquireMksTicket".format(self.url, vm_id)

            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='POST',
                                         url=url_rest_call,
                                           headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('GET', url_rest_call)

            if response.status_code != 200:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {}".format(url_rest_call,
                                                         response.content,
                                                    response.status_code))
                raise vimconn.vimconnException("get_vminstance_console : Failed to get "\
                                                                     "VM Mks ticket details")
            s = re.search("<Host>(.*?)</Host>",response.content)
            console_dict['server'] = s.group(1) if s else None
            s1 = re.search("<Port>(\d+)</Port>",response.content)
            console_dict['port'] = s1.group(1) if s1 else None


            url_rest_call = "{}/api/vApp/vm-{}/screen/action/acquireTicket".format(self.url, vm_id)

            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='POST',
                                         url=url_rest_call,
                                           headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('GET', url_rest_call)

            if response.status_code != 200:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {}".format(url_rest_call,
                                                         response.content,
                                                    response.status_code))
                raise vimconn.vimconnException("get_vminstance_console : Failed to get "\
                                                                     "VM console details")
            s = re.search(">.*?/(vm-\d+.*)</",response.content)
            console_dict['suffix'] = s.group(1) if s else None
            console_dict['protocol'] = "https"

        return console_dict

    # NOT USED METHODS in current version

    def host_vim2gui(self, host, server_dict):
        """Transform host dictionary from VIM format to GUI format,
        and append to the server_dict
        """
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def get_hosts_info(self):
        """Get the information of deployed hosts
        Returns the hosts content"""
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def get_hosts(self, vim_tenant):
        """Get the hosts and deployed instances
        Returns the hosts content"""
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def get_processor_rankings(self):
        """Get the processor rankings in the VIM database"""
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def new_host(self, host_data):
        """Adds a new host to VIM"""
        '''Returns status code of the VIM response'''
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def new_external_port(self, port_data):
        """Adds a external port to VIM"""
        '''Returns the port identifier'''
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def new_external_network(self, net_name, net_type):
        """Adds a external network to VIM (shared)"""
        '''Returns the network identifier'''
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def connect_port_network(self, port_id, network_id, admin=False):
        """Connects a external port to a network"""
        '''Returns status code of the VIM response'''
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def new_vminstancefromJSON(self, vm_data):
        """Adds a VM instance to VIM"""
        '''Returns the instance identifier'''
        raise vimconn.vimconnNotImplemented("Should have implemented this")

    def get_network_name_by_id(self, network_uuid=None):
        """Method gets vcloud director network named based on supplied uuid.

        Args:
            network_uuid: network_id

        Returns:
            The return network name.
        """

        if not network_uuid:
            return None

        try:
            org_dict = self.get_org(self.org_uuid)
            if 'networks' in org_dict:
                org_network_dict = org_dict['networks']
                for net_uuid in org_network_dict:
                    if net_uuid == network_uuid:
                        return org_network_dict[net_uuid]
        except:
            self.logger.debug("Exception in get_network_name_by_id")
            self.logger.debug(traceback.format_exc())

        return None

    def get_network_id_by_name(self, network_name=None):
        """Method gets vcloud director network uuid based on supplied name.

        Args:
            network_name: network_name
        Returns:
            The return network uuid.
            network_uuid: network_id
        """

        if not network_name:
            self.logger.debug("get_network_id_by_name() : Network name is empty")
            return None

        try:
            org_dict = self.get_org(self.org_uuid)
            if org_dict and 'networks' in org_dict:
                org_network_dict = org_dict['networks']
                for net_uuid,net_name in org_network_dict.iteritems():
                #For python3
                #for net_uuid,net_name in org_network_dict.items():
                    if net_name == network_name:
                        return net_uuid

        except KeyError as exp:
            self.logger.debug("get_network_id_by_name() : KeyError- {} ".format(exp))

        return None

    def list_org_action(self):
        """
        Method leverages vCloud director and query for available organization for particular user

        Args:
            vca - is active VCA connection.
            vdc_name - is a vdc name that will be used to query vms action

            Returns:
                The return XML respond
        """
        url_list = [self.url, '/api/org']
        vm_list_rest_call = ''.join(url_list)

        if self.client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

            response = self.perform_request(req_type='GET',
                                     url=vm_list_rest_call,
                                           headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('GET', vm_list_rest_call)

            if response.status_code == requests.codes.ok:
                return response.content

        return None

    def get_org_action(self, org_uuid=None):
        """
        Method leverages vCloud director and retrieve available object for organization.

        Args:
            org_uuid - vCD organization uuid
            self.client - is active connection.

            Returns:
                The return XML respond
        """

        if org_uuid is None:
            return None

        url_list = [self.url, '/api/org/', org_uuid]
        vm_list_rest_call = ''.join(url_list)

        if self.client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                     'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

            #response = requests.get(vm_list_rest_call, headers=headers, verify=False)
            response = self.perform_request(req_type='GET',
                                            url=vm_list_rest_call,
                                            headers=headers)
            if response.status_code == 403:
                response = self.retry_rest('GET', vm_list_rest_call)

            if response.status_code == requests.codes.ok:
                return response.content
        return None

    def get_org(self, org_uuid=None):
        """
        Method retrieves available organization in vCloud Director

        Args:
            org_uuid - is a organization uuid.

            Returns:
                The return dictionary with following key
                    "network" - for network list under the org
                    "catalogs" - for network list under the org
                    "vdcs" - for vdc list under org
        """

        org_dict = {}

        if org_uuid is None:
            return org_dict

        content = self.get_org_action(org_uuid=org_uuid)
        try:
            vdc_list = {}
            network_list = {}
            catalog_list = {}
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            for child in vm_list_xmlroot:
                if child.attrib['type'] == 'application/vnd.vmware.vcloud.vdc+xml':
                    vdc_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
                    org_dict['vdcs'] = vdc_list
                if child.attrib['type'] == 'application/vnd.vmware.vcloud.orgNetwork+xml':
                    network_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
                    org_dict['networks'] = network_list
                if child.attrib['type'] == 'application/vnd.vmware.vcloud.catalog+xml':
                    catalog_list[child.attrib['href'].split("/")[-1:][0]] = child.attrib['name']
                    org_dict['catalogs'] = catalog_list
        except:
            pass

        return org_dict

    def get_org_list(self):
        """
        Method retrieves available organization in vCloud Director

        Args:
            vca - is active VCA connection.

            Returns:
                The return dictionary and key for each entry VDC UUID
        """

        org_dict = {}

        content = self.list_org_action()
        try:
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            for vm_xml in vm_list_xmlroot:
                if vm_xml.tag.split("}")[1] == 'Org':
                    org_uuid = vm_xml.attrib['href'].split('/')[-1:]
                    org_dict[org_uuid[0]] = vm_xml.attrib['name']
        except:
            pass

        return org_dict

    def vms_view_action(self, vdc_name=None):
        """ Method leverages vCloud director vms query call

        Args:
            vca - is active VCA connection.
            vdc_name - is a vdc name that will be used to query vms action

            Returns:
                The return XML respond
        """
        vca = self.connect()
        if vdc_name is None:
            return None

        url_list = [vca.host, '/api/vms/query']
        vm_list_rest_call = ''.join(url_list)

        if not (not vca.vcloud_session or not vca.vcloud_session.organization):
            refs = filter(lambda ref: ref.name == vdc_name and ref.type_ == 'application/vnd.vmware.vcloud.vdc+xml',
                          vca.vcloud_session.organization.Link)
            #For python3
            #refs = [ref for ref in vca.vcloud_session.organization.Link if ref.name == vdc_name and\
            #        ref.type_ == 'application/vnd.vmware.vcloud.vdc+xml']
            if len(refs) == 1:
                response = Http.get(url=vm_list_rest_call,
                                    headers=vca.vcloud_session.get_vcloud_headers(),
                                    verify=vca.verify,
                                    logger=vca.logger)
                if response.status_code == requests.codes.ok:
                    return response.content

        return None

    def get_vapp_list(self, vdc_name=None):
        """
        Method retrieves vApp list deployed vCloud director and returns a dictionary
        contains a list of all vapp deployed for queried VDC.
        The key for a dictionary is vApp UUID


        Args:
            vca - is active VCA connection.
            vdc_name - is a vdc name that will be used to query vms action

            Returns:
                The return dictionary and key for each entry vapp UUID
        """

        vapp_dict = {}
        if vdc_name is None:
            return vapp_dict

        content = self.vms_view_action(vdc_name=vdc_name)
        try:
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            for vm_xml in vm_list_xmlroot:
                if vm_xml.tag.split("}")[1] == 'VMRecord':
                    if vm_xml.attrib['isVAppTemplate'] == 'true':
                        rawuuid = vm_xml.attrib['container'].split('/')[-1:]
                        if 'vappTemplate-' in rawuuid[0]:
                            # vm in format vappTemplate-e63d40e7-4ff5-4c6d-851f-96c1e4da86a5 we remove
                            # vm and use raw UUID as key
                            vapp_dict[rawuuid[0][13:]] = vm_xml.attrib
        except:
            pass

        return vapp_dict

    def get_vm_list(self, vdc_name=None):
        """
        Method retrieves VM's list deployed vCloud director. It returns a dictionary
        contains a list of all VM's deployed for queried VDC.
        The key for a dictionary is VM UUID


        Args:
            vca - is active VCA connection.
            vdc_name - is a vdc name that will be used to query vms action

            Returns:
                The return dictionary and key for each entry vapp UUID
        """
        vm_dict = {}

        if vdc_name is None:
            return vm_dict

        content = self.vms_view_action(vdc_name=vdc_name)
        try:
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            for vm_xml in vm_list_xmlroot:
                if vm_xml.tag.split("}")[1] == 'VMRecord':
                    if vm_xml.attrib['isVAppTemplate'] == 'false':
                        rawuuid = vm_xml.attrib['href'].split('/')[-1:]
                        if 'vm-' in rawuuid[0]:
                            # vm in format vm-e63d40e7-4ff5-4c6d-851f-96c1e4da86a5 we remove
                            #  vm and use raw UUID as key
                            vm_dict[rawuuid[0][3:]] = vm_xml.attrib
        except:
            pass

        return vm_dict

    def get_vapp(self, vdc_name=None, vapp_name=None, isuuid=False):
        """
        Method retrieves VM deployed vCloud director. It returns VM attribute as dictionary
        contains a list of all VM's deployed for queried VDC.
        The key for a dictionary is VM UUID


        Args:
            vca - is active VCA connection.
            vdc_name - is a vdc name that will be used to query vms action

            Returns:
                The return dictionary and key for each entry vapp UUID
        """
        vm_dict = {}
        vca = self.connect()
        if not vca:
            raise vimconn.vimconnConnectionException("self.connect() is failed")

        if vdc_name is None:
            return vm_dict

        content = self.vms_view_action(vdc_name=vdc_name)
        try:
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            for vm_xml in vm_list_xmlroot:
                if vm_xml.tag.split("}")[1] == 'VMRecord' and vm_xml.attrib['isVAppTemplate'] == 'false':
                    # lookup done by UUID
                    if isuuid:
                        if vapp_name in vm_xml.attrib['container']:
                            rawuuid = vm_xml.attrib['href'].split('/')[-1:]
                            if 'vm-' in rawuuid[0]:
                                vm_dict[rawuuid[0][3:]] = vm_xml.attrib
                                break
                    # lookup done by Name
                    else:
                        if vapp_name in vm_xml.attrib['name']:
                            rawuuid = vm_xml.attrib['href'].split('/')[-1:]
                            if 'vm-' in rawuuid[0]:
                                vm_dict[rawuuid[0][3:]] = vm_xml.attrib
                                break
        except:
            pass

        return vm_dict

    def get_network_action(self, network_uuid=None):
        """
        Method leverages vCloud director and query network based on network uuid

        Args:
            vca - is active VCA connection.
            network_uuid - is a network uuid

            Returns:
                The return XML respond
        """

        if network_uuid is None:
            return None

        url_list = [self.url, '/api/network/', network_uuid]
        vm_list_rest_call = ''.join(url_list)

        if self.client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                     'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

            response = self.perform_request(req_type='GET',
                                            url=vm_list_rest_call,
                                            headers=headers)
            #Retry login if session expired & retry sending request
            if response.status_code == 403:
                response = self.retry_rest('GET', vm_list_rest_call)

            if response.status_code == requests.codes.ok:
                return response.content

        return None

    def get_vcd_network(self, network_uuid=None):
        """
        Method retrieves available network from vCloud Director

        Args:
            network_uuid - is VCD network UUID

        Each element serialized as key : value pair

        Following keys available for access.    network_configuration['Gateway'}
        <Configuration>
          <IpScopes>
            <IpScope>
                <IsInherited>true</IsInherited>
                <Gateway>172.16.252.100</Gateway>
                <Netmask>255.255.255.0</Netmask>
                <Dns1>172.16.254.201</Dns1>
                <Dns2>172.16.254.202</Dns2>
                <DnsSuffix>vmwarelab.edu</DnsSuffix>
                <IsEnabled>true</IsEnabled>
                <IpRanges>
                    <IpRange>
                        <StartAddress>172.16.252.1</StartAddress>
                        <EndAddress>172.16.252.99</EndAddress>
                    </IpRange>
                </IpRanges>
            </IpScope>
        </IpScopes>
        <FenceMode>bridged</FenceMode>

        Returns:
                The return dictionary and key for each entry vapp UUID
        """

        network_configuration = {}
        if network_uuid is None:
            return network_uuid

        try:
            content = self.get_network_action(network_uuid=network_uuid)
            vm_list_xmlroot = XmlElementTree.fromstring(content)

            network_configuration['status'] = vm_list_xmlroot.get("status")
            network_configuration['name'] = vm_list_xmlroot.get("name")
            network_configuration['uuid'] = vm_list_xmlroot.get("id").split(":")[3]

            for child in vm_list_xmlroot:
                if child.tag.split("}")[1] == 'IsShared':
                    network_configuration['isShared'] = child.text.strip()
                if child.tag.split("}")[1] == 'Configuration':
                    for configuration in child.iter():
                        tagKey = configuration.tag.split("}")[1].strip()
                        if tagKey != "":
                            network_configuration[tagKey] = configuration.text.strip()
            return network_configuration
        except Exception as exp :
            self.logger.debug("get_vcd_network: Failed with Exception {}".format(exp))
            raise vimconn.vimconnException("get_vcd_network: Failed with Exception {}".format(exp))

        return network_configuration

    def delete_network_action(self, network_uuid=None):
        """
        Method delete given network from vCloud director

        Args:
            network_uuid - is a network uuid that client wish to delete

            Returns:
                The return None or XML respond or false
        """
        client = self.connect_as_admin()
        if not client:
            raise vimconn.vimconnConnectionException("Failed to connect vCD as admin")
        if network_uuid is None:
            return False

        url_list = [self.url, '/api/admin/network/', network_uuid]
        vm_list_rest_call = ''.join(url_list)

        if client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                     'x-vcloud-authorization': client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='DELETE',
                                            url=vm_list_rest_call,
                                            headers=headers)
            if response.status_code == 202:
                return True

        return False

    def create_network(self, network_name=None, net_type='bridge', parent_network_uuid=None,
                       ip_profile=None, isshared='true'):
        """
        Method create network in vCloud director

        Args:
            network_name - is network name to be created.
            net_type - can be 'bridge','data','ptp','mgmt'.
            ip_profile is a dict containing the IP parameters of the network
            isshared - is a boolean
            parent_network_uuid - is parent provider vdc network that will be used for mapping.
            It optional attribute. by default if no parent network indicate the first available will be used.

            Returns:
                The return network uuid or return None
        """

        new_network_name = [network_name, '-', str(uuid.uuid4())]
        content = self.create_network_rest(network_name=''.join(new_network_name),
                                           ip_profile=ip_profile,
                                           net_type=net_type,
                                           parent_network_uuid=parent_network_uuid,
                                           isshared=isshared)
        if content is None:
            self.logger.debug("Failed create network {}.".format(network_name))
            return None

        try:
            vm_list_xmlroot = XmlElementTree.fromstring(content)
            vcd_uuid = vm_list_xmlroot.get('id').split(":")
            if len(vcd_uuid) == 4:
                self.logger.info("Created new network name: {} uuid: {}".format(network_name, vcd_uuid[3]))
                return vcd_uuid[3]
        except:
            self.logger.debug("Failed create network {}".format(network_name))
            return None

    def create_network_rest(self, network_name=None, net_type='bridge', parent_network_uuid=None,
                            ip_profile=None, isshared='true'):
        """
        Method create network in vCloud director

        Args:
            network_name - is network name to be created.
            net_type - can be 'bridge','data','ptp','mgmt'.
            ip_profile is a dict containing the IP parameters of the network
            isshared - is a boolean
            parent_network_uuid - is parent provider vdc network that will be used for mapping.
            It optional attribute. by default if no parent network indicate the first available will be used.

            Returns:
                The return network uuid or return None
        """
        client_as_admin = self.connect_as_admin()
        if not client_as_admin:
            raise vimconn.vimconnConnectionException("Failed to connect vCD.")
        if network_name is None:
            return None

        url_list = [self.url, '/api/admin/vdc/', self.tenant_id]
        vm_list_rest_call = ''.join(url_list)

        if client_as_admin._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                     'x-vcloud-authorization': client_as_admin._session.headers['x-vcloud-authorization']}

            response = self.perform_request(req_type='GET',
                                            url=vm_list_rest_call,
                                            headers=headers)

            provider_network = None
            available_networks = None
            add_vdc_rest_url = None

            if response.status_code != requests.codes.ok:
                self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
                                                                                          response.status_code))
                return None
            else:
                try:
                    vm_list_xmlroot = XmlElementTree.fromstring(response.content)
                    for child in vm_list_xmlroot:
                        if child.tag.split("}")[1] == 'ProviderVdcReference':
                            provider_network = child.attrib.get('href')
                            # application/vnd.vmware.admin.providervdc+xml
                        if child.tag.split("}")[1] == 'Link':
                            if child.attrib.get('type') == 'application/vnd.vmware.vcloud.orgVdcNetwork+xml' \
                                    and child.attrib.get('rel') == 'add':
                                add_vdc_rest_url = child.attrib.get('href')
                except:
                    self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
                    self.logger.debug("Respond body {}".format(response.content))
                    return None

            # find  pvdc provided available network
            response = self.perform_request(req_type='GET',
                                            url=provider_network,
                                            headers=headers)
            if response.status_code != requests.codes.ok:
                self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
                                                                                          response.status_code))
                return None

            if parent_network_uuid is None:
                try:
                    vm_list_xmlroot = XmlElementTree.fromstring(response.content)
                    for child in vm_list_xmlroot.iter():
                        if child.tag.split("}")[1] == 'AvailableNetworks':
                            for networks in child.iter():
                                # application/vnd.vmware.admin.network+xml
                                if networks.attrib.get('href') is not None:
                                    available_networks = networks.attrib.get('href')
                                    break
                except:
                    return None

            try:
                #Configure IP profile of the network
                ip_profile = ip_profile if ip_profile is not None else DEFAULT_IP_PROFILE

                if 'subnet_address' not in ip_profile or ip_profile['subnet_address'] is None:
                    subnet_rand = random.randint(0, 255)
                    ip_base = "192.168.{}.".format(subnet_rand)
                    ip_profile['subnet_address'] = ip_base + "0/24"
                else:
                    ip_base = ip_profile['subnet_address'].rsplit('.',1)[0] + '.'

                if 'gateway_address' not in ip_profile or ip_profile['gateway_address'] is None:
                    ip_profile['gateway_address']=ip_base + "1"
                if 'dhcp_count' not in ip_profile or ip_profile['dhcp_count'] is None:
                    ip_profile['dhcp_count']=DEFAULT_IP_PROFILE['dhcp_count']
                if 'dhcp_enabled' not in ip_profile or ip_profile['dhcp_enabled'] is None:
                    ip_profile['dhcp_enabled']=DEFAULT_IP_PROFILE['dhcp_enabled']
                if 'dhcp_start_address' not in ip_profile or ip_profile['dhcp_start_address'] is None:
                    ip_profile['dhcp_start_address']=ip_base + "3"
                if 'ip_version' not in ip_profile or ip_profile['ip_version'] is None:
                    ip_profile['ip_version']=DEFAULT_IP_PROFILE['ip_version']
                if 'dns_address' not in ip_profile or ip_profile['dns_address'] is None:
                    ip_profile['dns_address']=ip_base + "2"

                gateway_address=ip_profile['gateway_address']
                dhcp_count=int(ip_profile['dhcp_count'])
                subnet_address=self.convert_cidr_to_netmask(ip_profile['subnet_address'])

                if ip_profile['dhcp_enabled']==True:
                    dhcp_enabled='true'
                else:
                    dhcp_enabled='false'
                dhcp_start_address=ip_profile['dhcp_start_address']

                #derive dhcp_end_address from dhcp_start_address & dhcp_count
                end_ip_int = int(netaddr.IPAddress(dhcp_start_address))
                end_ip_int += dhcp_count - 1
                dhcp_end_address = str(netaddr.IPAddress(end_ip_int))

                ip_version=ip_profile['ip_version']
                dns_address=ip_profile['dns_address']
            except KeyError as exp:
                self.logger.debug("Create Network REST: Key error {}".format(exp))
                raise vimconn.vimconnException("Create Network REST: Key error{}".format(exp))

            # either use client provided UUID or search for a first available
            #  if both are not defined we return none
            if parent_network_uuid is not None:
                provider_network = None
                available_networks = None
                add_vdc_rest_url = None

                url_list = [self.url, '/api/admin/vdc/', self.tenant_id, '/networks']
                add_vdc_rest_url = ''.join(url_list)

                url_list = [self.url, '/api/admin/network/', parent_network_uuid]
                available_networks = ''.join(url_list)

            #Creating all networks as Direct Org VDC type networks.
            #Unused in case of Underlay (data/ptp) network interface.
            fence_mode="isolated"
            is_inherited='false'
            dns_list = dns_address.split(";")
            dns1 = dns_list[0]
            dns2_text = ""
            if len(dns_list) >= 2:
                dns2_text = "\n                                                <Dns2>{}</Dns2>\n".format(dns_list[1])
            data = """ <OrgVdcNetwork name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5">
                            <Description>Openmano created</Description>
                                    <Configuration>
                                        <IpScopes>
                                            <IpScope>
                                                <IsInherited>{1:s}</IsInherited>
                                                <Gateway>{2:s}</Gateway>
                                                <Netmask>{3:s}</Netmask>
                                                <Dns1>{4:s}</Dns1>{5:s}
                                                <IsEnabled>{6:s}</IsEnabled>
                                                <IpRanges>
                                                    <IpRange>
                                                        <StartAddress>{7:s}</StartAddress>
                                                        <EndAddress>{8:s}</EndAddress>
                                                    </IpRange>
                                                </IpRanges>
                                            </IpScope>
                                        </IpScopes>
                                        <FenceMode>{9:s}</FenceMode>
                                    </Configuration>
                                    <IsShared>{10:s}</IsShared>
                        </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
                                                    subnet_address, dns1, dns2_text, dhcp_enabled,
                                                    dhcp_start_address, dhcp_end_address,
                                                    fence_mode, isshared)

            headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml'
            try:
                response = self.perform_request(req_type='POST',
                                           url=add_vdc_rest_url,
                                           headers=headers,
                                           data=data)

                if response.status_code != 201:
                    self.logger.debug("Create Network POST REST API call failed. Return status code {}, Response content: {}"
                                      .format(response.status_code,response.content))
                else:
                    network_task = self.get_task_from_response(response.content)
                    self.logger.debug("Create Network REST : Waiting for Network creation complete")
                    time.sleep(5)
                    result = self.client.get_task_monitor().wait_for_success(task=network_task)
                    if result.get('status') == 'success':
                        return response.content
                    else:
                        self.logger.debug("create_network_rest task failed. Network Create response : {}"
                                          .format(response.content))
            except Exception as exp:
                self.logger.debug("create_network_rest : Exception : {} ".format(exp))

        return None

    def convert_cidr_to_netmask(self, cidr_ip=None):
        """
        Method sets convert CIDR netmask address to normal IP format
        Args:
            cidr_ip : CIDR IP address
            Returns:
                netmask : Converted netmask
        """
        if cidr_ip is not None:
            if '/' in cidr_ip:
                network, net_bits = cidr_ip.split('/')
                netmask = socket.inet_ntoa(struct.pack(">I", (0xffffffff << (32 - int(net_bits))) & 0xffffffff))
            else:
                netmask = cidr_ip
            return netmask
        return None

    def get_provider_rest(self, vca=None):
        """
        Method gets provider vdc view from vcloud director

        Args:
            network_name - is network name to be created.
            parent_network_uuid - is parent provider vdc network that will be used for mapping.
            It optional attribute. by default if no parent network indicate the first available will be used.

            Returns:
                The return xml content of respond or None
        """

        url_list = [self.url, '/api/admin']
        if vca:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='GET',
                                            url=''.join(url_list),
                                            headers=headers)

        if response.status_code == requests.codes.ok:
            return response.content
        return None

    def create_vdc(self, vdc_name=None):

        vdc_dict = {}

        xml_content = self.create_vdc_from_tmpl_rest(vdc_name=vdc_name)
        if xml_content is not None:
            try:
                task_resp_xmlroot = XmlElementTree.fromstring(xml_content)
                for child in task_resp_xmlroot:
                    if child.tag.split("}")[1] == 'Owner':
                        vdc_id = child.attrib.get('href').split("/")[-1]
                        vdc_dict[vdc_id] = task_resp_xmlroot.get('href')
                        return vdc_dict
            except:
                self.logger.debug("Respond body {}".format(xml_content))

        return None

    def create_vdc_from_tmpl_rest(self, vdc_name=None):
        """
        Method create vdc in vCloud director based on VDC template.
        it uses pre-defined template.

        Args:
            vdc_name -  name of a new vdc.

            Returns:
                The return xml content of respond or None
        """
        # pre-requesite atleast one vdc template should be available in vCD
        self.logger.info("Creating new vdc {}".format(vdc_name))
        vca = self.connect_as_admin()
        if not vca:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")
        if vdc_name is None:
            return None

        url_list = [self.url, '/api/vdcTemplates']
        vm_list_rest_call = ''.join(url_list)

        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                    'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}
        response = self.perform_request(req_type='GET',
                                        url=vm_list_rest_call,
                                        headers=headers)

        # container url to a template
        vdc_template_ref = None
        try:
            vm_list_xmlroot = XmlElementTree.fromstring(response.content)
            for child in vm_list_xmlroot:
                # application/vnd.vmware.admin.providervdc+xml
                # we need find a template from witch we instantiate VDC
                if child.tag.split("}")[1] == 'VdcTemplate':
                    if child.attrib.get('type') == 'application/vnd.vmware.admin.vdcTemplate+xml':
                        vdc_template_ref = child.attrib.get('href')
        except:
            self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
            self.logger.debug("Respond body {}".format(response.content))
            return None

        # if we didn't found required pre defined template we return None
        if vdc_template_ref is None:
            return None

        try:
            # instantiate vdc
            url_list = [self.url, '/api/org/', self.org_uuid, '/action/instantiate']
            vm_list_rest_call = ''.join(url_list)
            data = """<InstantiateVdcTemplateParams name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5">
                                        <Source href="{1:s}"></Source>
                                        <Description>opnemano</Description>
                                        </InstantiateVdcTemplateParams>""".format(vdc_name, vdc_template_ref)

            headers['Content-Type'] = 'application/vnd.vmware.vcloud.instantiateVdcTemplateParams+xml'

            response = self.perform_request(req_type='POST',
                                            url=vm_list_rest_call,
                                            headers=headers,
                                            data=data)

            vdc_task = self.get_task_from_response(response.content)
            self.client.get_task_monitor().wait_for_success(task=vdc_task)

            # if we all ok we respond with content otherwise by default None
            if response.status_code >= 200 and response.status_code < 300:
                return response.content
            return None
        except:
            self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
            self.logger.debug("Respond body {}".format(response.content))

        return None

    def create_vdc_rest(self, vdc_name=None):
        """
        Method create network in vCloud director

        Args:
            vdc_name - vdc name to be created
            Returns:
                The return response
        """

        self.logger.info("Creating new vdc {}".format(vdc_name))

        vca = self.connect_as_admin()
        if not vca:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")
        if vdc_name is None:
            return None

        url_list = [self.url, '/api/admin/org/', self.org_uuid]
        vm_list_rest_call = ''.join(url_list)

        if vca._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                      'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='GET',
                                            url=vm_list_rest_call,
                                            headers=headers)

            provider_vdc_ref = None
            add_vdc_rest_url = None
            available_networks = None

            if response.status_code != requests.codes.ok:
                self.logger.debug("REST API call {} failed. Return status code {}".format(vm_list_rest_call,
                                                                                          response.status_code))
                return None
            else:
                try:
                    vm_list_xmlroot = XmlElementTree.fromstring(response.content)
                    for child in vm_list_xmlroot:
                        # application/vnd.vmware.admin.providervdc+xml
                        if child.tag.split("}")[1] == 'Link':
                            if child.attrib.get('type') == 'application/vnd.vmware.admin.createVdcParams+xml' \
                                    and child.attrib.get('rel') == 'add':
                                add_vdc_rest_url = child.attrib.get('href')
                except:
                    self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
                    self.logger.debug("Respond body {}".format(response.content))
                    return None

                response = self.get_provider_rest(vca=vca)
                try:
                    vm_list_xmlroot = XmlElementTree.fromstring(response)
                    for child in vm_list_xmlroot:
                        if child.tag.split("}")[1] == 'ProviderVdcReferences':
                            for sub_child in child:
                                provider_vdc_ref = sub_child.attrib.get('href')
                except:
                    self.logger.debug("Failed parse respond for rest api call {}".format(vm_list_rest_call))
                    self.logger.debug("Respond body {}".format(response))
                    return None

                if add_vdc_rest_url is not None and provider_vdc_ref is not None:
                    data = """ <CreateVdcParams name="{0:s}" xmlns="http://www.vmware.com/vcloud/v1.5"><Description>{1:s}</Description>
                            <AllocationModel>ReservationPool</AllocationModel>
                            <ComputeCapacity><Cpu><Units>MHz</Units><Allocated>2048</Allocated><Limit>2048</Limit></Cpu>
                            <Memory><Units>MB</Units><Allocated>2048</Allocated><Limit>2048</Limit></Memory>
                            </ComputeCapacity><NicQuota>0</NicQuota><NetworkQuota>100</NetworkQuota>
                            <VdcStorageProfile><Enabled>true</Enabled><Units>MB</Units><Limit>20480</Limit><Default>true</Default></VdcStorageProfile>
                            <ProviderVdcReference
                            name="Main Provider"
                            href="{2:s}" />
                    <UsesFastProvisioning>true</UsesFastProvisioning></CreateVdcParams>""".format(escape(vdc_name),
                                                                                                  escape(vdc_name),
                                                                                                  provider_vdc_ref)

                    headers['Content-Type'] = 'application/vnd.vmware.admin.createVdcParams+xml'

                    response = self.perform_request(req_type='POST',
                                                    url=add_vdc_rest_url,
                                                    headers=headers,
                                                    data=data)

                    # if we all ok we respond with content otherwise by default None
                    if response.status_code == 201:
                        return response.content
        return None

    def get_vapp_details_rest(self, vapp_uuid=None, need_admin_access=False):
        """
        Method retrieve vapp detail from vCloud director

        Args:
            vapp_uuid - is vapp identifier.

            Returns:
                The return network uuid or return None
        """

        parsed_respond = {}
        vca = None

        if need_admin_access:
            vca = self.connect_as_admin()
        else:
            vca = self.client

        if not vca:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")
        if vapp_uuid is None:
            return None

        url_list = [self.url, '/api/vApp/vapp-', vapp_uuid]
        get_vapp_restcall = ''.join(url_list)

        if vca._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='GET',
                                            url=get_vapp_restcall,
                                            headers=headers)

            if response.status_code == 403:
                if need_admin_access == False:
                    response = self.retry_rest('GET', get_vapp_restcall)

            if response.status_code != requests.codes.ok:
                self.logger.debug("REST API call {} failed. Return status code {}".format(get_vapp_restcall,
                                                                                          response.status_code))
                return parsed_respond

            try:
                xmlroot_respond = XmlElementTree.fromstring(response.content)
                parsed_respond['ovfDescriptorUploaded'] = xmlroot_respond.attrib['ovfDescriptorUploaded']

                namespaces = {"vssd":"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" ,
                              'ovf': 'http://schemas.dmtf.org/ovf/envelope/1',
                              'vmw': 'http://www.vmware.com/schema/ovf',
                              'vm': 'http://www.vmware.com/vcloud/v1.5',
                              'rasd':"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
                              "vmext":"http://www.vmware.com/vcloud/extension/v1.5",
                              "xmlns":"http://www.vmware.com/vcloud/v1.5"
                             }

                created_section = xmlroot_respond.find('vm:DateCreated', namespaces)
                if created_section is not None:
                    parsed_respond['created'] = created_section.text

                network_section = xmlroot_respond.find('vm:NetworkConfigSection/vm:NetworkConfig', namespaces)
                if network_section is not None and 'networkName' in network_section.attrib:
                    parsed_respond['networkname'] = network_section.attrib['networkName']

                ipscopes_section = \
                    xmlroot_respond.find('vm:NetworkConfigSection/vm:NetworkConfig/vm:Configuration/vm:IpScopes',
                                         namespaces)
                if ipscopes_section is not None:
                    for ipscope in ipscopes_section:
                        for scope in ipscope:
                            tag_key = scope.tag.split("}")[1]
                            if tag_key == 'IpRanges':
                                ip_ranges = scope.getchildren()
                                for ipblock in ip_ranges:
                                    for block in ipblock:
                                        parsed_respond[block.tag.split("}")[1]] = block.text
                            else:
                                parsed_respond[tag_key] = scope.text

                # parse children section for other attrib
                children_section = xmlroot_respond.find('vm:Children/', namespaces)
                if children_section is not None:
                    parsed_respond['name'] = children_section.attrib['name']
                    parsed_respond['nestedHypervisorEnabled'] = children_section.attrib['nestedHypervisorEnabled'] \
                     if  "nestedHypervisorEnabled" in children_section.attrib else None
                    parsed_respond['deployed'] = children_section.attrib['deployed']
                    parsed_respond['status'] = children_section.attrib['status']
                    parsed_respond['vmuuid'] = children_section.attrib['id'].split(":")[-1]
                    network_adapter = children_section.find('vm:NetworkConnectionSection', namespaces)
                    nic_list = []
                    for adapters in network_adapter:
                        adapter_key = adapters.tag.split("}")[1]
                        if adapter_key == 'PrimaryNetworkConnectionIndex':
                            parsed_respond['primarynetwork'] = adapters.text
                        if adapter_key == 'NetworkConnection':
                            vnic = {}
                            if 'network' in adapters.attrib:
                                vnic['network'] = adapters.attrib['network']
                            for adapter in adapters:
                                setting_key = adapter.tag.split("}")[1]
                                vnic[setting_key] = adapter.text
                            nic_list.append(vnic)

                    for link in children_section:
                        if link.tag.split("}")[1] == 'Link' and 'rel' in link.attrib:
                            if link.attrib['rel'] == 'screen:acquireTicket':
                                parsed_respond['acquireTicket'] = link.attrib
                            if link.attrib['rel'] == 'screen:acquireMksTicket':
                                parsed_respond['acquireMksTicket'] = link.attrib

                    parsed_respond['interfaces'] = nic_list
                    vCloud_extension_section = children_section.find('xmlns:VCloudExtension', namespaces)
                    if vCloud_extension_section is not None:
                        vm_vcenter_info = {}
                        vim_info = vCloud_extension_section.find('vmext:VmVimInfo', namespaces)
                        vmext = vim_info.find('vmext:VmVimObjectRef', namespaces)
                        if vmext is not None:
                            vm_vcenter_info["vm_moref_id"] = vmext.find('vmext:MoRef', namespaces).text
                        parsed_respond["vm_vcenter_info"]= vm_vcenter_info

                    virtual_hardware_section = children_section.find('ovf:VirtualHardwareSection', namespaces)
                    vm_virtual_hardware_info = {}
                    if virtual_hardware_section is not None:
                        for item in virtual_hardware_section.iterfind('ovf:Item',namespaces):
                            if item.find("rasd:Description",namespaces).text == "Hard disk":
                                disk_size = item.find("rasd:HostResource" ,namespaces
                                                ).attrib["{"+namespaces['vm']+"}capacity"]

                                vm_virtual_hardware_info["disk_size"]= disk_size
                                break

                        for link in virtual_hardware_section:
                            if link.tag.split("}")[1] == 'Link' and 'rel' in link.attrib:
                                if link.attrib['rel'] == 'edit' and link.attrib['href'].endswith("/disks"):
                                    vm_virtual_hardware_info["disk_edit_href"] = link.attrib['href']
                                    break

                    parsed_respond["vm_virtual_hardware"]= vm_virtual_hardware_info
            except Exception as exp :
                self.logger.info("Error occurred calling rest api for getting vApp details {}".format(exp))
        return parsed_respond

    def acquire_console(self, vm_uuid=None):

        if vm_uuid is None:
            return None
        if self.client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            vm_dict = self.get_vapp_details_rest(vapp_uuid=vm_uuid)
            console_dict = vm_dict['acquireTicket']
            console_rest_call = console_dict['href']

            response = self.perform_request(req_type='POST',
                                            url=console_rest_call,
                                            headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('POST', console_rest_call)

            if response.status_code == requests.codes.ok:
                return response.content

        return None

    def modify_vm_disk(self, vapp_uuid, flavor_disk):
        """
        Method retrieve vm disk details

        Args:
            vapp_uuid - is vapp identifier.
            flavor_disk - disk size as specified in VNFD (flavor)

            Returns:
                The return network uuid or return None
        """
        status = None
        try:
            #Flavor disk is in GB convert it into MB
            flavor_disk = int(flavor_disk) * 1024
            vm_details = self.get_vapp_details_rest(vapp_uuid)
            if vm_details:
                vm_name = vm_details["name"]
                self.logger.info("VM: {} flavor_disk :{}".format(vm_name , flavor_disk))

            if vm_details and "vm_virtual_hardware" in vm_details:
                vm_disk = int(vm_details["vm_virtual_hardware"]["disk_size"])
                disk_edit_href = vm_details["vm_virtual_hardware"]["disk_edit_href"]

                self.logger.info("VM: {} VM_disk :{}".format(vm_name , vm_disk))

                if flavor_disk > vm_disk:
                    status = self.modify_vm_disk_rest(disk_edit_href ,flavor_disk)
                    self.logger.info("Modify disk of VM {} from {} to {} MB".format(vm_name,
                                                         vm_disk,  flavor_disk ))
                else:
                    status = True
                    self.logger.info("No need to modify disk of VM {}".format(vm_name))

            return status
        except Exception as exp:
            self.logger.info("Error occurred while modifing disk size {}".format(exp))


    def modify_vm_disk_rest(self, disk_href , disk_size):
        """
        Method retrieve modify vm disk size

        Args:
            disk_href - vCD API URL to GET and PUT disk data
            disk_size - disk size as specified in VNFD (flavor)

            Returns:
                The return network uuid or return None
        """
        if disk_href is None or disk_size is None:
            return None

        if self.client._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                                url=disk_href,
                                                headers=headers)

        if response.status_code == 403:
            response = self.retry_rest('GET', disk_href)

        if response.status_code != requests.codes.ok:
            self.logger.debug("GET REST API call {} failed. Return status code {}".format(disk_href,
                                                                            response.status_code))
            return None
        try:
            lxmlroot_respond = lxmlElementTree.fromstring(response.content)
            namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
            #For python3
            #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix}
            namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"

            for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces):
                if item.find("rasd:Description",namespaces).text == "Hard disk":
                    disk_item = item.find("rasd:HostResource" ,namespaces )
                    if disk_item is not None:
                        disk_item.attrib["{"+namespaces['xmlns']+"}capacity"] = str(disk_size)
                        break

            data = lxmlElementTree.tostring(lxmlroot_respond, encoding='utf8', method='xml',
                                             xml_declaration=True)

            #Send PUT request to modify disk size
            headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'

            response = self.perform_request(req_type='PUT',
                                                url=disk_href,
                                                headers=headers,
                                                data=data)
            if response.status_code == 403:
                add_headers = {'Content-Type': headers['Content-Type']}
                response = self.retry_rest('PUT', disk_href, add_headers, data)

            if response.status_code != 202:
                self.logger.debug("PUT REST API call {} failed. Return status code {}".format(disk_href,
                                                                            response.status_code))
            else:
                modify_disk_task = self.get_task_from_response(response.content)
                result = self.client.get_task_monitor().wait_for_success(task=modify_disk_task)
                if result.get('status') == 'success':
                    return True
                else:
                    return False
            return None

        except Exception as exp :
                self.logger.info("Error occurred calling rest api for modifing disk size {}".format(exp))
                return None

    def add_pci_devices(self, vapp_uuid , pci_devices , vmname_andid):
        """
            Method to attach pci devices to VM

             Args:
                vapp_uuid - uuid of vApp/VM
                pci_devices - pci devices infromation as specified in VNFD (flavor)

            Returns:
                The status of add pci device task , vm object and
                vcenter_conect object
        """
        vm_obj = None
        self.logger.info("Add pci devices {} into vApp {}".format(pci_devices , vapp_uuid))
        vcenter_conect, content = self.get_vcenter_content()
        vm_moref_id = self.get_vm_moref_id(vapp_uuid)

        if vm_moref_id:
            try:
                no_of_pci_devices = len(pci_devices)
                if no_of_pci_devices > 0:
                    #Get VM and its host
                    host_obj, vm_obj = self.get_vm_obj(content, vm_moref_id)
                    self.logger.info("VM {} is currently on host {}".format(vm_obj, host_obj))
                    if host_obj and vm_obj:
                        #get PCI devies from host on which vapp is currently installed
                        avilable_pci_devices = self.get_pci_devices(host_obj, no_of_pci_devices)

                        if avilable_pci_devices is None:
                            #find other hosts with active pci devices
                            new_host_obj , avilable_pci_devices = self.get_host_and_PCIdevices(
                                                                content,
                                                                no_of_pci_devices
                                                                )

                            if new_host_obj is not None and avilable_pci_devices is not None and len(avilable_pci_devices)> 0:
                                #Migrate vm to the host where PCI devices are availble
                                self.logger.info("Relocate VM {} on new host {}".format(vm_obj, new_host_obj))
                                task = self.relocate_vm(new_host_obj, vm_obj)
                                if task is not None:
                                    result = self.wait_for_vcenter_task(task, vcenter_conect)
                                    self.logger.info("Migrate VM status: {}".format(result))
                                    host_obj = new_host_obj
                                else:
                                    self.logger.info("Fail to migrate VM : {}".format(result))
                                    raise vimconn.vimconnNotFoundException(
                                    "Fail to migrate VM : {} to host {}".format(
                                                    vmname_andid,
                                                    new_host_obj)
                                        )

                        if host_obj is not None and avilable_pci_devices is not None and len(avilable_pci_devices)> 0:
                            #Add PCI devices one by one
                            for pci_device in avilable_pci_devices:
                                task = self.add_pci_to_vm(host_obj, vm_obj, pci_device)
                                if task:
                                    status= self.wait_for_vcenter_task(task, vcenter_conect)
                                    if status:
                                        self.logger.info("Added PCI device {} to VM {}".format(pci_device,str(vm_obj)))
                                else:
                                    self.logger.error("Fail to add PCI device {} to VM {}".format(pci_device,str(vm_obj)))
                            return True, vm_obj, vcenter_conect
                        else:
                            self.logger.error("Currently there is no host with"\
                                              " {} number of avaialble PCI devices required for VM {}".format(
                                                                            no_of_pci_devices,
                                                                            vmname_andid)
                                              )
                            raise vimconn.vimconnNotFoundException(
                                    "Currently there is no host with {} "\
                                    "number of avaialble PCI devices required for VM {}".format(
                                                                            no_of_pci_devices,
                                                                            vmname_andid))
                else:
                    self.logger.debug("No infromation about PCI devices {} ",pci_devices)

            except vmodl.MethodFault as error:
                self.logger.error("Error occurred while adding PCI devices {} ",error)
        return None, vm_obj, vcenter_conect

    def get_vm_obj(self, content, mob_id):
        """
            Method to get the vsphere VM object associated with a given morf ID
             Args:
                vapp_uuid - uuid of vApp/VM
                content - vCenter content object
                mob_id - mob_id of VM

            Returns:
                    VM and host object
        """
        vm_obj = None
        host_obj = None
        try :
            container = content.viewManager.CreateContainerView(content.rootFolder,
                                                        [vim.VirtualMachine], True
                                                        )
            for vm in container.view:
                mobID = vm._GetMoId()
                if mobID == mob_id:
                    vm_obj = vm
                    host_obj = vm_obj.runtime.host
                    break
        except Exception as exp:
            self.logger.error("Error occurred while finding VM object : {}".format(exp))
        return host_obj, vm_obj

    def get_pci_devices(self, host, need_devices):
        """
            Method to get the details of pci devices on given host
             Args:
                host - vSphere host object
                need_devices - number of pci devices needed on host

             Returns:
                array of pci devices
        """
        all_devices = []
        all_device_ids = []
        used_devices_ids = []

        try:
            if host:
                pciPassthruInfo = host.config.pciPassthruInfo
                pciDevies = host.hardware.pciDevice

            for pci_status in pciPassthruInfo:
                if pci_status.passthruActive:
                    for device in pciDevies:
                        if device.id == pci_status.id:
                            all_device_ids.append(device.id)
                            all_devices.append(device)

            #check if devices are in use
            avalible_devices = all_devices
            for vm in host.vm:
                if vm.runtime.powerState == vim.VirtualMachinePowerState.poweredOn:
                    vm_devices = vm.config.hardware.device
                    for device in vm_devices:
                        if type(device) is vim.vm.device.VirtualPCIPassthrough:
                            if device.backing.id in all_device_ids:
                                for use_device in avalible_devices:
                                    if use_device.id == device.backing.id:
                                        avalible_devices.remove(use_device)
                                used_devices_ids.append(device.backing.id)
                                self.logger.debug("Device {} from devices {}"\
                                        "is in use".format(device.backing.id,
                                                           device)
                                            )
            if len(avalible_devices) < need_devices:
                self.logger.debug("Host {} don't have {} number of active devices".format(host,
                                                                            need_devices))
                self.logger.debug("found only {} devives {}".format(len(avalible_devices),
                                                                    avalible_devices))
                return None
            else:
                required_devices = avalible_devices[:need_devices]
                self.logger.info("Found {} PCI devivces on host {} but required only {}".format(
                                                            len(avalible_devices),
                                                            host,
                                                            need_devices))
                self.logger.info("Retruning {} devices as {}".format(need_devices,
                                                                required_devices ))
                return required_devices

        except Exception as exp:
            self.logger.error("Error {} occurred while finding pci devices on host: {}".format(exp, host))

        return None

    def get_host_and_PCIdevices(self, content, need_devices):
        """
         Method to get the details of pci devices infromation on all hosts

            Args:
                content - vSphere host object
                need_devices - number of pci devices needed on host

            Returns:
                 array of pci devices and host object
        """
        host_obj = None
        pci_device_objs = None
        try:
            if content:
                container = content.viewManager.CreateContainerView(content.rootFolder,
                                                            [vim.HostSystem], True)
                for host in container.view:
                    devices = self.get_pci_devices(host, need_devices)
                    if devices:
                        host_obj = host
                        pci_device_objs = devices
                        break
        except Exception as exp:
            self.logger.error("Error {} occurred while finding pci devices on host: {}".format(exp, host_obj))

        return host_obj,pci_device_objs

    def relocate_vm(self, dest_host, vm) :
        """
         Method to get the relocate VM to new host

            Args:
                dest_host - vSphere host object
                vm - vSphere VM object

            Returns:
                task object
        """
        task = None
        try:
            relocate_spec = vim.vm.RelocateSpec(host=dest_host)
            task = vm.Relocate(relocate_spec)
            self.logger.info("Migrating {} to destination host {}".format(vm, dest_host))
        except Exception as exp:
            self.logger.error("Error occurred while relocate VM {} to new host {}: {}".format(
                                                                            dest_host, vm, exp))
        return task

    def wait_for_vcenter_task(self, task, actionName='job', hideResult=False):
        """
        Waits and provides updates on a vSphere task
        """
        while task.info.state == vim.TaskInfo.State.running:
            time.sleep(2)

        if task.info.state == vim.TaskInfo.State.success:
            if task.info.result is not None and not hideResult:
                self.logger.info('{} completed successfully, result: {}'.format(
                                                            actionName,
                                                            task.info.result))
            else:
                self.logger.info('Task {} completed successfully.'.format(actionName))
        else:
            self.logger.error('{} did not complete successfully: {} '.format(
                                                            actionName,
                                                            task.info.error)
                              )

        return task.info.result

    def add_pci_to_vm(self,host_object, vm_object, host_pci_dev):
        """
         Method to add pci device in given VM

            Args:
                host_object - vSphere host object
                vm_object - vSphere VM object
                host_pci_dev -  host_pci_dev must be one of the devices from the
                                host_object.hardware.pciDevice list
                                which is configured as a PCI passthrough device

            Returns:
                task object
        """
        task = None
        if vm_object and host_object and host_pci_dev:
            try :
                #Add PCI device to VM
                pci_passthroughs = vm_object.environmentBrowser.QueryConfigTarget(host=None).pciPassthrough
                systemid_by_pciid = {item.pciDevice.id: item.systemId for item in pci_passthroughs}

                if host_pci_dev.id not in systemid_by_pciid:
                    self.logger.error("Device {} is not a passthrough device ".format(host_pci_dev))
                    return None

                deviceId = hex(host_pci_dev.deviceId % 2**16).lstrip('0x')
                backing = vim.VirtualPCIPassthroughDeviceBackingInfo(deviceId=deviceId,
                                            id=host_pci_dev.id,
                                            systemId=systemid_by_pciid[host_pci_dev.id],
                                            vendorId=host_pci_dev.vendorId,
                                            deviceName=host_pci_dev.deviceName)

                hba_object = vim.VirtualPCIPassthrough(key=-100, backing=backing)

                new_device_config = vim.VirtualDeviceConfigSpec(device=hba_object)
                new_device_config.operation = "add"
                vmConfigSpec = vim.vm.ConfigSpec()
                vmConfigSpec.deviceChange = [new_device_config]

                task = vm_object.ReconfigVM_Task(spec=vmConfigSpec)
                self.logger.info("Adding PCI device {} into VM {} from host {} ".format(
                                                            host_pci_dev, vm_object, host_object)
                                )
            except Exception as exp:
                self.logger.error("Error occurred while adding pci devive {} to VM {}: {}".format(
                                                                            host_pci_dev,
                                                                            vm_object,
                                                                             exp))
        return task

    def get_vm_vcenter_info(self):
        """
        Method to get details of vCenter and vm

            Args:
                vapp_uuid - uuid of vApp or VM

            Returns:
                Moref Id of VM and deails of vCenter
        """
        vm_vcenter_info = {}

        if self.vcenter_ip is not None:
            vm_vcenter_info["vm_vcenter_ip"] = self.vcenter_ip
        else:
            raise vimconn.vimconnException(message="vCenter IP is not provided."\
                                           " Please provide vCenter IP while attaching datacenter to tenant in --config")
        if self.vcenter_port is not None:
            vm_vcenter_info["vm_vcenter_port"] = self.vcenter_port
        else:
            raise vimconn.vimconnException(message="vCenter port is not provided."\
                                           " Please provide vCenter port while attaching datacenter to tenant in --config")
        if self.vcenter_user is not None:
            vm_vcenter_info["vm_vcenter_user"] = self.vcenter_user
        else:
            raise vimconn.vimconnException(message="vCenter user is not provided."\
                                           " Please provide vCenter user while attaching datacenter to tenant in --config")

        if self.vcenter_password is not None:
            vm_vcenter_info["vm_vcenter_password"] = self.vcenter_password
        else:
            raise vimconn.vimconnException(message="vCenter user password is not provided."\
                                           " Please provide vCenter user password while attaching datacenter to tenant in --config")

        return vm_vcenter_info


    def get_vm_pci_details(self, vmuuid):
        """
            Method to get VM PCI device details from vCenter

            Args:
                vm_obj - vSphere VM object

            Returns:
                dict of PCI devives attached to VM

        """
        vm_pci_devices_info = {}
        try:
            vcenter_conect, content = self.get_vcenter_content()
            vm_moref_id = self.get_vm_moref_id(vmuuid)
            if vm_moref_id:
                #Get VM and its host
                if content:
                    host_obj, vm_obj = self.get_vm_obj(content, vm_moref_id)
                    if host_obj and vm_obj:
                        vm_pci_devices_info["host_name"]= host_obj.name
                        vm_pci_devices_info["host_ip"]= host_obj.config.network.vnic[0].spec.ip.ipAddress
                        for device in vm_obj.config.hardware.device:
                            if type(device) == vim.vm.device.VirtualPCIPassthrough:
                                device_details={'devide_id':device.backing.id,
                                                'pciSlotNumber':device.slotInfo.pciSlotNumber,
                                            }
                                vm_pci_devices_info[device.deviceInfo.label] = device_details
                else:
                    self.logger.error("Can not connect to vCenter while getting "\
                                          "PCI devices infromationn")
                return vm_pci_devices_info
        except Exception as exp:
            self.logger.error("Error occurred while getting VM infromationn"\
                             " for VM : {}".format(exp))
            raise vimconn.vimconnException(message=exp)


    def reserve_memory_for_all_vms(self, vapp, memory_mb):
        """
            Method to reserve memory for all VMs
            Args :
                vapp - VApp
                memory_mb - Memory in MB
            Returns:
                None
        """

        self.logger.info("Reserve memory for all VMs")
        for vms in vapp.get_all_vms():
            vm_id = vms.get('id').split(':')[-1]

            url_rest_call = "{}/api/vApp/vm-{}/virtualHardwareSection/memory".format(self.url, vm_id)

            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItem+xml'
            response = self.perform_request(req_type='GET',
                                            url=url_rest_call,
                                            headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('GET', url_rest_call)

            if response.status_code != 200:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {}".format(url_rest_call,
                                                            response.content,
                                                            response.status_code))
                raise vimconn.vimconnException("reserve_memory_for_all_vms : Failed to get "\
                                               "memory")

            bytexml = bytes(bytearray(response.content, encoding='utf-8'))
            contentelem = lxmlElementTree.XML(bytexml)
            namespaces = {prefix:uri for prefix,uri in contentelem.nsmap.iteritems() if prefix}
            namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"

            # Find the reservation element in the response
            memelem_list = contentelem.findall(".//rasd:Reservation", namespaces)
            for memelem in memelem_list:
                memelem.text = str(memory_mb)

            newdata = lxmlElementTree.tostring(contentelem, pretty_print=True)

            response = self.perform_request(req_type='PUT',
                                            url=url_rest_call,
                                            headers=headers,
                                            data=newdata)

            if response.status_code == 403:
                add_headers = {'Content-Type': headers['Content-Type']}
                response = self.retry_rest('PUT', url_rest_call, add_headers, newdata)

            if response.status_code != 202:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {} ".format(url_rest_call,
                                  response.content,
                                  response.status_code))
                raise vimconn.vimconnException("reserve_memory_for_all_vms : Failed to update "\
                                               "virtual hardware memory section")
            else:
                mem_task = self.get_task_from_response(response.content)
                result = self.client.get_task_monitor().wait_for_success(task=mem_task)
                if result.get('status') == 'success':
                    self.logger.info("reserve_memory_for_all_vms(): VM {} succeeded "\
                                      .format(vm_id))
                else:
                    self.logger.error("reserve_memory_for_all_vms(): VM {} failed "\
                                      .format(vm_id))

    def connect_vapp_to_org_vdc_network(self, vapp_id, net_name):
        """
            Configure VApp network config with org vdc network
            Args :
                vapp - VApp
            Returns:
                None
        """

        self.logger.info("Connecting vapp {} to org vdc network {}".
                         format(vapp_id, net_name))

        url_rest_call = "{}/api/vApp/vapp-{}/networkConfigSection/".format(self.url, vapp_id)

        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                   'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
        response = self.perform_request(req_type='GET',
                                        url=url_rest_call,
                                        headers=headers)

        if response.status_code == 403:
            response = self.retry_rest('GET', url_rest_call)

        if response.status_code != 200:
            self.logger.error("REST call {} failed reason : {}"\
                              "status code : {}".format(url_rest_call,
                                                        response.content,
                                                        response.status_code))
            raise vimconn.vimconnException("connect_vapp_to_org_vdc_network : Failed to get "\
                                           "network config section")

        data = response.content
        headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConfigSection+xml'
        net_id = self.get_network_id_by_name(net_name)
        if not net_id:
            raise vimconn.vimconnException("connect_vapp_to_org_vdc_network : Failed to find "\
                                           "existing network")

        bytexml = bytes(bytearray(data, encoding='utf-8'))
        newelem = lxmlElementTree.XML(bytexml)
        namespaces = {prefix: uri for prefix, uri in newelem.nsmap.iteritems() if prefix}
        namespaces["xmlns"] = "http://www.vmware.com/vcloud/v1.5"
        nwcfglist = newelem.findall(".//xmlns:NetworkConfig", namespaces)

        # VCD 9.7 returns an incorrect parentnetwork element. Fix it before PUT operation
        parentnetworklist = newelem.findall(".//xmlns:ParentNetwork", namespaces)
        if parentnetworklist:
            for pn in parentnetworklist:
                if "href" not in pn.keys():
                    id_val = pn.get("id")
                    href_val = "{}/api/network/{}".format(self.url, id_val)
                    pn.set("href", href_val)

        newstr = """<NetworkConfig networkName="{}">
                  <Configuration>
                       <ParentNetwork href="{}/api/network/{}"/>
                       <FenceMode>bridged</FenceMode>
                  </Configuration>
              </NetworkConfig>
           """.format(net_name, self.url, net_id)
        newcfgelem = lxmlElementTree.fromstring(newstr)
        if nwcfglist:
            nwcfglist[0].addnext(newcfgelem)

        newdata = lxmlElementTree.tostring(newelem, pretty_print=True)

        response = self.perform_request(req_type='PUT',
                                        url=url_rest_call,
                                        headers=headers,
                                        data=newdata)

        if response.status_code == 403:
            add_headers = {'Content-Type': headers['Content-Type']}
            response = self.retry_rest('PUT', url_rest_call, add_headers, newdata)

        if response.status_code != 202:
            self.logger.error("REST call {} failed reason : {}"\
                              "status code : {} ".format(url_rest_call,
                              response.content,
                              response.status_code))
            raise vimconn.vimconnException("connect_vapp_to_org_vdc_network : Failed to update "\
                                           "network config section")
        else:
            vapp_task = self.get_task_from_response(response.content)
            result = self.client.get_task_monitor().wait_for_success(task=vapp_task)
            if result.get('status') == 'success':
                self.logger.info("connect_vapp_to_org_vdc_network(): Vapp {} connected to "\
                                 "network {}".format(vapp_id, net_name))
            else:
                self.logger.error("connect_vapp_to_org_vdc_network(): Vapp {} failed to "\
                                  "connect to network {}".format(vapp_id, net_name))

    def remove_primary_network_adapter_from_all_vms(self, vapp):
        """
            Method to remove network adapter type to vm
            Args :
                vapp - VApp
            Returns:
                None
        """

        self.logger.info("Removing network adapter from all VMs")
        for vms in vapp.get_all_vms():
            vm_id = vms.get('id').split(':')[-1]

            url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.url, vm_id)

            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                       'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='GET',
                                            url=url_rest_call,
                                            headers=headers)

            if response.status_code == 403:
                response = self.retry_rest('GET', url_rest_call)

            if response.status_code != 200:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {}".format(url_rest_call,
                                                            response.content,
                                                            response.status_code))
                raise vimconn.vimconnException("remove_primary_network_adapter : Failed to get "\
                                               "network connection section")

            data = response.content
            data = data.split('<Link rel="edit"')[0]

            headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'

            newdata = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                      <NetworkConnectionSection xmlns="http://www.vmware.com/vcloud/v1.5"
                              xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
                              xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData"
                              xmlns:common="http://schemas.dmtf.org/wbem/wscim/1/common"
                              xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"
                              xmlns:vmw="http://www.vmware.com/schema/ovf"
                              xmlns:ovfenv="http://schemas.dmtf.org/ovf/environment/1"
                              xmlns:vmext="http://www.vmware.com/vcloud/extension/v1.5"
                              xmlns:ns9="http://www.vmware.com/vcloud/versions"
                              href="{url}" type="application/vnd.vmware.vcloud.networkConnectionSection+xml" ovf:required="false">
                              <ovf:Info>Specifies the available VM network connections</ovf:Info>
                             <PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
                             <Link rel="edit" href="{url}" type="application/vnd.vmware.vcloud.networkConnectionSection+xml"/>
                      </NetworkConnectionSection>""".format(url=url_rest_call)
            response = self.perform_request(req_type='PUT',
                                            url=url_rest_call,
                                            headers=headers,
                                            data=newdata)

            if response.status_code == 403:
                add_headers = {'Content-Type': headers['Content-Type']}
                response = self.retry_rest('PUT', url_rest_call, add_headers, newdata)

            if response.status_code != 202:
                self.logger.error("REST call {} failed reason : {}"\
                                  "status code : {} ".format(url_rest_call,
                                  response.content,
                                  response.status_code))
                raise vimconn.vimconnException("remove_primary_network_adapter : Failed to update "\
                                               "network connection section")
            else:
                nic_task = self.get_task_from_response(response.content)
                result = self.client.get_task_monitor().wait_for_success(task=nic_task)
                if result.get('status') == 'success':
                    self.logger.info("remove_primary_network_adapter(): VM {} conneced to "\
                                      "default NIC type".format(vm_id))
                else:
                    self.logger.error("remove_primary_network_adapter(): VM {} failed to "\
                                      "connect NIC type".format(vm_id))

    def add_network_adapter_to_vms(self, vapp, network_name, primary_nic_index, nicIndex, net, nic_type=None):
        """
            Method to add network adapter type to vm
            Args :
                network_name - name of network
                primary_nic_index - int value for primary nic index
                nicIndex - int value for nic index
                nic_type - specify model name to which add to vm
            Returns:
                None
        """

        self.logger.info("Add network adapter to VM: network_name {} nicIndex {} nic_type {}".\
                         format(network_name, nicIndex, nic_type))
        try:
            ip_address = None
            floating_ip = False
            mac_address = None
            if 'floating_ip' in net: floating_ip = net['floating_ip']

            # Stub for ip_address feature
            if 'ip_address' in net: ip_address = net['ip_address']

            if 'mac_address' in net: mac_address = net['mac_address']

            if floating_ip:
                allocation_mode = "POOL"
            elif ip_address:
                allocation_mode = "MANUAL"
            else:
                allocation_mode = "DHCP"

            if not nic_type:
                for vms in vapp.get_all_vms():
                    vm_id = vms.get('id').split(':')[-1]

                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.url, vm_id)

                    headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                    response = self.perform_request(req_type='GET',
                                                    url=url_rest_call,
                                                    headers=headers)

                    if response.status_code == 403:
                        response = self.retry_rest('GET', url_rest_call)

                    if response.status_code != 200:
                        self.logger.error("REST call {} failed reason : {}"\
                                             "status code : {}".format(url_rest_call,
                                                                    response.content,
                                                               response.status_code))
                        raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to get "\
                                                                         "network connection section")

                    data = response.content
                    data = data.split('<Link rel="edit"')[0]
                    if '<PrimaryNetworkConnectionIndex>' not in data:
                        self.logger.debug("add_network_adapter PrimaryNIC not in data")
                        item = """<PrimaryNetworkConnectionIndex>{}</PrimaryNetworkConnectionIndex>
                                <NetworkConnection network="{}">
                                <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                <IsConnected>true</IsConnected>
                                <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                </NetworkConnection>""".format(primary_nic_index, network_name, nicIndex,
                                                                                         allocation_mode)
                        # Stub for ip_address feature
                        if ip_address:
                            ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                            item =  item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))

                        if mac_address:
                            mac_tag = '<MACAddress>{}</MACAddress>'.format(mac_address)
                            item =  item.replace('</IsConnected>\n','</IsConnected>\n{}\n'.format(mac_tag))

                        data = data.replace('</ovf:Info>\n','</ovf:Info>\n{}\n</NetworkConnectionSection>'.format(item))
                    else:
                        self.logger.debug("add_network_adapter PrimaryNIC in data")
                        new_item = """<NetworkConnection network="{}">
                                    <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                    <IsConnected>true</IsConnected>
                                    <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                    </NetworkConnection>""".format(network_name, nicIndex,
                                                                          allocation_mode)
                        # Stub for ip_address feature
                        if ip_address:
                            ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                            new_item =  new_item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))

                        if mac_address:
                            mac_tag = '<MACAddress>{}</MACAddress>'.format(mac_address)
                            new_item =  new_item.replace('</IsConnected>\n','</IsConnected>\n{}\n'.format(mac_tag))

                        data = data + new_item + '</NetworkConnectionSection>'

                    headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'

                    response = self.perform_request(req_type='PUT',
                                                    url=url_rest_call,
                                                    headers=headers,
                                                    data=data)

                    if response.status_code == 403:
                        add_headers = {'Content-Type': headers['Content-Type']}
                        response = self.retry_rest('PUT', url_rest_call, add_headers, data)

                    if response.status_code != 202:
                        self.logger.error("REST call {} failed reason : {}"\
                                            "status code : {} ".format(url_rest_call,
                                                                    response.content,
                                                               response.status_code))
                        raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                            "network connection section")
                    else:
                        nic_task = self.get_task_from_response(response.content)
                        result = self.client.get_task_monitor().wait_for_success(task=nic_task)
                        if result.get('status') == 'success':
                            self.logger.info("add_network_adapter_to_vms(): VM {} conneced to "\
                                                               "default NIC type".format(vm_id))
                        else:
                            self.logger.error("add_network_adapter_to_vms(): VM {} failed to "\
                                                              "connect NIC type".format(vm_id))
            else:
                for vms in vapp.get_all_vms():
                    vm_id = vms.get('id').split(':')[-1]

                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.url, vm_id)

                    headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
                    response = self.perform_request(req_type='GET',
                                                    url=url_rest_call,
                                                    headers=headers)

                    if response.status_code == 403:
                        response = self.retry_rest('GET', url_rest_call)

                    if response.status_code != 200:
                        self.logger.error("REST call {} failed reason : {}"\
                                            "status code : {}".format(url_rest_call,
                                                                   response.content,
                                                              response.status_code))
                        raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to get "\
                                                                        "network connection section")
                    data = response.content
                    data = data.split('<Link rel="edit"')[0]
                    vcd_netadapter_type = nic_type
                    if nic_type in ['SR-IOV', 'VF']:
                        vcd_netadapter_type = "SRIOVETHERNETCARD"

                    if '<PrimaryNetworkConnectionIndex>' not in data:
                        self.logger.debug("add_network_adapter PrimaryNIC not in data nic_type {}".format(nic_type))
                        item = """<PrimaryNetworkConnectionIndex>{}</PrimaryNetworkConnectionIndex>
                                <NetworkConnection network="{}">
                                <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                <IsConnected>true</IsConnected>
                                <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                <NetworkAdapterType>{}</NetworkAdapterType>
                                </NetworkConnection>""".format(primary_nic_index, network_name, nicIndex,
                                                                               allocation_mode, vcd_netadapter_type)
                        # Stub for ip_address feature
                        if ip_address:
                            ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                            item =  item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))

                        if mac_address:
                            mac_tag = '<MACAddress>{}</MACAddress>'.format(mac_address)
                            item = item.replace('</IsConnected>\n','</IsConnected>\n{}\n'.format(mac_tag))

                        data = data.replace('</ovf:Info>\n','</ovf:Info>\n{}\n</NetworkConnectionSection>'.format(item))
                    else:
                        self.logger.debug("add_network_adapter PrimaryNIC in data nic_type {}".format(nic_type))
                        new_item = """<NetworkConnection network="{}">
                                    <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                    <IsConnected>true</IsConnected>
                                    <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                    <NetworkAdapterType>{}</NetworkAdapterType>
                                    </NetworkConnection>""".format(network_name, nicIndex,
                                                                allocation_mode, vcd_netadapter_type)
                        # Stub for ip_address feature
                        if ip_address:
                            ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                            new_item =  new_item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))

                        if mac_address:
                            mac_tag = '<MACAddress>{}</MACAddress>'.format(mac_address)
                            new_item =  new_item.replace('</IsConnected>\n','</IsConnected>\n{}\n'.format(mac_tag))

                        data = data + new_item + '</NetworkConnectionSection>'

                    headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'

                    response = self.perform_request(req_type='PUT',
                                                    url=url_rest_call,
                                                    headers=headers,
                                                    data=data)

                    if response.status_code == 403:
                        add_headers = {'Content-Type': headers['Content-Type']}
                        response = self.retry_rest('PUT', url_rest_call, add_headers, data)

                    if response.status_code != 202:
                        self.logger.error("REST call {} failed reason : {}"\
                                            "status code : {}".format(url_rest_call,
                                                                   response.content,
                                                              response.status_code))
                        raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                           "network connection section")
                    else:
                        nic_task = self.get_task_from_response(response.content)
                        result = self.client.get_task_monitor().wait_for_success(task=nic_task)
                        if result.get('status') == 'success':
                            self.logger.info("add_network_adapter_to_vms(): VM {} "\
                                               "conneced to NIC type {}".format(vm_id, nic_type))
                        else:
                            self.logger.error("add_network_adapter_to_vms(): VM {} "\
                                               "failed to connect NIC type {}".format(vm_id, nic_type))
        except Exception as exp:
            self.logger.error("add_network_adapter_to_vms() : exception occurred "\
                                               "while adding Network adapter")
            raise vimconn.vimconnException(message=exp)


    def set_numa_affinity(self, vmuuid, paired_threads_id):
        """
            Method to assign numa affinity in vm configuration parammeters
            Args :
                vmuuid - vm uuid
                paired_threads_id - one or more virtual processor
                                    numbers
            Returns:
                return if True
        """
        try:
            vcenter_conect, content = self.get_vcenter_content()
            vm_moref_id = self.get_vm_moref_id(vmuuid)

            host_obj, vm_obj = self.get_vm_obj(content ,vm_moref_id)
            if vm_obj:
                config_spec = vim.vm.ConfigSpec()
                config_spec.extraConfig = []
                opt = vim.option.OptionValue()
                opt.key = 'numa.nodeAffinity'
                opt.value = str(paired_threads_id)
                config_spec.extraConfig.append(opt)
                task = vm_obj.ReconfigVM_Task(config_spec)
                if task:
                    result = self.wait_for_vcenter_task(task, vcenter_conect)
                    extra_config = vm_obj.config.extraConfig
                    flag = False
                    for opts in extra_config:
                        if 'numa.nodeAffinity' in opts.key:
                            flag = True
                            self.logger.info("set_numa_affinity: Sucessfully assign numa affinity "\
                                                     "value {} for vm {}".format(opt.value, vm_obj))
                        if flag:
                            return
            else:
                self.logger.error("set_numa_affinity: Failed to assign numa affinity")
        except Exception as exp:
            self.logger.error("set_numa_affinity : exception occurred while setting numa affinity "\
                                                       "for VM {} : {}".format(vm_obj, vm_moref_id))
            raise vimconn.vimconnException("set_numa_affinity : Error {} failed to assign numa "\
                                                                           "affinity".format(exp))


    def cloud_init(self, vapp, cloud_config):
        """
        Method to inject ssh-key
        vapp - vapp object
        cloud_config a dictionary with:
                'key-pairs': (optional) list of strings with the public key to be inserted to the default user
                'users': (optional) list of users to be inserted, each item is a dict with:
                    'name': (mandatory) user name,
                    'key-pairs': (optional) list of strings with the public key to be inserted to the user
                'user-data': (optional) can be a string with the text script to be passed directly to cloud-init,
                    or a list of strings, each one contains a script to be passed, usually with a MIMEmultipart file
                'config-files': (optional). List of files to be transferred. Each item is a dict with:
                    'dest': (mandatory) string with the destination absolute path
                    'encoding': (optional, by default text). Can be one of:
                        'b64', 'base64', 'gz', 'gz+b64', 'gz+base64', 'gzip+b64', 'gzip+base64'
                    'content' (mandatory): string with the content of the file
                    'permissions': (optional) string with file permissions, typically octal notation '0644'
                    'owner': (optional) file owner, string with the format 'owner:group'
                'boot-data-drive': boolean to indicate if user-data must be passed using a boot drive (hard disk
        """
        try:
            if not isinstance(cloud_config, dict):
                raise Exception("cloud_init : parameter cloud_config is not a dictionary")
            else:
                key_pairs = []
                userdata = []
                if "key-pairs" in cloud_config:
                    key_pairs = cloud_config["key-pairs"]

                if "users" in cloud_config:
                    userdata = cloud_config["users"]

                self.logger.debug("cloud_init : Guest os customization started..")
                customize_script = self.format_script(key_pairs=key_pairs, users_list=userdata)
                customize_script = customize_script.replace("&","&amp;")
                self.guest_customization(vapp, customize_script)

        except Exception as exp:
            self.logger.error("cloud_init : exception occurred while injecting "\
                                                                       "ssh-key")
            raise vimconn.vimconnException("cloud_init : Error {} failed to inject "\
                                                               "ssh-key".format(exp))

    def format_script(self, key_pairs=[], users_list=[]):
        bash_script = """#!/bin/sh
        echo performing customization tasks with param $1 at `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log
        if [ "$1" = "precustomization" ];then
            echo performing precustomization tasks   on `date "+DATE: %Y-%m-%d - TIME: %H:%M:%S"` >> /root/customization.log
        """

        keys = "\n".join(key_pairs)
        if keys:
            keys_data = """
            if [ ! -d /root/.ssh ];then
                mkdir /root/.ssh
                chown root:root /root/.ssh
                chmod 700 /root/.ssh
                touch /root/.ssh/authorized_keys
                chown root:root /root/.ssh/authorized_keys
                chmod 600 /root/.ssh/authorized_keys
                # make centos with selinux happy
                which restorecon && restorecon -Rv /root/.ssh
            else
                touch /root/.ssh/authorized_keys
                chown root:root /root/.ssh/authorized_keys
                chmod 600 /root/.ssh/authorized_keys
            fi
            echo '{key}' >> /root/.ssh/authorized_keys
            """.format(key=keys)

            bash_script+= keys_data

        for user in users_list:
            if 'name' in user: user_name = user['name']
            if 'key-pairs' in user:
                user_keys = "\n".join(user['key-pairs'])
            else:
                user_keys = None

            add_user_name = """
                useradd -d /home/{user_name} -m -g users -s /bin/bash {user_name}
                """.format(user_name=user_name)

            bash_script+= add_user_name

            if user_keys:
                user_keys_data = """
                mkdir /home/{user_name}/.ssh
                chown {user_name}:{user_name} /home/{user_name}/.ssh
                chmod 700 /home/{user_name}/.ssh
                touch /home/{user_name}/.ssh/authorized_keys
                chown {user_name}:{user_name} /home/{user_name}/.ssh/authorized_keys
                chmod 600 /home/{user_name}/.ssh/authorized_keys
                # make centos with selinux happy
                which restorecon && restorecon -Rv /home/{user_name}/.ssh
                echo '{user_key}' >> /home/{user_name}/.ssh/authorized_keys
                """.format(user_name=user_name,user_key=user_keys)

                bash_script+= user_keys_data

        return bash_script+"\n\tfi"

    def guest_customization(self, vapp, customize_script):
        """
        Method to customize guest os
        vapp - Vapp object
        customize_script - Customize script to be run at first boot of VM.
        """
        for vm in vapp.get_all_vms():
            vm_id = vm.get('id').split(':')[-1]
            vm_name = vm.get('name')
            vm_name = vm_name.replace('_','-')

            vm_customization_url = "{}/api/vApp/vm-{}/guestCustomizationSection/".format(self.url, vm_id)
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

            headers['Content-Type'] = "application/vnd.vmware.vcloud.guestCustomizationSection+xml"

            data = """<GuestCustomizationSection
                           xmlns="http://www.vmware.com/vcloud/v1.5"
                           xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"
                           ovf:required="false" href="{}" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml">
                           <ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
                           <Enabled>true</Enabled>
                           <ChangeSid>false</ChangeSid>
                           <VirtualMachineId>{}</VirtualMachineId>
                           <JoinDomainEnabled>false</JoinDomainEnabled>
                           <UseOrgSettings>false</UseOrgSettings>
                           <AdminPasswordEnabled>false</AdminPasswordEnabled>
                           <AdminPasswordAuto>true</AdminPasswordAuto>
                           <AdminAutoLogonEnabled>false</AdminAutoLogonEnabled>
                           <AdminAutoLogonCount>0</AdminAutoLogonCount>
                           <ResetPasswordRequired>false</ResetPasswordRequired>
                           <CustomizationScript>{}</CustomizationScript>
                           <ComputerName>{}</ComputerName>
                           <Link href="{}" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" rel="edit"/>
                       </GuestCustomizationSection>
                   """.format(vm_customization_url,
                                             vm_id,
                                  customize_script,
                                           vm_name,
                              vm_customization_url)

            response = self.perform_request(req_type='PUT',
                                             url=vm_customization_url,
                                             headers=headers,
                                             data=data)
            if response.status_code == 202:
                guest_task = self.get_task_from_response(response.content)
                self.client.get_task_monitor().wait_for_success(task=guest_task)
                self.logger.info("guest_customization : customized guest os task "\
                                             "completed for VM {}".format(vm_name))
            else:
                self.logger.error("guest_customization : task for customized guest os"\
                                                    "failed for VM {}".format(vm_name))
                raise vimconn.vimconnException("guest_customization : failed to perform"\
                                       "guest os customization on VM {}".format(vm_name))

    def add_new_disk(self, vapp_uuid, disk_size):
        """
            Method to create an empty vm disk

            Args:
                vapp_uuid - is vapp identifier.
                disk_size - size of disk to be created in GB

            Returns:
                None
        """
        status = False
        vm_details = None
        try:
            #Disk size in GB, convert it into MB
            if disk_size is not None:
                disk_size_mb = int(disk_size) * 1024
                vm_details = self.get_vapp_details_rest(vapp_uuid)

            if vm_details and "vm_virtual_hardware" in vm_details:
                self.logger.info("Adding disk to VM: {} disk size:{}GB".format(vm_details["name"], disk_size))
                disk_href = vm_details["vm_virtual_hardware"]["disk_edit_href"]
                status = self.add_new_disk_rest(disk_href, disk_size_mb)

        except Exception as exp:
            msg = "Error occurred while creating new disk {}.".format(exp)
            self.rollback_newvm(vapp_uuid, msg)

        if status:
            self.logger.info("Added new disk to VM: {} disk size:{}GB".format(vm_details["name"], disk_size))
        else:
            #If failed to add disk, delete VM
            msg = "add_new_disk: Failed to add new disk to {}".format(vm_details["name"])
            self.rollback_newvm(vapp_uuid, msg)


    def add_new_disk_rest(self, disk_href, disk_size_mb):
        """
        Retrives vApp Disks section & add new empty disk

        Args:
            disk_href: Disk section href to addd disk
            disk_size_mb: Disk size in MB

            Returns: Status of add new disk task
        """
        status = False
        if self.client._session:
            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
            response = self.perform_request(req_type='GET',
                                            url=disk_href,
                                            headers=headers)

        if response.status_code == 403:
            response = self.retry_rest('GET', disk_href)

        if response.status_code != requests.codes.ok:
            self.logger.error("add_new_disk_rest: GET REST API call {} failed. Return status code {}"
                              .format(disk_href, response.status_code))
            return status
        try:
            #Find but type & max of instance IDs assigned to disks
            lxmlroot_respond = lxmlElementTree.fromstring(response.content)
            namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
            #For python3
            #namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.items() if prefix}
            namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
            instance_id = 0
            for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces):
                if item.find("rasd:Description",namespaces).text == "Hard disk":
                    inst_id = int(item.find("rasd:InstanceID" ,namespaces).text)
                    if inst_id > instance_id:
                        instance_id = inst_id
                        disk_item = item.find("rasd:HostResource" ,namespaces)
                        bus_subtype = disk_item.attrib["{"+namespaces['xmlns']+"}busSubType"]
                        bus_type = disk_item.attrib["{"+namespaces['xmlns']+"}busType"]

            instance_id = instance_id + 1
            new_item =   """<Item>
                                <rasd:Description>Hard disk</rasd:Description>
                                <rasd:ElementName>New disk</rasd:ElementName>
                                <rasd:HostResource
                                    xmlns:vcloud="http://www.vmware.com/vcloud/v1.5"
                                    vcloud:capacity="{}"
                                    vcloud:busSubType="{}"
                                    vcloud:busType="{}"></rasd:HostResource>
                                <rasd:InstanceID>{}</rasd:InstanceID>
                                <rasd:ResourceType>17</rasd:ResourceType>
                            </Item>""".format(disk_size_mb, bus_subtype, bus_type, instance_id)

            new_data = response.content
            #Add new item at the bottom
            new_data = new_data.replace('</Item>\n</RasdItemsList>', '</Item>\n{}\n</RasdItemsList>'.format(new_item))

            # Send PUT request to modify virtual hardware section with new disk
            headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'

            response = self.perform_request(req_type='PUT',
                                            url=disk_href,
                                            data=new_data,
                                            headers=headers)

            if response.status_code == 403:
                add_headers = {'Content-Type': headers['Content-Type']}
                response = self.retry_rest('PUT', disk_href, add_headers, new_data)

            if response.status_code != 202:
                self.logger.error("PUT REST API call {} failed. Return status code {}. Response Content:{}"
                                  .format(disk_href, response.status_code, response.content))
            else:
                add_disk_task = self.get_task_from_response(response.content)
                result = self.client.get_task_monitor().wait_for_success(task=add_disk_task)
                if result.get('status') == 'success':
                    status = True
                else:
                    self.logger.error("Add new disk REST task failed to add {} MB disk".format(disk_size_mb))

        except Exception as exp:
            self.logger.error("Error occurred calling rest api for creating new disk {}".format(exp))

        return status


    def add_existing_disk(self, catalogs=None, image_id=None, size=None, template_name=None, vapp_uuid=None):
        """
            Method to add existing disk to vm
            Args :
                catalogs - List of VDC catalogs
                image_id - Catalog ID
                template_name - Name of template in catalog
                vapp_uuid - UUID of vApp
            Returns:
                None
        """
        disk_info = None
        vcenter_conect, content = self.get_vcenter_content()
        #find moref-id of vm in image
        catalog_vm_info = self.get_vapp_template_details(catalogs=catalogs,
                                                         image_id=image_id,
                                                        )

        if catalog_vm_info and "vm_vcenter_info" in catalog_vm_info:
            if "vm_moref_id" in catalog_vm_info["vm_vcenter_info"]:
                catalog_vm_moref_id = catalog_vm_info["vm_vcenter_info"].get("vm_moref_id", None)
                if catalog_vm_moref_id:
                    self.logger.info("Moref_id of VM in catalog : {}" .format(catalog_vm_moref_id))
                    host, catalog_vm_obj = self.get_vm_obj(content, catalog_vm_moref_id)
                    if catalog_vm_obj:
                        #find existing disk
                        disk_info = self.find_disk(catalog_vm_obj)
                    else:
                        exp_msg = "No VM with image id {} found".format(image_id)
                        self.rollback_newvm(vapp_uuid, exp_msg, exp_type="NotFound")
        else:
            exp_msg = "No Image found with image ID {} ".format(image_id)
            self.rollback_newvm(vapp_uuid, exp_msg, exp_type="NotFound")

        if disk_info:
            self.logger.info("Existing disk_info : {}".format(disk_info))
            #get VM
            vm_moref_id = self.get_vm_moref_id(vapp_uuid)
            host, vm_obj = self.get_vm_obj(content, vm_moref_id)
            if vm_obj:
                status = self.add_disk(vcenter_conect=vcenter_conect,
                                       vm=vm_obj,
                                       disk_info=disk_info,
                                       size=size,
                                       vapp_uuid=vapp_uuid
                                       )
            if status:
                self.logger.info("Disk from image id {} added to {}".format(image_id,
                                                                            vm_obj.config.name)
                                 )
        else:
            msg = "No disk found with image id {} to add in VM {}".format(
                                                            image_id,
                                                            vm_obj.config.name)
            self.rollback_newvm(vapp_uuid, msg, exp_type="NotFound")


    def find_disk(self, vm_obj):
        """
         Method to find details of existing disk in VM
            Args :
                vm_obj - vCenter object of VM
                image_id - Catalog ID
            Returns:
                disk_info : dict of disk details
        """
        disk_info = {}
        if vm_obj:
            try:
                devices = vm_obj.config.hardware.device
                for device in devices:
                    if type(device) is vim.vm.device.VirtualDisk:
                        if isinstance(device.backing,vim.vm.device.VirtualDisk.FlatVer2BackingInfo) and hasattr(device.backing, 'fileName'):
                            disk_info["full_path"] = device.backing.fileName
                            disk_info["datastore"] = device.backing.datastore
                            disk_info["capacityKB"] = device.capacityInKB
                            break
            except Exception as exp:
                self.logger.error("find_disk() : exception occurred while "\
                                  "getting existing disk details :{}".format(exp))
        return disk_info


    def add_disk(self, vcenter_conect=None, vm=None, size=None, vapp_uuid=None, disk_info={}):
        """
         Method to add existing disk in VM
            Args :
                vcenter_conect - vCenter content object
                vm - vCenter vm object
                disk_info : dict of disk details
            Returns:
                status : status of add disk task
        """
        datastore = disk_info["datastore"] if "datastore" in disk_info else None
        fullpath = disk_info["full_path"] if "full_path" in disk_info else None
        capacityKB = disk_info["capacityKB"] if "capacityKB" in disk_info else None
        if size is not None:
            #Convert size from GB to KB
            sizeKB = int(size) * 1024 * 1024
            #compare size of existing disk and user given size.Assign whicherver is greater
            self.logger.info("Add Existing disk : sizeKB {} , capacityKB {}".format(
                                                                    sizeKB, capacityKB))
            if sizeKB > capacityKB:
                capacityKB = sizeKB

        if datastore and fullpath and capacityKB:
            try:
                spec = vim.vm.ConfigSpec()
                # get all disks on a VM, set unit_number to the next available
                unit_number = 0
                for dev in vm.config.hardware.device:
                    if hasattr(dev.backing, 'fileName'):
                        unit_number = int(dev.unitNumber) + 1
                        # unit_number 7 reserved for scsi controller
                        if unit_number == 7:
                            unit_number += 1
                    if isinstance(dev, vim.vm.device.VirtualDisk):
                        #vim.vm.device.VirtualSCSIController
                        controller_key = dev.controllerKey

                self.logger.info("Add Existing disk : unit number {} , controller key {}".format(
                                                                    unit_number, controller_key))
                # add disk here
                dev_changes = []
                disk_spec = vim.vm.device.VirtualDeviceSpec()
                disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
                disk_spec.device = vim.vm.device.VirtualDisk()
                disk_spec.device.backing = \
                    vim.vm.device.VirtualDisk.FlatVer2BackingInfo()
                disk_spec.device.backing.thinProvisioned = True
                disk_spec.device.backing.diskMode = 'persistent'
                disk_spec.device.backing.datastore  = datastore
                disk_spec.device.backing.fileName  = fullpath

                disk_spec.device.unitNumber = unit_number
                disk_spec.device.capacityInKB = capacityKB
                disk_spec.device.controllerKey = controller_key
                dev_changes.append(disk_spec)
                spec.deviceChange = dev_changes
                task = vm.ReconfigVM_Task(spec=spec)
                status = self.wait_for_vcenter_task(task, vcenter_conect)
                return status
            except Exception as exp:
                exp_msg = "add_disk() : exception {} occurred while adding disk "\
                          "{} to vm {}".format(exp,
                                               fullpath,
                                               vm.config.name)
                self.rollback_newvm(vapp_uuid, exp_msg)
        else:
            msg = "add_disk() : Can not add disk to VM with disk info {} ".format(disk_info)
            self.rollback_newvm(vapp_uuid, msg)


    def get_vcenter_content(self):
        """
         Get the vsphere content object
        """
        try:
            vm_vcenter_info = self.get_vm_vcenter_info()
        except Exception as exp:
            self.logger.error("Error occurred while getting vCenter infromationn"\
                             " for VM : {}".format(exp))
            raise vimconn.vimconnException(message=exp)

        context = None
        if hasattr(ssl, '_create_unverified_context'):
            context = ssl._create_unverified_context()

        vcenter_conect = SmartConnect(
                    host=vm_vcenter_info["vm_vcenter_ip"],
                    user=vm_vcenter_info["vm_vcenter_user"],
                    pwd=vm_vcenter_info["vm_vcenter_password"],
                    port=int(vm_vcenter_info["vm_vcenter_port"]),
                    sslContext=context
                )
        atexit.register(Disconnect, vcenter_conect)
        content = vcenter_conect.RetrieveContent()
        return vcenter_conect, content


    def get_vm_moref_id(self, vapp_uuid):
        """
        Get the moref_id of given VM
        """
        try:
            if vapp_uuid:
                vm_details = self.get_vapp_details_rest(vapp_uuid, need_admin_access=True)
                if vm_details and "vm_vcenter_info" in vm_details:
                    vm_moref_id = vm_details["vm_vcenter_info"].get("vm_moref_id", None)
            return vm_moref_id

        except Exception as exp:
            self.logger.error("Error occurred while getting VM moref ID "\
                             " for VM : {}".format(exp))
            return None


    def get_vapp_template_details(self, catalogs=None, image_id=None , template_name=None):
        """
            Method to get vApp template details
                Args :
                    catalogs - list of VDC catalogs
                    image_id - Catalog ID to find
                    template_name : template name in catalog
                Returns:
                    parsed_respond : dict of vApp tempalte details
        """
        parsed_response = {}

        vca = self.connect_as_admin()
        if not vca:
            raise vimconn.vimconnConnectionException("Failed to connect vCD")

        try:
            org, vdc = self.get_vdc_details()
            catalog = self.get_catalog_obj(image_id, catalogs)
            if catalog:
                items = org.get_catalog_item(catalog.get('name'), catalog.get('name'))
                catalog_items = [items.attrib]

                if len(catalog_items) == 1:
                    headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}

                    response = self.perform_request(req_type='GET',
                                                    url=catalog_items[0].get('href'),
                                                    headers=headers)
                    catalogItem = XmlElementTree.fromstring(response.content)
                    entity = [child for child in catalogItem if child.get("type") == "application/vnd.vmware.vcloud.vAppTemplate+xml"][0]
                    vapp_tempalte_href = entity.get("href")
                    #get vapp details and parse moref id

                    namespaces = {"vssd":"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" ,
                                  'ovf': 'http://schemas.dmtf.org/ovf/envelope/1',
                                  'vmw': 'http://www.vmware.com/schema/ovf',
                                  'vm': 'http://www.vmware.com/vcloud/v1.5',
                                  'rasd':"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData",
                                  'vmext':"http://www.vmware.com/vcloud/extension/v1.5",
                                  'xmlns':"http://www.vmware.com/vcloud/v1.5"
                                }

                    if vca._session:
                        response = self.perform_request(req_type='GET',
                                                    url=vapp_tempalte_href,
                                                    headers=headers)

                        if response.status_code != requests.codes.ok:
                            self.logger.debug("REST API call {} failed. Return status code {}".format(
                                                vapp_tempalte_href, response.status_code))

                        else:
                            xmlroot_respond = XmlElementTree.fromstring(response.content)
                            children_section = xmlroot_respond.find('vm:Children/', namespaces)
                            if children_section is not None:
                                vCloud_extension_section = children_section.find('xmlns:VCloudExtension', namespaces)
                            if vCloud_extension_section is not None:
                                vm_vcenter_info = {}
                                vim_info = vCloud_extension_section.find('vmext:VmVimInfo', namespaces)
                                vmext = vim_info.find('vmext:VmVimObjectRef', namespaces)
                                if vmext is not None:
                                    vm_vcenter_info["vm_moref_id"] = vmext.find('vmext:MoRef', namespaces).text
                                parsed_response["vm_vcenter_info"]= vm_vcenter_info

        except Exception as exp :
            self.logger.info("Error occurred calling rest api for getting vApp details {}".format(exp))

        return parsed_response


    def rollback_newvm(self, vapp_uuid, msg , exp_type="Genric"):
        """
            Method to delete vApp
                Args :
                    vapp_uuid - vApp UUID
                    msg - Error message to be logged
                    exp_type : Exception type
                Returns:
                    None
        """
        if vapp_uuid:
            status = self.delete_vminstance(vapp_uuid)
        else:
            msg = "No vApp ID"
        self.logger.error(msg)
        if exp_type == "Genric":
            raise vimconn.vimconnException(msg)
        elif exp_type == "NotFound":
            raise vimconn.vimconnNotFoundException(message=msg)

    def add_sriov(self, vapp_uuid, sriov_nets, vmname_andid):
        """
            Method to attach SRIOV adapters to VM

             Args:
                vapp_uuid - uuid of vApp/VM
                sriov_nets - SRIOV devices infromation as specified in VNFD (flavor)
                vmname_andid - vmname

            Returns:
                The status of add SRIOV adapter task , vm object and
                vcenter_conect object
        """
        vm_obj = None
        vcenter_conect, content = self.get_vcenter_content()
        vm_moref_id = self.get_vm_moref_id(vapp_uuid)

        if vm_moref_id:
            try:
                no_of_sriov_devices = len(sriov_nets)
                if no_of_sriov_devices > 0:
                    #Get VM and its host
                    host_obj, vm_obj = self.get_vm_obj(content, vm_moref_id)
                    self.logger.info("VM {} is currently on host {}".format(vm_obj, host_obj))
                    if host_obj and vm_obj:
                        #get SRIOV devies from host on which vapp is currently installed
                        avilable_sriov_devices = self.get_sriov_devices(host_obj,
                                                                no_of_sriov_devices,
                                                                )

                        if len(avilable_sriov_devices) == 0:
                            #find other hosts with active pci devices
                            new_host_obj , avilable_sriov_devices = self.get_host_and_sriov_devices(
                                                                content,
                                                                no_of_sriov_devices,
                                                                )

                            if new_host_obj is not None and len(avilable_sriov_devices)> 0:
                                #Migrate vm to the host where SRIOV devices are available
                                self.logger.info("Relocate VM {} on new host {}".format(vm_obj,
                                                                                    new_host_obj))
                                task = self.relocate_vm(new_host_obj, vm_obj)
                                if task is not None:
                                    result = self.wait_for_vcenter_task(task, vcenter_conect)
                                    self.logger.info("Migrate VM status: {}".format(result))
                                    host_obj = new_host_obj
                                else:
                                    self.logger.info("Fail to migrate VM : {}".format(result))
                                    raise vimconn.vimconnNotFoundException(
                                    "Fail to migrate VM : {} to host {}".format(
                                                    vmname_andid,
                                                    new_host_obj)
                                        )

                        if host_obj is not None and avilable_sriov_devices is not None and len(avilable_sriov_devices)> 0:
                            #Add SRIOV devices one by one
                            for sriov_net in sriov_nets:
                                network_name = sriov_net.get('net_id')
                                dvs_portgr_name = self.create_dvPort_group(network_name)
                                if sriov_net.get('type') == "VF" or sriov_net.get('type') == "SR-IOV":
                                    #add vlan ID ,Modify portgroup for vlan ID
                                    self.configure_vlanID(content, vcenter_conect, network_name)

                                task = self.add_sriov_to_vm(content,
                                                            vm_obj,
                                                            host_obj,
                                                            network_name,
                                                            avilable_sriov_devices[0]
                                                            )
                                if task:
                                    status= self.wait_for_vcenter_task(task, vcenter_conect)
                                    if status:
                                        self.logger.info("Added SRIOV {} to VM {}".format(
                                                                        no_of_sriov_devices,
                                                                        str(vm_obj)))
                                else:
                                    self.logger.error("Fail to add SRIOV {} to VM {}".format(
                                                                        no_of_sriov_devices,
                                                                        str(vm_obj)))
                                    raise vimconn.vimconnUnexpectedResponse(
                                    "Fail to add SRIOV adapter in VM ".format(str(vm_obj))
                                        )
                            return True, vm_obj, vcenter_conect
                        else:
                            self.logger.error("Currently there is no host with"\
                                              " {} number of avaialble SRIOV "\
                                              "VFs required for VM {}".format(
                                                                no_of_sriov_devices,
                                                                vmname_andid)
                                              )
                            raise vimconn.vimconnNotFoundException(
                                    "Currently there is no host with {} "\
                                    "number of avaialble SRIOV devices required for VM {}".format(
                                                                            no_of_sriov_devices,
                                                                            vmname_andid))
                else:
                    self.logger.debug("No infromation about SRIOV devices {} ",sriov_nets)

            except vmodl.MethodFault as error:
                self.logger.error("Error occurred while adding SRIOV {} ",error)
        return None, vm_obj, vcenter_conect


    def get_sriov_devices(self,host, no_of_vfs):
        """
            Method to get the details of SRIOV devices on given host
             Args:
                host - vSphere host object
                no_of_vfs - number of VFs needed on host

             Returns:
                array of SRIOV devices
        """
        sriovInfo=[]
        if host:
            for device in host.config.pciPassthruInfo:
                if isinstance(device,vim.host.SriovInfo) and device.sriovActive:
                    if device.numVirtualFunction >= no_of_vfs:
                        sriovInfo.append(device)
                        break
        return sriovInfo


    def get_host_and_sriov_devices(self, content, no_of_vfs):
        """
         Method to get the details of SRIOV devices infromation on all hosts

            Args:
                content - vSphere host object
                no_of_vfs - number of pci VFs needed on host

            Returns:
                 array of SRIOV devices and host object
        """
        host_obj = None
        sriov_device_objs = None
        try:
            if content:
                container = content.viewManager.CreateContainerView(content.rootFolder,
                                                            [vim.HostSystem], True)
                for host in container.view:
                    devices = self.get_sriov_devices(host, no_of_vfs)
                    if devices:
                        host_obj = host
                        sriov_device_objs = devices
                        break
        except Exception as exp:
            self.logger.error("Error {} occurred while finding SRIOV devices on host: {}".format(exp, host_obj))

        return host_obj,sriov_device_objs


    def add_sriov_to_vm(self,content, vm_obj, host_obj, network_name, sriov_device):
        """
         Method to add SRIOV adapter to vm

            Args:
                host_obj - vSphere host object
                vm_obj - vSphere vm object
                content - vCenter content object
                network_name - name of distributed virtaul portgroup
                sriov_device - SRIOV device info

            Returns:
                 task object
        """
        devices = []
        vnic_label = "sriov nic"
        try:
            dvs_portgr = self.get_dvport_group(network_name)
            network_name = dvs_portgr.name
            nic = vim.vm.device.VirtualDeviceSpec()
            # VM device
            nic.operation = vim.vm.device.VirtualDeviceSpec.Operation.add
            nic.device = vim.vm.device.VirtualSriovEthernetCard()
            nic.device.addressType = 'assigned'
            #nic.device.key = 13016
            nic.device.deviceInfo = vim.Description()
            nic.device.deviceInfo.label = vnic_label
            nic.device.deviceInfo.summary = network_name
            nic.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo()

            nic.device.backing.network = self.get_obj(content, [vim.Network], network_name)
            nic.device.backing.deviceName = network_name
            nic.device.backing.useAutoDetect = False
            nic.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo()
            nic.device.connectable.startConnected = True
            nic.device.connectable.allowGuestControl = True

            nic.device.sriovBacking = vim.vm.device.VirtualSriovEthernetCard.SriovBackingInfo()
            nic.device.sriovBacking.physicalFunctionBacking = vim.vm.device.VirtualPCIPassthrough.DeviceBackingInfo()
            nic.device.sriovBacking.physicalFunctionBacking.id = sriov_device.id

            devices.append(nic)
            vmconf = vim.vm.ConfigSpec(deviceChange=devices)
            task = vm_obj.ReconfigVM_Task(vmconf)
            return task
        except Exception as exp:
            self.logger.error("Error {} occurred while adding SRIOV adapter in VM: {}".format(exp, vm_obj))
            return None


    def create_dvPort_group(self, network_name):
        """
         Method to create disributed virtual portgroup

            Args:
                network_name - name of network/portgroup

            Returns:
                portgroup key
        """
        try:
            new_network_name = [network_name, '-', str(uuid.uuid4())]
            network_name=''.join(new_network_name)
            vcenter_conect, content = self.get_vcenter_content()

            dv_switch = self.get_obj(content, [vim.DistributedVirtualSwitch], self.dvs_name)
            if dv_switch:
                dv_pg_spec = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()
                dv_pg_spec.name = network_name

                dv_pg_spec.type = vim.dvs.DistributedVirtualPortgroup.PortgroupType.earlyBinding
                dv_pg_spec.defaultPortConfig = vim.dvs.VmwareDistributedVirtualSwitch.VmwarePortConfigPolicy()
                dv_pg_spec.defaultPortConfig.securityPolicy = vim.dvs.VmwareDistributedVirtualSwitch.SecurityPolicy()
                dv_pg_spec.defaultPortConfig.securityPolicy.allowPromiscuous = vim.BoolPolicy(value=False)
                dv_pg_spec.defaultPortConfig.securityPolicy.forgedTransmits = vim.BoolPolicy(value=False)
                dv_pg_spec.defaultPortConfig.securityPolicy.macChanges = vim.BoolPolicy(value=False)

                task = dv_switch.AddDVPortgroup_Task([dv_pg_spec])
                self.wait_for_vcenter_task(task, vcenter_conect)

                dvPort_group = self.get_obj(content, [vim.dvs.DistributedVirtualPortgroup], network_name)
                if dvPort_group:
                    self.logger.info("Created disributed virtaul port group: {}".format(dvPort_group))
                    return dvPort_group.key
            else:
                self.logger.debug("No disributed virtual switch found with name {}".format(network_name))

        except Exception as exp:
            self.logger.error("Error occurred while creating disributed virtaul port group {}"\
                             " : {}".format(network_name, exp))
        return None

    def reconfig_portgroup(self, content, dvPort_group_name , config_info={}):
        """
         Method to reconfigure disributed virtual portgroup

            Args:
                dvPort_group_name - name of disributed virtual portgroup
                content - vCenter content object
                config_info - disributed virtual portgroup configuration

            Returns:
                task object
        """
        try:
            dvPort_group = self.get_dvport_group(dvPort_group_name)
            if dvPort_group:
                dv_pg_spec = vim.dvs.DistributedVirtualPortgroup.ConfigSpec()
                dv_pg_spec.configVersion = dvPort_group.config.configVersion
                dv_pg_spec.defaultPortConfig = vim.dvs.VmwareDistributedVirtualSwitch.VmwarePortConfigPolicy()
                if "vlanID" in config_info:
                    dv_pg_spec.defaultPortConfig.vlan = vim.dvs.VmwareDistributedVirtualSwitch.VlanIdSpec()
                    dv_pg_spec.defaultPortConfig.vlan.vlanId = config_info.get('vlanID')

                task = dvPort_group.ReconfigureDVPortgroup_Task(spec=dv_pg_spec)
                return task
            else:
                return None
        except Exception as exp:
            self.logger.error("Error occurred while reconfiguraing disributed virtaul port group {}"\
                             " : {}".format(dvPort_group_name, exp))
            return None


    def destroy_dvport_group(self , dvPort_group_name):
        """
         Method to destroy disributed virtual portgroup

            Args:
                network_name - name of network/portgroup

            Returns:
                True if portgroup successfully got deleted else false
        """
        vcenter_conect, content = self.get_vcenter_content()
        try:
            status = None
            dvPort_group = self.get_dvport_group(dvPort_group_name)
            if dvPort_group:
                task = dvPort_group.Destroy_Task()
                status = self.wait_for_vcenter_task(task, vcenter_conect)
            return status
        except vmodl.MethodFault as exp:
            self.logger.error("Caught vmodl fault {} while deleting disributed virtaul port group {}".format(
                                                                    exp, dvPort_group_name))
            return None


    def get_dvport_group(self, dvPort_group_name):
        """
        Method to get disributed virtual portgroup

            Args:
                network_name - name of network/portgroup

            Returns:
                portgroup object
        """
        vcenter_conect, content = self.get_vcenter_content()
        dvPort_group = None
        try:
            container = content.viewManager.CreateContainerView(content.rootFolder, [vim.dvs.DistributedVirtualPortgroup], True)
            for item in container.view:
                if item.key == dvPort_group_name:
                    dvPort_group = item
                    break
            return dvPort_group
        except vmodl.MethodFault as exp:
            self.logger.error("Caught vmodl fault {} for disributed virtaul port group {}".format(
                                                                            exp, dvPort_group_name))
            return None

    def get_vlanID_from_dvs_portgr(self, dvPort_group_name):
        """
         Method to get disributed virtual portgroup vlanID

            Args:
                network_name - name of network/portgroup

            Returns:
                vlan ID
        """
        vlanId = None
        try:
            dvPort_group = self.get_dvport_group(dvPort_group_name)
            if dvPort_group:
                vlanId = dvPort_group.config.defaultPortConfig.vlan.vlanId
        except vmodl.MethodFault as exp:
            self.logger.error("Caught vmodl fault {} for disributed virtaul port group {}".format(
                                                                            exp, dvPort_group_name))
        return vlanId


    def configure_vlanID(self, content, vcenter_conect, dvPort_group_name):
        """
         Method to configure vlanID in disributed virtual portgroup vlanID

            Args:
                network_name - name of network/portgroup

            Returns:
                None
        """
        vlanID = self.get_vlanID_from_dvs_portgr(dvPort_group_name)
        if vlanID == 0:
            #configure vlanID
            vlanID = self.genrate_vlanID(dvPort_group_name)
            config = {"vlanID":vlanID}
            task = self.reconfig_portgroup(content, dvPort_group_name,
                                    config_info=config)
            if task:
                status= self.wait_for_vcenter_task(task, vcenter_conect)
                if status:
                    self.logger.info("Reconfigured Port group {} for vlan ID {}".format(
                                                        dvPort_group_name,vlanID))
            else:
                self.logger.error("Fail reconfigure portgroup {} for vlanID{}".format(
                                        dvPort_group_name, vlanID))


    def genrate_vlanID(self, network_name):
        """
         Method to get unused vlanID
            Args:
                network_name - name of network/portgroup
            Returns:
                vlanID
        """
        vlan_id = None
        used_ids = []
        if self.config.get('vlanID_range') == None:
            raise vimconn.vimconnConflictException("You must provide a 'vlanID_range' "\
                        "at config value before creating sriov network with vlan tag")
        if "used_vlanIDs" not in self.persistent_info:
                self.persistent_info["used_vlanIDs"] = {}
        else:
            used_ids = self.persistent_info["used_vlanIDs"].values()
            #For python3
            #used_ids = list(self.persistent_info["used_vlanIDs"].values())

        for vlanID_range in self.config.get('vlanID_range'):
            start_vlanid , end_vlanid = vlanID_range.split("-")
            if start_vlanid > end_vlanid:
                raise vimconn.vimconnConflictException("Invalid vlan ID range {}".format(
                                                                        vlanID_range))

            for id in xrange(int(start_vlanid), int(end_vlanid) + 1):
            #For python3
            #for id in range(int(start_vlanid), int(end_vlanid) + 1):
                if id not in used_ids:
                    vlan_id = id
                    self.persistent_info["used_vlanIDs"][network_name] = vlan_id
                    return vlan_id
        if vlan_id is None:
            raise vimconn.vimconnConflictException("All Vlan IDs are in use")


    def get_obj(self, content, vimtype, name):
        """
         Get the vsphere object associated with a given text name
        """
        obj = None
        container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
        for item in container.view:
            if item.name == name:
                obj = item
                break
        return obj


    def insert_media_to_vm(self, vapp, image_id):
        """
        Method to insert media CD-ROM (ISO image) from catalog to vm.
        vapp - vapp object to get vm id
        Image_id - image id for cdrom to be inerted to vm
        """
        # create connection object
        vca = self.connect()
        try:
            # fetching catalog details
            rest_url = "{}/api/catalog/{}".format(self.url, image_id)
            if vca._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}
                response = self.perform_request(req_type='GET',
                                                url=rest_url,
                                                headers=headers)

            if response.status_code != 200:
                self.logger.error("REST call {} failed reason : {}"\
                             "status code : {}".format(url_rest_call,
                                                    response.content,
                                               response.status_code))
                raise vimconn.vimconnException("insert_media_to_vm(): Failed to get "\
                                                                    "catalog details")
            # searching iso name and id
            iso_name,media_id = self.get_media_details(vca, response.content)

            if iso_name and media_id:
                data ="""<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                     <ns6:MediaInsertOrEjectParams
                     xmlns="http://www.vmware.com/vcloud/versions" xmlns:ns2="http://schemas.dmtf.org/ovf/envelope/1" 
                     xmlns:ns3="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" 
                     xmlns:ns4="http://schemas.dmtf.org/wbem/wscim/1/common" 
                     xmlns:ns5="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" 
                     xmlns:ns6="http://www.vmware.com/vcloud/v1.5" 
                     xmlns:ns7="http://www.vmware.com/schema/ovf" 
                     xmlns:ns8="http://schemas.dmtf.org/ovf/environment/1" 
                     xmlns:ns9="http://www.vmware.com/vcloud/extension/v1.5">
                     <ns6:Media
                        type="application/vnd.vmware.vcloud.media+xml"
                        name="{}"
                        id="urn:vcloud:media:{}"
                        href="https://{}/api/media/{}"/>
                     </ns6:MediaInsertOrEjectParams>""".format(iso_name, media_id,
                                                                self.url,media_id)

                for vms in vapp.get_all_vms():
                    vm_id = vms.get('id').split(':')[-1]

                    headers['Content-Type'] = 'application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml'
                    rest_url = "{}/api/vApp/vm-{}/media/action/insertMedia".format(self.url,vm_id)

                    response = self.perform_request(req_type='POST',
                                                       url=rest_url,
                                                          data=data,
                                                    headers=headers)

                    if response.status_code != 202:
                        error_msg = "insert_media_to_vm() : Failed to insert CD-ROM to vm. Reason {}. " \
                                    "Status code {}".format(response.text, response.status_code)
                        self.logger.error(error_msg)
                        raise vimconn.vimconnException(error_msg)
                    else:
                        task = self.get_task_from_response(response.content)
                        result = self.client.get_task_monitor().wait_for_success(task=task)
                        if result.get('status') == 'success':
                            self.logger.info("insert_media_to_vm(): Sucessfully inserted media ISO"\
                                                                    " image to vm {}".format(vm_id))

        except Exception as exp:
            self.logger.error("insert_media_to_vm() : exception occurred "\
                                            "while inserting media CD-ROM")
            raise vimconn.vimconnException(message=exp)


    def get_media_details(self, vca, content):
        """
        Method to get catalog item details
        vca - connection object
        content - Catalog details
        Return - Media name, media id
        """
        cataloghref_list = []
        try:
            if content:
                vm_list_xmlroot = XmlElementTree.fromstring(content)
                for child in vm_list_xmlroot.iter():
                    if 'CatalogItem' in child.tag:
                        cataloghref_list.append(child.attrib.get('href'))
                if cataloghref_list is not None:
                    for href in cataloghref_list:
                        if href:
                            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': vca._session.headers['x-vcloud-authorization']}
                            response = self.perform_request(req_type='GET',
                                                                  url=href,
                                                           headers=headers)
                            if response.status_code != 200:
                                self.logger.error("REST call {} failed reason : {}"\
                                             "status code : {}".format(href,
                                                           response.content,
                                                      response.status_code))
                                raise vimconn.vimconnException("get_media_details : Failed to get "\
                                                                         "catalogitem details")
                            list_xmlroot = XmlElementTree.fromstring(response.content)
                            for child in list_xmlroot.iter():
                                if 'Entity' in child.tag:
                                    if 'media' in child.attrib.get('href'):
                                        name = child.attrib.get('name')
                                        media_id = child.attrib.get('href').split('/').pop()
                                        return name,media_id
                            else:
                                self.logger.debug("Media name and id not found")
                                return False,False
        except Exception as exp:
            self.logger.error("get_media_details : exception occurred "\
                                               "getting media details")
            raise vimconn.vimconnException(message=exp)


    def retry_rest(self, method, url, add_headers=None, data=None):
        """ Method to get Token & retry respective REST request
            Args:
                api - REST API - Can be one of 'GET' or 'PUT' or 'POST'
                url - request url to be used
                add_headers - Additional headers (optional)
                data - Request payload data to be passed in request
            Returns:
                response - Response of request
        """
        response = None

        #Get token
        self.get_token()

        if self.client._session:
                headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                           'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

        if add_headers:
            headers.update(add_headers)

        if method == 'GET':
            response = self.perform_request(req_type='GET',
                                            url=url,
                                            headers=headers)
        elif method == 'PUT':
            response = self.perform_request(req_type='PUT',
                                            url=url,
                                            headers=headers,
                                            data=data)
        elif method == 'POST':
            response = self.perform_request(req_type='POST',
                                            url=url,
                                            headers=headers,
                                            data=data)
        elif method == 'DELETE':
            response = self.perform_request(req_type='DELETE',
                                            url=url,
                                            headers=headers)
        return response


    def get_token(self):
        """ Generate a new token if expired

            Returns:
                The return client object that letter can be used to connect to vCloud director as admin for VDC
        """
        try:
            self.logger.debug("Generate token for vca {} as {} to datacenter {}.".format(self.org_name,
                                                                                      self.user,
                                                                                      self.org_name))
            host = self.url
            client = Client(host, verify_ssl_certs=False)
            client.set_highest_supported_version()
            client.set_credentials(BasicLoginCredentials(self.user, self.org_name, self.passwd))
            # connection object
            self.client = client

        except:
            raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: "
                                                     "{} as user: {}".format(self.org_name, self.user))

        if not client:
            raise vimconn.vimconnConnectionException("Failed while reconnecting vCD")


    def get_vdc_details(self):
        """ Get VDC details using pyVcloud Lib

            Returns org and vdc object
        """
        vdc = None
        try:
            org = Org(self.client, resource=self.client.get_org())
            vdc = org.get_vdc(self.tenant_name)
        except Exception as e:
            # pyvcloud not giving a specific exception, Refresh nevertheless
            self.logger.debug("Received exception {}, refreshing token ".format(str(e)))

        #Retry once, if failed by refreshing token
        if vdc is None:
            self.get_token()
            org = Org(self.client, resource=self.client.get_org())
            vdc = org.get_vdc(self.tenant_name)

        return org, vdc


    def perform_request(self, req_type, url, headers=None, data=None):
        """Perform the POST/PUT/GET/DELETE request."""

        #Log REST request details
        self.log_request(req_type, url=url, headers=headers, data=data)
        # perform request and return its result
        if req_type == 'GET':
            response = requests.get(url=url,
                                headers=headers,
                                verify=False)
        elif req_type == 'PUT':
            response = requests.put(url=url,
                                headers=headers,
                                data=data,
                                verify=False)
        elif req_type == 'POST':
            response = requests.post(url=url,
                                 headers=headers,
                                 data=data,
                                 verify=False)
        elif req_type == 'DELETE':
            response = requests.delete(url=url,
                                 headers=headers,
                                 verify=False)
        #Log the REST response
        self.log_response(response)

        return response


    def log_request(self, req_type, url=None, headers=None, data=None):
        """Logs REST request details"""

        if req_type is not None:
            self.logger.debug("Request type: {}".format(req_type))

        if url is not None:
            self.logger.debug("Request url: {}".format(url))

        if headers is not None:
            for header in headers:
                self.logger.debug("Request header: {}: {}".format(header, headers[header]))

        if data is not None:
            self.logger.debug("Request data: {}".format(data))


    def log_response(self, response):
        """Logs REST response details"""

        self.logger.debug("Response status code: {} ".format(response.status_code))


    def get_task_from_response(self, content):
        """
        content - API response content(response.content)
        return task object
        """
        xmlroot = XmlElementTree.fromstring(content)
        if xmlroot.tag.split('}')[1] == "Task":
            return xmlroot
        else:
            for ele in xmlroot:
                if ele.tag.split("}")[1] == "Tasks":
                    task = ele[0]
                    break
            return task


    def power_on_vapp(self,vapp_id, vapp_name):
        """
        vapp_id - vApp uuid
        vapp_name - vAapp name
        return - Task object
        """
        headers = {'Accept':'application/*+xml;version=' + API_VERSION,
                   'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}

        poweron_href = "{}/api/vApp/vapp-{}/power/action/powerOn".format(self.url,
                                                                          vapp_id)
        response = self.perform_request(req_type='POST',
                                       url=poweron_href,
                                        headers=headers)

        if response.status_code != 202:
            self.logger.error("REST call {} failed reason : {}"\
                         "status code : {} ".format(poweron_href,
                                                response.content,
                                           response.status_code))
            raise vimconn.vimconnException("power_on_vapp() : Failed to power on "\
                                                      "vApp {}".format(vapp_name))
        else:
            poweron_task = self.get_task_from_response(response.content)
            return poweron_task


