You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by je...@apache.org on 2010/02/09 14:50:20 UTC

svn commit: r908030 - /incubator/libcloud/trunk/libcloud/drivers/vcloud.py

Author: jerry
Date: Tue Feb  9 13:50:19 2010
New Revision: 908030

URL: http://svn.apache.org/viewvc?rev=908030&view=rev
Log:
80-col formatting update: drivers/vcloud.py

Modified:
    incubator/libcloud/trunk/libcloud/drivers/vcloud.py

Modified: incubator/libcloud/trunk/libcloud/drivers/vcloud.py
URL: http://svn.apache.org/viewvc/incubator/libcloud/trunk/libcloud/drivers/vcloud.py?rev=908030&r1=908029&r2=908030&view=diff
==============================================================================
--- incubator/libcloud/trunk/libcloud/drivers/vcloud.py (original)
+++ incubator/libcloud/trunk/libcloud/drivers/vcloud.py Tue Feb  9 13:50:19 2010
@@ -17,7 +17,8 @@
 """
 from libcloud.providers import Provider
 from libcloud.types import NodeState, InvalidCredsException
-from libcloud.base import Node, Response, ConnectionUserAndKey, NodeDriver, NodeSize, NodeImage, NodeAuthPassword, NodeLocation
+from libcloud.base import Node, Response, ConnectionUserAndKey, NodeDriver
+from libcloud.base import NodeSize, NodeImage, NodeAuthPassword, NodeLocation
 
 import base64
 import httplib
@@ -26,7 +27,10 @@
 from xml.etree import ElementTree as ET
 from xml.parsers.expat import ExpatError
 
-#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)."
+"""
+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)]
 
 DEFAULT_TASK_COMPLETION_TIMEOUT = 600
@@ -37,12 +41,14 @@
 def fixxpath(root, xpath):
     """ElementTree wants namespaces in its xpaths, so here we add them."""
     namespace, root_tag = root.tag[1:].split("}", 1)
-    fixed_xpath = "/".join(["{%s}%s" % (namespace, e) for e in xpath.split("/")])
+    fixed_xpath = "/".join(["{%s}%s" % (namespace, e)
+                            for e in xpath.split("/")])
     return fixed_xpath
 
 class InstantiateVAppXML(object):
-    
-    def __init__(self, name, template, net_href, cpus, memory, password=None, row=None, group=None):
+
+    def __init__(self, name, template, net_href, cpus, memory,
+                 password=None, row=None, group=None):
         self.name = name
         self.template = template
         self.net_href = net_href
@@ -56,12 +62,12 @@
 
     def tostring(self):
         return ET.tostring(self.root)
-    
+
     def _build_xmltree(self):
         self.root = self._make_instantiation_root()
 
         self._add_vapp_template(self.root)
