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/26 15:12:03 UTC

[1/3] git commit: LIBCLOUD-468: Add VPC subnet calls to the EC2 driver.

Updated Branches:
  refs/heads/trunk abf8f8e1a -> 5a68e0070


LIBCLOUD-468: Add VPC subnet calls to the EC2 driver.

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/ee69f99a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/ee69f99a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/ee69f99a

Branch: refs/heads/trunk
Commit: ee69f99a6f0de10b7bd86f078f2d38cffbb120dd
Parents: abf8f8e
Author: Chris DeRamus <ch...@divvycloud.com>
Authored: Thu Dec 26 07:22:29 2013 -0500
Committer: Tomaz Muraus <to...@apache.org>
Committed: Thu Dec 26 14:13:23 2013 +0100

----------------------------------------------------------------------
 libcloud/compute/drivers/ec2.py                 | 154 +++++++++++++++++++
 .../test/compute/fixtures/ec2/create_subnet.xml |  11 ++
 .../test/compute/fixtures/ec2/delete_subnet.xml |   4 +
 .../compute/fixtures/ec2/describe_subnets.xml   |  37 +++++
 libcloud/test/compute/test_ec2.py               |  39 +++++
 5 files changed, 245 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/ee69f99a/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index c3d2cc3..61d6f4b 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -595,6 +595,23 @@ class EC2Network(object):
                 % (self.id, self.name))
 
 
+class EC2NetworkSubnet(object):
+    """
+    Represents information about a VPC (Virtual Private Cloud) subnet
+
+    Note: This class is EC2 specific.
+    """
+
+    def __init__(self, id, name, state, extra=None):
+        self.id = id
+        self.name = name
+        self.state = state
+        self.extra = extra or {}
+
+    def __repr__(self):
+        return (('<EC2NetworkSubnet: id=%s, name=%s') % (self.id, self.name))
+
+
 class BaseEC2NodeDriver(NodeDriver):
     """
     Base Amazon EC2 node driver.
@@ -961,6 +978,75 @@ class BaseEC2NodeDriver(NodeDriver):
 
         return EC2Network(vpc_id, name, cidr_block, extra=extra)
 
+    def _to_subnets(self, response):
+        return [self._to_subnet(el) for el in response.findall(
+            fixxpath(xpath='subnetSet/item', namespace=NAMESPACE))
+        ]
+
+    def _to_subnet(self, element):
+        # Get the subnet ID
+        subnet_id = findtext(element=element,
+                             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
+
+        # If we don't get anything back then use the subnet_id
+        name = tags.get('Name', subnet_id)
+
+        state = findtext(element=element,
+                         xpath='state',
+                         namespace=NAMESPACE)
+
+        # Build our extra attributes map
+        extra_attributes_map = {
+            'cidr_block': {
+                'xpath': 'cidrBlock',
+                'type': str
+            },
+            'available_ips': {
+                'xpath': 'availableIpAddressCount',
+                'type': int
+            },
+            'zone': {
+                'xpath': 'availabilityZone',
+                'type': str
+            },
+            'vpc_id': {
+                'xpath': 'vpcId',
+                'type': str
+            }
+        }
+
+        # Define and build our extra dictionary
+        extra = {}
+        for attribute, values in extra_attributes_map.items():
+            type_func = values['type']
+            value = findattr(element=element, xpath=values['xpath'],
+                             namespace=NAMESPACE)
+            extra[attribute] = type_func(value)
+
+        # Also include our tags
+        extra['tags'] = tags
+
+        return EC2NetworkSubnet(subnet_id, name, state, extra=extra)
+
     def ex_list_reserved_nodes(self):
         """
         List all reserved instances/nodes which can be purchased from Amazon
@@ -1557,6 +1643,74 @@ class BaseEC2NodeDriver(NodeDriver):
 
         return element == 'true'
 
