Bug782 fix: use_existing_flavors flag was not working
[osm/RO.git] / osm_ro / vimconn_vmware.py
index 82d6a69..f343eea 100644 (file)
@@ -29,6 +29,9 @@ from progressbar import Percentage, Bar, ETA, FileTransferSpeed, ProgressBar
 
 import vimconn
 import os
 
 import vimconn
 import os
+import shutil
+import subprocess
+import tempfile
 import traceback
 import itertools
 import requests
 import traceback
 import itertools
 import requests
@@ -42,23 +45,19 @@ from xml.etree import ElementTree as XmlElementTree
 from lxml import etree as lxmlElementTree
 
 import yaml
 from lxml import etree as lxmlElementTree
 
 import yaml
-from pyvcloud import Http
-from pyvcloud.vcloudair import VCA
-from pyvcloud.schema.vcd.v1_5.schemas.vcloud import sessionType, organizationType, \
-    vAppType, organizationListType, vdcType, catalogType, queryRecordViewType, \
-    networkType, vcloudType, taskType, diskType, vmsType, vdcTemplateListType, mediaType
+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
 from xml.sax.saxutils import escape
-
-from pyvcloud.schema.vcd.v1_5.schemas.admin.vCloudEntities import TaskType
-from pyvcloud.schema.vcd.v1_5.schemas.vcloud.taskType import TaskType as GenericTask
-from pyvcloud.schema.vcd.v1_5.schemas.vcloud.vAppType import TaskType as VappTask
-from pyvcloud.schema.vcd.v1_5.schemas.admin.vCloudEntities import TasksInProgressType
-
 import logging
 import json
 import time
 import uuid
 import httplib
 import logging
 import json
 import time
 import uuid
 import httplib
+#For python3
+#import http.client
 import hashlib
 import socket
 import struct
 import hashlib
 import socket
 import struct
@@ -80,11 +79,11 @@ DEFAULT_IP_PROFILE = {'dhcp_count':50,
 INTERVAL_TIME = 5
 MAX_WAIT_TIME = 1800
 
 INTERVAL_TIME = 5
 MAX_WAIT_TIME = 1800
 
-VCAVERSION = '5.9'
+API_VERSION = '27.0'
 
 
-__author__ = "Mustafa Bayramov, Arpita Kate, Sachin Bhangare"
-__date__ = "$12-Jan-2017 11:09:29$"
-__version__ = '0.1'
+__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: "Could not be created",
 #     0: "Unresolved",
@@ -178,6 +177,10 @@ class vimconnector(vimconn.vimconnector):
         self.nsx_manager = None
         self.nsx_user = None
         self.nsx_password = None
         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 tenant_name is not None:
             orgnameandtenant = tenant_name.split(":")
@@ -210,6 +213,9 @@ class vimconnector(vimconn.vimconnector):
         self.vcenter_user = config.get("vcenter_user", None)
         self.vcenter_password = config.get("vcenter_password", 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']
 # ############# Stub code for SRIOV #################
 #         try:
 #             self.dvs_name = config['dv_switch_name']
@@ -219,7 +225,7 @@ class vimconnector(vimconn.vimconnector):
 #         self.vlanID_range = config.get("vlanID_range", None)
 
         self.org_uuid = None
 #         self.vlanID_range = config.get("vlanID_range", None)
 
         self.org_uuid = None
-        self.vca = None
+        self.client = None
 
         if not url:
             raise vimconn.vimconnException('url param can not be NoneType')
 
         if not url:
             raise vimconn.vimconnException('url param can not be NoneType')
@@ -292,59 +298,41 @@ class vimconnector(vimconn.vimconnector):
             Organization creation / provider network creation etc.
 
             Returns:
             Organization creation / provider network creation etc.
 
             Returns:
-                The return vca object that letter can be used to connect to vcloud direct as admin for provider vdc
+                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))
 
 
-        self.logger.debug("Logging in to a vca {} as admin.".format(self.org_name))
-
-        vca_admin = VCA(host=self.url,
-                        username=self.admin_user,
-                        service_type=STANDALONE,
-                        version=VCAVERSION,
-                        verify=False,
-                        log=False)
-        result = vca_admin.login(password=self.admin_password, org='System')
-        if not result:
-            raise vimconn.vimconnConnectionException(
-                "Can't connect to a vCloud director as: {}".format(self.admin_user))
-        result = vca_admin.login(token=vca_admin.token, org='System', org_url=vca_admin.vcloud_session.org_url)
-        if result is True:
-            self.logger.info(
-                "Successfully logged to a vcloud direct org: {} as user: {}".format('System', self.admin_user))
+        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 vca_admin
+        return client_as_admin
 
     def connect(self):
         """ Method connect as normal user to vCloud director.
 
             Returns:
 
     def connect(self):
         """ Method connect as normal user to vCloud director.
 
             Returns:
-                The return vca object that letter can be used to connect to vCloud director as admin for VDC
+                The return client object that latter can be used to connect to vCloud director as admin for VDC
         """
         """
-
         try:
         try:
-            self.logger.debug("Logging in to a vca {} as {} to datacenter {}.".format(self.org_name,
+            self.logger.debug("Logging into vCD {} as {} to datacenter {}.".format(self.org_name,
                                                                                       self.user,
                                                                                       self.org_name))
                                                                                       self.user,
                                                                                       self.org_name))
-            vca = VCA(host=self.url,
-                      username=self.user,
-                      service_type=STANDALONE,
-                      version=VCAVERSION,
-                      verify=False,
-                      log=False)
-
-            result = vca.login(password=self.passwd, org=self.org_name)
-            if not result:
-                raise vimconn.vimconnConnectionException("Can't connect to a vCloud director as: {}".format(self.user))
-            result = vca.login(token=vca.token, org=self.org_name, org_url=vca.vcloud_session.org_url)
-            if result is True:
-                self.logger.info(
-                    "Successfully logged to a vcloud direct org: {} as user: {}".format(self.org_name, self.user))
-
+            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))
 
         except:
             raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: "
                                                      "{} as user: {}".format(self.org_name, self.user))
 
-        return vca
+        return client
 
     def init_organization(self):
         """ Method initialize organization UUID and VDC parameters.
 
     def init_organization(self):
         """ Method initialize organization UUID and VDC parameters.
@@ -357,18 +345,18 @@ class vimconnector(vimconn.vimconnector):
             Returns:
                 The return vca object that letter can be used to connect to vcloud direct as admin
         """
             Returns:
                 The return vca object that letter can be used to connect to vcloud direct as admin
         """
-        vca = self.connect()
-        if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed.")
+        client = self.connect()
+        if not client:
+            raise vimconn.vimconnConnectionException("Failed to connect vCD.")
 
 
-        self.vca = vca
+        self.client = client
         try:
             if self.org_uuid is None:
         try:
             if self.org_uuid is None:
-                org_dict = self.get_org_list()
-                for org in org_dict:
+                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.
                     # we set org UUID at the init phase but we can do it only when we have valid credential.
-                    if org_dict[org] == self.org_name:
-                        self.org_uuid = org
+                    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:
                         self.logger.debug("Setting organization UUID {}".format(self.org_uuid))
                         break
                 else:
@@ -421,7 +409,7 @@ class vimconnector(vimconn.vimconnector):
         vdc_task = self.create_vdc(vdc_name=tenant_name)
         if vdc_task is not None:
             vdc_uuid, value = vdc_task.popitem()
         vdc_task = self.create_vdc(vdc_name=tenant_name)
         if vdc_task is not None:
             vdc_uuid, value = vdc_task.popitem()
-            self.logger.info("Crated new vdc {} and uuid: {}".format(tenant_name, vdc_uuid))
+            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))
             return vdc_uuid
         else:
             raise vimconn.vimconnException("Failed create tenant {}".format(tenant_name))
@@ -437,17 +425,19 @@ class vimconnector(vimconn.vimconnector):
         """
         vca = self.connect_as_admin()
         if not vca:
         """
         vca = self.connect_as_admin()
         if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
 
         if tenant_id is not None:
 
         if tenant_id is not None:
-            if vca.vcloud_session and vca.vcloud_session.organization:
+            if vca._session:
                 #Get OrgVDC
                 #Get OrgVDC
-                url_list = [self.vca.host, '/api/vdc/', tenant_id]
+                url_list = [self.url, '/api/vdc/', tenant_id]
                 orgvdc_herf = ''.join(url_list)
                 orgvdc_herf = ''.join(url_list)
