You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2012/04/19 06:01:07 UTC

svn commit: r1327809 [1/2] - in /libcloud/trunk: ./ libcloud/compute/ libcloud/compute/drivers/ test/compute/ test/compute/fixtures/vcloud_1_5/

Author: tomaz
Date: Thu Apr 19 04:01:06 2012
New Revision: 1327809

URL: http://svn.apache.org/viewvc?rev=1327809&view=rev
Log:
Add support for vCloud 1.5 to the VMware vCloud driver. This patch has been
contributed by Michal Galet and is part of LIBCLOUD-183.

Added:
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalogItem_3132e037_759b_4627_9056_ca66466fa607.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalog_cddb3cb2_3394_4b14_b831_11fbc4028da4.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_network_dca8b667_6c8f_4c3e_be57_7a9425dba4f4.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org_96726c78_4ae3_402f_b08b_7a78c6903d2a.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_sessions.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy_error.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_undeployTest.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_powerOn.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_vapp_8c57a5b6_e61b_48ca_8a78_3b70ee65ef6a_power_action_reset.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_vapp_access_to_resource_forbidden.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0_action_cloneVApp.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vdc_3d9ae28c_1de9_4307_8107_9356ff8ba6d0_action_instantiateVAppTemplate.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/get_api_vApp_vm_dd75d1d3_5b7b_48f0_aff3_69622ab7e045_guestCustomizationSection.xml
    libcloud/trunk/test/compute/fixtures/vcloud_1_5/put_api_vApp_vm_dd75d1d3_5b7b_48f0_aff3_69622ab7e045_guestCustomizationSection.xml
Modified:
    libcloud/trunk/CHANGES
    libcloud/trunk/libcloud/compute/drivers/vcloud.py
    libcloud/trunk/libcloud/compute/providers.py
    libcloud/trunk/test/compute/test_vcloud.py

Modified: libcloud/trunk/CHANGES
URL: http://svn.apache.org/viewvc/libcloud/trunk/CHANGES?rev=1327809&r1=1327808&r2=1327809&view=diff
==============================================================================
--- libcloud/trunk/CHANGES (original)
+++ libcloud/trunk/CHANGES Thu Apr 19 04:01:06 2012
@@ -47,6 +47,11 @@ Changes with Apache Libcloud in developm
     - Add ex_userdata argument to the OpenStack 1.1 driver.
       [Jay Doane]
 
+
+    - Modify Vmware vCloud driver and implement new features
+      for the vCloud version 1.5.
+      [Michal Galet, Sengor Kusturica]
+
   *) Storage
 
     - Large object upload support for CloudFiles driver

Modified: libcloud/trunk/libcloud/compute/drivers/vcloud.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/drivers/vcloud.py?rev=1327809&r1=1327808&r2=1327809&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/drivers/vcloud.py (original)
+++ libcloud/trunk/libcloud/compute/drivers/vcloud.py Thu Apr 19 04:01:06 2012
@@ -15,6 +15,8 @@
 """
 VMware vCloud driver.
 """
+import sys
+import re
 import base64
 from libcloud.utils.py3 import httplib
 from libcloud.utils.py3 import urlparse
@@ -25,6 +27,7 @@ urlparse = urlparse.urlparse
 import time
 
 from xml.etree import ElementTree as ET
+from xml.etree.ElementTree import _ElementInterface
 from xml.parsers.expat import ExpatError
 
 from libcloud.common.base import XmlResponse, ConnectionUserAndKey
@@ -38,10 +41,13 @@ from libcloud.compute.base import NodeSi
 From vcloud api "The VirtualQuantity element defines the number of MB
 of memory. This should be either 512 or a multiple of 1024 (1 GB)."
 """
-VIRTUAL_MEMORY_VALS = [512] + [1024 * i for i in range(1,9)]
+VIRTUAL_MEMORY_VALS = [512] + [1024 * i for i in range(1, 9)]
 
 DEFAULT_TASK_COMPLETION_TIMEOUT = 600
 
+DEFAULT_API_VERSION = '0.8'
+
+
 def fixxpath(root, xpath):
     """ElementTree wants namespaces in its xpaths, so here we add them."""
     namespace, root_tag = root.tag[1:].split("}", 1)
@@ -49,9 +55,19 @@ def fixxpath(root, xpath):
                             for e in xpath.split("/")])
     return fixed_xpath
 
+
 def get_url_path(url):
     return urlparse(url.strip()).path
 
+
+class Vdc:
+    """Virtual datacenter (vDC) representation"""
+    def __init__(self, id, name, driver):
+        self.id = id
+        self.name = name
+        self.driver = driver
+
+
 class InstantiateVAppXML(object):
 
     def __init__(self, name, template, net_href, cpus, memory,
@@ -159,7 +175,7 @@ class InstantiateVAppXML(object):
     def _add_memory(self, parent):
         mem_item = ET.SubElement(
             parent,
-            "Item",
+            'Item',
             {'xmlns': "http://schemas.dmtf.org/ovf/envelope/1"}
         )
         self._add_instance_id(mem_item, '2')
@@ -171,7 +187,7 @@ class InstantiateVAppXML(object):
     def _add_instance_id(self, parent, id):
         elm = ET.SubElement(
             parent,
-            "InstanceID",
+            'InstanceID',
             {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData'}
         )
         elm.text = id
@@ -180,7 +196,7 @@ class InstantiateVAppXML(object):
     def _add_resource_type(self, parent, type):
         elm = ET.SubElement(
             parent,
-            "ResourceType",
+            'ResourceType',
             {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData'}
         )
         elm.text = type
@@ -189,7 +205,7 @@ class InstantiateVAppXML(object):
     def _add_virtual_quantity(self, parent, amount):
         elm = ET.SubElement(
              parent,
-             "VirtualQuantity",
+             'VirtualQuantity',
              {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData'}
          )
         elm.text = amount
@@ -198,16 +214,18 @@ class InstantiateVAppXML(object):
     def _add_network_association(self, parent):
         return ET.SubElement(
             parent,
-            "NetworkAssociation",
+            'NetworkAssociation',
             {'href': self.net_href}
         )
 
+
 class VCloudResponse(XmlResponse):
 
     def success(self):
         return self.status in (httplib.OK, httplib.CREATED,
                                httplib.NO_CONTENT, httplib.ACCEPTED)
 
+
 class VCloudConnection(ConnectionUserAndKey):
     """
     Connection class for the vCloud driver
@@ -231,7 +249,8 @@ class VCloudConnection(ConnectionUserAnd
             'Authorization':
                 "Basic %s"
                 % base64.b64encode(b('%s:%s' % (self.user_id, self.key))),
-            'Content-Length': 0
+            'Content-Length': 0,
+            'Accept': 'application/*+xml'
         }
 
     def _get_auth_token(self):
@@ -256,15 +275,17 @@ class VCloudConnection(ConnectionUserAnd
 
     def add_default_headers(self, headers):
         headers['Cookie'] = self.token
+        headers['Accept'] = 'application/*+xml'
         return headers
 
+
 class VCloudNodeDriver(NodeDriver):
     """
     vCloud node driver
     """
 
     type = Provider.VCLOUD
-    name = "vCloud"
+    name = 'vCloud'
     connectionCls = VCloudConnection
     org = None
     _vdcs = None
@@ -275,29 +296,45 @@ class VCloudNodeDriver(NodeDriver):
                       '3': NodeState.PENDING,
                       '4': NodeState.RUNNING}
 
+    def __new__(cls, key, secret=None, secure=True, host=None, port=None,
+                api_version=DEFAULT_API_VERSION, **kwargs):
+        if cls is VCloudNodeDriver:
+            if api_version == '0.8':
+                cls = VCloudNodeDriver
+            elif api_version == '1.5':
+                cls = VCloud_1_5_NodeDriver
+            else:
+                raise NotImplementedError(
+                    "No VCloudNodeDriver found for API version %s" %
+                    (api_version))
+        return super(VCloudNodeDriver, cls).__new__(cls)
+
     @property
     def vdcs(self):