+    def ex_list_subnets(self):
+        """
+        Return a list of :class:`EC2NetworkSubnet` objects for the
+        current region.
+
+        :rtype:     ``list`` of :class:`EC2NetworkSubnet`
+        """
+        params = {'Action': 'DescribeSubnets'}
+
+        return self._to_subnets(
+            self.connection.request(self.path, params=params).object
+        )
+
+    def ex_create_subnet(self, vpc_id, cidr_block,
+                         availability_zone, name=None):
+        """
+        Create a network subnet within a VPC
+
+        :param      vpc_id: The ID of the VPC that the subnet should be
+                            associated with
+        :type       vpc_id: ``str``
+
+        :param      cidr_block: The CIDR block assigned to the subnet
+        :type       cidr_block: ``str``
+
+        :param      availability_zone: The availability zone where the subnet
+                                       should reside
+        :type       availability_zone: ``str``
+
+        :param      name: An optional name for the network
+        :type       name: ``str``
+
+        :rtype:     :class: `EC2NetworkSubnet`
+        """
+        params = {'Action': 'CreateSubnet',
+                  'VpcId': vpc_id,
+                  'CidrBlock': cidr_block,
+                  'AvailabilityZone': availability_zone}
+
+        response = self.connection.request(self.path, params=params).object
+        element = response.findall(fixxpath(xpath='subnet',
+                                            namespace=NAMESPACE))[0]
+
+        subnet = self._to_subnet(element)
+
+        if name is not None:
+            self.ex_create_tags(subnet, {'Name': name})
+
+        return subnet
+
+    def ex_delete_subnet(self, subnet_id):
+        """
+        Deletes a VPC subnet.
+
+        :param      subnet_id: The ID of the subnet
+        :type       subnet_id: ``str``
+
+        :rtype:     ``bool``
+        """
+        params = {'Action': 'DeleteSubnet', 'SubnetId': subnet_id}
+
+        result = self.connection.request(self.path, params=params).object
+        element = findtext(element=result,
+                           xpath='return',
+                           namespace=NAMESPACE)
+
+        return element == 'true'
+
     def ex_list_security_groups(self):
         """
         List existing Security Groups.

http://git-wip-us.apache.org/repos/asf/libcloud/blob/ee69f99a/libcloud/test/compute/fixtures/ec2/create_subnet.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/create_subnet.xml b/libcloud/test/compute/fixtures/ec2/create_subnet.xml
new file mode 100644
index 0000000..b04a69e
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/create_subnet.xml
@@ -0,0 +1,11 @@
+<CreateSubnetResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
+    <requestId>e94b315e-6424-4536-b48d-0dfb47732c72</requestId>
+    <subnet>
+        <subnetId>subnet-ce0e7ce6</subnetId>
+        <state>pending</state>
+        <vpcId>vpc-532135d1</vpcId>
+        <cidrBlock>192.168.51.128/26</cidrBlock>
+        <availableIpAddressCount>59</availableIpAddressCount>
+        <availabilityZone>us-east-1b</availabilityZone>
+    </subnet>
+</CreateSubnetResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/ee69f99a/libcloud/test/compute/fixtures/ec2/delete_subnet.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/delete_subnet.xml b/libcloud/test/compute/fixtures/ec2/delete_subnet.xml
new file mode 100644
index 0000000..dd5ed64
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/delete_subnet.xml
@@ -0,0 +1,4 @@
+<DeleteSubnetResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
+    <requestId>5cd6fa89-35bd-4aac-99ed-na8af7</requestId>
+    <return>true</return>
+</DeleteSubnetResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/ee69f99a/libcloud/test/compute/fixtures/ec2/describe_subnets.xml
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/ec2/describe_subnets.xml b/libcloud/test/compute/fixtures/ec2/describe_subnets.xml
new file mode 100644
index 0000000..3d14d50
--- /dev/null
+++ b/libcloud/test/compute/fixtures/ec2/describe_subnets.xml
@@ -0,0 +1,37 @@
+<DescribeSubnetsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
+    <requestId>67bba371-8044-45a7-b4a3-d72fef8b96d8</requestId>
+    <subnetSet>
+        <item>
+            <subnetId>subnet-ce0e7ce5</subnetId>
+            <state>available</state>
+            <vpcId>vpc-532135d1</vpcId>
+            <cidrBlock>192.168.51.0/25</cidrBlock>
+            <availableIpAddressCount>123</availableIpAddressCount>
+            <availabilityZone>us-east-1a</availabilityZone>
+            <defaultForAz>false</defaultForAz>
+            <mapPublicIpOnLaunch>false</mapPublicIpOnLaunch>
+            <tagSet>
+                <item>
+                    <key>Name</key>
+                    <value>Test Subnet 1</value>
+                </item>
+            </tagSet>
+        </item>
+        <item>
+            <subnetId>subnet-ce0e7ce6</subnetId>
+            <state>available</state>
+            <vpcId>vpc-532135d1</vpcId>
+            <cidrBlock>192.168.51.128/64</cidrBlock>
+            <availableIpAddressCount>59</availableIpAddressCount>
+            <availabilityZone>us-east-1b</availabilityZone>
+            <defaultForAz>false</defaultForAz>
+            <mapPublicIpOnLaunch>false</mapPublicIpOnLaunch>
+            <tagSet>
+                <item>
+                    <key>Name</key>
+                    <value>Test Subnet 2</value>
+                </item>
+            </tagSet>
+        </item>
+    </subnetSet>
+</DescribeSubnetsResponse>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/libcloud/blob/ee69f99a/libcloud/test/compute/test_ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index 44116a0..3283d55 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -811,6 +811,33 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
         resp = self.driver.ex_delete_network(vpc)
         self.assertTrue(resp)
 
+    def test_ex_list_subnets(self):
+        subnets = self.driver.ex_list_subnets()
+
+        self.assertEqual(len(subnets), 2)
+
+        self.assertEqual('subnet-ce0e7ce5', subnets[0].id)
+        self.assertEqual('available', subnets[0].state)
+        self.assertEqual(123, subnets[0].extra['available_ips'])
+
+        self.assertEqual('subnet-ce0e7ce6', subnets[1].id)
+        self.assertEqual('available', subnets[1].state)
+        self.assertEqual(59, subnets[1].extra['available_ips'])
+
+    def test_ex_create_subnet(self):
+        subnet = self.driver.ex_create_subnet('vpc-532135d1',
+                                              '192.168.51.128/26',
+                                              'us-east-1b',
+                                              name='Test Subnet')
+
+        self.assertEqual('subnet-ce0e7ce6', subnet.id)
+        self.assertEqual('pending', subnet.state)
+        self.assertEqual('vpc-532135d1', subnet.extra['vpc_id'])
+
+    def test_ex_delete_subnet(self):
+        resp = self.driver.ex_delete_subnet('subnet-ce0e7ce6')
+        self.assertTrue(resp)
+
 
 class EC2USWest1Tests(EC2Tests):
     region = 'us-west-1'
@@ -1106,6 +1133,18 @@ class EC2MockHttp(MockHttpTestCase):
         body = self.fixtures.load('delete_vpc.xml')
         return (httplib.OK, body, {}, httplib.responses[httplib.OK])
 
+    def _DescribeSubnets(self, method, url, body, headers):
+        body = self.fixtures.load('describe_subnets.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _CreateSubnet(self, method, url, body, headers):
+        body = self.fixtures.load('create_subnet.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
+    def _DeleteSubnet(self, method, url, body, headers):
+        body = self.fixtures.load('delete_subnet.xml')
+        return (httplib.OK, body, {}, httplib.responses[httplib.OK])
+
 
 class EucMockHttp(EC2MockHttp):
     fixtures = ComputeFileFixtures('ec2')


[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/5a68e007
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/5a68e007
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/5a68e007

Branch: refs/heads/trunk
Commit: 5a68e0070b7a1febea4014493db2f086fe40eb01
Parents: 4abc219
Author: Tomaz Muraus <to...@apache.org>
Authored: Thu Dec 26 14:32:24 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Thu Dec 26 14:32:24 2013 +0100

----------------------------------------------------------------------
 CHANGES | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/5a68e007/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 644ce3e..04190d1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -112,7 +112,11 @@ Changes with Apache Libcloud in development
      [Chris DeRamus]
 
    - Add extension methods for VPC management (ex_list_networks,
-     ex_create_network, ex_delete_network) to the EC2 driver. (LIBCLOUD-477)
+     ex_create_network, ex_delete_network) to the EC2 driver. (LIBCLOUD-467)
+     [Chris DeRamus]
+
+   - Add extension methods for VPC subnet management (ex_list_subnets,
+     ex_create_subnet, ex_delete_subnet) to the EC2 driver. (LIBCLOUD-468)
      [Chris DeRamus]
 
   *) Storage


[2/3] git commit: Modify ex_delete_subnet method to take a EC2NetworkSubnet instance instead.

Posted by to...@apache.org.
Modify ex_delete_subnet method to take a EC2NetworkSubnet instance instead.


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

Branch: refs/heads/trunk
Commit: 4abc21946cfd42f8b6f773caa8d847edd17f88ae
Parents: ee69f99
Author: Tomaz Muraus <to...@apache.org>
Authored: Thu Dec 26 14:16:05 2013 +0100
Committer: Tomaz Muraus <to...@apache.org>
Committed: Thu Dec 26 14:16:05 2013 +0100

----------------------------------------------------------------------
 libcloud/compute/drivers/ec2.py   | 8 ++++----
 libcloud/test/compute/test_ec2.py | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/4abc2194/libcloud/compute/drivers/ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py
index 61d6f4b..a13201e 100644
--- a/libcloud/compute/drivers/ec2.py
+++ b/libcloud/compute/drivers/ec2.py
@@ -1693,16 +1693,16 @@ class BaseEC2NodeDriver(NodeDriver):
 
         return subnet
 
-    def ex_delete_subnet(self, subnet_id):
+    def ex_delete_subnet(self, subnet):
         """
         Deletes a VPC subnet.
 
-        :param      subnet_id: The ID of the subnet
-        :type       subnet_id: ``str``
+        :param      subnet: The subnet to delete
+        :type       subnet: :class:`.EC2NetworkSubnet`
 
         :rtype:     ``bool``
         """
-        params = {'Action': 'DeleteSubnet', 'SubnetId': subnet_id}
+        params = {'Action': 'DeleteSubnet', 'SubnetId': subnet.id}
 
         result = self.connection.request(self.path, params=params).object
         element = findtext(element=result,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/4abc2194/libcloud/test/compute/test_ec2.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py
index 3283d55..239b9ef 100644
--- a/libcloud/test/compute/test_ec2.py
+++ b/libcloud/test/compute/test_ec2.py
@@ -835,7 +835,8 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin):
         self.assertEqual('vpc-532135d1', subnet.extra['vpc_id'])
 
     def test_ex_delete_subnet(self):
-        resp = self.driver.ex_delete_subnet('subnet-ce0e7ce6')
+        subnet = self.driver.ex_list_subnets()[0]
+        resp = self.driver.ex_delete_subnet(subnet=subnet)
         self.assertTrue(resp)