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 2013/12/27 13:07:47 UTC

[1/3] git commit: Issue LIBCLOUD-473: Add more EBS attributes to the "extra" dictionary in the StorageVolume class.

Updated Branches:
  refs/heads/trunk 166a11f6e -> 0cdfa4615


Issue LIBCLOUD-473: Add more EBS attributes to the "extra" dictionary in the
StorageVolume class.

Also refactor code to use new "_get_resource_tags" method.

Signed-off-by: Tomaz Muraus <to...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/480b4654
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/480b4654
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/480b4654

Branch: refs/heads/trunk
Commit: 480b46543759411816988a4676eab8bdab27a12b
Parents: 166a11f
Author: Chris DeRamus <ch...@divvycloud.com>
Authored: Thu Dec 26 11:36:06 2013 -0500
Committer: Tomaz Muraus <to...@apache.org>
Committed: Fri Dec 27 12:49:24 2013 +0100

----------------------------------------------------------------------
 libcloud/compute/drivers/ec2.py                 | 169 ++++++++++++-------
 .../compute/fixtures/ec2/describe_volumes.xml   |  19 +++
 libcloud/test/compute/test_ec2.py               |   9 +-
 3 files changed, 133 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/480b4654/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index bc9377f..1f11734 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -759,13 +759,9 @@ class BaseEC2NodeDriver(NodeDriver):
 
         instance_id = findtext(element=element, xpath='instanceId',
                                namespace=NAMESPACE)
-        tags = dict((findtext(element=item, xpath='key', namespace=NAMESPACE),
-                     findtext(element=item, xpath='value',
-                              namespace=NAMESPACE))
-                    for item in findall(element=element,
-                                        xpath='tagSet/item',
-                                        namespace=NAMESPACE)
-                    )
+
+        # Get our tags
+        tags = self._get_resource_tags(element)
 
         name = tags.get('Name', instance_id)
 
@@ -872,23 +868,83 @@ class BaseEC2NodeDriver(NodeDriver):
         )
         return n
 
-    def _to_volume(self, element, name):
+    def _to_volume(self, element, name=None):
+        """
+        Parse the XML element and return a StorageVolume object.
+
+        :param      name: An optional name for the volume. If not provided
+                          then the ID of the volume will be used in its place.
+        :type       name: ``str``
+
+        :rtype:     :class:`StorageVolume`
+        """
         volId = findtext(element=element, xpath='volumeId',
                          namespace=NAMESPACE)
         size = findtext(element=element, xpath='size', namespace=NAMESPACE)
-        state = findtext(element=element, xpath='status', namespace=NAMESPACE)
-        create_time = findtext(element=element, xpath='createTime',
-                               namespace=NAMESPACE)
-        device = findtext(element=element, xpath='attachmentSet/item/device',
-                          namespace=NAMESPACE)
+
+        # Get our tags
+        tags = self._get_resource_tags(element)
+
+        # If name was not passed into the method then
+        # fall back then use the volume id
+        name = name if name else tags.get('Name', volId)
+
+        # Build our extra attributes map
+        extra_attributes_map = {
+            'device': {
+                'xpath': 'device',
+                'cast_func': str
+            },
+            'iops': {
+                'xpath': 'iops',
+                'cast_func': int
+            },
+            'zone': {
+                'xpath': 'availabilityZone',
+                'cast_func': str
+            },
+            'create_time': {
+                'xpath': 'createTime',
+                'cast_func': parse_date
+            },
+            'state': {
+                'xpath': 'status',
+                'cast_func': str
+            },
+            'attach_time': {
+                'xpath': 'attachmentSet/item/attachTime',
+                'cast_func': parse_date
+            },
+            'attachment_status': {
+                'xpath': 'attachmentSet/item/status',
+                'cast_func': str
+            },
+            'instance_id': {
+                'xpath': 'attachmentSet/item/instanceId',
+                'cast_func': str
+            },
+            'delete': {
+                'xpath': 'attachmentSet/item/deleteOnTermination',
+                'cast_func': str
+            }
+        }
+
+        # Define and build our extra dictionary
+        extra = {}
+        for attribute, values in extra_attributes_map.items():
+            cast_func = values['cast_func']
+            value = findattr(element=element, xpath=values['xpath'],
+                             namespace=NAMESPACE)
+            if value is not None:
+                extra[attribute] = cast_func(value)
+            else:
+                extra[attribute] = None
 
         return StorageVolume(id=volId,
                              name=name,
                              size=int(size),
                              driver=self,
-                             extra={'state': state,
-                                    'device': device,
-                                    'create-time': parse_date(create_time)})
+                             extra=extra)
 
     def _to_snapshots(self, response):
         return [self._to_snapshot(el) for el in response.findall(
@@ -922,23 +978,8 @@ class BaseEC2NodeDriver(NodeDriver):
                           xpath='vpcId',
                           namespace=NAMESPACE)
 
-        # Get our tag items
-        tag_items = findall(element=element,
-                            xpath='tagSet/item',
-                            namespace=NAMESPACE)
-
-        # Loop through all tag items to build our dictionary
-        tags = {}
-        for tag in tag_items:
-            key = findtext(element=tag,
-                           xpath='key',
-                           namespace=NAMESPACE)
-
-            value = findtext(element=tag,
-                             xpath='value',
-                             namespace=NAMESPACE)
-
-            tags[key] = value
+        # Get our tags
+        tags = self._get_resource_tags(element)
 
         # Set our name if the Name key/value if available
         # If we don't get anything back then use the vpc_id
@@ -976,6 +1017,9 @@ class BaseEC2NodeDriver(NodeDriver):
                              namespace=NAMESPACE)
             extra[attribute] = type_func(value)
 