-        instantionation_params = ET.SubElement(self.root, 
+        instantionation_params = ET.SubElement(self.root,
                                                "InstantiationParams")
 
         product = self._make_product_section(instantionation_params)
@@ -75,7 +81,7 @@
 
     def _make_instantiation_root(self):
         return ET.Element(
-            "InstantiateVAppTemplateParams", 
+            "InstantiateVAppTemplateParams",
             {'name': self.name,
              'xml:lang': 'en',
              'xmlns': "http://www.vmware.com/vcloud/v0.8",
@@ -84,7 +90,7 @@
 
     def _add_vapp_template(self, parent):
         return ET.SubElement(
-            parent, 
+            parent,
             "VAppTemplate",
             {'href': self.template}
         )
@@ -110,13 +116,13 @@
 
     def _add_property(self, parent, ovfkey, ovfvalue):
         return ET.SubElement(
-            parent, 
+            parent,
             "Property",
             {'xmlns': 'http://schemas.dmtf.org/ovf/envelope/1',
              'ovf:key': ovfkey,
              'ovf:value': ovfvalue}
         )
-    
+
     def _make_virtual_hardware(self, parent):
         vh = ET.SubElement(
             parent,
@@ -155,7 +161,7 @@
 
     def _add_instance_id(self, parent, id):
         elm = ET.SubElement(
-            parent, 
+            parent,
             "InstanceID",
             {'xmlns': 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData'}
         )
@@ -201,7 +207,7 @@
         return self.error
 
     def success(self):
-        return self.status in (httplib.OK, httplib.CREATED, 
+        return self.status in (httplib.OK, httplib.CREATED,
                                httplib.NO_CONTENT, httplib.ACCEPTED)
 
 class VCloudConnection(ConnectionUserAndKey):
@@ -215,18 +221,24 @@
         return super(VCloudConnection, self).request(*args, **kwargs)
 
     def check_org(self):
-        self._get_auth_token() # the only way to get our org is by logging in.
+        # the only way to get our org is by logging in.
+        self._get_auth_token()
 
     def _get_auth_headers(self):
         """Some providers need different headers than others"""
-        return {'Authorization': "Basic %s" % base64.b64encode('%s:%s' % (self.user_id, self.key)),
-                'Content-Length': 0}
+        return {
+            'Authorization':
+                "Basic %s"
+                % base64.b64encode('%s:%s' % (self.user_id, self.key)),
+            'Content-Length': 0
+        }
 
     def _get_auth_token(self):
         if not self.token:
-            conn = self.conn_classes[self.secure](self.host, 
+            conn = self.conn_classes[self.secure](self.host,
                                                   self.port[self.secure])
-            conn.request(method='POST', url='/api/v0.8/login', headers=self._get_auth_headers())
+            conn.request(method='POST', url='/api/v0.8/login',
+                         headers=self._get_auth_headers())
 
             resp = conn.getresponse()
             headers = dict(resp.getheaders())
@@ -237,7 +249,9 @@
             except KeyError:
                 raise InvalidCredsException()
 
-            self.driver.org = get_url_path(body.find(fixxpath(body, 'Org')).get('href'))
+            self.driver.org = get_url_path(
+                body.find(fixxpath(body, 'Org')).get('href')
+            )
 
     def add_default_headers(self, headers):
         headers['Cookie'] = self.token
@@ -261,10 +275,13 @@
         if not self._vdcs:
             self.connection.check_org() # make sure the org is set.
             res = self.connection.request(self.org)
-            self._vdcs = [get_url_path(i.get('href'))
-                          for i in res.object.findall(fixxpath(res.object, "Link"))
-                          if i.get('type') == 'application/vnd.vmware.vcloud.vdc+xml']
-            
+            self._vdcs = [
+                get_url_path(i.get('href'))
+                for i
+                in res.object.findall(fixxpath(res.object, "Link"))
+                if i.get('type') == 'application/vnd.vmware.vcloud.vdc+xml'
+            ]
+
         return self._vdcs
 
     @property
@@ -273,7 +290,10 @@
         for vdc in self.vdcs:
             res = self.connection.request(vdc).object
             networks.extend(
-                [network for network in res.findall(fixxpath(res, "AvailableNetworks/Network"))]
+                [network
+                 for network in res.findall(
+                     fixxpath(res, "AvailableNetworks/Network")
+                 )]
             )
 
         return networks
@@ -292,7 +312,9 @@
         # 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')
         for connection in connections:
-          ips = [ip.text for ip in connection.findall(fixxpath(elm, "IpAddress"))]
+          ips = [ip.text
+                 for ip
+                 in connection.findall(fixxpath(elm, "IpAddress"))]
           if connection.get('Network') == 'Internal':
             private_ips.extend(ips)
           else:
@@ -309,68 +331,88 @@
 
     def _get_catalog_hrefs(self):
         res = self.connection.request(self.org)
-        catalogs = [get_url_path(i.get('href'))
-                    for i in res.object.findall(fixxpath(res.object, "Link"))
-                    if i.get('type') == 'application/vnd.vmware.vcloud.catalog+xml']
+        catalogs = [
+            get_url_path(i.get('href'))
+            for i in res.object.findall(fixxpath(res.object, "Link"))
+            if i.get('type') == 'application/vnd.vmware.vcloud.catalog+xml'
+        ]
 
         return catalogs
-      
-    def _wait_for_task_completion(self, task_href, timeout=DEFAULT_TASK_COMPLETION_TIMEOUT):
+
+    def _wait_for_task_completion(self, task_href,
+                                  timeout=DEFAULT_TASK_COMPLETION_TIMEOUT):
         start_time = time.time()
         res = self.connection.request(task_href)
         status = res.object.get('status')
         while status != 'success':
           if status == 'error':
-              raise Exception("Error status returned by task %s." % task_href)
+              raise Exception("Error status returned by task %s."
+                              % task_href)
           if status == 'canceled':
-              raise Exception("Canceled status returned by task %s." % task_href)
+              raise Exception("Canceled status returned by task %s."
+                              % task_href)
           if (time.time() - start_time >= timeout):
-              raise Exception("Timeout while waiting for task %s." % task_href)
+              raise Exception("Timeout while waiting for task %s."
+                              % task_href)
           time.sleep(5)
           res = self.connection.request(task_href)
           status = res.object.get('status')
-      
+
     def destroy_node(self, node):
         node_path = get_url_path(node.id)
         # blindly poweroff node, it will throw an exception if already off
         try:
-            res = self.connection.request('%s/power/action/poweroff' % node_path,
-                                    method='POST')
+            res = self.connection.request('%s/power/action/poweroff'
+                                          % node_path,
+                                          method='POST')
             self._wait_for_task_completion(res.object.get('href'))
-        except Exception, e: 
+        except Exception, e:
             pass
 
         try:
             res = self.connection.request('%s/action/undeploy' % node_path,
                                           method='POST')
             self._wait_for_task_completion(res.object.get('href'))
-        except ExpatError: # the undeploy response is malformed XML atm. We can remove this whent he providers fix the problem.
+        except ExpatError:
+            # The undeploy response is malformed XML atm.
+            # We can remove this whent he providers fix the problem.
             pass
-        except Exception, e: # some vendors don't implement undeploy at all yet, so catch this and move on.
+        except Exception, e:
+            # Some vendors don't implement undeploy at all yet,
+            # so catch this and move on.
             pass
 
         res = self.connection.request(node_path, method='DELETE')
         return res.status == 202
 
     def reboot_node(self, node):
-        res = self.connection.request('%s/power/action/reset' % get_url_path(node.id),
-                                      method='POST') 
+        res = self.connection.request('%s/power/action/reset'
+                                      % get_url_path(node.id),
+                                      method='POST')
         return res.status == 202 or res.status == 204
 
     def list_nodes(self):
         nodes = []
         for vdc in self.vdcs:
-            res = self.connection.request(vdc) 
-            elms = res.object.findall(fixxpath(res.object, "ResourceEntities/ResourceEntity"))
-            vapps = [(i.get('name'), get_url_path(i.get('href')))
-                        for i in elms
-                            if i.get('type') == 'application/vnd.vmware.vcloud.vApp+xml' and 
-                               i.get('name')]
+            res = self.connection.request(vdc)
+            elms = res.object.findall(fixxpath(
+                res.object, "ResourceEntities/ResourceEntity")
+            )
+            vapps = [
+                (i.get('name'), get_url_path(i.get('href')))
+                for i in elms
+                if i.get('type')
+                    == 'application/vnd.vmware.vcloud.vApp+xml'
+                    and i.get('name')
+            ]
 
             for vapp_name, vapp_href in vapps:
                 res = self.connection.request(
                     vapp_href,
-                    headers={'Content-Type': 'application/vnd.vmware.vcloud.vApp+xml'}
+                    headers={
+                        'Content-Type':
+                            'application/vnd.vmware.vcloud.vApp+xml'
+                    }
                 )
                 nodes.append(self._to_node(vapp_name, res.object))
 
@@ -386,9 +428,8 @@
             price=None,
             driver=self.connection.driver
         )
-
         return ns
-        
+
     def list_sizes(self):
         sizes = [self._to_size(i) for i in VIRTUAL_MEMORY_VALS]
         return sizes
@@ -397,13 +438,17 @@
         """Given a catalog href returns contained catalog item hrefs"""
         res = self.connection.request(
             catalog,
-            headers={'Content-Type': 'application/vnd.vmware.vcloud.catalog+xml'}
+            headers={
+                'Content-Type':
+                    'application/vnd.vmware.vcloud.catalog+xml'
+            }
         ).object
 
         cat_items = res.findall(fixxpath(res, "CatalogItems/CatalogItem"))
         cat_item_hrefs = [i.get('href')
                           for i in cat_items
-                          if i.get('type') == 'application/vnd.vmware.vcloud.catalogItem+xml']
+                          if i.get('type') ==
+                              'application/vnd.vmware.vcloud.catalogItem+xml']
 
         return cat_item_hrefs
 
@@ -411,40 +456,53 @@
         """Given a catalog item href returns elementree"""
         res = self.connection.request(
             catalog_item,
-            headers={'Content-Type': 'application/vnd.vmware.vcloud.catalogItem+xml'}
+            headers={
+                'Content-Type':
+                    'application/vnd.vmware.vcloud.catalogItem+xml'
+            }
         ).object
 
         return res
-        
+
     def list_images(self):
         images = []
         for vdc in self.vdcs:
             res = self.connection.request(vdc).object
-            res_ents = res.findall(fixxpath(res, "ResourceEntities/ResourceEntity"))
-            images += [self._to_image(i) 
-                       for i in res_ents 
-                       if i.get('type') == 'application/vnd.vmware.vcloud.vAppTemplate+xml']
-        
+            res_ents = res.findall(fixxpath(
+                res, "ResourceEntities/ResourceEntity")
+            )
+            images += [
+                self._to_image(i)
+                for i in res_ents
+                if i.get('type') ==
+                    'application/vnd.vmware.vcloud.vAppTemplate+xml'
+            ]
+
         for catalog in self._get_catalog_hrefs():
             for cat_item in self._get_catalogitems_hrefs(catalog):
-                res = self._get_catalogitem(cat_item) 
+                res = self._get_catalogitem(cat_item)
                 res_ents = res.findall(fixxpath(res, 'Entity'))
-                images += [self._to_image(i)
-                           for i in res_ents
-                           if i.get('type') ==  'application/vnd.vmware.vcloud.vAppTemplate+xml']
+                images += [
+                    self._to_image(i)
+                    for i in res_ents
+                    if i.get('type') ==
+                        'application/vnd.vmware.vcloud.vAppTemplate+xml'
+                ]
 
         return images
 
     def create_node(self, **kwargs):
         """Creates and returns node.
 
-           Non-standard optional keyword arguments:
-           network -- link to a "Network" e.g., "https://services.vcloudexpress.terremark.com/api/v0.8/network/7"
-           vdc -- link to a "VDC" e.g., "https://services.vcloudexpress.terremark.com/api/v0.8/vdc/1"
-           cpus -- number of virtual cpus (limit depends on provider)
-           password
-           row
-           group 
+        Non-standard optional keyword arguments:
+        network -- link to a "Network" e.g.,
+            "https://services.vcloudexpress.terremark.com/api/v0.8/network/7"
+        vdc -- link to a "VDC" e.g.,
+            "https://services.vcloudexpress.terremark.com/api/v0.8/vdc/1"
+        cpus -- number of virtual cpus (limit depends on provider)
+        password
+        row
+        group
         """
         name = kwargs['name']
         image = kwargs['image']
@@ -465,8 +523,8 @@
                 raise ValueError('auth must be of NodeAuthPassword type')
 
         instantiate_xml = InstantiateVAppXML(
-            name=name, 
-            template=image.id, 
+            name=name,
+            template=image.id,
             net_href=network,
             cpus=str(kwargs.get('cpus', 1)),
             memory=str(size.ram),
@@ -476,19 +534,25 @@
         )
 
         # Instantiate VM and get identifier.
-        res = self.connection.request('%s/action/instantiateVAppTemplate' % kwargs.get('vdc', self.vdcs[0]),
-                                      data=instantiate_xml.tostring(),
-                                      method='POST',
-                                      headers={'Content-Type': 'application/vnd.vmware.vcloud.instantiateVAppTemplateParams+xml'})
+        res = self.connection.request(
+            '%s/action/instantiateVAppTemplate'
+                % kwargs.get('vdc', self.vdcs[0]),
+            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'))
 
         # Deploy the VM from the identifier.
         res = self.connection.request('%s/action/deploy' % vapp_href,
                                       method='POST')
-        
+
         self._wait_for_task_completion(res.object.get('href'))
-        
+
         # Power on the VM.
         res = self.connection.request('%s/power/action/powerOn' % vapp_href,
                                       method='POST')
@@ -501,13 +565,15 @@
     features = {"create_node": ["password"]}
 
 class HostingComConnection(VCloudConnection):
-    host = "vcloud.safesecureweb.com" 
-    
+    host = "vcloud.safesecureweb.com"
+
     def _get_auth_headers(self):
         """hosting.com doesn't follow the standard vCloud authentication API"""
-        return {'Authentication': base64.b64encode('%s:%s' % (self.user_id, self.key)),
-                   'Content-Length': 0} 
-
+        return {
+            'Authentication':
+                base64.b64encode('%s:%s' % (self.user_id, self.key)),
+            'Content-Length': 0
+        }
 
 class HostingComDriver(VCloudNodeDriver):
     connectionCls = HostingComConnection