-                response = Http.get(url=orgvdc_herf,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+
+                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. "\
 
                 if response.status_code != requests.codes.ok:
                     self.logger.debug("delete_tenant():GET REST API call {} failed. "\
@@ -457,22 +447,19 @@ class vimconnector(vimconn.vimconnector):
 
                 lxmlroot_respond = lxmlElementTree.fromstring(response.content)
                 namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
 
                 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'
 
                 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'
 
-                #Delete OrgVDC
-                response = Http.delete(url=vdc_remove_href,
-                                    headers=vca.vcloud_session.get_vcloud_headers(),
-                                    verify=vca.verify,
-                                    logger=vca.logger)
+                response = self.perform_request(req_type='DELETE',
+                                                url=vdc_remove_href,
+                                                headers=headers)
 
                 if response.status_code == 202:
 
                 if response.status_code == 202:
-                        delete_vdc_task = taskType.parseString(response.content, True)
-                        if type(delete_vdc_task) is GenericTask:
-                            self.vca.block_until_completed(delete_vdc_task)
-                            self.logger.info("Deleted tenant with ID {}".format(tenant_id))
-                            return tenant_id
+                    time.sleep(5)
+                    return tenant_id
                 else:
                     self.logger.debug("delete_tenant(): DELETE REST API call {} failed. "\
                                       "Return status code {}".format(vdc_remove_href,
                 else:
                     self.logger.debug("delete_tenant(): DELETE REST API call {} failed. "\
                                       "Return status code {}".format(vdc_remove_href,
@@ -516,17 +503,35 @@ class vimconnector(vimconn.vimconnector):
 
         return vdclist
 
 
         return vdclist
 
-    def new_network(self, net_name, net_type, ip_profile=None, shared=False):
+    def new_network(self, net_name, net_type, ip_profile=None, shared=False, vlan=None):
         """Adds a tenant network to VIM
         """Adds a tenant network to VIM
-            net_name is the name
-            net_type can be 'bridge','data'.'ptp'.
-            ip_profile is a dict containing the IP parameters of the network
-            shared is a boolean
-        Returns the network identifier"""
+        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))
 
 
         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'
         isshared = 'false'
         if shared:
             isshared = 'true'
@@ -540,7 +545,7 @@ class vimconnector(vimconn.vimconnector):
         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:
         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
+            return network_uuid, created_items
         else:
             raise vimconn.vimconnUnexpectedResponse("Failed create a new network {}".format(net_name))
 
         else:
             raise vimconn.vimconnUnexpectedResponse("Failed create a new network {}".format(net_name))
 
@@ -556,35 +561,67 @@ class vimconnector(vimconn.vimconnector):
         if not self.tenant_name:
             raise vimconn.vimconnConnectionException("Tenant name is empty.")
 
         if not self.tenant_name:
             raise vimconn.vimconnConnectionException("Tenant name is empty.")
 
-        vdc = self.get_vdc_details()
+        org, vdc = self.get_vdc_details()
         if vdc is None:
             raise vimconn.vimconnConnectionException("Can't retrieve information for a VDC {}".format(self.tenant_name))
 
         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]
-        networks = self.vca.get_networks(vdc.get_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:
         network_list = []
         try:
-            for network in networks:
-                filter_dict = {}
-                netid = network.get_id().split(":")
-                if len(netid) != 4:
-                    continue
+            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["name"] = network.get_name()
-                filter_dict["id"] = netid[3]
-                filter_dict["shared"] = network.get_IsShared()
-                filter_dict["tenant_id"] = vdc_uuid
-                if network.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))
+                            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:
         except:
-            self.logger.debug("Error in get_vcd_network_list")
-            self.logger.debug(traceback.format_exc())
+            self.logger.debug("Error in get_vcd_network_list", exc_info=True)
             pass
 
         self.logger.debug("get_vcd_network_list returning {}".format(network_list))
             pass
 
         self.logger.debug("get_vcd_network_list returning {}".format(network_list))
@@ -612,50 +649,81 @@ class vimconnector(vimconn.vimconnector):
         if not self.tenant_name:
             raise vimconn.vimconnConnectionException("Tenant name is empty.")
 
         if not self.tenant_name:
             raise vimconn.vimconnConnectionException("Tenant name is empty.")
 
-        vdc = self.get_vdc_details()
+        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:
         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]
-            networks = self.vca.get_networks(vdc.get_name())
-            network_list = []
+            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)
 
 
-            for network in networks:
-                filter_entry = {}
-                net_uuid = network.get_id().split(":")
-                if len(net_uuid) != 4:
-                    continue
-                else:
-                    net_uuid = net_uuid[3]
-                # create dict entry
-                self.logger.debug("Adding  {} to a list vcd id {} network {}".format(net_uuid,
-                                                                                     vdcid,
-                                                                                     network.get_name()))
-                filter_entry["name"] = network.get_name()
-                filter_entry["id"] = net_uuid
-                filter_entry["shared"] = network.get_IsShared()
-                filter_entry["tenant_id"] = vdcid
-                if network.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()
+            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)
 
 
-                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:
-            self.logger.debug("Error in get_vcd_network_list")
-            self.logger.debug(traceback.format_exc())
+                            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
 
         self.logger.debug("Returning {}".format(network_list))
         return network_list
@@ -665,38 +733,71 @@ class vimconnector(vimconn.vimconnector):
            Return a dict with  the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]"""
 
         try:
            Return a dict with  the fields at filter_dict (see get_network_list) plus some VIM specific>}, ...]"""
 
         try:
-            vdc = self.get_vdc_details()
-            vdc_id = vdc.get_id().split(":")[3]
+            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)
 
 
-            networks = self.vca.get_networks(vdc.get_name())
             filter_dict = {}
 
             filter_dict = {}
 
-            for network in networks:
-                vdc_network_id = network.get_id().split(":")
-                if len(vdc_network_id) == 4 and vdc_network_id[3] == net_id:
-                    filter_dict["name"] = network.get_name()
-                    filter_dict["id"] = vdc_network_id[3]
-                    filter_dict["shared"] = network.get_IsShared()
-                    filter_dict["tenant_id"] = vdc_id
-                    if network.get_status() == 1:
-                        filter_dict["admin_state_up"] = True
+            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:
                     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
-        except:
+                        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())
             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
 
 
         return filter_dict
 
-    def delete_network(self, net_id):
+    def delete_network(self, net_id, created_items=None):
         """
         """
-            Method Deletes a tenant network from VIM, provide the network id.
-
-            Returns the network identifier or raise an exception
+        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 #################
         """
 
         # ############# Stub code for SRIOV #################
@@ -791,7 +892,7 @@ class vimconnector(vimconn.vimconnector):
         new_flavor=flavor_data
         ram = flavor_data.get(FLAVOR_RAM_KEY, 1024)
         cpu = flavor_data.get(FLAVOR_VCPUS_KEY, 1)
         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, 1)
+        disk = flavor_data.get(FLAVOR_DISK_KEY, 0)
 
         if not isinstance(ram, int):
             raise vimconn.vimconnException("Non-integer value for ram")
 
         if not isinstance(ram, int):
             raise vimconn.vimconnException("Non-integer value for ram")
@@ -806,7 +907,8 @@ class vimconnector(vimconn.vimconnector):
             if numas:
                 for numa in numas:
                     #overwrite ram and vcpus
             if numas:
                 for numa in numas:
                     #overwrite ram and vcpus
-                    ram = numa['memory']*1024
+                    if 'memory' in numa:
+                        ram = numa['memory']*1024
                     if 'paired-threads' in numa:
                         cpu = numa['paired-threads']*2
                     elif 'cores' in numa:
                     if 'paired-threads' in numa:
                         cpu = numa['paired-threads']*2
                     elif 'cores' in numa:
@@ -853,16 +955,19 @@ class vimconnector(vimconn.vimconnector):
             Return:
                 returns the image identifier in UUID format or raises an exception on error
         """
             Return:
                 returns the image identifier in UUID format or raises an exception on error
         """
-        vca = self.connect_as_admin()
-        if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+        conn = self.connect_as_admin()
+        if not conn:
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
         # Get Catalog details
         # Get Catalog details
-        url_list = [self.vca.host, '/api/catalog/', image_id]
+        url_list = [self.url, '/api/catalog/', image_id]
         catalog_herf = ''.join(url_list)
         catalog_herf = ''.join(url_list)
-        response = Http.get(url=catalog_herf,
-                            headers=vca.vcloud_session.get_vcloud_headers(),
-                            verify=vca.verify,
-                            logger=vca.logger)
+
+        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. "\
 
         if response.status_code != requests.codes.ok:
             self.logger.debug("delete_image():GET REST API call {} failed. "\
@@ -872,6 +977,8 @@ class vimconnector(vimconn.vimconnector):
 
         lxmlroot_respond = lxmlElementTree.fromstring(response.content)
         namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
 
         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)
         namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
 
         catalogItems_section = lxmlroot_respond.find("xmlns:CatalogItems",namespaces)
@@ -879,11 +986,9 @@ class vimconnector(vimconn.vimconnector):
         for catalogItem in catalogItems:
             catalogItem_href = catalogItem.attrib['href']
 
         for catalogItem in catalogItems:
             catalogItem_href = catalogItem.attrib['href']
 
-            #GET details of catalogItem
-            response = Http.get(url=catalogItem_href,
-                            headers=vca.vcloud_session.get_vcloud_headers(),
-                            verify=vca.verify,
-                            logger=vca.logger)
+            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. "\
 
             if response.status_code != requests.codes.ok:
                 self.logger.debug("delete_image():GET REST API call {} failed. "\
@@ -895,26 +1000,26 @@ class vimconnector(vimconn.vimconnector):
 
             lxmlroot_respond = lxmlElementTree.fromstring(response.content)
             namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
 
             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
             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 = Http.delete(url= catalogitem_remove_href,
-                                    headers=vca.vcloud_session.get_vcloud_headers(),
-                                    verify=vca.verify,
-                                    logger=vca.logger)
+            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
             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.vca.host, '/api/admin/catalog/', image_id]
+        url_list = [self.url, '/api/admin/catalog/', image_id]
         catalog_remove_herf = ''.join(url_list)
         catalog_remove_herf = ''.join(url_list)
-        response = Http.delete(url= catalog_remove_herf,
-                                    headers=vca.vcloud_session.get_vcloud_headers(),
-                                    verify=vca.verify,
-                                    logger=vca.logger)
+        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))
 
         if response.status_code == requests.codes.no_content:
             self.logger.debug("Deleted Catalog {}".format(image_id))
@@ -931,9 +1036,8 @@ class vimconnector(vimconn.vimconnector):
         :return:
         """
         for catalog in catalogs:
         :return:
         """
         for catalog in catalogs:
-            if catalog.name == catalog_name:
-                return True
-        return False
+            if catalog['name'] == catalog_name:
+                return catalog['id']
 
     def create_vimcatalog(self, vca=None, catalog_name=None):
         """ Create new catalog entry in vCloud director.
 
     def create_vimcatalog(self, vca=None, catalog_name=None):
         """ Create new catalog entry in vCloud director.
@@ -943,17 +1047,19 @@ class vimconnector(vimconn.vimconnector):
                 catalog_name catalog that client wish to create.   Note no validation done for a name.
                 Client must make sure that provide valid string representation.
 
                 catalog_name catalog that client wish to create.   Note no validation done for a name.
                 Client must make sure that provide valid string representation.
 
-             Return (bool) True if catalog created.
+             Returns catalog id if catalog created else None.
 
         """
         try:
 
         """
         try:
-            task = vca.create_catalog(catalog_name, catalog_name)
-            result = vca.block_until_completed(task)
-            if not result:
-                return False
-            catalogs = vca.get_catalogs()
-        except:
-            return False
+            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
         return self.catalog_exists(catalog_name, catalogs)
 
     # noinspection PyIncorrectDocstring
@@ -979,37 +1085,45 @@ class vimconnector(vimconn.vimconnector):
         #  status change.
         #  if VCD can parse OVF we upload VMDK file
         try:
         #  status change.
         #  if VCD can parse OVF we upload VMDK file
         try:
-            for catalog in vca.get_catalogs():
-                if catalog_name != catalog.name:
+            for catalog in vca.list_catalogs():
+                if catalog_name != catalog['name']:
                     continue
                     continue
-                link = filter(lambda link: link.get_type() == "application/vnd.vmware.vcloud.media+xml" and
-                                           link.get_rel() == 'add', catalog.get_Link())
-                assert len(link) == 1
+                catalog_href = "{}/api/catalog/{}/action/upload".format(self.url, catalog['id'])
                 data = """
                 data = """
-                <UploadVAppTemplateParams name="%s" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1"><Description>%s vApp Template</Description></UploadVAppTemplateParams>
-                """ % (escape(catalog_name), escape(description))
-                headers = vca.vcloud_session.get_vcloud_headers()
-                headers['Content-Type'] = 'application/vnd.vmware.vcloud.uploadVAppTemplateParams+xml'
-                response = Http.post(link[0].get_href(), headers=headers, data=data, verify=vca.verify, logger=self.logger)
+                <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
                 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 = Http.get(href, headers=vca.vcloud_session.get_vcloud_headers(),
-                                        verify=vca.verify, logger=self.logger)
+
+                    response = self.perform_request(req_type='GET',
+                                                    url=href,
+                                                    headers=headers)
 
                     if response.status_code == requests.codes.ok:
 
                     if response.status_code == requests.codes.ok:
-                        media = mediaType.parseString(response.content, True)
-                        link = filter(lambda link: link.get_rel() == 'upload:default',
-                                      media.get_Files().get_File()[0].get_Link())[0]
-                        headers = vca.vcloud_session.get_vcloud_headers()
                         headers['Content-Type'] = 'Content-Type text/xml'
                         headers['Content-Type'] = 'Content-Type text/xml'
-                        response = Http.put(link.get_href(),
-                                            data=open(media_file_name, 'rb'),
-                                            headers=headers,
-                                            verify=vca.verify, logger=self.logger)
+                        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,
                         if response.status_code != requests.codes.ok:
                             self.logger.debug(
                                 "Failed create vApp template for catalog name {} and image {}".format(catalog_name,
@@ -1023,73 +1137,64 @@ class vimconnector(vimconn.vimconnector):
 
                     # uploading VMDK file
                     # check status of OVF upload and upload remaining files.
 
                     # uploading VMDK file
                     # check status of OVF upload and upload remaining files.
-                    response = Http.get(template,
-                                        headers=vca.vcloud_session.get_vcloud_headers(),
-                                        verify=vca.verify,
-                                        logger=self.logger)
+                    response = self.perform_request(req_type='GET',
+                                                    url=template,
+                                                    headers=headers)
 
                     if response.status_code == requests.codes.ok:
 
                     if response.status_code == requests.codes.ok:
-                        media = mediaType.parseString(response.content, True)
-                        number_of_files = len(media.get_Files().get_File())
-                        for index in xrange(0, number_of_files):
-                            links_list = filter(lambda link: link.get_rel() == 'upload:default',
-                                                media.get_Files().get_File()[index].get_Link())
-                            for link in links_list:
-                                # we skip ovf since it already uploaded.
-                                if 'ovf' in link.get_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.get_href().split("/")[-1]
-                                if not os.path.isfile(file_vmdk):
-                                    return False
-                                statinfo = os.stat(file_vmdk)
-                                if statinfo.st_size == 0:
+                        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
                                     return False
-                                hrefvmdk = link.get_href()
-
-                                if progress:
-                                    print("Uploading file: {}".format(file_vmdk))
-                                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 = vca.vcloud_session.get_vcloud_headers()
-                                        headers['Content-Range'] = 'bytes %s-%s/%s' % (
-                                            bytes_transferred, len(my_bytes) - 1, statinfo.st_size)
-                                        headers['Content-Length'] = str(len(my_bytes))
-                                        response = Http.put(hrefvmdk,
-                                                            headers=headers,
-                                                            data=my_bytes,
-                                                            verify=vca.verify,
-                                                            logger=None)
-
-                                        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
+                        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))
         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))
@@ -1129,9 +1234,9 @@ class vimconnector(vimconn.vimconnector):
         """
 
         for catalog in catalogs:
         """
 
         for catalog in catalogs:
-            if catalog.name == catalog_name:
-                catalog_id = catalog.get_id().split(":")
-                return catalog_id[3]
+            if catalog['name'] == catalog_name:
+                catalog_id = catalog['id']
+                return catalog_id
         return None
 
     def get_catalogbyid(self, catalog_uuid=None, catalogs=None):
         return None
 
     def get_catalogbyid(self, catalog_uuid=None, catalogs=None):
@@ -1148,9 +1253,9 @@ class vimconnector(vimconn.vimconnector):
             return None
 
         for catalog in catalogs:
             return None
 
         for catalog in catalogs:
-            catalog_id = catalog.get_id().split(":")[3]
+            catalog_id = catalog.get('id')
             if catalog_id == catalog_uuid:
             if catalog_id == catalog_uuid:
-                return catalog.name
+                return catalog.get('name')
         return None
 
     def get_catalog_obj(self, catalog_uuid=None, catalogs=None):
         return None
 
     def get_catalog_obj(self, catalog_uuid=None, catalogs=None):
@@ -1167,7 +1272,7 @@ class vimconnector(vimconn.vimconnector):
             return None
 
         for catalog in catalogs:
             return None
 
         for catalog in catalogs:
-            catalog_id = catalog.get_id().split(":")[3]
+            catalog_id = catalog.get('id')
             if catalog_id == catalog_uuid:
                 return catalog
         return None
             if catalog_id == catalog_uuid:
                 return catalog
         return None
@@ -1216,43 +1321,43 @@ class vimconnector(vimconn.vimconnector):
                           "vdc catalog name {}".format(filename, catalog_name, path, catalog_md5_name))
 
         try:
                           "vdc catalog name {}".format(filename, catalog_name, path, catalog_md5_name))
 
         try:
-            catalogs = self.vca.get_catalogs()
+            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))
         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))
-            result = self.create_vimcatalog(self.vca, catalog_md5_name)
-            if not result:
+            if self.create_vimcatalog(org, catalog_md5_name) is None:
                 raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))
                 raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))
-            result = self.upload_vimimage(vca=self.vca, catalog_name=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))
                                           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, self.vca.get_catalogs())
+            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
         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:
+                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)))
                     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, self.vca.get_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 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))
-        result = self.create_vimcatalog(self.vca, catalog_md5_name)
-        if not result:
+        if self.create_vimcatalog(org, catalog_md5_name) is None:
             raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))
 
             raise vimconn.vimconnException("Failed create new catalog {} ".format(catalog_md5_name))
 
-        result = self.upload_vimimage(vca=self.vca, catalog_name=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))
 
                                       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, self.vca.get_catalogs())
+        return self.get_catalogid(catalog_md5_name, org.list_catalogs())
 
     def get_image_list(self, filter_dict={}):
         '''Obtain tenant images from VIM
 
     def get_image_list(self, filter_dict={}):
         '''Obtain tenant images from VIM
@@ -1267,14 +1372,15 @@ class vimconnector(vimconn.vimconnector):
         '''
 
         try:
         '''
 
         try:
+            org, vdc = self.get_vdc_details()
             image_list = []
             image_list = []
-            catalogs = self.vca.get_catalogs()
+            catalogs = org.list_catalogs()
             if len(catalogs) == 0:
                 return image_list
             else:
                 for catalog in catalogs:
             if len(catalogs) == 0:
                 return image_list
             else:
                 for catalog in catalogs:
-                    catalog_uuid = catalog.get_id().split(":")[3]
-                    name = catalog.name
+                    catalog_uuid = catalog.get('id')
+                    name = catalog.get('name')
                     filtered_dict = {}
                     if filter_dict.get("name") and filter_dict["name"] != name:
                         continue
                     filtered_dict = {}
                     if filter_dict.get("name") and filter_dict["name"] != name:
                         continue
@@ -1305,6 +1411,9 @@ class vimconnector(vimconn.vimconnector):
         try:
             refs = filter(lambda ref: ref.name == vapp_name and ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml',
                           vdc.ResourceEntities.ResourceEntity)
         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:
             if len(refs) == 1:
                 return refs[0].href.split("vapp")[1][1:]
         except Exception as e:
@@ -1329,6 +1438,9 @@ class vimconnector(vimconn.vimconnector):
             refs = filter(lambda ref:
                           ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml',
                           vdc.ResourceEntities.ResourceEntity)
             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
             for ref in refs:
                 vappid = ref.href.split("vapp")[1][1:]
                 # find vapp with respected vapp uuid
@@ -1339,34 +1451,30 @@ class vimconnector(vimconn.vimconnector):
             return False
         return False
 
             return False
         return False
 
-    def get_namebyvappid(self, vdc=None, vapp_uuid=None):
+    def get_namebyvappid(self, vapp_uuid=None):
         """Method returns vApp name from vCD and lookup done by vapp_id.
 
         Args:
         """Method returns vApp name from vCD and lookup done by vapp_id.
 
         Args:
-            vca: Connector to VCA
-            vdc: The VDC object.
             vapp_uuid: vappid is application identifier
 
         Returns:
             The return vApp name otherwise None
         """
             vapp_uuid: vappid is application identifier
 
         Returns:
             The return vApp name otherwise None
         """
-
         try:
         try:
-            refs = filter(lambda ref: ref.type_ == 'application/vnd.vmware.vcloud.vApp+xml',
-                          vdc.ResourceEntities.ResourceEntity)
-            for ref in refs:
-                # we care only about UUID the rest doesn't matter
-                vappid = ref.href.split("vapp")[1][1:]
-                if vappid == vapp_uuid:
-                    response = Http.get(ref.href, headers=self.vca.vcloud_session.get_vcloud_headers(), verify=self.vca.verify,
-                                        logger=self.logger)
-
-                    #Retry login if session expired & retry sending request
-                    if response.status_code == 403:
-                        response = self.retry_rest('GET', ref.href)
-
-                    tree = XmlElementTree.fromstring(response.content)
-                    return tree.attrib['name']
+            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
         except Exception as e:
             self.logger.exception(e)
             return None
@@ -1382,15 +1490,15 @@ class vimconnector(vimconn.vimconnector):
                 '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
                 '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, e2000, ...
+                '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'
                 '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'
-                     'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
+                     'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
                            can created unconnected
                            can created unconnected
-                     'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
+                     '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
                      '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
@@ -1420,31 +1528,43 @@ class vimconnector(vimconn.vimconnector):
             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
             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 the instance identifier or raises an exception on error
+        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.info("Creating new instance for entry {}".format(name))
-        self.logger.debug("desc {} boot {} image_id: {} flavor_id: {} net_list: {} cloud_config {} disk_list {}".format(
-                                    description, start, image_id, flavor_id, net_list, cloud_config, disk_list))
+        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)
 
 
         #new vm name = vmname + tenant_id + uuid
         new_vm_name = [name, '-', str(uuid.uuid4())]
         vmname_andid = ''.join(new_vm_name)
 
-        # if vm already deployed we return existing uuid
-        # vapp_uuid = self.get_vappid(vca.get_vdc(self.tenant_name), name)
-        # if vapp_uuid is not None:
-        #     return vapp_uuid
+        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.
         # we check for presence of VDC, Catalog entry and Flavor.
-        vdc = self.get_vdc_details()
+        org, vdc = self.get_vdc_details()
         if vdc is None:
             raise vimconn.vimconnNotFoundException(
                 "new_vminstance(): Failed create vApp {}: (Failed retrieve VDC information)".format(name))
         if vdc is None:
             raise vimconn.vimconnNotFoundException(
                 "new_vminstance(): Failed create vApp {}: (Failed retrieve VDC information)".format(name))
-        catalogs = self.vca.get_catalogs()
+        catalogs = org.list_catalogs()
         if catalogs is None:
             #Retry once, if failed by refreshing token
             self.get_token()
         if catalogs is None:
             #Retry once, if failed by refreshing token
             self.get_token()
-            catalogs = self.vca.get_catalogs()
+            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))
         if catalogs is None:
             raise vimconn.vimconnNotFoundException(
                 "new_vminstance(): Failed create vApp {}: (Failed retrieve catalogs list)".format(name))
@@ -1456,7 +1576,6 @@ class vimconnector(vimconn.vimconnector):
             raise vimconn.vimconnNotFoundException("new_vminstance(): Failed create vApp {}: "
                                                    "(Failed retrieve catalog information {})".format(name, image_id))
 
             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
         # Set vCPU and Memory based on flavor.
         vm_cpus = None
         vm_memory = None
@@ -1492,6 +1611,7 @@ class vimconnector(vimconn.vimconnector):
         #If no mgmt, then the 1st NN in netlist is considered as primary net. 
         primary_net = None
         primary_netname = None
         #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:
         network_mode = 'bridged'
         if net_list is not None and len(net_list) > 0:
             for net in net_list:
@@ -1502,6 +1622,8 @@ class vimconnector(vimconn.vimconnector):
 
             try:
                 primary_net_id = primary_net['net_id']
 
             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']
                 network_dict = self.get_vcd_network(network_uuid=primary_net_id)
                 if 'name' in network_dict:
                     primary_netname = network_dict['name']
@@ -1514,16 +1636,146 @@ class vimconnector(vimconn.vimconnector):
         # use: 'data', 'bridge', 'mgmt'
         # create vApp.  Set vcpu and ram based on flavor id.
         try:
         # 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):
             for retry in (1,2):
-                vapptask = self.vca.create_vapp(self.tenant_name, vmname_andid, templateName,
-                                           self.get_catalogbyid(image_id, catalogs),
-                                           network_name=None,  # None while creating vapp
-                                           network_mode=network_mode,
-                                           vm_name=vmname_andid,
-                                           vm_cpus=vm_cpus,  # can be None if flavor is None
-                                           vm_memory=vm_memory)  # can be None if flavor is None
-
-                if not vapptask and retry==1:
+                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:
                     self.get_token() # Retry getting token
                     continue
                 else:
@@ -1532,8 +1784,15 @@ class vimconnector(vimconn.vimconnector):
             if vapptask is None or vapptask is False:
                 raise vimconn.vimconnUnexpectedResponse(
                     "new_vminstance(): failed to create vApp {}".format(vmname_andid))
             if vapptask is None or vapptask is False:
                 raise vimconn.vimconnUnexpectedResponse(
                     "new_vminstance(): failed to create vApp {}".format(vmname_andid))
-            if type(vapptask) is VappTask:
-                self.vca.block_until_completed(vapptask)
+
+            # 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(
 
         except Exception as exp:
             raise vimconn.vimconnUnexpectedResponse(
@@ -1541,7 +1800,10 @@ class vimconnector(vimconn.vimconnector):
 
         # we should have now vapp in undeployed state.
         try:
 
         # we should have now vapp in undeployed state.
         try:
-            vapp_uuid = self.get_vappid(self.get_vdc_details(), vmname_andid)
+            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(
 
         except Exception as exp:
             raise vimconn.vimconnUnexpectedResponse(
@@ -1556,14 +1818,13 @@ class vimconnector(vimconn.vimconnector):
         #Add PCI passthrough/SRIOV configrations
         vm_obj = None
         pci_devices_info = []
         #Add PCI passthrough/SRIOV configrations
         vm_obj = None
         pci_devices_info = []
-        sriov_net_info = []
         reserve_memory = False
 
         for net in net_list:
         reserve_memory = False
 
         for net in net_list:
-            if net["type"]=="PF":
+            if net["type"] == "PF" or net["type"] == "PCI-PASSTHROUGH":
                 pci_devices_info.append(net)
                 pci_devices_info.append(net)
-            elif  (net["type"]=="VF" or  net["type"]=="VFnotShared") and 'net_id'in net:
-                sriov_net_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:
 
         #Add PCI
         if len(pci_devices_info) > 0:
@@ -1584,7 +1845,6 @@ class vimconnector(vimconn.vimconnector):
                                                             vmname_andid)
                                  )
 
                                                             vmname_andid)
                                  )
 
-        vapp = self.vca.get_vapp(self.get_vdc_details(), vmname_andid)
         # Modify vm disk
         if vm_disk:
             #Assuming there is only one disk in ovf and fast provisioning in organization vDC is disabled
         # Modify vm disk
         if vm_disk:
             #Assuming there is only one disk in ovf and fast provisioning in organization vDC is disabled
@@ -1627,9 +1887,18 @@ class vimconnector(vimconn.vimconnector):
 
         # add NICs & connect to networks in netlist
         try:
 
         # 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))
             self.logger.info("Request to connect VM to a network: {}".format(net_list))
-            nicIndex = 0
             primary_nic_index = 0
             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
             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
@@ -1656,92 +1925,99 @@ class vimconnector(vimconn.vimconnector):
                                   - NONE (No IP addressing mode specified.)"""
 
                 if primary_netname is not None:
                                   - NONE (No IP addressing mode specified.)"""
 
                 if primary_netname is not None:
-                    nets = filter(lambda n: n.name == interface_net_name, self.vca.get_networks(self.tenant_name))
+                    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:
                     if len(nets) == 1:
-                        self.logger.info("new_vminstance(): Found requested network: {}".format(nets[0].name))
+                        self.logger.info("new_vminstance(): Found requested network: {}".format(nets[0].get('name')))
 
 
-                        vapp = self.vca.get_vapp(self.get_vdc_details(), vmname_andid)
-                        task = vapp.connect_to_network(nets[0].name, nets[0].href)
-                        if type(task) is GenericTask:
-                            self.vca.block_until_completed(task)
-                        # connect network to VM - with all DHCP by default
+                        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','VF','VFnotShared']
+                        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 'type' in net and net['type'] not in type_list:
                             # fetching nic type from vnf
                             if 'model' in net:
-                                nic_type = net['model']
+                                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 "\
                                 self.logger.info("new_vminstance(): adding network adapter "\
-                                                          "to a network {}".format(nets[0].name))
-                                self.add_network_adapter_to_vms(vapp, nets[0].name,
+                                                          "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 "\
                                                                 primary_nic_index,
                                                                 nicIndex,
                                                                 net,
                                                                 nic_type=nic_type)
                             else:
                                 self.logger.info("new_vminstance(): adding network adapter "\
-                                                         "to a network {}".format(nets[0].name))
-                                self.add_network_adapter_to_vms(vapp, nets[0].name,
+                                                         "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,
                                                                 primary_nic_index,
                                                                 nicIndex,
-                                                                net)
+                                                                net,
+                                                                nic_type=nic_type)
                 nicIndex += 1
 
                 nicIndex += 1
 
-            vapp = self.vca.get_vapp(self.get_vdc_details(), vmname_andid)
             # cloud-init for ssh-key injection
             if cloud_config:
             # cloud-init for ssh-key injection
             if cloud_config:
-                self.cloud_init(vapp,cloud_config)
-
-            # deploy and power on vm
-            self.logger.debug("new_vminstance(): Deploying vApp {} ".format(name))
-            deploytask = vapp.deploy(powerOn=False)
-            if type(deploytask) is GenericTask:
-                self.vca.block_until_completed(deploytask)
-
-        # ############# Stub code for SRIOV #################
-        #Add SRIOV
-#         if len(sriov_net_info) > 0:
-#             self.logger.info("Need to add SRIOV adapters {} into VM {}".format(sriov_net_info,
-#                                                                         vmname_andid ))
-#             sriov_status, vm_obj, vcenter_conect = self.add_sriov(vapp_uuid,
-#                                                                   sriov_net_info,
-#                                                                   vmname_andid)
-#             if sriov_status:
-#                 self.logger.info("Added SRIOV {} to VM {}".format(
-#                                                             sriov_net_info,
-#                                                             vmname_andid)
-#                                  )
-#                 reserve_memory = True
-#             else:
-#                 self.logger.info("Fail to add SRIOV {} to VM {}".format(
-#                                                             sriov_net_info,
-#                                                             vmname_andid)
-#                                  )
+                # 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:
 
             # If VM has PCI devices or SRIOV reserve memory for VM
             if reserve_memory:
-                memReserve = vm_obj.config.hardware.memoryMB
-                spec = vim.vm.ConfigSpec()
-                spec.memoryAllocation = vim.ResourceAllocationInfo(reservation=memReserve)
-                task = vm_obj.ReconfigVM_Task(spec=spec)
-                if task:
-                    result = self.wait_for_vcenter_task(task, vcenter_conect)
-                    self.logger.info("Reserved memory {} MB for "
-                                     "VM VM status: {}".format(str(memReserve), result))
-                else:
-                    self.logger.info("Fail to reserved memory {} to VM {}".format(
-                                                                str(memReserve), str(vm_obj)))
+                self.reserve_memory_for_all_vms(vapp, memory_mb)
 
 
-            self.logger.debug("new_vminstance(): power on vApp {} ".format(name))
+            self.logger.debug("new_vminstance(): starting power on vApp {} ".format(vmname_andid))
 
 
-            vapp = self.vca.get_vapp(self.get_vdc_details(), vmname_andid)
-            poweron_task = vapp.poweron()
-            if type(poweron_task) is GenericTask:
-                self.vca.block_until_completed(poweron_task)
+            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 :
+        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
             # it might be a case if specific mandatory entry in dict is empty or some other pyVcloud exception
-            self.logger.debug("new_vminstance(): Failed create new vm instance {} with 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))
                               .format(name, exp))
             raise vimconn.vimconnException("new_vminstance(): Failed create new vm instance {} with exception {}"
                                            .format(name, exp))
@@ -1751,14 +2027,16 @@ class vimconnector(vimconn.vimconnector):
         vapp_uuid = None
         while wait_time <= MAX_WAIT_TIME:
             try:
         vapp_uuid = None
         while wait_time <= MAX_WAIT_TIME:
             try:
-                vapp = self.vca.get_vapp(self.get_vdc_details(), vmname_andid)
+                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))
 
             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:
-                vapp_uuid = self.get_vappid(self.get_vdc_details(), vmname_andid)
+            #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))
                 break
             else:
                 self.logger.debug("new_vminstance(): Wait for vApp {} to deploy".format(name))
@@ -1766,11 +2044,623 @@ class vimconnector(vimconn.vimconnector):
 
             wait_time +=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:
         if vapp_uuid is not None:
-            return vapp_uuid
+            return vapp_uuid, None
         else:
             raise vimconn.vimconnUnexpectedResponse("new_vminstance(): Failed create new vm instance {}".format(name))
 
         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
     ##
     ##
     ##  based on current discussion
@@ -1791,7 +2681,7 @@ class vimconnector(vimconn.vimconnector):
 
         self.logger.debug("Client requesting vm instance {} ".format(vim_vm_uuid))
 
 
         self.logger.debug("Client requesting vm instance {} ".format(vim_vm_uuid))
 
-        vdc = self.get_vdc_details()
+        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))
         if vdc is None:
             raise vimconn.vimconnConnectionException(
                 "Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))
@@ -1825,7 +2715,7 @@ class vimconnector(vimconn.vimconnector):
 
         return vm_dict
 
 
         return vm_dict
 
-    def delete_vminstance(self, vm__vim_uuid):
+    def delete_vminstance(self, vm__vim_uuid, created_items=None):
         """Method poweroff and remove VM instance from vcloud director network.
 
         Args:
         """Method poweroff and remove VM instance from vcloud director network.
 
         Args:
@@ -1837,42 +2727,38 @@ class vimconnector(vimconn.vimconnector):
 
         self.logger.debug("Client requesting delete vm instance {} ".format(vm__vim_uuid))
 
 
         self.logger.debug("Client requesting delete vm instance {} ".format(vm__vim_uuid))
 
-        vdc = self.get_vdc_details()
-        if vdc is None:
+        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:
             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(vdc, vm__vim_uuid)
+            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)
             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)
-            else:
-                self.logger.info("Deleting vApp {} and UUID {}".format(vapp_name, 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.
 
             # Delete vApp and wait for status change if task executed and vApp is None.
-            vapp = self.vca.get_vapp(self.get_vdc_details(), vapp_name)
 
             if vapp:
 
             if vapp:
-                if vapp.me.deployed:
+                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:
                     self.logger.info("Powering off vApp {}".format(vapp_name))
                     #Power off vApp
                     powered_off = False
                     wait_time = 0
                     while wait_time <= MAX_WAIT_TIME:
-                        vapp = self.vca.get_vapp(self.get_vdc_details(), vapp_name)
-                        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)
+                        power_off_task = vapp.power_off()
+                        result = self.client.get_task_monitor().wait_for_success(task=power_off_task)
 
 
-                        power_off_task = vapp.poweroff()
-                        if type(power_off_task) is GenericTask:
-                            result = self.vca.block_until_completed(power_off_task)
-                            if result:
-                                powered_off = True
-                                break
+                        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)
                         else:
                             self.logger.info("Wait for vApp {} to power off".format(vapp_name))
                             time.sleep(INTERVAL_TIME)
@@ -1888,17 +2774,16 @@ class vimconnector(vimconn.vimconnector):
                     wait_time = 0
                     undeployed = False
                     while wait_time <= MAX_WAIT_TIME:
                     wait_time = 0
                     undeployed = False
                     while wait_time <= MAX_WAIT_TIME:
-                        vapp = self.vca.get_vapp(self.get_vdc_details(), vapp_name)
+                        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)
                         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(action='powerOff')
+                        undeploy_task = vapp.undeploy()
 
 
-                        if type(undeploy_task) is GenericTask:
-                            result = self.vca.block_until_completed(undeploy_task)
-                            if result:
-                                undeployed = True
-                                break
+                        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)
                         else:
                             self.logger.debug("Wait for vApp {} to undeploy".format(vapp_name))
                             time.sleep(INTERVAL_TIME)
@@ -1906,47 +2791,52 @@ class vimconnector(vimconn.vimconnector):
                         wait_time +=INTERVAL_TIME
 
                     if not undeployed:
                         wait_time +=INTERVAL_TIME
 
                     if not undeployed:
-                        self.logger.debug("delete_vminstance(): Failed to undeploy vApp {} ".format(vm__vim_uuid)) 
+                        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))
 
                 # delete vapp
                 self.logger.info("Start deletion of vApp {} ".format(vapp_name))
-                vapp = self.vca.get_vapp(self.get_vdc_details(), vapp_name)
 
                 if vapp is not None:
                     wait_time = 0
                     result = False
 
                     while wait_time <= MAX_WAIT_TIME:
 
                 if vapp is not None:
                     wait_time = 0
                     result = False
 
                     while wait_time <= MAX_WAIT_TIME:
-                        vapp = self.vca.get_vapp(self.get_vdc_details(), vapp_name)
+                        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)
 
                         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 = vapp.delete()
+                        delete_task = vdc_obj.delete_vapp(vapp.name, force=True)
 
 
-                        if type(delete_task) is GenericTask:
-                            self.vca.block_until_completed(delete_task)
-                            result = self.vca.block_until_completed(delete_task)
-                            if result:
-                                break
+                        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
 
                         else:
                             self.logger.debug("Wait for vApp {} to delete".format(vapp_name))
                             time.sleep(INTERVAL_TIME)
 
                         wait_time +=INTERVAL_TIME
 
-                    if not result:
+                    if result is None:
                         self.logger.debug("delete_vminstance(): Failed delete uuid {} ".format(vm__vim_uuid))
                         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))
 
         except:
             self.logger.debug(traceback.format_exc())
             raise vimconn.vimconnException("delete_vminstance(): Failed delete vm instance {}".format(vm__vim_uuid))
 
-        if self.vca.get_vapp(self.get_vdc_details(), vapp_name) is None:
-            self.logger.info("Deleted vm instance {} sccessfully".format(vm__vim_uuid))
-            return vm__vim_uuid
-        else:
-            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
 
     def refresh_vms_status(self, vm_list):
         """Get the status of the virtual machines and their interfaces/ports
@@ -1974,51 +2864,95 @@ class vimconnector(vimconn.vimconnector):
 
         self.logger.debug("Client requesting refresh vm status for {} ".format(vm_list))
 
 
         self.logger.debug("Client requesting refresh vm status for {} ".format(vm_list))
 
-        vdc = self.get_vdc_details()
+        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:
         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:
-            vmname = self.get_namebyvappid(self.get_vdc_details(), vmuuid)
-            if vmname is not None:
+            vapp_name = self.get_namebyvappid(vmuuid)
+            if vapp_name is not None:
 
                 try:
                     vm_pci_details = self.get_vm_pci_details(vmuuid)
 
                 try:
                     vm_pci_details = self.get_vm_pci_details(vmuuid)
-                    the_vapp = self.vca.get_vapp(self.get_vdc_details(), vmname)
-                    vm_info = the_vapp.get_vms_details()
-                    vm_status = vm_info[0]['status']
-                    vm_info[0].update(vm_pci_details)
-
-                    vm_dict = {'status': vcdStatusCode2manoFormat[the_vapp.me.get_status()],
-                               'error_msg': vcdStatusCode2manoFormat[the_vapp.me.get_status()],
-                               'vim_info': yaml.safe_dump(vm_info), 'interfaces': []}
-
-                    # get networks
-                    vm_app_networks = the_vapp.get_vms_network_info()
-                    for vapp_network in vm_app_networks:
-                        for vm_network in vapp_network:
-                            if vm_network['name'] == vmname:
-                                #Assign IP Address based on MAC Address in NSX DHCP lease info
-                                if vm_network['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_network['mac'] is not None:
-                                        vm_network['ip'] = self.get_ipaddr_from_NSXedge(nsx_edge_list, vm_network['mac'])
-
-                                vm_net_id = self.get_network_id_by_name(vm_network['network_name'])
-                                interface = {"mac_address": vm_network['mac'],
-                                             "vim_net_id": vm_net_id,
-                                             "vim_interface_id": vm_net_id,
-                                             'ip_address': vm_network['ip']}
-                                # interface['vim_info'] = yaml.safe_dump(vm_network)
-                                vm_dict["interfaces"].append(interface)
+                    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)
                     # 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())
                 except Exception as exp:
                     self.logger.debug("Error in response {}".format(exp))
                     self.logger.debug(traceback.format_exc())
@@ -2129,7 +3063,7 @@ class vimconnector(vimconn.vimconnector):
             self.logger.debug("ParseError in response from NSX Manager {}".format(Err.message), exc_info=True)
 
 
             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):