+        """
+        vCloud virtual data centers (vDCs).
+        @return: C{list} of L{Vdc} objects
+        """
         if not self._vdcs:
-            self.connection.check_org() # make sure the org is set.
+            self.connection.check_org()  # make sure the org is set.  # pylint: disable-msg=E1101
             res = self.connection.request(self.org)
             self._vdcs = [
-                get_url_path(i.get('href'))
+                Vdc(i.get('href'), i.get('name'), self)
                 for i
                 in res.object.findall(fixxpath(res.object, "Link"))
                 if i.get('type') == 'application/vnd.vmware.vcloud.vdc+xml'
             ]
-
         return self._vdcs
 
     @property
     def networks(self):
         networks = []
         for vdc in self.vdcs:
-            res = self.connection.request(vdc).object
+            res = self.connection.request(vdc.id).object
             networks.extend(
                 [network
                  for network in res.findall(
-                     fixxpath(res, "AvailableNetworks/Network")
+                     fixxpath(res, 'AvailableNetwors/Network')
                  )]
             )
 
@@ -309,13 +346,21 @@ class VCloudNodeDriver(NodeDriver):
                           driver=self.connection.driver)
         return image
 
-    def _to_node(self, name, elm):
+    def _to_node(self, elm):
         state = self.NODE_STATE_MAP[elm.get('status')]
+        name = elm.get('name')
         public_ips = []
         private_ips = []
 
         # Following code to find private IPs works for Terremark
-        connections = elm.findall('{http://schemas.dmtf.org/ovf/envelope/1}NetworkConnectionSection/{http://www.vmware.com/vcloud/v0.8}NetworkConnection')
+        connections = elm.findall('%s/%s' % (
+                '{http://schemas.dmtf.org/ovf/envelope/1}NetworkConnectionSection',
+                fixxpath(elm, 'NetworkConnection')
+            )
+        )
+        if not connections:
+            connections = elm.findall(fixxpath(elm, 'Children/Vm/NetworkConnectionSection/NetworkConnection'))
+
         for connection in connections:
             ips = [ip.text
                    for ip
@@ -351,8 +396,13 @@ class VCloudNodeDriver(NodeDriver):
         status = res.object.get('status')
         while status != 'success':
             if status == 'error':
-                raise Exception("Error status returned by task %s."
-                                % task_href)
+                # Get error reason from the response body
+                error_elem = res.object.find(fixxpath(res.object, 'Error'))
+                error_msg = "Unknown error"
+                if error_elem != None:
+                    error_msg = error_elem.get('message')
+                raise Exception("Error status returned by task %s.: %s"
+                                % (task_href, error_msg))
             if status == 'canceled':
                 raise Exception("Canceled status returned by task %s."
                                 % task_href)
@@ -388,18 +438,18 @@ class VCloudNodeDriver(NodeDriver):
             pass
 
         res = self.connection.request(node_path, method='DELETE')
-        return res.status == 202
+        return res.status == httplib.ACCEPTED
 
     def reboot_node(self, node):
         res = self.connection.request('%s/power/action/reset'
                                       % get_url_path(node.id),
                                       method='POST')
-        return res.status == 202 or res.status == 204
+        return res.status in [httplib.ACCEPTED, httplib.NO_CONTENT]
 
     def list_nodes(self):
         nodes = []
         for vdc in self.vdcs:
-            res = self.connection.request(vdc)
+            res = self.connection.request(vdc.id)
             elms = res.object.findall(fixxpath(
                 res.object, "ResourceEntities/ResourceEntity")
             )
@@ -412,14 +462,19 @@ class VCloudNodeDriver(NodeDriver):
             ]
 
             for vapp_name, vapp_href in vapps:
-                res = self.connection.request(
-                    vapp_href,
-                    headers={
-                        'Content-Type':
-                            'application/vnd.vmware.vcloud.vApp+xml'
-                    }
-                )
-                nodes.append(self._to_node(vapp_name, res.object))
+                try:
+                    res = self.connection.request(
+                        vapp_href,
+                        headers={'Content-Type': 'application/vnd.vmware.vcloud.vApp+xml'}
+                    )
+                    nodes.append(self._to_node(res.object))
+                except Exception:
+                    # The vApp was probably removed since the previous vDC query, ignore
+                    e = sys.exc_info()[1]
+                    if not (isinstance(e.args[0], _ElementInterface) and
+                            e.args[0].tag.endswith('Error') and
+                            e.args[0].get('minorErrorCode') == 'ACCESS_TO_RESOURCE_IS_FORBIDDEN'):
+                        raise e
 
         return nodes
 
@@ -472,7 +527,7 @@ class VCloudNodeDriver(NodeDriver):
     def list_images(self, location=None):
         images = []
         for vdc in self.vdcs:
-            res = self.connection.request(vdc).object
+            res = self.connection.request(vdc.id).object
             res_ents = res.findall(fixxpath(
                 res, "ResourceEntities/ResourceEntity")
             )
@@ -494,7 +549,23 @@ class VCloudNodeDriver(NodeDriver):
                         'application/vnd.vmware.vcloud.vAppTemplate+xml'
                 ]
 
-        return images
+        def idfun(image):
+            return image.id
+        return self._uniquer(images, idfun)
+
+    def _uniquer(self, seq, idfun=None):
+        if idfun is None:
+            def idfun(x):
+                return x
+        seen = {}
+        result = []
+        for item in seq:
+            marker = idfun(item)
+            if marker in seen:
+                continue
+            seen[marker] = 1
+            result.append(item)
+        return result
 
     def create_node(self, **kwargs):
         """Creates and returns node.
@@ -550,7 +621,7 @@ class VCloudNodeDriver(NodeDriver):
         # Instantiate VM and get identifier.
         res = self.connection.request(
             '%s/action/instantiateVAppTemplate'
-                % kwargs.get('vdc', self.vdcs[0]),
+                % kwargs.get('vdc', self.vdcs[0].id),
             data=instantiate_xml.tostring(),
             method='POST',
             headers={
@@ -558,7 +629,6 @@ class VCloudNodeDriver(NodeDriver):
                     'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'
             }
         )
-        vapp_name = res.object.get('name')
         vapp_href = get_url_path(res.object.get('href'))
 
         # Deploy the VM from the identifier.
@@ -572,12 +642,13 @@ class VCloudNodeDriver(NodeDriver):
                                       method='POST')
 
         res = self.connection.request(vapp_href)
-        node = self._to_node(vapp_name, res.object)
+        node = self._to_node(res.object)
 
         return node
 
     features = {"create_node": ["password"]}
 
+
 class HostingComConnection(VCloudConnection):
     """
     vCloud connection subclass for Hosting.com
@@ -593,12 +664,14 @@ class HostingComConnection(VCloudConnect
             'Content-Length': 0
         }
 
+
 class HostingComDriver(VCloudNodeDriver):
     """
     vCloud node driver for Hosting.com
     """
     connectionCls = HostingComConnection
 
+
 class TerremarkConnection(VCloudConnection):
     """
     vCloud connection subclass for Terremark
@@ -606,6 +679,7 @@ class TerremarkConnection(VCloudConnecti
 
     host = "services.vcloudexpress.terremark.com"
 
+
 class TerremarkDriver(VCloudNodeDriver):
     """
     vCloud node driver for Terremark
@@ -615,3 +689,422 @@ class TerremarkDriver(VCloudNodeDriver):
 
     def list_locations(self):
         return [NodeLocation(0, "Terremark Texas", 'US', self)]
