Updated Branches: refs/heads/trunk ab2b06f3c -> a447f9619
Issue: LIBCLOUD-477 Add list/delete/create network (VPC) calls within EC2 Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/6d6c2c7b Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/6d6c2c7b Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/6d6c2c7b Branch: refs/heads/trunk Commit: 6d6c2c7b3ed00a9020c175c8f9b392924a872a6a Parents: f75780f Author: Chris DeRamus <[email protected]> Authored: Fri Dec 20 12:56:25 2013 -0500 Committer: Chris DeRamus <[email protected]> Committed: Fri Dec 20 12:56:25 2013 -0500 ---------------------------------------------------------------------- libcloud/compute/drivers/ec2.py | 125 +++++++++++++++++++ .../test/compute/fixtures/ec2/create_vpc.xml | 10 ++ .../test/compute/fixtures/ec2/delete_vpc.xml | 4 + .../test/compute/fixtures/ec2/describe_vpcs.xml | 28 +++++ libcloud/test/compute/test_ec2.py | 43 +++++++ 5 files changed, 210 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/6d6c2c7b/libcloud/compute/drivers/ec2.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py index b94dbdb..9cc8281 100644 --- a/libcloud/compute/drivers/ec2.py +++ b/libcloud/compute/drivers/ec2.py @@ -1236,6 +1236,131 @@ class BaseEC2NodeDriver(NodeDriver): 'keyFingerprint': fingerprint } + def ex_list_networks(self): + """ + Return all private virtual private cloud (VPC) networks + + :return: list of network dicts + :rtype: ``list`` + """ + params = {'Action': 'DescribeVpcs'} + + result = self.connection.request(self.path, + params=params.copy()).object + + # The list which we return + networks = [] + for element in findall(element=result, + xpath='vpcSet/item', + namespace=NAMESPACE): + + # Get the network id + vpc_id = findtext(element=element, + xpath='vpcId', + namespace=NAMESPACE) + + # Get tags + 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)) + + # Set our name is the Name key/value if available + # If we don't get anything back then use the vpc_id + name = tags.get('Name', vpc_id) + + networks.append({'vpc_id': vpc_id, + 'name': name, + 'state': findtext(element=element, + xpath='state', + namespace=NAMESPACE), + 'cidr_block': findtext(element=element, + xpath='cidrBlock', + namespace=NAMESPACE), + 'dhcp_options_id': findtext(element=element, + xpath='dhcpOptionsId', + namespace=NAMESPACE), + 'tags': tags, + 'instance_tenancy': findtext(element=element, + xpath= + 'instance_tenancy', + namespace=NAMESPACE), + 'is_default': findtext(element=element, + xpath='isDefault', + namespace=NAMESPACE)}) + + return networks + + def ex_create_network(self, cidr_block, name=None, + instance_tenancy='default'): + """ + Create a network/VPC + + :param cidr_block: The CIDR block assigned to the network + :type cidr_block: ``str`` + + :param name: An optional name for the network + :type name: ``str`` + + :param instance_tenancy: The allowed tenancy of instances launched + into the VPC. + Valid values: default/dedicated + :type instance_tenancy: ``str`` + + :return: Dictionary of network properties + :rtype: ``dict`` + """ + params = {'Action': 'CreateVpc', + 'CidrBlock': cidr_block, + 'InstanceTenancy': instance_tenancy} + + result = self.connection.request(self.path, params=params).object + + # Get our properties + response = {'vpc_id': findtext(element=result, + xpath='vpc/vpcId', + namespace=NAMESPACE), + 'state': findtext(element=result, + xpath='vpc/state', + namespace=NAMESPACE), + 'cidr_block': findtext(element=result, + xpath='vpc/cidrBlock', + namespace=NAMESPACE)} + + # Attempt to tag our network if the name was provided + if name is not None: + # Build a resource object + class Resource: + pass + + resource = Resource() + resource.id = response['vpc_id'] + self.ex_create_tags(resource, {'Name': name}) + + return response + + def ex_destroy_network(self, vpc_id): + """ + Deletes a network/VPC. + + :param vpc_id: The ID of the VPC + :type vpc_id: ``str`` + + :rtype: ``bool`` + """ + params = {'Action': 'DeleteVpc', 'VpcId': vpc_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/6d6c2c7b/libcloud/test/compute/fixtures/ec2/create_vpc.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/create_vpc.xml b/libcloud/test/compute/fixtures/ec2/create_vpc.xml new file mode 100644 index 0000000..70bff31 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/create_vpc.xml @@ -0,0 +1,10 @@ +<CreateVpcResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> + <requestId>7a662fe5-1f34-4e17-9ee9-69a28a8ac0be</requestId> + <vpc> + <vpcId>vpc-ad3527cf</vpcId> + <state>pending</state> + <cidrBlock>192.168.55.0/24</cidrBlock> + <dhcpOptionsId>dopt-7eded312</dhcpOptionsId> + <instanceTenancy>default</instanceTenancy> + </vpc> +</CreateVpcResponse> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/6d6c2c7b/libcloud/test/compute/fixtures/ec2/delete_vpc.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/delete_vpc.xml b/libcloud/test/compute/fixtures/ec2/delete_vpc.xml new file mode 100644 index 0000000..e402a50 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/delete_vpc.xml @@ -0,0 +1,4 @@ +<DeleteVpcResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> + <requestId>85793fa6-2ece-480c-855f-0f82c3257e50</requestId> + <return>true</return> +</DeleteVpcResponse> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/6d6c2c7b/libcloud/test/compute/fixtures/ec2/describe_vpcs.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/describe_vpcs.xml b/libcloud/test/compute/fixtures/ec2/describe_vpcs.xml new file mode 100644 index 0000000..ae1f516 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/describe_vpcs.xml @@ -0,0 +1,28 @@ +<DescribeVpcsResponse xmlns="http://ec2.amazonaws.com/doc/2013-10-15/"> + <requestId>be8cfa34-0710-4895-941f-961c5738f8f8</requestId> + <vpcSet> + <item> + <vpcId>vpc-532335e1</vpcId> + <state>available</state> + <cidrBlock>192.168.51.0/24</cidrBlock> + <dhcpOptionsId>dopt-7eded312</dhcpOptionsId> + <tagSet></tagSet> + <instanceTenancy>default</instanceTenancy> + <isDefault>false</isDefault> + </item> + <item> + <vpcId>vpc-62ded30e</vpcId> + <state>available</state> + <cidrBlock>192.168.51.1/24</cidrBlock> + <dhcpOptionsId>dopt-7eded312</dhcpOptionsId> + <tagSet> + <item> + <key>Name</key> + <value>Test VPC</value> + </item> + </tagSet> + <instanceTenancy>default</instanceTenancy> + <isDefault>false</isDefault> + </item> + </vpcSet> +</DescribeVpcsResponse> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/libcloud/blob/6d6c2c7b/libcloud/test/compute/test_ec2.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py index d4caacc..48aaf8d 100644 --- a/libcloud/test/compute/test_ec2.py +++ b/libcloud/test/compute/test_ec2.py @@ -708,6 +708,37 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin): 'max-elastic-ips': 5} self.assertEqual(limits['resource'], expected) + def test_ex_list_networks(self): + vpcs = self.driver.ex_list_networks() + + self.assertEqual(len(vpcs), 2) + + self.assertEqual('vpc-532335e1', vpcs[0]['vpc_id']) + self.assertEqual('available', vpcs[0]['state']) + self.assertEqual('dopt-7eded312', vpcs[0]['dhcp_options_id']) + self.assertEqual('vpc-532335e1', vpcs[0]['name']) + + self.assertEqual('vpc-62ded30e', vpcs[1]['vpc_id']) + self.assertEqual('available', vpcs[1]['state']) + self.assertEqual('dopt-7eded312', vpcs[1]['dhcp_options_id']) + self.assertEqual('Test VPC', vpcs[1]['name']) + + def test_ex_create_network(self): + vpc = self.driver.ex_create_network('192.168.55.0/24', + name='Test VPC', + instance_tenancy='default') + + self.assertEqual('vpc-ad3527cf', vpc['vpc_id']) + self.assertEqual('pending', vpc['state']) + self.assertEqual('192.168.55.0/24', vpc['cidr_block']) + + def test_ex_destroy_network(self): + vpcs = self.driver.ex_list_networks() + vpc = vpcs[0] + + resp = self.driver.ex_destroy_network(vpc['vpc_id']) + self.assertTrue(resp) + class EC2USWest1Tests(EC2Tests): region = 'us-west-1' @@ -979,6 +1010,18 @@ class EC2MockHttp(MockHttpTestCase): body = self.fixtures.load('describe_account_attributes.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _DescribeVpcs(self, method, url, body, headers): + body = self.fixtures.load('describe_vpcs.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _CreateVpc(self, method, url, body, headers): + body = self.fixtures.load('create_vpc.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _DeleteVpc(self, method, url, body, headers): + body = self.fixtures.load('delete_vpc.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + class EucMockHttp(EC2MockHttp): fixtures = ComputeFileFixtures('ec2')