+    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"""
 
         """Send and action over a VM instance from VIM
         Returns the vm_id if the action was successfully sent to the VIM"""
 
@@ -2137,11 +3071,11 @@ class vimconnector(vimconn.vimconnector):
         if vm__vim_uuid is None or action_dict is None:
             raise vimconn.vimconnException("Invalid request. VM id or action is None.")
 
         if vm__vim_uuid is None or action_dict is None:
             raise vimconn.vimconnException("Invalid request. VM id or action is None.")
 
-        vdc = self.get_vdc_details()
+        org, vdc = self.get_vdc_details()
         if vdc is None:
         if vdc is None:
-            return -1, "Failed to get a reference of VDC for a tenant {}".format(self.tenant_name)
+            raise  vimconn.vimconnException("Failed to get a reference of VDC for a tenant {}".format(self.tenant_name))
 
 
-        vapp_name = self.get_namebyvappid(vdc, vm__vim_uuid)
+        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))
         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))
@@ -2149,46 +3083,47 @@ class vimconnector(vimconn.vimconnector):
             self.logger.info("Action_vminstance vApp {} and UUID {}".format(vapp_name, vm__vim_uuid))
 
         try:
             self.logger.info("Action_vminstance vApp {} and UUID {}".format(vapp_name, vm__vim_uuid))
 
         try:
-            the_vapp = self.vca.get_vapp(vdc, vapp_name)
-            # TODO fix all status
+            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:
             if "start" in action_dict:
-                vm_info = the_vapp.get_vms_details()
-                vm_status = vm_info[0]['status']
                 self.logger.info("action_vminstance: Power on vApp: {}".format(vapp_name))
                 self.logger.info("action_vminstance: Power on vApp: {}".format(vapp_name))
-                if vm_status == "Suspended" or vm_status == "Powered off":
-                    power_on_task = the_vapp.poweron()
-                    result = self.vca.block_until_completed(power_on_task)
-                    self.instance_actions_result("start", result, 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))
             elif "rebuild" in action_dict:
                 self.logger.info("action_vminstance: Rebuild vApp: {}".format(vapp_name))
-                rebuild_task = the_vapp.deploy(powerOn=True)
-                result = self.vca.block_until_completed(rebuild_task)
+                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))
                 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 = the_vapp.undeploy(action='suspend')
-                result = self.vca.block_until_completed(pause_task)
+                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))
                 self.instance_actions_result("pause", result, vapp_name)
             elif "resume" in action_dict:
                 self.logger.info("action_vminstance: resume vApp: {}".format(vapp_name))
-                power_task = the_vapp.poweron()
-                result = self.vca.block_until_completed(power_task)
+                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]
                 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))
                 self.logger.info("action_vminstance: {} vApp: {}".format(action_name, vapp_name))
-                power_off_task = the_vapp.undeploy(action='powerOff')
-                result = self.vca.block_until_completed(power_off_task)
+                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:
                 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 = the_vapp.undeploy(action='force')
+                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))
                 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 = the_vapp.reboot()
+                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
             else:
                 raise vimconn.vimconnException("action_vminstance: Invalid action {} or action is None.".format(action_dict))
             return vm__vim_uuid
@@ -2197,12 +3132,12 @@ class vimconnector(vimconn.vimconnector):
             raise vimconn.vimconnException("action_vminstance: Failed with Exception {}".format(exp))
 
     def instance_actions_result(self, action, result, vapp_name):
             raise vimconn.vimconnException("action_vminstance: Failed with Exception {}".format(exp))
 
     def instance_actions_result(self, action, result, vapp_name):
-        if result:
+        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))
 
             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="vnc"):
+    def get_vminstance_console(self, vm_id, console_type="novnc"):
         """
         Get a console for the virtual machine
         Params:
         """
         Get a console for the virtual machine
         Params:
@@ -2216,7 +3151,57 @@ class vimconnector(vimconn.vimconnector):
                 port:     the http, ssh, ... port
                 suffix:   extra text, e.g. the http path and query string
         """
                 port:     the http, ssh, ... port
                 suffix:   extra text, e.g. the http path and query string
         """
-        raise vimconn.vimconnNotImplemented("Should have implemented this")
+        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
 
 
     # NOT USED METHODS in current version
 
@@ -2310,6 +3295,8 @@ class vimconnector(vimconn.vimconnector):
             if org_dict and 'networks' in org_dict:
                 org_network_dict = org_dict['networks']
                 for net_uuid,net_name in org_network_dict.iteritems():
             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
 
                     if net_name == network_name:
                         return net_uuid
 
@@ -2329,15 +3316,16 @@ class vimconnector(vimconn.vimconnector):
             Returns:
                 The return XML respond
         """
             Returns:
                 The return XML respond
         """
-
-        url_list = [self.vca.host, '/api/org']
+        url_list = [self.url, '/api/org']
         vm_list_rest_call = ''.join(url_list)
 
         vm_list_rest_call = ''.join(url_list)
 
-        if not (not self.vca.vcloud_session or not self.vca.vcloud_session.organization):
-            response = Http.get(url=vm_list_rest_call,
-                                headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+        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 == 403:
                 response = self.retry_rest('GET', vm_list_rest_call)
@@ -2349,11 +3337,11 @@ class vimconnector(vimconn.vimconnector):
 
     def get_org_action(self, org_uuid=None):
         """
 
     def get_org_action(self, org_uuid=None):
         """
-        Method leverages vCloud director and retrieve available object fdr organization.
+        Method leverages vCloud director and retrieve available object for organization.
 
         Args:
 
         Args:
-            vca - is active VCA connection.
-            vdc_name - is a vdc name that will be used to query vms action
+            org_uuid - vCD organization uuid
+            self.client - is active connection.
 
             Returns:
                 The return XML respond
 
             Returns:
                 The return XML respond
@@ -2362,22 +3350,22 @@ class vimconnector(vimconn.vimconnector):
         if org_uuid is None:
             return None
 
         if org_uuid is None:
             return None
 
-        url_list = [self.vca.host, '/api/org/', org_uuid]
+        url_list = [self.url, '/api/org/', org_uuid]
         vm_list_rest_call = ''.join(url_list)
 
         vm_list_rest_call = ''.join(url_list)
 
-        if not (not self.vca.vcloud_session or not self.vca.vcloud_session.organization):
-            response = Http.get(url=vm_list_rest_call,
-                                headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+        if self.client._session:
+            headers = {'Accept':'application/*+xml;version=' + API_VERSION,
+                     'x-vcloud-authorization': self.client._session.headers['x-vcloud-authorization']}
 
 
-            #Retry login if session expired & retry sending request
+            #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
             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):
         return None
 
     def get_org(self, org_uuid=None):
@@ -2465,6 +3453,9 @@ class vimconnector(vimconn.vimconnector):
         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)
         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(),
             if len(refs) == 1:
                 response = Http.get(url=vm_list_rest_call,
                                     headers=vca.vcloud_session.get_vcloud_headers(),
@@ -2606,15 +3597,16 @@ class vimconnector(vimconn.vimconnector):
         if network_uuid is None:
             return None
 
         if network_uuid is None:
             return None
 
-        url_list = [self.vca.host, '/api/network/', network_uuid]
+        url_list = [self.url, '/api/network/', network_uuid]
         vm_list_rest_call = ''.join(url_list)
 
         vm_list_rest_call = ''.join(url_list)
 
-        if not (not self.vca.vcloud_session or not self.vca.vcloud_session.organization):
-            response = Http.get(url=vm_list_rest_call,
-                                headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+        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)
             #Retry login if session expired & retry sending request
             if response.status_code == 403:
                 response = self.retry_rest('GET', vm_list_rest_call)
@@ -2695,22 +3687,21 @@ class vimconnector(vimconn.vimconnector):
             Returns:
                 The return None or XML respond or false
         """
             Returns:
                 The return None or XML respond or false
         """
-
-        vca = self.connect_as_admin()
-        if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+        client = self.connect_as_admin()
+        if not client:
+            raise vimconn.vimconnConnectionException("Failed to connect vCD as admin")
         if network_uuid is None:
             return False
 
         if network_uuid is None:
             return False
 
-        url_list = [vca.host, '/api/admin/network/', network_uuid]
+        url_list = [self.url, '/api/admin/network/', network_uuid]
         vm_list_rest_call = ''.join(url_list)
 
         vm_list_rest_call = ''.join(url_list)
 
-        if not (not vca.vcloud_session or not vca.vcloud_session.organization):
-            response = Http.delete(url=vm_list_rest_call,
-                                   headers=vca.vcloud_session.get_vcloud_headers(),
-                                   verify=vca.verify,
-                                   logger=vca.logger)
-
+        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
 
             if response.status_code == 202:
                 return True
 
@@ -2769,20 +3760,22 @@ class vimconnector(vimconn.vimconnector):
             Returns:
                 The return network uuid or return None
         """
             Returns:
                 The return network uuid or return None
         """
-
-        vca = self.connect_as_admin()
-        if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed.")
+        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
 
         if network_name is None:
             return None
 
-        url_list = [vca.host, '/api/admin/vdc/', self.tenant_id]
+        url_list = [self.url, '/api/admin/vdc/', self.tenant_id]
         vm_list_rest_call = ''.join(url_list)
         vm_list_rest_call = ''.join(url_list)
-        if not (not vca.vcloud_session or not vca.vcloud_session.organization):
-            response = Http.get(url=vm_list_rest_call,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+
+        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
 
             provider_network = None
             available_networks = None
@@ -2809,17 +3802,14 @@ class vimconnector(vimconn.vimconnector):
                     return None
 
             # find  pvdc provided available network
                     return None
 
             # find  pvdc provided available network
-            response = Http.get(url=provider_network,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+            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 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
 
-            # available_networks.split("/")[-1]
-
             if parent_network_uuid is None:
                 try:
                     vm_list_xmlroot = XmlElementTree.fromstring(response.content)
             if parent_network_uuid is None:
                 try:
                     vm_list_xmlroot = XmlElementTree.fromstring(response.content)
@@ -2881,12 +3871,19 @@ class vimconnector(vimconn.vimconnector):
             # 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:
             # 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:
-                url_list = [vca.host, '/api/admin/network/', parent_network_uuid]
+                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)
 
                 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.
             #Creating all networks as Direct Org VDC type networks.
             #Unused in case of Underlay (data/ptp) network interface.
-            fence_mode="bridged"
+            fence_mode="isolated"
             is_inherited='false'
             dns_list = dns_address.split(";")
             dns1 = dns_list[0]
             is_inherited='false'
             dns_list = dns_address.split(";")
             dns1 = dns_list[0]
@@ -2911,41 +3908,34 @@ class vimconnector(vimconn.vimconnector):
                                                 </IpRanges>
                                             </IpScope>
                                         </IpScopes>
                                                 </IpRanges>
                                             </IpScope>
                                         </IpScopes>
-                                        <ParentNetwork href="{9:s}"/>
-                                        <FenceMode>{10:s}</FenceMode>
+                                        <FenceMode>{9:s}</FenceMode>
                                     </Configuration>
                                     </Configuration>
-                                    <IsShared>{11:s}</IsShared>
+                                    <IsShared>{10:s}</IsShared>
                         </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
                                                     subnet_address, dns1, dns2_text, dhcp_enabled,
                         </OrgVdcNetwork> """.format(escape(network_name), is_inherited, gateway_address,
                                                     subnet_address, dns1, dns2_text, dhcp_enabled,
-                                                    dhcp_start_address, dhcp_end_address, available_networks,
+                                                    dhcp_start_address, dhcp_end_address,
                                                     fence_mode, isshared)
 
                                                     fence_mode, isshared)
 