+        # Add tags to the extra dict
+        extra['tags'] = tags
+
         return EC2Network(vpc_id, name, cidr_block, extra=extra)
 
     def _to_subnets(self, response):
@@ -989,23 +1033,8 @@ class BaseEC2NodeDriver(NodeDriver):
                              xpath='subnetId',
                              namespace=NAMESPACE)
 
-        # Get our tag items
-        tag_items = findall(element=element,
-                            xpath='tagSet/item',
-                            namespace=NAMESPACE)
-
-        # Loop through all tag items to build our dictionary
-        tags = {}
-        for tag in tag_items:
-            key = findtext(element=tag,
-                           xpath='key',
-                           namespace=NAMESPACE)
-
-            value = findtext(element=tag,
-                             xpath='value',
-                             namespace=NAMESPACE)
-
-            tags[key] = value
+        # Get our tags
+        tags = self._get_resource_tags(element)
 
         # If we don't get anything back then use the subnet_id
         name = tags.get('Name', subnet_id)
@@ -1194,7 +1223,7 @@ class BaseEC2NodeDriver(NodeDriver):
                 'Filter.1.Value': node.id,
             })
         response = self.connection.request(self.path, params=params).object
-        volumes = [self._to_volume(el, '') for el in response.findall(
+        volumes = [self._to_volume(el) for el in response.findall(
             fixxpath(xpath='volumeSet/item', namespace=NAMESPACE))
         ]
         return volumes
@@ -2182,18 +2211,9 @@ class BaseEC2NodeDriver(NodeDriver):
                   'Filter.1.Value.0': 'instance',
                   }
 
-        result = self.connection.request(self.path,
-                                         params=params.copy()).object
-
-        tags = {}
-        for element in findall(element=result, xpath='tagSet/item',
-                               namespace=NAMESPACE):
-            key = findtext(element=element, xpath='key', namespace=NAMESPACE)
-            value = findtext(element=element,
-                             xpath='value', namespace=NAMESPACE)
+        result = self.connection.request(self.path, params=params).object
 
-            tags[key] = value
-        return tags
+        return self._get_resource_tags(result)
 
     def ex_create_tags(self, resource, tags):
         """
@@ -2724,6 +2744,31 @@ class BaseEC2NodeDriver(NodeDriver):
         return {'instance_id': node.id,
                 'timestamp': timestamp,
                 'output': output}
+    def _get_resource_tags(self, element):
+        """
+        Return a dictionary with key/value pairs.
+
+        :rtype: ``dict``
+        """
+        tags = {}
+
+        # Get our tag set by parsing the element
+        tag_set = findall(element=element,
+                          xpath='tagSet/item',
+                          namespace=NAMESPACE)
+
+        for tag in tag_set:
+            key = findtext(element=tag,
+                           xpath='key',
+                           namespace=NAMESPACE)
+
+            value = findtext(element=tag,
+                             xpath='value',
+                             namespace=NAMESPACE)
+
+            tags[key] = value
+
+        return tags
 
     def _get_common_security_group_params(self, group_id, protocol,
                                           from_port, to_port, cidr_ips,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/480b4654/libcloud/test/compute/fixtures/ec2/describe_volumes.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/describe_volumes.xml b/libcloud/test/compute/fixtures/ec2/describe_volumes.xml
index 56b7e4b..5dde8e4 100644
--- a/libcloud/test/compute/fixtures/ec2/describe_volumes.xml
+++ b/libcloud/test/compute/fixtures/ec2/describe_volumes.xml
@@ -19,5 +19,24 @@
             <createTime>2013-10-08T19:36:49.000Z</createTime>
             <attachmentSet/>
         </item>
+        <item>
+            <volumeId>vol-b6c851ec</volumeId>
+            <size>8</size>
+            <snapshotId>snap-30d37269</snapshotId>
+            <availabilityZone>us-east-1d</availabilityZone>
+            <status>in-use</status>
+            <createTime>2013-06-25T02:04:12.000Z</createTime>
+            <attachmentSet>
+                <item>
+                    <volumeId>vol-b6c851ec</volumeId>
+                    <instanceId>i-d334b4b3</instanceId>
+                    <device>/dev/sda1</device>
+                    <status>attached</status>
+                    <attachTime>2013-06-25T02:04:12.000Z</attachTime>
+                    <deleteOnTermination>true</deleteOnTermination>
+                </item>
+            </attachmentSet>
+            <volumeType>standard</volumeType>
+        </item>
     </volumeSet>
 </DescribeVolumesResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/480b4654/libcloud/test/compute/test_ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index 3a29793..6d71202 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -641,7 +641,7 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
     def test_list_volumes(self):
         volumes = self.driver.list_volumes()
 
-        self.assertEqual(len(volumes), 2)
+        self.assertEqual(len(volumes), 3)
 
         self.assertEqual('vol-10ae5e2b', volumes[0].id)
         self.assertEqual(1, volumes[0].size)
@@ -651,6 +651,11 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
         self.assertEqual(11, volumes[1].size)
         self.assertEqual('available', volumes[1].extra['state'])
 
+        self.assertEqual('vol-b6c851ec', volumes[2].id)
+        self.assertEqual(8, volumes[2].size)
+        self.assertEqual('in-use', volumes[2].extra['state'])
+        self.assertEqual('i-d334b4b3', volumes[2].extra['instance_id'])
+
     def test_create_volume(self):
         location = self.driver.list_locations()[0]
         vol = self.driver.create_volume(10, 'vol', location)
@@ -658,7 +663,7 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
         self.assertEqual(10, vol.size)
         self.assertEqual('vol', vol.name)
         self.assertEqual('creating', vol.extra['state'])
-        self.assertTrue(isinstance(vol.extra['create-time'], datetime))
+        self.assertTrue(isinstance(vol.extra['create_time'], datetime))
 
     def test_destroy_volume(self):
         vol = StorageVolume(id='vol-4282672b', name='test',


[3/3] git commit: Update CHANGES.

Posted by to...@apache.org.
Update CHANGES.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0cdfa461
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0cdfa461
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0cdfa461

Branch: refs/heads/trunk
Commit: 0cdfa46151711c4196b5c8d4b420c44fad7accd9
Parents: 950fed4
Author: Tomaz Muraus <to...@apache.org>
Authored: Fri Dec 27 13:04:12 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Fri Dec 27 13:04:12 2013 +0100

----------------------------------------------------------------------
 CHANGES | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/0cdfa461/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 290ea2f..a56d823 100644
--- a/CHANGES
+++ b/CHANGES
@@ -123,6 +123,10 @@ Changes with Apache Libcloud in development
      (LIBCLOUD-471)
      [Chris DeRamus]
 
+   - Include additional provider-specific attributes in the 'extra' dictionary
+     of the StorageVolume class in the EC2 driver. (LIBCLOUD-473)
+     [Chris DeRamus]
+
   *) Storage
 
     - Allow user to specify 'Content-Disposition' header in the CloudFiles


[2/3] git commit: Update docstrings, fix lint issue which arose during the conflict resolution.

Posted by to...@apache.org.
Update docstrings, fix lint issue which arose during the conflict resolution.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/950fed44
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/950fed44
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/950fed44

Branch: refs/heads/trunk
Commit: 950fed4406dc7a57724070f607cf4c52a592c77c
Parents: 480b465
Author: Tomaz Muraus <to...@apache.org>
Authored: Fri Dec 27 12:53:09 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Fri Dec 27 13:00:19 2013 +0100

----------------------------------------------------------------------
 libcloud/compute/drivers/ec2.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/950fed44/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index 1f11734..48fbdbc 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -873,7 +873,9 @@ class BaseEC2NodeDriver(NodeDriver):
         Parse the XML element and return a StorageVolume object.
 
         :param      name: An optional name for the volume. If not provided
-                          then the ID of the volume will be used in its place.
+                          then either tag with a key "Name" or volume ID
+                          will be used (which ever is available first in that
+                          order).
         :type       name: ``str``
 
         :rtype:     :class:`StorageVolume`
@@ -2744,9 +2746,11 @@ class BaseEC2NodeDriver(NodeDriver):
         return {'instance_id': node.id,
                 'timestamp': timestamp,
                 'output': output}
+
     def _get_resource_tags(self, element):
         """
-        Return a dictionary with key/value pairs.
+        Parse tags from the provided element and return a dictionary with
+        key/value pairs.
 
         :rtype: ``dict``
         """