+
+
+class VCloud_1_5_Connection(VCloudConnection):
+
+    def _get_auth_token(self):
+        if not self.token:
+            # Log In
+            conn = self.conn_classes[self.secure](self.host,
+                                                  self.port)
+            conn.request(method='POST', url='/api/sessions',
+                         headers=self._get_auth_headers())
+
+            resp = conn.getresponse()
+            headers = dict(resp.getheaders())
+
+            # Set authorization token
+            try:
+                self.token = headers['x-vcloud-authorization']
+            except KeyError:
+                raise InvalidCredsError()
+
+            # Get the URL of the Organization
+            body = ET.XML(resp.read())
+            org_name = body.get('org')
+            org_list_url = get_url_path(
+                next((link for link in body.findall(fixxpath(body, 'Link'))
+                    if link.get('type') == 'application/vnd.vmware.vcloud.orgList+xml')).get('href')
+            )
+
+            conn.request(method='GET', url=org_list_url,
+                         headers=self.add_default_headers({}))
+            body = ET.XML(conn.getresponse().read())
+            self.driver.org = get_url_path(
+                next((org for org in body.findall(fixxpath(body, 'Org'))
+                    if org.get('name') == org_name)).get('href')
+            )
+
+    def add_default_headers(self, headers):
+        headers['Accept'] = 'application/*+xml;version=1.5'
+        headers['x-vcloud-authorization'] = self.token
+        return headers
+
+
+class Instantiate_1_5_VAppXML(object):
+    def __init__(self, name, template, network):
+        self.name = name
+        self.template = template
+        self.network = network
+        self._build_xmltree()
+
+    def tostring(self):
+        return ET.tostring(self.root)
+
+    def _build_xmltree(self):
+        self.root = self._make_instantiation_root()
+
+        if self.network:
+            instantionation_params = ET.SubElement(self.root, "InstantiationParams")
+            network_config_section = ET.SubElement(instantionation_params, "NetworkConfigSection")
+            ET.SubElement(network_config_section, "Info", {'xmlns': "http://schemas.dmtf.org/ovf/envelope/1"})
+            network_config = ET.SubElement(network_config_section, "NetworkConfig")
+            self._add_network_association(network_config)
+
+        self._add_vapp_template(self.root)
+
+    def _make_instantiation_root(self):
+        return ET.Element(
+            "InstantiateVAppTemplateParams",
+                {'name': self.name,
+                 'deploy': 'false',
+                 'powerOn': 'false',
+                 'xml:lang': 'en',
+                 'xmlns': "http://www.vmware.com/vcloud/v1.5",
+                 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
+        )
+
+    def _add_vapp_template(self, parent):
+        return ET.SubElement(
+            parent,
+            "Source",
+                {'href': self.template}
+        )
+
+    def _add_network_association(self, parent):
+        parent.set('networkName', self.network.get('name'))
+        configuration = ET.SubElement(parent, 'Configuration')
+        ET.SubElement(configuration, 'ParentNetwork', {'href': self.network.get('href')})
+        configuration.append(self.network.find(fixxpath(self.network, 'Configuration/FenceMode')))
+
+
+class VCloud_1_5_NodeDriver(VCloudNodeDriver):
+
+    connectionCls = VCloud_1_5_Connection
+
+    # Based on http://pubs.vmware.com/vcloud-api-1-5/api_prog/GUID-843BE3AD-5EF6-4442-B864-BCAE44A51867.html
+    NODE_STATE_MAP = {'-1': NodeState.UNKNOWN,
+                      '0': NodeState.PENDING,
+                      '1': NodeState.PENDING,
+                      '2': NodeState.PENDING,
+                      '3': NodeState.PENDING,
+                      '4': NodeState.RUNNING,
+                      '5': NodeState.RUNNING,
+                      '6': NodeState.UNKNOWN,
+                      '7': NodeState.UNKNOWN,
+                      '8': NodeState.TERMINATED,
+                      '9': NodeState.UNKNOWN,
+                      '10': NodeState.UNKNOWN}
+
+    def list_locations(self):
+        return [NodeLocation(id=self.connection.host, name=self.connection.host, country="N/A", driver=self)]
+
+    def ex_find_node(self, node_name, vdcs=None):
+        """
+        Searches for node across specified vDCs. This is more effective than querying all nodes to get a single
+        instance.
+
+        @param node_name: The name of the node to search for
+        @type node_name: C{string}
+
+        @param vdcs: None, vDC or a list of vDCs to search in. If None all vDCs will be searched.
+        @type node_name: L{Vdc}
+
+        @return: C{Node} node instance or None if not found
+        """
+        if not vdcs:
+            vdcs = self.vdcs
+        if not getattr(vdcs, '__iter__', False):
+            vdcs = [vdcs]
+        for vdc in vdcs:
+            res = self.connection.request(vdc.id)
+            entity_elems = res.object.findall(fixxpath(res.object, "ResourceEntities/ResourceEntity"))
+            for entity_elem in entity_elems:
+                if entity_elem.get('type') == 'application/vnd.vmware.vcloud.vApp+xml' and entity_elem.get('name') == node_name:
+                    res = self.connection.request(entity_elem.get('href'),
+                                                  headers={'Content-Type': 'application/vnd.vmware.vcloud.vApp+xml'})
+                    return self._to_node(res.object)
+        return None
+
+    def destroy_node(self, node):
+        try:
+            self.ex_undeploy_node(node)
+        except Exception:
+            # Some vendors don't implement undeploy at all yet,
+            # so catch this and move on.
+            pass
+
+        res = self.connection.request(get_url_path(node.id), method='DELETE')
+        return res.status == httplib.ACCEPTED
+
+    def reboot_node(self, node):
+        res = self.connection.request('%s/power/action/reset'
+                                      % get_url_path(node.id),
+                                      method='POST')
+        if res.status in [httplib.ACCEPTED, httplib.NO_CONTENT]:
+            self._wait_for_task_completion(res.object.get('href'))
+            return True
+        else:
+            return False
+
+    def ex_deploy_node(self, node):
+        """
+        Deploys existing node. Equal to vApp "start" operation.
+
+        @param node: The node to be deployed
+        @type node: L{Node}
+
+        @return: C{Node} deployed node
+        """
+        deploy_xml = ET.Element('DeployVAppParams', {'powerOn': 'true',
+                                                     'xmlns': 'http://www.vmware.com/vcloud/v1.5'})
+        res = self.connection.request('%s/action/deploy' % get_url_path(node.id),
+                                      data=ET.tostring(deploy_xml),
+                                      method='POST',
+                                      headers={
+                                          'Content-Type': 'application/vnd.vmware.vcloud.deployVAppParams+xml'
+                                      })
+        self._wait_for_task_completion(res.object.get('href'))
+        res = self.connection.request(get_url_path(node.id))
+        return self._to_node(res.object)
+
+    def ex_undeploy_node(self, node):
+        """
+        Undeploys existing node. Equal to vApp "stop" operation.
+
+        @param node: The node to be deployed
+        @type node: L{Node}
+
+        @return: C{Node} undeployed node instance
+        """
+        undeploy_xml = ET.Element('UndeployVAppParams', {'xmlns': 'http://www.vmware.com/vcloud/v1.5'})
+        undeploy_power_action_xml = ET.SubElement(undeploy_xml, 'UndeployPowerAction')
+        undeploy_power_action_xml.text = 'shutdown'
+
+        try:
+            res = self.connection.request('%s/action/undeploy' % get_url_path(node.id),
+                                          data=ET.tostring(undeploy_xml),
+                                          method='POST',
+                                          headers={
+                                              'Content-Type': 'application/vnd.vmware.vcloud.undeployVAppParams+xml'
+                                          })
+            self._wait_for_task_completion(res.object.get('href'))
+        except Exception:
+            undeploy_power_action_xml.text = 'powerOff'
+            res = self.connection.request('%s/action/undeploy' % get_url_path(node.id),
+                                          data=ET.tostring(undeploy_xml),
+                                          method='POST',
+                                          headers={
+                                              'Content-Type': 'application/vnd.vmware.vcloud.undeployVAppParams+xml'
+                                          })
+            self._wait_for_task_completion(res.object.get('href'))
+
+        res = self.connection.request(get_url_path(node.id))
+        return self._to_node(res.object)
+
+    def create_node(self, **kwargs):
+        """Creates and returns node. If the source image is:
+           - vApp template - a new vApp is instantiated from template
+           - existing vApp - a new vApp is cloned from the source vApp. Can not clone more vApps is parallel otherwise
+                             resource busy error is raised.
+
+
+        See L{NodeDriver.create_node} for more keyword args.
+
+        @keyword    image:  OS Image to boot on node. (required). Can be a NodeImage or existing Node that will be
+                            cloned.
+        @type       image:  L{NodeImage} or L{Node}
+
+        Non-standard optional keyword arguments:
+        @keyword    ex_network: link to a "Network" e.g., "https://services.vcloudexpress.terremark.com/api/network/7"
+        @type       ex_network: C{string}
+
+        @keyword    ex_vdc: link to a "VDC" e.g., "https://services.vcloudexpress.terremark.com/api/vdc/1"
+        @type       ex_vdc: C{string}
+
+        @keyword    ex_vm_names: list of names to be used as a VM and computer name. The name must be max. 15 characters
+                                 long and follow the host name requirements
+        @type       ex_vm_names: C{list} of L{string}
+
+        """
+        name = kwargs['name']
+        image = kwargs['image']
+        size = kwargs.get('size', None)
+        ex_vm_names = kwargs.get('ex_vm_names')
+
+        self._validate_vm_names(ex_vm_names)
+
+        # Some providers don't require a network link
+        network_href = kwargs.get('ex_network', None)
+        if network_href:
+            network_elem = self.connection.request(network_href).object
+        else:
+            network_elem = None
+
+        vdc = kwargs.get('ex_vdc', self.vdcs[0])
+        if not vdc:
+            vdc = self.vdcs[0]
+
+        if self._is_node(image):
+            vapp_name, vapp_href = self._clone_node(name, image, vdc)
+        else:
+            vapp_name, vapp_href = self._instantiate_node(name, image, network_elem, vdc)
+
+        self._change_vm_names(vapp_href, ex_vm_names)
+
+        # Power on the VM.
+        # Retry 3 times: when instantiating large number of VMs at the same time some may fail on resource allocation
+        retry = 3
+        while True:
+            try:
+                res = self.connection.request('%s/power/action/powerOn' % vapp_href,
+                                              method='POST')
+                self._wait_for_task_completion(res.object.get('href'))
+                break
+            except Exception:
+                if retry <= 0:
+                    raise
+                retry -= 1
+                time.sleep(10)
+
+        res = self.connection.request(vapp_href)
+        node = self._to_node(res.object)
+
+        return node
+
+    def _instantiate_node(self, name, image, network_elem, vdc):
+        instantiate_xml = Instantiate_1_5_VAppXML(
+            name=name,
+            template=image.id,
+            network=network_elem
+        )
+
+        # Instantiate VM and get identifier.
+        res = self.connection.request(
+            '%s/action/instantiateVAppTemplate' % vdc.id,
+            data=instantiate_xml.tostring(),
+            method='POST',
+            headers={
+                'Content-Type':
+                    'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'
+            }
+        )
+        vapp_name = res.object.get('name')
+        vapp_href = get_url_path(res.object.get('href'))
+
+        task_href = res.object.find(fixxpath(res.object, "Tasks/Task")).get('href')
+        self._wait_for_task_completion(task_href)
+        return vapp_name, vapp_href
+
+    def _clone_node(self, name, sourceNode, vdc):
+
+        clone_xml = ET.Element("CloneVAppParams",
+                {'name': name, 'deploy': 'false', 'powerOn': 'false',
+                 'xmlns': "http://www.vmware.com/vcloud/v1.5",
+                 'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance"}
+        )
+        ET.SubElement(clone_xml, 'Description').text = 'Clone of ' + sourceNode.name
+        ET.SubElement(clone_xml, 'Source', {'href': sourceNode.id})
+
+        res = self.connection.request(
+            '%s/action/cloneVApp' % vdc.id,
+            data=ET.tostring(clone_xml),
+            method='POST',
+            headers={
+                'Content-Type':
+                    'application/vnd.vmware.vcloud.cloneVAppParams+xml'
+            }
+        )
+        vapp_name = res.object.get('name')
+        vapp_href = get_url_path(res.object.get('href'))
+
+        task_href = res.object.find(fixxpath(res.object, "Tasks/Task")).get('href')
+        self._wait_for_task_completion(task_href)
+
+        res = self.connection.request(vapp_href)
+
+        vms = res.object.findall(fixxpath(res.object, "Children/Vm"))
+
+        # Fix the networking for VMs
+        for i, vm in enumerate(vms):
+            # Remove network
+            network_xml = ET.Element("NetworkConnectionSection", {
+                'ovf:required': 'false',
+                'xmlns': "http://www.vmware.com/vcloud/v1.5",
+                'xmlns:ovf': 'http://schemas.dmtf.org/ovf/envelope/1'})
+            ET.SubElement(network_xml, "ovf:Info").text = 'Specifies the available VM network connections'
+            res = self.connection.request('%s/networkConnectionSection' % get_url_path(vm.get('href')),
+                                          data=ET.tostring(network_xml),
+                                          method='PUT',
+                                          headers={'Content-Type': 'application/vnd.vmware.vcloud.networkConnectionSection+xml'}
+            )
+            self._wait_for_task_completion(res.object.get('href'))
+
+            # Re-add network
+            network_xml = vm.find(fixxpath(vm, 'NetworkConnectionSection'))
+            network_conn_xml = network_xml.find(fixxpath(network_xml, 'NetworkConnection'))
+            network_conn_xml.set('needsCustomization', 'true')
+            network_conn_xml.remove(network_conn_xml.find(fixxpath(network_xml, 'IpAddress')))
+            network_conn_xml.remove(network_conn_xml.find(fixxpath(network_xml, 'MACAddress')))
+
+            res = self.connection.request('%s/networkConnectionSection' % get_url_path(vm.get('href')),
+                                          data=ET.tostring(network_xml),
+                                          method='PUT',
+                                          headers={'Content-Type': 'application/vnd.vmware.vcloud.networkConnectionSection+xml'}
+            )
+            self._wait_for_task_completion(res.object.get('href'))
+
+        return vapp_name, vapp_href
+
+    @staticmethod
+    def _validate_vm_names(names):
+        if names is None:
+            return
+        hname_re = re.compile('^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9]*)[\-])*([A-Za-z]|[A-Za-z][A-Za-z0-9]*[A-Za-z0-9])$')
+        for name in names:
+            if len(name) > 15:
+                raise ValueError('The VM name "' + name + '" is too long for the computer name (max 15 chars allowed).')
+            if not hname_re.match(name):
+                raise ValueError('The VM name "' + name + '" can not be used. "' + name + '" is not a valid computer name for the VM.')
+
+    def _change_vm_names(self, vapp_href, vm_names):
+        if vm_names is None:
+            return
+
+        res = self.connection.request(vapp_href)
+        vms = res.object.findall(fixxpath(res.object, "Children/Vm"))
+
+        for i, vm in enumerate(vms):
+            if len(vm_names) <= i:
+                return
+
+            # Get GuestCustomizationSection
+            res = self.connection.request('%s/guestCustomizationSection' % get_url_path(vm.get('href')))
+
+            # Update GuestCustomizationSection
+            res.object.find(fixxpath(res.object, 'ComputerName')).text = vm_names[i]
+            # Remove AdminPassword from customization section
+            admin_pass = res.object.find(fixxpath(res.object, 'AdminPassword'))
+            if admin_pass is not None:
+                res.object.remove(admin_pass)
+            res = self.connection.request('%s/guestCustomizationSection' % get_url_path(vm.get('href')),
+                                          data=ET.tostring(res.object),
+                                          method='PUT',
+                                          headers={'Content-Type': 'application/vnd.vmware.vcloud.guestCustomizationSection+xml'}
+            )
+            self._wait_for_task_completion(res.object.get('href'))
+
+            # Update Vm name
+            req_xml = ET.Element("Vm", {
+                'name': vm_names[i],
+                'xmlns': "http://www.vmware.com/vcloud/v1.5"})
+            res = self.connection.request(get_url_path(vm.get('href')),
+                                          data=ET.tostring(req_xml),
+                                          method='PUT',
+                                          headers={'Content-Type': 'application/vnd.vmware.vcloud.vm+xml'}
+            )
+            self._wait_for_task_completion(res.object.get('href'))
+
+    def _is_node(self, node_or_image):
+        return isinstance(node_or_image, Node)

Modified: libcloud/trunk/libcloud/compute/providers.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/compute/providers.py?rev=1327809&r1=1327808&r2=1327809&view=diff
==============================================================================
--- libcloud/trunk/libcloud/compute/providers.py (original)
+++ libcloud/trunk/libcloud/compute/providers.py Thu Apr 19 04:01:06 2012
@@ -101,6 +101,8 @@ DRIVERS = {
         ('libcloud.compute.drivers.openstack', 'OpenStackNodeDriver'),
     Provider.NINEFOLD:
         ('libcloud.compute.drivers.ninefold', 'NinefoldNodeDriver'),
+    Provider.VCLOUD:
+        ('libcloud.compute.drivers.vcloud', 'VCloudNodeDriver'),
     Provider.TERREMARK:
         ('libcloud.compute.drivers.vcloud', 'TerremarkDriver'),
     Provider.CLOUDSTACK:

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalogItem_3132e037_759b_4627_9056_ca66466fa607.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalogItem_3132e037_759b_4627_9056_ca66466fa607.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalogItem_3132e037_759b_4627_9056_ca66466fa607.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalogItem_3132e037_759b_4627_9056_ca66466fa607.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,7 @@
+<CatalogItem name="VMMasterTemplate" id="urn:vcloud:catalogitem:3132e037-759b-4627-9056-ca66466fa607" type="application/vnd.vmware.vcloud.catalogItem+xml" href="https://vm-vcloud/api/catalogItem/3132e037-759b-4627-9056-ca66466fa607" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Link rel="up" type="application/vnd.vmware.vcloud.catalog+xml" href="https://vm-vcloud/api/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/catalogItem/3132e037-759b-4627-9056-ca66466fa607/metadata"/>
+   <Link rel="edit" type="application/vnd.vmware.vcloud.catalogItem+xml" href="https://vm-vcloud/api/catalogItem/3132e037-759b-4627-9056-ca66466fa607"/>
+   <Link rel="remove" href="https://vm-vcloud/api/catalogItem/3132e037-759b-4627-9056-ca66466fa607"/>
+   <Entity type="application/vnd.vmware.vcloud.vAppTemplate+xml" name="ScrumVM_Master" href="https://vm-vcloud/api/vAppTemplate/vappTemplate-ac1bc027-bf8c-4050-8643-4971f691c158"/>
+</CatalogItem>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalog_cddb3cb2_3394_4b14_b831_11fbc4028da4.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalog_cddb3cb2_3394_4b14_b831_11fbc4028da4.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalog_cddb3cb2_3394_4b14_b831_11fbc4028da4.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_catalog_cddb3cb2_3394_4b14_b831_11fbc4028da4.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,9 @@
+<Catalog name="Dev" id="urn:vcloud:catalog:cddb3cb2-3394-4b14-b831-11fbc4028da4" type="application/vnd.vmware.vcloud.catalog+xml" href="https://vm-vcloud/api/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Link rel="up" type="application/vnd.vmware.vcloud.org+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+   <Link rel="add" type="application/vnd.vmware.vcloud.catalogItem+xml" href="https://vm-vcloud/api/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4/catalogItems"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4/metadata"/>
+   <CatalogItems>
+      <CatalogItem type="application/vnd.vmware.vcloud.catalogItem+xml" name="VMMasterTemplate" href="https://vm-vcloud/api/catalogItem/3132e037-759b-4627-9056-ca66466fa607"/>
+   </CatalogItems>
+   <IsPublished>false</IsPublished>
+</Catalog>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_network_dca8b667_6c8f_4c3e_be57_7a9425dba4f4.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_network_dca8b667_6c8f_4c3e_be57_7a9425dba4f4.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_network_dca8b667_6c8f_4c3e_be57_7a9425dba4f4.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_network_dca8b667_6c8f_4c3e_be57_7a9425dba4f4.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,49 @@
+<OrgNetwork name="vCloud - Default" id="urn:vcloud:network:dca8b667-6c8f-4c3e-be57-7a9425dba4f4" type="application/vnd.vmware.vcloud.orgNetwork+xml" href="https://vm-vcloud/api/network/dca8b667-6c8f-4c3e-be57-7a9425dba4f4" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Link rel="up" type="application/vnd.vmware.vcloud.org+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+    <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/network/dca8b667-6c8f-4c3e-be57-7a9425dba4f4/metadata"/>
+    <Description/>
+    <Configuration>
+        <IpScope>
+            <IsInherited>true</IsInherited>
+            <Gateway>65.41.64.1</Gateway>
+            <Netmask>255.255.252.0</Netmask>
+            <Dns1>65.41.42.113</Dns1>
+            <Dns2>65.41.42.114</Dns2>
+            <DnsSuffix>vm.netsuite.com</DnsSuffix>
+            <IpRanges>
+                <IpRange>
+                    <StartAddress>65.41.65.1</StartAddress>
+                    <EndAddress>65.41.65.64</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.65.70</StartAddress>
+                    <EndAddress>65.41.65.88</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.65.90</StartAddress>
+                    <EndAddress>65.41.66.6</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.66.8</StartAddress>
+                    <EndAddress>65.41.66.67</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.66.69</StartAddress>
+                    <EndAddress>65.41.66.108</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.66.110</StartAddress>
+                    <EndAddress>65.41.66.227</EndAddress>
+                </IpRange>
+                <IpRange>
+                    <StartAddress>65.41.66.229</StartAddress>
+                    <EndAddress>65.41.67.254</EndAddress>
+                </IpRange>
+            </IpRanges>
+        </IpScope>
+        <FenceMode>bridged</FenceMode>
+        <RetainNetInfoAcrossDeployments>false</RetainNetInfoAcrossDeployments>
+        <SyslogServerSettings/>
+    </Configuration>
+    <AllowedExternalIpAddresses/>
+</OrgNetwork>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,3 @@
+<OrgList type="application/vnd.vmware.vcloud.orgList+xml" href="https://vm-vcloud/api/org/" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Org type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+</OrgList>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org_96726c78_4ae3_402f_b08b_7a78c6903d2a.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org_96726c78_4ae3_402f_b08b_7a78c6903d2a.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org_96726c78_4ae3_402f_b08b_7a78c6903d2a.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_org_96726c78_4ae3_402f_b08b_7a78c6903d2a.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,11 @@
+<Org name="MyOrg" id="urn:vcloud:org:96726c78-4ae3-402f-b08b-7a78c6903d2a" type="application/vnd.vmware.vcloud.org+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Link rel="down" type="application/vnd.vmware.vcloud.vdc+xml" name="MyOrg" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.tasksList+xml" href="https://vm-vcloud/api/tasksList/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.catalog+xml" name="NS-Dev" href="https://vm-vcloud/api/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4/controlAccess/"/>
+   <Link rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a/catalog/cddb3cb2-3394-4b14-b831-11fbc4028da4/action/controlAccess"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.orgNetwork+xml" name="vCloud - Default" href="https://vm-vcloud/api/network/dca8b667-6c8f-4c3e-be57-7a9425dba4f4"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a/metadata"/>
+   <Description/>
+   <FullName>MyOrg Product Development</FullName>
+</Org>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_sessions.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_sessions.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_sessions.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_sessions.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,9 @@
+<Session user="a" org="MyOrg" type="application/vnd.vmware.vcloud.session+xml" href="https://vm-vcloud/api/session/"
+		 xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd"
+		 xmlns="http://www.vmware.com/vcloud/v1.5"
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Link rel="down" type="application/vnd.vmware.vcloud.orgList+xml" href="https://vm-vcloud/api/org/"/>
+   <Link rel="down" type="application/vnd.vmware.admin.vcloud+xml" href="https://vm-vcloud/api/admin/"/>
+   <Link rel="down" type="application/vnd.vmware.vcloud.query.queryList+xml" href="https://vm-vcloud/api/query"/>
+   <Link rel="entityResolver" type="application/vnd.vmware.vcloud.entity+xml" href="https://vm-vcloud/api/entity/"/>
+</Session>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_b034df55_fe81_4798_bc81_1f0fd0ead450.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,9 @@
+<Task status="success" startTime="2011-12-20T10:27:39.678-05:00" operationName="resetVapp"
+      operation="Reset Virtual Application" expiryTime="2012-03-19T10:27:39.678-04:00"
+      endTime="2011-12-20T10:27:46.630-05:00" name="task"
+      id="urn:vcloud:task:b034df55-fe81-4798-bc81-1f0fd0ead450" type="application/vnd.vmware.vcloud.task+xml" href="https://vm-vcloud/api/task/b034df55-fe81-4798-bc81-1f0fd0ead450" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Owner type="application/vnd.vmware.vcloud.vApp+xml" name="" href="https://vm-vcloud/api/vApp/vapp-0d647cbf-867e-442d-8d2d-d0c2d235fbdf"/>
+    <User type="application/vnd.vmware.admin.user+xml" name="labmanapi" href="https://vm-vcloud/api/admin/user/46f62cc3-65e0-4417-967a-a538ec6caea3"/>
+    <Organization type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+	<Progress>100</Progress>
+</Task>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,7 @@
+<Task status="success" startTime="2012-01-11T04:11:06.125-05:00" operationName="vappUndeployPowerOff" operation="Stopping Virtual Application (b0331206-dcc4-4874-b90a-351ff6502124)" expiryTime="2012-04-10T04:11:06.125-04:00" name="task" id="urn:vcloud:task:54516828-af1e-4723-9a0e-7783b0065d39" type="application/vnd.vmware.vcloud.task+xml"
+      href="https://vm-vcloud/api/task/undeploy" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Link rel="task:cancel" href="https://vm-vcloud/api/task/54516828-af1e-4723-9a0e-7783b0065d39/action/cancel"/>
+    <Owner type="application/vnd.vmware.vcloud.vApp+xml" name="" href="https://vm-vcloud/api/vApp/vapp-b0331206-dcc4-4874-b90a-351ff6502124"/>
+    <User type="application/vnd.vmware.admin.user+xml" name="labmanapi" href="https://vm-vcloud/api/admin/user/46f62cc3-65e0-4417-967a-a538ec6caea3"/>
+    <Organization type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+</Task>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy_error.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy_error.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy_error.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_task_undeploy_error.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,7 @@
+<Task status="error" startTime="2012-02-07T05:25:54.910-05:00" operationName="vappUndeployPowerOff" operation="Stopped Virtual Application null(21e95e3f-3e62-4d9e-9aa1-c2204fd79772)" expiryTime="2012-05-07T05:25:54.910-04:00" endTime="2012-02-07T05:25:55.416-05:00" name="task" id="urn:vcloud:task:7c31af92-fe70-4455-a33d-1740f17c5efa" type="application/vnd.vmware.vcloud.task+xml"
+      href="https://vm-vcloud/api/task/undeployError" xsi:schemaLocation="http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+   <Owner type="application/vnd.vmware.vcloud.vApp+xml" href="https://vm-vcloud/api/vApp/vapp-21e95e3f-3e62-4d9e-9aa1-c2204fd79772"/>
+   <Error minorErrorCode="INTERNAL_SERVER_ERROR" message="Error in powering off or suspending virtual machines. Contact the Administrator if the problem persists.  - MultipleExceptions have occurred  - Error on power off or suspend.  - Failed to shutdown guest os for the VM &quot;tc-megamainline (388a8e0b-a91d-4893-b5b8-f7b294a56d30)&quot; as required VM tools were found unavailable.  - Cannot complete operation because VMware Tools is not running in this virtual machine.  - Error on power off or suspend.  - Failed to shutdown guest os for the VM &quot;tc-megamainline (388a8e0b-a91d-4893-b5b8-f7b294a56d30)&quot; as required VM tools were found unavailable.  - Cannot complete operation because VMware Tools is not running in this virtual machine." majorErrorCode="500"/>
+   <User type="application/vnd.vmware.admin.user+xml" name="labmanapi" href="https://vm-vcloud/api/admin/user/46f62cc3-65e0-4417-967a-a538ec6caea3"/>
+   <Organization type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+</Task>
\ No newline at end of file

Added: libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_undeployTest.xml
URL: http://svn.apache.org/viewvc/libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_undeployTest.xml?rev=1327809&view=auto
==============================================================================
--- libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_undeployTest.xml (added)
+++ libcloud/trunk/test/compute/fixtures/vcloud_1_5/api_vApp_undeployTest.xml Thu Apr 19 04:01:06 2012
@@ -0,0 +1,271 @@
+<VApp deployed="false" status="8" name="undeployTest" id="urn:vcloud:vapp:8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a" xsi:schemaLocation="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_VirtualSystemSettingData.xsd http://schemas.dmtf.org/ovf/envelope/1 http://schemas.dmtf.org/ovf/envelope/1/dsp8023_1.1.0.xsd http://www.vmware.com/vcloud/v1.5 http://65.41.64.27/api/v1.5/schema/master.xsd http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2.22.0/CIM_ResourceAllocationSettingData.xsd" xmlns="http://www.vmware.com/vcloud/v1.5" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schem
 as.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <Link rel="power:powerOn" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/power/action/powerOn"/>
+    <Link rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/action/deploy"/>
+    <Link rel="down" type="application/vnd.vmware.vcloud.vAppNetwork+xml" name="vCloud - Default" href="https://vm-vcloud/api/network/da178ef6-b21b-4f19-816e-798a294d2b22"/>
+    <Link rel="down" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/controlAccess/"/>
+    <Link rel="controlAccess" type="application/vnd.vmware.vcloud.controlAccess+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/action/controlAccess"/>
+    <Link rel="recompose" type="application/vnd.vmware.vcloud.recomposeVAppParams+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/action/recomposeVApp"/>
+    <Link rel="up" type="application/vnd.vmware.vcloud.vdc+xml" href="https://vm-vcloud/api/vdc/3d9ae28c-1de9-4307-8107-9356ff8ba6d0"/>
+    <Link rel="edit" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a"/>
+    <Link rel="remove" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a"/>
+    <Link rel="down" type="application/vnd.vmware.vcloud.owner+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/owner"/>
+    <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/metadata"/>
+    <Description/>
+    <Tasks>
+        <Task status="error" startTime="2012-01-16T11:05:15.687-05:00" operationName="vappDeploy" operation="Running Virtual Application mgalet-test2(8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a)" expiryTime="2012-04-15T11:05:15.687-04:00" endTime="2012-01-16T11:05:15.913-05:00" name="task" id="urn:vcloud:task:9eafc5d0-60b3-4a59-a721-f11ca4695e3e" type="application/vnd.vmware.vcloud.task+xml" href="https://vm-vcloud/api/task/9eafc5d0-60b3-4a59-a721-f11ca4695e3e">
+            <Owner type="application/vnd.vmware.vcloud.vApp+xml" name="mgalet-test2" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a"/>
+            <Error minorErrorCode="BAD_REQUEST" message="There are insufficient CPU or memory resources to complete the operation." majorErrorCode="400"/>
+            <User type="application/vnd.vmware.admin.user+xml" name="mgalet" href="https://vm-vcloud/api/admin/user/a0d29e8e-2b32-4739-ab7d-6a3e795be4db"/>
+            <Organization type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+        </Task>
+        <Task status="error" startTime="2012-01-16T11:05:31.984-05:00" operationName="vappDeploy" operation="Running Virtual Application mgalet-test2(8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a)" expiryTime="2012-04-15T11:05:31.984-04:00" endTime="2012-01-16T11:05:32.208-05:00" name="task" id="urn:vcloud:task:b4fe0c19-bfac-4f68-9f0b-2955efe4a486" type="application/vnd.vmware.vcloud.task+xml" href="https://vm-vcloud/api/task/b4fe0c19-bfac-4f68-9f0b-2955efe4a486">
+            <Owner type="application/vnd.vmware.vcloud.vApp+xml" name="mgalet-test2" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a"/>
+            <Error minorErrorCode="BAD_REQUEST" message="There are insufficient CPU or memory resources to complete the operation." majorErrorCode="400"/>
+            <User type="application/vnd.vmware.admin.user+xml" name="mgalet" href="https://vm-vcloud/api/admin/user/a0d29e8e-2b32-4739-ab7d-6a3e795be4db"/>
+            <Organization type="application/vnd.vmware.vcloud.org+xml" name="MyOrg" href="https://vm-vcloud/api/org/96726c78-4ae3-402f-b08b-7a78c6903d2a"/>
+        </Task>
+    </Tasks>
+    <LeaseSettingsSection type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/leaseSettingsSection/" ovf:required="false">
+        <ovf:Info>Lease settings section</ovf:Info>
+        <Link rel="edit" type="application/vnd.vmware.vcloud.leaseSettingsSection+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/leaseSettingsSection/"/>
+        <DeploymentLeaseInSeconds>0</DeploymentLeaseInSeconds>
+        <StorageLeaseInSeconds>0</StorageLeaseInSeconds>
+    </LeaseSettingsSection>
+    <ovf:StartupSection vcloud:href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/startupSection/" vcloud:type="application/vnd.vmware.vcloud.startupSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
+        <ovf:Info>VApp startup section</ovf:Info>
+        <ovf:Item ovf:stopDelay="0" ovf:stopAction="powerOff" ovf:startDelay="0" ovf:startAction="powerOn" ovf:order="0" ovf:id="mgalet-test2"/>
+        <Link rel="edit" type="application/vnd.vmware.vcloud.startupSection+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/startupSection/"/>
+    </ovf:StartupSection>
+    <ovf:NetworkSection vcloud:href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/networkSection/" vcloud:type="application/vnd.vmware.vcloud.networkSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
+        <ovf:Info>The list of logical networks</ovf:Info>
+        <ovf:Network ovf:name="vCloud - Default">
+            <ovf:Description/>
+        </ovf:Network>
+    </ovf:NetworkSection>
+    <NetworkConfigSection type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/networkConfigSection/" ovf:required="false">
+        <ovf:Info>The configuration parameters for logical networks</ovf:Info>
+        <Link rel="edit" type="application/vnd.vmware.vcloud.networkConfigSection+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a/networkConfigSection/"/>
+        <NetworkConfig networkName="vCloud - Default">
+            <Link rel="repair" href="https://vm-vcloud/api/admin/network/da178ef6-b21b-4f19-816e-798a294d2b22/action/reset"/>
+            <Description/>
+            <Configuration>
+                <IpScope>
+                    <IsInherited>true</IsInherited>
+                    <Gateway>65.41.64.1</Gateway>
+                    <Netmask>255.255.252.0</Netmask>
+                    <Dns1>65.41.42.113</Dns1>
+                    <Dns2>65.41.42.114</Dns2>
+                    <DnsSuffix>vm.myorg.com</DnsSuffix>
+                    <IpRanges>
+                        <IpRange>
+                            <StartAddress>65.41.67.1</StartAddress>
+                            <EndAddress>65.41.67.254</EndAddress>
+                        </IpRange>
+                    </IpRanges>
+                </IpScope>
+                <ParentNetwork type="application/vnd.vmware.vcloud.network+xml" name="vCloud - Default" href="https://vm-vcloud/api/network/dca8b667-6c8f-4c3e-be57-7a9425dba4f4"/>
+                <FenceMode>bridged</FenceMode>
+                <RetainNetInfoAcrossDeployments>false</RetainNetInfoAcrossDeployments>
+                <Features>
+                    <DhcpService>
+                        <IsEnabled>false</IsEnabled>
+                        <DefaultLeaseTime>3600</DefaultLeaseTime>
+                        <MaxLeaseTime>7200</MaxLeaseTime>
+                        <IpRange>
+                            <StartAddress>65.41.64.2</StartAddress>
+                            <EndAddress>65.41.67.0</EndAddress>
+                        </IpRange>
+                    </DhcpService>
+                    <FirewallService>
+                        <IsEnabled>true</IsEnabled>
+                        <DefaultAction>drop</DefaultAction>
+                        <LogDefaultAction>false</LogDefaultAction>
+                        <FirewallRule>
+                            <IsEnabled>true</IsEnabled>
+                            <Description>Allow all outgoing traffic</Description>
+                            <Policy>allow</Policy>
+                            <Protocols>
+                                <Any>true</Any>
+                            </Protocols>
+                            <Port>-1</Port>
+                            <DestinationIp>Any</DestinationIp>
+                            <SourcePort>-1</SourcePort>
+                            <SourceIp>Any</SourceIp>
+                            <Direction>out</Direction>
+                            <EnableLogging>false</EnableLogging>
+                        </FirewallRule>
+                    </FirewallService>
+                    <NatService>
+                        <IsEnabled>true</IsEnabled>
+                        <NatType>ipTranslation</NatType>
+                        <Policy>allowTraffic</Policy>
+                        <NatRule>
+                            <OneToOneVmRule>
+                                <MappingMode>automatic</MappingMode>
+                                <VAppScopedVmId>ScrumVM_Master</VAppScopedVmId>
+                                <VmNicId>0</VmNicId>
+                            </OneToOneVmRule>
+                        </NatRule>
+                    </NatService>
+                    <StaticRoutingService>
+                        <IsEnabled>false</IsEnabled>
+                    </StaticRoutingService>
+                </Features>
+                <SyslogServerSettings/>
+            </Configuration>
+            <IsDeployed>false</IsDeployed>
+        </NetworkConfig>
+    </NetworkConfigSection>
+    <Owner type="application/vnd.vmware.vcloud.owner+xml">
+        <User type="application/vnd.vmware.admin.user+xml" name="mgalet" href="https://vm-vcloud/api/admin/user/a0d29e8e-2b32-4739-ab7d-6a3e795be4db"/>
+    </Owner>
+    <InMaintenanceMode>false</InMaintenanceMode>
+    <Children>
+        <Vm needsCustomization="false" deployed="false" status="8" name="mgalet-test2" id="urn:vcloud:vm:dd75d1d3-5b7b-48f0-aff3-69622ab7e045" type="application/vnd.vmware.vcloud.vm+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045">
+            <Link rel="power:powerOn" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/power/action/powerOn"/>
+            <Link rel="deploy" type="application/vnd.vmware.vcloud.deployVAppParams+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/action/deploy"/>
+            <Link rel="edit" type="application/vnd.vmware.vcloud.vm+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045"/>
+            <Link rel="remove" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045"/>
+            <Link rel="down" type="application/vnd.vmware.vcloud.metadata+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/metadata"/>
+            <Link rel="screen:thumbnail" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/screen"/>
+            <Link rel="media:insertMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/media/action/insertMedia"/>
+            <Link rel="media:ejectMedia" type="application/vnd.vmware.vcloud.mediaInsertOrEjectParams+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/media/action/ejectMedia"/>
+            <Link rel="upgrade" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/action/upgradeHardwareVersion"/>
+            <Link rel="up" type="application/vnd.vmware.vcloud.vApp+xml" href="https://vm-vcloud/api/vApp/vapp-8c57a5b6-e61b-48ca-8a78-3b70ee65ef6a"/>
+            <Description/>
+            <ovf:VirtualHardwareSection ovf:transport="" vcloud:href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
+                <ovf:Info>Virtual hardware requirements</ovf:Info>
+                <ovf:System>
+                    <vssd:ElementName>Virtual Hardware Family</vssd:ElementName>
+                    <vssd:InstanceID>0</vssd:InstanceID>
+                    <vssd:VirtualSystemIdentifier>mgalet-test2</vssd:VirtualSystemIdentifier>
+                    <vssd:VirtualSystemType>vmx-07</vssd:VirtualSystemType>
+                </ovf:System>
+                <ovf:Item>
+                    <rasd:Address>00:50:56:01:00:99</rasd:Address>
+                    <rasd:AddressOnParent>0</rasd:AddressOnParent>
+                    <rasd:AutomaticAllocation>true</rasd:AutomaticAllocation>
+                    <rasd:Connection vcloud:ipAddress="65.41.67.2" vcloud:primaryNetworkConnection="true" vcloud:ipAddressingMode="POOL">vCloud - Default</rasd:Connection>
+                    <rasd:Description>PCNet32 ethernet adapter</rasd:Description>
+                    <rasd:ElementName>Network adapter 0</rasd:ElementName>
+                    <rasd:InstanceID>1</rasd:InstanceID>
+                    <rasd:ResourceSubType>PCNet32</rasd:ResourceSubType>
+                    <rasd:ResourceType>10</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item>
+                    <rasd:Address>0</rasd:Address>
+                    <rasd:Description>SCSI Controller</rasd:Description>
+                    <rasd:ElementName>SCSI Controller 0</rasd:ElementName>
+                    <rasd:InstanceID>2</rasd:InstanceID>
+                    <rasd:ResourceSubType>lsilogic</rasd:ResourceSubType>
+                    <rasd:ResourceType>6</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item>
+                    <rasd:AddressOnParent>0</rasd:AddressOnParent>
+                    <rasd:Description>Hard disk</rasd:Description>
+                    <rasd:ElementName>Hard disk 1</rasd:ElementName>
+                    <rasd:HostResource vcloud:capacity="61440" vcloud:busSubType="lsilogic" vcloud:busType="6"/>
+                    <rasd:InstanceID>2000</rasd:InstanceID>
+                    <rasd:Parent>2</rasd:Parent>
+                    <rasd:ResourceType>17</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item>
+                    <rasd:Address>0</rasd:Address>
+                    <rasd:Description>IDE Controller</rasd:Description>
+                    <rasd:ElementName>IDE Controller 0</rasd:ElementName>
+                    <rasd:InstanceID>3</rasd:InstanceID>
+                    <rasd:ResourceType>5</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item>
+                    <rasd:AddressOnParent>0</rasd:AddressOnParent>
+                    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+                    <rasd:Description>CD/DVD Drive</rasd:Description>
+                    <rasd:ElementName>CD/DVD Drive 1</rasd:ElementName>
+                    <rasd:HostResource/>
+                    <rasd:InstanceID>3002</rasd:InstanceID>
+                    <rasd:Parent>3</rasd:Parent>
+                    <rasd:ResourceType>15</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item>
+                    <rasd:AddressOnParent>0</rasd:AddressOnParent>
+                    <rasd:AutomaticAllocation>false</rasd:AutomaticAllocation>
+                    <rasd:Description>Floppy Drive</rasd:Description>
+                    <rasd:ElementName>Floppy Drive 1</rasd:ElementName>
+                    <rasd:HostResource/>
+                    <rasd:InstanceID>8000</rasd:InstanceID>
+                    <rasd:ResourceType>14</rasd:ResourceType>
+                </ovf:Item>
+                <ovf:Item vcloud:href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/cpu" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
+                    <rasd:AllocationUnits>hertz * 10^6</rasd:AllocationUnits>
+                    <rasd:Description>Number of Virtual CPUs</rasd:Description>
+                    <rasd:ElementName>2 virtual CPU(s)</rasd:ElementName>
+                    <rasd:InstanceID>4</rasd:InstanceID>
+                    <rasd:Reservation>0</rasd:Reservation>
+                    <rasd:ResourceType>3</rasd:ResourceType>
+                    <rasd:VirtualQuantity>2</rasd:VirtualQuantity>
+                    <rasd:Weight>0</rasd:Weight>
+                    <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/cpu"/>
+                </ovf:Item>
+                <ovf:Item vcloud:href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/memory" vcloud:type="application/vnd.vmware.vcloud.rasdItem+xml">
+                    <rasd:AllocationUnits>byte * 2^20</rasd:AllocationUnits>
+                    <rasd:Description>Memory Size</rasd:Description>
+                    <rasd:ElementName>4096 MB of memory</rasd:ElementName>
+                    <rasd:InstanceID>5</rasd:InstanceID>
+                    <rasd:Reservation>0</rasd:Reservation>
+                    <rasd:ResourceType>4</rasd:ResourceType>
+                    <rasd:VirtualQuantity>4096</rasd:VirtualQuantity>
+                    <rasd:Weight>0</rasd:Weight>
+                    <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/memory"/>
+                </ovf:Item>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/cpu"/>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/cpu"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/memory"/>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItem+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/memory"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/disks"/>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/disks"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/media"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/networkCards"/>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/networkCards"/>
+                <Link rel="down" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/serialPorts"/>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.rasdItemsList+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/virtualHardwareSection/serialPorts"/>
+            </ovf:VirtualHardwareSection>
+            <ovf:OperatingSystemSection ovf:id="80" vcloud:href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/operatingSystemSection/" vcloud:type="application/vnd.vmware.vcloud.operatingSystemSection+xml" vmw:osType="rhel5_64Guest" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5" xmlns:vmw="http://www.vmware.com/schema/ovf">
+                <ovf:Info>Specifies the operating system installed</ovf:Info>
+                <ovf:Description>Red Hat Enterprise Linux 5 (64-bit)</ovf:Description>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.operatingSystemSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/operatingSystemSection/"/>
+            </ovf:OperatingSystemSection>
+            <NetworkConnectionSection type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/networkConnectionSection/" ovf:required="false">
+                <ovf:Info>Specifies the available VM network connections</ovf:Info>
+                <PrimaryNetworkConnectionIndex>0</PrimaryNetworkConnectionIndex>
+                <NetworkConnection network="vCloud - Default" needsCustomization="false">
+                    <NetworkConnectionIndex>0</NetworkConnectionIndex>
+                    <IpAddress>65.41.67.2</IpAddress>
+                    <IsConnected>true</IsConnected>
+                    <MACAddress>00:50:56:01:00:99</MACAddress>
+                    <IpAddressAllocationMode>POOL</IpAddressAllocationMode>
+                </NetworkConnection>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.networkConnectionSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/networkConnectionSection/"/>
+            </NetworkConnectionSection>
+            <GuestCustomizationSection type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/guestCustomizationSection/" ovf:required="false">
+                <ovf:Info>Specifies Guest OS Customization Settings</ovf:Info>
+                <Enabled>true</Enabled>
+                <ChangeSid>false</ChangeSid>
+                <VirtualMachineId>dd75d1d3-5b7b-48f0-aff3-69622ab7e045</VirtualMachineId>
+                <JoinDomainEnabled>false</JoinDomainEnabled>
+                <UseOrgSettings>false</UseOrgSettings>
+                <AdminPasswordEnabled>true</AdminPasswordEnabled>
+                <AdminPasswordAuto>true</AdminPasswordAuto>
+                <AdminPassword>sN#9QH9#</AdminPassword>
+                <ResetPasswordRequired>false</ResetPasswordRequired>
+                <ComputerName>mgalet-test2</ComputerName>
+                <Link rel="edit" type="application/vnd.vmware.vcloud.guestCustomizationSection+xml" href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/guestCustomizationSection/"/>
+            </GuestCustomizationSection>
+            <RuntimeInfoSection vcloud:href="https://vm-vcloud/api/vApp/vm-dd75d1d3-5b7b-48f0-aff3-69622ab7e045/runtimeInfoSection" vcloud:type="application/vnd.vmware.vcloud.virtualHardwareSection+xml" xmlns:vcloud="http://www.vmware.com/vcloud/v1.5">
+                <ovf:Info>Specifies Runtime info</ovf:Info>
+                <VMWareTools version="8290"/>
+            </RuntimeInfoSection>
+            <VAppScopedLocalId>ScrumVM_Master</VAppScopedLocalId>
+        </Vm>
+    </Children>
+</VApp>
\ No newline at end of file