-            headers = vca.vcloud_session.get_vcloud_headers()
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml'
             try:
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.orgVdcNetwork+xml'
             try:
-                response = Http.post(url=add_vdc_rest_url,
-                                     headers=headers,
-                                     data=data,
-                                     verify=vca.verify,
-                                     logger=vca.logger)
+                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:
 
                 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 = networkType.parseString(response.content, True)
-                    create_nw_task = network.get_Tasks().get_Task()[0]
-
-                    # if we all ok we respond with content after network creation completes
-                    # otherwise by default return None
-                    if create_nw_task is not None:
-                        self.logger.debug("Create Network REST : Waiting for Network creation complete")
-                        status = vca.block_until_completed(create_nw_task)
-                        if status:
-                            return response.content
-                        else:
-                            self.logger.debug("create_network_rest task failed. Network Create response : {}"
-                                              .format(response.content))
+                    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))
 
             except Exception as exp:
                 self.logger.debug("create_network_rest : Exception : {} ".format(exp))
 
@@ -2981,11 +3971,13 @@ class vimconnector(vimconn.vimconnector):
                 The return xml content of respond or None
         """
 
                 The return xml content of respond or None
         """
 
-        url_list = [vca.host, '/api/admin']
-        response = Http.get(url=''.join(url_list),
-                            headers=vca.vcloud_session.get_vcloud_headers(),
-                            verify=vca.verify,
-                            logger=vca.logger)
+        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
 
         if response.status_code == requests.codes.ok:
             return response.content
@@ -3012,7 +4004,7 @@ class vimconnector(vimconn.vimconnector):
     def create_vdc_from_tmpl_rest(self, vdc_name=None):
         """
         Method create vdc in vCloud director based on VDC template.
     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 that must be named openmano
+        it uses pre-defined template.
 
         Args:
             vdc_name -  name of a new vdc.
 
         Args:
             vdc_name -  name of a new vdc.
@@ -3020,20 +4012,22 @@ class vimconnector(vimconn.vimconnector):
             Returns:
                 The return xml content of respond or None
         """
             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))
         self.logger.info("Creating new vdc {}".format(vdc_name))
-        vca = self.connect()
+        vca = self.connect_as_admin()
         if not vca:
         if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
         if vdc_name is None:
             return None
 
         if vdc_name is None:
             return None
 
-        url_list = [vca.host, '/api/vdcTemplates']
+        url_list = [self.url, '/api/vdcTemplates']
         vm_list_rest_call = ''.join(url_list)
         vm_list_rest_call = ''.join(url_list)
-        response = Http.get(url=vm_list_rest_call,
-                            headers=vca.vcloud_session.get_vcloud_headers(),
-                            verify=vca.verify,
-                            logger=vca.logger)
+
+        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
 
         # container url to a template
         vdc_template_ref = None
@@ -3056,20 +4050,22 @@ class vimconnector(vimconn.vimconnector):
 
         try:
             # instantiate vdc
 
         try:
             # instantiate vdc
-            url_list = [vca.host, '/api/org/', self.org_uuid, '/action/instantiate']
+            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)
             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 = vca.vcloud_session.get_vcloud_headers()
+
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.instantiateVdcTemplateParams+xml'
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.instantiateVdcTemplateParams+xml'
-            response = Http.post(url=vm_list_rest_call, headers=headers, data=data, verify=vca.verify,
-                                 logger=vca.logger)
 
 
-            vdc_task = taskType.parseString(response.content, True)
-            if type(vdc_task) is GenericTask:
-                self.vca.block_until_completed(vdc_task)
+            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:
 
             # if we all ok we respond with content otherwise by default None
             if response.status_code >= 200 and response.status_code < 300:
@@ -3086,29 +4082,28 @@ class vimconnector(vimconn.vimconnector):
         Method create network in vCloud director
 
         Args:
         Method create network in 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.
-
+            vdc_name - vdc name to be created
             Returns:
             Returns:
-                The return network uuid or return None
+                The return response
         """
 
         self.logger.info("Creating new vdc {}".format(vdc_name))
 
         vca = self.connect_as_admin()
         if not vca:
         """
 
         self.logger.info("Creating new vdc {}".format(vdc_name))
 
         vca = self.connect_as_admin()
         if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
         if vdc_name is None:
             return None
 
         if vdc_name is None:
             return None
 
-        url_list = [vca.host, '/api/admin/org/', self.org_uuid]
+        url_list = [self.url, '/api/admin/org/', self.org_uuid]
         vm_list_rest_call = ''.join(url_list)
         vm_list_rest_call = ''.join(url_list)
-        if not (not vca.vcloud_session or not vca.vcloud_session.organization):
-            response = Http.get(url=vm_list_rest_call,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+
+        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
 
             provider_vdc_ref = None
             add_vdc_rest_url = None
@@ -3158,10 +4153,12 @@ class vimconnector(vimconn.vimconnector):
                                                                                                   escape(vdc_name),
                                                                                                   provider_vdc_ref)
 
                                                                                                   escape(vdc_name),
                                                                                                   provider_vdc_ref)
 
-                    headers = vca.vcloud_session.get_vcloud_headers()
                     headers['Content-Type'] = 'application/vnd.vmware.admin.createVdcParams+xml'
                     headers['Content-Type'] = 'application/vnd.vmware.admin.createVdcParams+xml'
-                    response = Http.post(url=add_vdc_rest_url, headers=headers, data=data, verify=vca.verify,
-                                         logger=vca.logger)
+
+                    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:
 
                     # if we all ok we respond with content otherwise by default None
                     if response.status_code == 201:
@@ -3185,21 +4182,22 @@ class vimconnector(vimconn.vimconnector):
         if need_admin_access:
             vca = self.connect_as_admin()
         else:
         if need_admin_access:
             vca = self.connect_as_admin()
         else:
-            vca = self.vca
+            vca = self.client
 
         if not vca:
 
         if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
         if vapp_uuid is None:
             return None
 
         if vapp_uuid is None:
             return None
 
-        url_list = [vca.host, '/api/vApp/vapp-', vapp_uuid]
+        url_list = [self.url, '/api/vApp/vapp-', vapp_uuid]
         get_vapp_restcall = ''.join(url_list)
 
         get_vapp_restcall = ''.join(url_list)
 
-        if vca.vcloud_session and vca.vcloud_session.organization:
-            response = Http.get(url=get_vapp_restcall,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+        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:
 
             if response.status_code == 403:
                 if need_admin_access == False:
@@ -3309,20 +4307,21 @@ class vimconnector(vimconn.vimconnector):
                 self.logger.info("Error occurred calling rest api for getting vApp details {}".format(exp))
         return parsed_respond
 
                 self.logger.info("Error occurred calling rest api for getting vApp details {}".format(exp))
         return parsed_respond
 
-    def acuire_console(self, vm_uuid=None):
+    def acquire_console(self, vm_uuid=None):
 
         if vm_uuid is None:
             return None
 
         if vm_uuid is None:
             return None
-
-        if not (not self.vca.vcloud_session or not self.vca.vcloud_session.organization):
-            vm_dict = self.get_vapp_details_rest(self, vapp_uuid=vm_uuid)
+        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']
 
             console_dict = vm_dict['acquireTicket']
             console_rest_call = console_dict['href']
 
-            response = Http.post(url=console_rest_call,
-                                 headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                 verify=self.vca.verify,
-                                 logger=self.vca.logger)
+            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 == 403:
                 response = self.retry_rest('POST', console_rest_call)
 
@@ -3384,11 +4383,12 @@ class vimconnector(vimconn.vimconnector):
         if disk_href is None or disk_size is None:
             return None
 
         if disk_href is None or disk_size is None:
             return None
 
-        if self.vca.vcloud_session and self.vca.vcloud_session.organization:
-            response = Http.get(url=disk_href,
-                                headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+        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 == 403:
             response = self.retry_rest('GET', disk_href)
@@ -3400,6 +4400,8 @@ class vimconnector(vimconn.vimconnector):
         try:
             lxmlroot_respond = lxmlElementTree.fromstring(response.content)
             namespaces = {prefix:uri for prefix,uri in lxmlroot_respond.nsmap.iteritems() if prefix}
         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):
             namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
 
             for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces):
@@ -3413,14 +4415,12 @@ class vimconnector(vimconn.vimconnector):
                                              xml_declaration=True)
 
             #Send PUT request to modify disk size
                                              xml_declaration=True)
 
             #Send PUT request to modify disk size
-            headers = self.vca.vcloud_session.get_vcloud_headers()
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'
 
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'
 
-            response = Http.put(url=disk_href,
-                                data=data,
-                                headers=headers,
-                                verify=self.vca.verify, logger=self.logger)
-
+            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 == 403:
                 add_headers = {'Content-Type': headers['Content-Type']}
                 response = self.retry_rest('PUT', disk_href, add_headers, data)
@@ -3429,11 +4429,12 @@ class vimconnector(vimconn.vimconnector):
                 self.logger.debug("PUT REST API call {} failed. Return status code {}".format(disk_href,
                                                                             response.status_code))
             else:
                 self.logger.debug("PUT REST API call {} failed. Return status code {}".format(disk_href,
                                                                             response.status_code))
             else:
-                modify_disk_task = taskType.parseString(response.content, True)
-                if type(modify_disk_task) is GenericTask:
-                    status = self.vca.block_until_completed(modify_disk_task)
-                    return status
-
+                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 :
             return None
 
         except Exception as exp :
@@ -3805,6 +4806,249 @@ class vimconnector(vimconn.vimconnector):
                              " for VM : {}".format(exp))
             raise vimconn.vimconnException(message=exp)
 
                              " 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
     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
@@ -3817,14 +5061,19 @@ class vimconnector(vimconn.vimconnector):
                 None
         """
 
                 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
         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 '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:
             if floating_ip:
                 allocation_mode = "POOL"
             elif ip_address:
@@ -3833,15 +5082,16 @@ class vimconnector(vimconn.vimconnector):
                 allocation_mode = "DHCP"
 
             if not nic_type:
                 allocation_mode = "DHCP"
 
             if not nic_type:
-                for vms in vapp._get_vms():
-                    vm_id = (vms.id).split(':')[-1]
+                for vms in vapp.get_all_vms():
+                    vm_id = vms.get('id').split(':')[-1]
 
 
-                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.vca.host, vm_id)
+                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.url, vm_id)
 
 
-                    response = Http.get(url=url_rest_call,
-                                        headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                        verify=self.vca.verify,
-                                        logger=self.vca.logger)
+                    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 == 403:
                         response = self.retry_rest('GET', url_rest_call)
@@ -3855,7 +5105,9 @@ class vimconnector(vimconn.vimconnector):
                                                                          "network connection section")
 
                     data = response.content
                                                                          "network connection section")
 
                     data = response.content
+                    data = data.split('<Link rel="edit"')[0]
                     if '<PrimaryNetworkConnectionIndex>' not in data:
                     if '<PrimaryNetworkConnectionIndex>' not in data:
+                        self.logger.debug("add_network_adapter PrimaryNIC not in data")
                         item = """<PrimaryNetworkConnectionIndex>{}</PrimaryNetworkConnectionIndex>
                                 <NetworkConnection network="{}">
                                 <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                         item = """<PrimaryNetworkConnectionIndex>{}</PrimaryNetworkConnectionIndex>
                                 <NetworkConnection network="{}">
                                 <NetworkConnectionIndex>{}</NetworkConnectionIndex>
@@ -3868,8 +5120,13 @@ class vimconnector(vimconn.vimconnector):
                             ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                             item =  item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))
 
                             ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                             item =  item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))
 
-                        data = data.replace('</ovf:Info>\n','</ovf:Info>\n{}\n'.format(item))
+                        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:
                     else:
+                        self.logger.debug("add_network_adapter PrimaryNIC in data")
                         new_item = """<NetworkConnection network="{}">
                                     <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                     <IsConnected>true</IsConnected>
                         new_item = """<NetworkConnection network="{}">
                                     <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                     <IsConnected>true</IsConnected>
@@ -3881,13 +5138,18 @@ class vimconnector(vimconn.vimconnector):
                             ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                             new_item =  new_item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))
 
                             ip_tag = '<IpAddress>{}</IpAddress>'.format(ip_address)
                             new_item =  new_item.replace('</NetworkConnectionIndex>\n','</NetworkConnectionIndex>\n{}\n'.format(ip_tag))
 
-                        data = data.replace('</NetworkConnection>\n','</NetworkConnection>\n{}\n'.format(new_item))
+                        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 = self.vca.vcloud_session.get_vcloud_headers()
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'
-                    response = Http.put(url=url_rest_call, headers=headers, data=data,
-                                                                   verify=self.vca.verify,
-                                                                   logger=self.vca.logger)
+
+                    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']}
 
                     if response.status_code == 403:
                         add_headers = {'Content-Type': headers['Content-Type']}
@@ -3901,24 +5163,25 @@ class vimconnector(vimconn.vimconnector):
                         raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                             "network connection section")
                     else:
                         raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                             "network connection section")
                     else:
-                        nic_task = taskType.parseString(response.content, True)
-                        if isinstance(nic_task, GenericTask):
-                            self.vca.block_until_completed(nic_task)
+                        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:
                             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_vms():
-                    vm_id = (vms.id).split(':')[-1]
+                for vms in vapp.get_all_vms():
+                    vm_id = vms.get('id').split(':')[-1]
 
 
-                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.vca.host, vm_id)
+                    url_rest_call = "{}/api/vApp/vm-{}/networkConnectionSection/".format(self.url, vm_id)
 
 
-                    response = Http.get(url=url_rest_call,
-                                        headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                        verify=self.vca.verify,
-                                        logger=self.vca.logger)
+                    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 == 403:
                         response = self.retry_rest('GET', url_rest_call)
@@ -3931,7 +5194,13 @@ class vimconnector(vimconn.vimconnector):
                         raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to get "\
                                                                         "network connection section")
                     data = response.content
                         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:
                     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>
                         item = """<PrimaryNetworkConnectionIndex>{}</PrimaryNetworkConnectionIndex>
                                 <NetworkConnection network="{}">
                                 <NetworkConnectionIndex>{}</NetworkConnectionIndex>
@@ -3939,33 +5208,43 @@ class vimconnector(vimconn.vimconnector):
                                 <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                 <NetworkAdapterType>{}</NetworkAdapterType>
                                 </NetworkConnection>""".format(primary_nic_index, network_name, nicIndex,
                                 <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                 <NetworkAdapterType>{}</NetworkAdapterType>
                                 </NetworkConnection>""".format(primary_nic_index, network_name, nicIndex,
-                                                                               allocation_mode, nic_type)
+                                                                               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))
 
                         # 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))
 
-                        data = data.replace('</ovf:Info>\n','</ovf:Info>\n{}\n'.format(item))
+                        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:
                     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,
                         new_item = """<NetworkConnection network="{}">
                                     <NetworkConnectionIndex>{}</NetworkConnectionIndex>
                                     <IsConnected>true</IsConnected>
                                     <IpAddressAllocationMode>{}</IpAddressAllocationMode>
                                     <NetworkAdapterType>{}</NetworkAdapterType>
                                     </NetworkConnection>""".format(network_name, nicIndex,
-                                                                allocation_mode, nic_type)
+                                                                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))
 
                         # 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))
 
-                        data = data.replace('</NetworkConnection>\n','</NetworkConnection>\n{}\n'.format(new_item))
+                        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 = self.vca.vcloud_session.get_vcloud_headers()
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.networkConnectionSection+xml'
-                    response = Http.put(url=url_rest_call, headers=headers, data=data,
-                                                                   verify=self.vca.verify,
-                                                                   logger=self.vca.logger)
+
+                    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']}
 
                     if response.status_code == 403:
                         add_headers = {'Content-Type': headers['Content-Type']}
@@ -3979,9 +5258,9 @@ class vimconnector(vimconn.vimconnector):
                         raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                            "network connection section")
                     else:
                         raise vimconn.vimconnException("add_network_adapter_to_vms : Failed to update "\
                                                                            "network connection section")
                     else:
-                        nic_task = taskType.parseString(response.content, True)
-                        if isinstance(nic_task, GenericTask):
-                            self.vca.block_until_completed(nic_task)
+                        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.info("add_network_adapter_to_vms(): VM {} "\
                                                "conneced to NIC type {}".format(vm_id, nic_type))
                         else:
@@ -4004,39 +5283,31 @@ class vimconnector(vimconn.vimconnector):
                 return if True
         """
         try:
                 return if True
         """
         try:
-            vm_moref_id , vm_vcenter_host , vm_vcenter_username, vm_vcenter_port = self.get_vcenter_info_rest(vmuuid)
-            if vm_moref_id and vm_vcenter_host and vm_vcenter_username:
-                context = None
-                if hasattr(ssl, '_create_unverified_context'):
-                    context = ssl._create_unverified_context()
-                    vcenter_conect = SmartConnect(host=vm_vcenter_host, user=vm_vcenter_username,
-                                  pwd=self.passwd, port=int(vm_vcenter_port),
-                                  sslContext=context)
-                    atexit.register(Disconnect, vcenter_conect)
-                    content = vcenter_conect.RetrieveContent()
-
-                    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")
+            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))
         except Exception as exp:
             self.logger.error("set_numa_affinity : exception occurred while setting numa affinity "\
                                                        "for VM {} : {}".format(vm_obj, vm_moref_id))
@@ -4078,6 +5349,7 @@ class vimconnector(vimconn.vimconnector):
 
                 self.logger.debug("cloud_init : Guest os customization started..")
                 customize_script = self.format_script(key_pairs=key_pairs, users_list=userdata)
 
                 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.guest_customization(vapp, customize_script)
 
         except Exception as exp:
@@ -4087,8 +5359,7 @@ class vimconnector(vimconn.vimconnector):
                                                                "ssh-key".format(exp))
 
     def format_script(self, key_pairs=[], users_list=[]):
                                                                "ssh-key".format(exp))
 
     def format_script(self, key_pairs=[], users_list=[]):
-        bash_script = """
-        #!/bin/bash
+        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
         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
@@ -4152,11 +5423,49 @@ class vimconnector(vimconn.vimconnector):
         vapp - Vapp object
         customize_script - Customize script to be run at first boot of VM.
         """
         vapp - Vapp object
         customize_script - Customize script to be run at first boot of VM.
         """
-        for vm in vapp._get_vms():
-            vm_name = vm.name
-            task = vapp.customize_guest_os(vm_name, customization_script=customize_script)
-            if isinstance(task, GenericTask):
-                self.vca.block_until_completed(task)
+        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.info("guest_customization : customized guest os task "\
                                              "completed for VM {}".format(vm_name))
             else:
@@ -4212,11 +5521,12 @@ class vimconnector(vimconn.vimconnector):
             Returns: Status of add new disk task
         """
         status = False
             Returns: Status of add new disk task
         """
         status = False
-        if self.vca.vcloud_session and self.vca.vcloud_session.organization:
-            response = Http.get(url=disk_href,
-                                headers=self.vca.vcloud_session.get_vcloud_headers(),
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+        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 == 403:
             response = self.retry_rest('GET', disk_href)
@@ -4229,6 +5539,8 @@ class vimconnector(vimconn.vimconnector):
             #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}
             #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):
             namespaces["xmlns"]= "http://www.vmware.com/vcloud/v1.5"
             instance_id = 0
             for item in lxmlroot_respond.iterfind('xmlns:Item',namespaces):
@@ -4258,13 +5570,12 @@ class vimconnector(vimconn.vimconnector):
             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
             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 = self.vca.vcloud_session.get_vcloud_headers()
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'
 
             headers['Content-Type'] = 'application/vnd.vmware.vcloud.rasdItemsList+xml; charset=ISO-8859-1'
 
-            response = Http.put(url=disk_href,
-                                data=new_data,
-                                headers=headers,
-                                verify=self.vca.verify, logger=self.logger)
+            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']}
 
             if response.status_code == 403:
                 add_headers = {'Content-Type': headers['Content-Type']}
@@ -4274,11 +5585,12 @@ class vimconnector(vimconn.vimconnector):
                 self.logger.error("PUT REST API call {} failed. Return status code {}. Response Content:{}"
                                   .format(disk_href, response.status_code, response.content))
             else:
                 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 = taskType.parseString(response.content, True)
-                if type(add_disk_task) is GenericTask:
-                    status = self.vca.block_until_completed(add_disk_task)
-                    if not status:
-                        self.logger.error("Add new disk REST task failed to add {} MB disk".format(disk_size_mb))
+                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))
 
         except Exception as exp:
             self.logger.error("Error occurred calling rest api for creating new disk {}".format(exp))
@@ -4475,7 +5787,6 @@ class vimconnector(vimconn.vimconnector):
                 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)
                 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:
             return vm_moref_id
 
         except Exception as exp:
@@ -4498,18 +5809,22 @@ class vimconnector(vimconn.vimconnector):
 
         vca = self.connect_as_admin()
         if not vca:
 
         vca = self.connect_as_admin()
         if not vca:
-            raise vimconn.vimconnConnectionException("self.connect() is failed")
+            raise vimconn.vimconnConnectionException("Failed to connect vCD")
 
         try:
 
         try:
+            org, vdc = self.get_vdc_details()
             catalog = self.get_catalog_obj(image_id, catalogs)
             if catalog:
             catalog = self.get_catalog_obj(image_id, catalogs)
             if catalog:
-                template_name = self.get_catalogbyid(image_id, catalogs)
-                catalog_items = filter(lambda catalogItemRef: catalogItemRef.get_name() == template_name, catalog.get_CatalogItems().get_CatalogItem())
+                items = org.get_catalog_item(catalog.get('name'), catalog.get('name'))
+                catalog_items = [items.attrib]
+
                 if len(catalog_items) == 1:
                 if len(catalog_items) == 1:
-                    response = Http.get(catalog_items[0].get_href(),
-                                        headers=vca.vcloud_session.get_vcloud_headers(),
-                                        verify=vca.verify,
-                                        logger=vca.logger)
+                    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")
                     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")
@@ -4524,12 +5839,10 @@ class vimconnector(vimconn.vimconnector):
                                   'xmlns':"http://www.vmware.com/vcloud/v1.5"
                                 }
 
                                   'xmlns':"http://www.vmware.com/vcloud/v1.5"
                                 }
 
-                    if vca.vcloud_session and vca.vcloud_session.organization:
-                        response = Http.get(url=vapp_tempalte_href,
-                                            headers=vca.vcloud_session.get_vcloud_headers(),
-                                            verify=vca.verify,
-                                            logger=vca.logger
-                                            )
+                    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(
 
                         if response.status_code != requests.codes.ok:
                             self.logger.debug("REST API call {} failed. Return status code {}".format(
@@ -4633,7 +5946,7 @@ class vimconnector(vimconn.vimconnector):
                             for sriov_net in sriov_nets:
                                 network_name = sriov_net.get('net_id')
                                 dvs_portgr_name = self.create_dvPort_group(network_name)
                             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":
+                                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)
 
                                     #add vlan ID ,Modify portgroup for vlan ID
                                     self.configure_vlanID(content, vcenter_conect, network_name)
 
@@ -4963,6 +6276,8 @@ class vimconnector(vimconn.vimconnector):
                 self.persistent_info["used_vlanIDs"] = {}
         else:
             used_ids = self.persistent_info["used_vlanIDs"].values()
                 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("-")
 
         for vlanID_range in self.config.get('vlanID_range'):
             start_vlanid , end_vlanid = vlanID_range.split("-")
@@ -4971,6 +6286,8 @@ class vimconnector(vimconn.vimconnector):
                                                                         vlanID_range))
 
             for id in xrange(int(start_vlanid), int(end_vlanid) + 1):
                                                                         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
                 if id not in used_ids:
                     vlan_id = id
                     self.persistent_info["used_vlanIDs"][network_name] = vlan_id
@@ -5002,11 +6319,13 @@ class vimconnector(vimconn.vimconnector):
         vca = self.connect()
         try:
             # fetching catalog details
         vca = self.connect()
         try:
             # fetching catalog details
-            rest_url = "{}/api/catalog/{}".format(vca.host,image_id)
-            response = Http.get(url=rest_url,
-                                headers=vca.vcloud_session.get_vcloud_headers(),
-                                verify=vca.verify,
-                                logger=vca.logger)
+            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 : {}"\
 
             if response.status_code != 200:
                 self.logger.error("REST call {} failed reason : {}"\
@@ -5021,38 +6340,45 @@ class vimconnector(vimconn.vimconnector):
             if iso_name and media_id:
                 data ="""<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                      <ns6:MediaInsertOrEjectParams
             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">
+                     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"
                      <ns6:Media
                         type="application/vnd.vmware.vcloud.media+xml"
-                        name="{}.iso"
+                        name="{}"
                         id="urn:vcloud:media:{}"
                         href="https://{}/api/media/{}"/>
                      </ns6:MediaInsertOrEjectParams>""".format(iso_name, media_id,
                         id="urn:vcloud:media:{}"
                         href="https://{}/api/media/{}"/>
                      </ns6:MediaInsertOrEjectParams>""".format(iso_name, media_id,
-                                                                vca.host,media_id)
+                                                                self.url,media_id)
 
 
-                for vms in vapp._get_vms():
-                    vm_id = (vms.id).split(':')[-1]
+                for vms in vapp.get_all_vms():
+                    vm_id = vms.get('id').split(':')[-1]
 
 
-                    headers = vca.vcloud_session.get_vcloud_headers()
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml'
                     headers['Content-Type'] = 'application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml'
-                    rest_url = "{}/api/vApp/vm-{}/media/action/insertMedia".format(vca.host,vm_id)
+                    rest_url = "{}/api/vApp/vm-{}/media/action/insertMedia".format(self.url,vm_id)
 
 
-                    response = Http.post(url=rest_url,
-                                      headers=headers,
-                                            data=data,
-                                    verify=vca.verify,
-                                    logger=vca.logger)
+                    response = self.perform_request(req_type='POST',
+                                                       url=rest_url,
+                                                          data=data,
+                                                    headers=headers)
 
                     if response.status_code != 202:
 
                     if response.status_code != 202:
-                        self.logger.error("Failed to insert CD-ROM to vm")
-                        raise vimconn.vimconnException("insert_media_to_vm() : Failed to insert"\
-                                                                                    "ISO image to vm")
+                        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:
                     else:
-                        task = taskType.parseString(response.content, True)
-                        if isinstance(task, GenericTask):
-                            vca.block_until_completed(task)
+                        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))
                             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")
         except Exception as exp:
             self.logger.error("insert_media_to_vm() : exception occurred "\
                                             "while inserting media CD-ROM")
@@ -5076,10 +6402,11 @@ class vimconnector(vimconn.vimconnector):
                 if cataloghref_list is not None:
                     for href in cataloghref_list:
                         if href:
                 if cataloghref_list is not None:
                     for href in cataloghref_list:
                         if href:
-                            response = Http.get(url=href,
-                                        headers=vca.vcloud_session.get_vcloud_headers(),
-                                        verify=vca.verify,
-                                        logger=vca.logger)
+                            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,
                             if response.status_code != 200:
                                 self.logger.error("REST call {} failed reason : {}"\
                                              "status code : {}".format(href,
@@ -5118,33 +6445,31 @@ class vimconnector(vimconn.vimconnector):
         #Get token
         self.get_token()
 
         #Get token
         self.get_token()
 
-        headers=self.vca.vcloud_session.get_vcloud_headers()
+        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':
 
         if add_headers:
             headers.update(add_headers)
 
         if method == 'GET':
-            response = Http.get(url=url,
-                                headers=headers,
-                                verify=self.vca.verify,
-                                logger=self.vca.logger)
+            response = self.perform_request(req_type='GET',
+                                            url=url,
+                                            headers=headers)
         elif method == 'PUT':
         elif method == 'PUT':
-            response = Http.put(url=url,
-                                data=data,
-                                headers=headers,
-                                verify=self.vca.verify,
-                                logger=self.logger)
+            response = self.perform_request(req_type='PUT',
+                                            url=url,
+                                            headers=headers,
+                                            data=data)
         elif method == 'POST':
         elif method == 'POST':
-            response = Http.post(url=url,
-                                 headers=headers,
-                                 data=data,
-                                 verify=self.vca.verify,
-                                 logger=self.vca.logger)
+            response = self.perform_request(req_type='POST',
+                                            url=url,
+                                            headers=headers,
+                                            data=data)
         elif method == 'DELETE':
         elif method == 'DELETE':
-            response = Http.delete(url=url,
-                                 headers=headers,
-                                 verify=self.vca.verify,
-                                 logger=self.vca.logger)
+            response = self.perform_request(req_type='DELETE',
+                                            url=url,
+                                            headers=headers)
         return response
 
 
         return response
 
 
@@ -5152,51 +6477,142 @@ class vimconnector(vimconn.vimconnector):
         """ Generate a new token if expired
 
             Returns:
         """ Generate a new token if expired
 
             Returns:
-                The return vca object that letter can be used to connect to vCloud director as admin for VDC
+                The return client object that letter can be used to connect to vCloud director as admin for VDC
         """
         """
-        vca = None
-
         try:
             self.logger.debug("Generate token for vca {} as {} to datacenter {}.".format(self.org_name,
                                                                                       self.user,
                                                                                       self.org_name))
         try:
             self.logger.debug("Generate token for vca {} as {} to datacenter {}.".format(self.org_name,
                                                                                       self.user,
                                                                                       self.org_name))
-            vca = VCA(host=self.url,
-                      username=self.user,
-                      service_type=STANDALONE,
-                      version=VCAVERSION,
-                      verify=False,
-                      log=False)
-
-            result = vca.login(password=self.passwd, org=self.org_name)
-            if result is True:
-                result = vca.login(token=vca.token, org=self.org_name, org_url=vca.vcloud_session.org_url)
-                if result is True:
-                    self.logger.info(
-                        "Successfully generated token for vcloud direct org: {} as user: {}".format(self.org_name, self.user))
-                    #Update vca
-                    self.vca = vca
-                    return
+            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))
 
 
         except:
             raise vimconn.vimconnConnectionException("Can't connect to a vCloud director org: "
                                                      "{} as user: {}".format(self.org_name, self.user))
 
-        if not vca or not result:
-            raise vimconn.vimconnConnectionException("self.connect() is failed while reconnecting")
+        if not client:
+            raise vimconn.vimconnConnectionException("Failed while reconnecting vCD")
 
 
     def get_vdc_details(self):
         """ Get VDC details using pyVcloud Lib
 
 
 
     def get_vdc_details(self):
         """ Get VDC details using pyVcloud Lib
 
-            Returns vdc object
+            Returns org and vdc object
         """
         """
-        vdc = self.vca.get_vdc(self.tenant_name)
+        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()
 
         #Retry once, if failed by refreshing token
         if vdc is None:
             self.get_token()
-            vdc = self.vca.get_vdc(self.tenant_name)
+            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."""
 
 
-        return vdc
+        #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