Updated Branches: refs/heads/trunk 5e77186bb -> 6e96a8aee
Issue LIBCLOUD-417: Add support for more EC2 Elastic IP Address operations. Add support for: DisassociateAddress ReleaseAddress AllocateAddress Signed-off-by: Tomaz Muraus <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/455f11c9 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/455f11c9 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/455f11c9 Branch: refs/heads/trunk Commit: 455f11c9d40ead11d3e4ad7a2f38f4f90b78c866 Parents: 5e77186 Author: Patrick Armstrong <[email protected]> Authored: Tue Oct 15 12:46:06 2013 -0400 Committer: Tomaz Muraus <[email protected]> Committed: Wed Oct 23 21:46:15 2013 +0200 ---------------------------------------------------------------------- docs/compute/drivers/ec2.rst | 10 ++++ .../create_ec2_node_and_associate_elastic_ip.py | 28 +++++++++++ libcloud/compute/drivers/ec2.py | 51 +++++++++++++++++++- .../compute/fixtures/ec2/allocate_address.xml | 5 ++ .../fixtures/ec2/disassociate_address.xml | 4 ++ .../compute/fixtures/ec2/release_address.xml | 4 ++ libcloud/test/compute/test_ec2.py | 24 +++++++++ 7 files changed, 124 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/docs/compute/drivers/ec2.rst ---------------------------------------------------------------------- diff --git a/docs/compute/drivers/ec2.rst b/docs/compute/drivers/ec2.rst index 27aff4a..51a1a33 100644 --- a/docs/compute/drivers/ec2.rst +++ b/docs/compute/drivers/ec2.rst @@ -1,6 +1,16 @@ Amazon EC2 Driver Documentation =============================== +Examples +-------- + +Allocate, Associate, Disassociate, and Release an Elastic IP +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. literalinclude:: /examples/compute/create_ec2_node_and_associate_elastic_ip.py + :language: python + + API Docs -------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/docs/examples/compute/create_ec2_node_and_associate_elastic_ip.py ---------------------------------------------------------------------- diff --git a/docs/examples/compute/create_ec2_node_and_associate_elastic_ip.py b/docs/examples/compute/create_ec2_node_and_associate_elastic_ip.py new file mode 100644 index 0000000..0f44143 --- /dev/null +++ b/docs/examples/compute/create_ec2_node_and_associate_elastic_ip.py @@ -0,0 +1,28 @@ +from libcloud.compute.types import Provider +from libcloud.compute.providers import get_driver + +ACCESS_ID = 'your access id' +SECRET_KEY = 'your secret key' + +IMAGE_ID = 'ami-c8052d8d' +SIZE_ID = 't1.micro' + +cls = get_driver(Provider.EC2_US_WEST) +driver = cls(ACCESS_ID, SECRET_KEY) + +sizes = driver.list_sizes() +images = driver.list_images() + +size = [s for s in sizes if s.id == SIZE_ID][0] +image = [i for i in images if i.id == IMAGE_ID][0] + +node = driver.create_node(name='test-node', image=image, size=size) + +# Here we allocate and associate an elastic IP +elastic_ip = driver.ex_allocate_address() +driver.ex_associate_addresses(node, elastic_ip) + +# When we are done with our elastic IP, we can disassociate from our +# node, and release it +driver.ex_disassociate_address(elastic_ip) +driver.ex_release_address(elastic_ip) http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/libcloud/compute/drivers/ec2.py ---------------------------------------------------------------------- diff --git a/libcloud/compute/drivers/ec2.py b/libcloud/compute/drivers/ec2.py index b4f414c..7eecacc 100644 --- a/libcloud/compute/drivers/ec2.py +++ b/libcloud/compute/drivers/ec2.py @@ -1300,6 +1300,36 @@ class BaseEC2NodeDriver(NodeDriver): 'Filter.0.Value.0': node.id }) + def ex_allocate_address(self): + """ + Allocate a new Elastic IP address + + :return: String representation of allocated IP address + :rtype: ``str`` + """ + params = {'Action': 'AllocateAddress'} + + response = self.connection.request(self.path, params=params).object + public_ip = findtext(element=response, xpath='publicIp', + namespace=NAMESPACE) + return public_ip + + def ex_release_address(self, elastic_ip_address): + """ + Release an Elastic IP address + + :param elastic_ip_address: Elastic IP address which should be used + :type elastic_ip_address: ``str`` + + :return: True on success, False otherwise. + :rtype: ``bool`` + """ + params = {'Action': 'ReleaseAddress'} + + params.update({'PublicIp': elastic_ip_address}) + response = self.connection.request(self.path, params=params).object + return self._get_boolean(response) + def ex_describe_all_addresses(self, only_allocated=False): """ Return all the Elastic IP addresses for this account @@ -1337,7 +1367,7 @@ class BaseEC2NodeDriver(NodeDriver): def ex_associate_addresses(self, node, elastic_ip_address): """ - Associate an IP address with a particular node. + Associate an Elastic IP address with a particular node. :param node: Node instance :type node: :class:`Node` @@ -1345,11 +1375,28 @@ class BaseEC2NodeDriver(NodeDriver): :param elastic_ip_address: IP address which should be used :type elastic_ip_address: ``str`` + :return: True on success, False otherwise. :rtype: ``bool`` """ params = {'Action': 'AssociateAddress'} - params.update(self._pathlist('InstanceId', [node.id])) + params.update({'InstanceId': node.id}) + params.update({'PublicIp': elastic_ip_address}) + res = self.connection.request(self.path, params=params).object + return self._get_boolean(res) + + def ex_disassociate_address(self, elastic_ip_address): + """ + Disassociate an Elastic IP address + + :param elastic_ip_address: Elastic IP address which should be used + :type elastic_ip_address: ``str`` + + :return: True on success, False otherwise. + :rtype: ``bool`` + """ + params = {'Action': 'DisassociateAddress'} + params.update({'PublicIp': elastic_ip_address}) res = self.connection.request(self.path, params=params).object return self._get_boolean(res) http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/libcloud/test/compute/fixtures/ec2/allocate_address.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/allocate_address.xml b/libcloud/test/compute/fixtures/ec2/allocate_address.xml new file mode 100644 index 0000000..eaa54bb --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/allocate_address.xml @@ -0,0 +1,5 @@ +<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/"> + <requestId>56926e0e-5fa3-41f3-927c-17212def59df</requestId> + <publicIp>192.0.2.1</publicIp> + <domain>standard</domain> +</AllocateAddressResponse> http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/libcloud/test/compute/fixtures/ec2/disassociate_address.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/disassociate_address.xml b/libcloud/test/compute/fixtures/ec2/disassociate_address.xml new file mode 100644 index 0000000..25a9990 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/disassociate_address.xml @@ -0,0 +1,4 @@ +<DisassociateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/"> + <requestId>dfb841f8-cc26-4f45-a3ac-dc08589eec1d</requestId> + <return>true</return> +</DisassociateAddressResponse> http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/libcloud/test/compute/fixtures/ec2/release_address.xml ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/fixtures/ec2/release_address.xml b/libcloud/test/compute/fixtures/ec2/release_address.xml new file mode 100644 index 0000000..35243c7 --- /dev/null +++ b/libcloud/test/compute/fixtures/ec2/release_address.xml @@ -0,0 +1,4 @@ +<ReleaseAddressResponse xmlns="http://ec2.amazonaws.com/doc/2010-08-31/"> + <requestId>23ec1390-8c1d-4a3e-8042-b1ad84933f57</requestId> + <return>true</return> +</ReleaseAddressResponse> http://git-wip-us.apache.org/repos/asf/libcloud/blob/455f11c9/libcloud/test/compute/test_ec2.py ---------------------------------------------------------------------- diff --git a/libcloud/test/compute/test_ec2.py b/libcloud/test/compute/test_ec2.py index 687d62e..81da921 100644 --- a/libcloud/test/compute/test_ec2.py +++ b/libcloud/test/compute/test_ec2.py @@ -459,11 +459,23 @@ class EC2Tests(LibcloudTestCase, TestCaseMixin): self.assertEqual(len(elastic_ips2), 2) self.assertTrue('1.2.3.5' not in elastic_ips2) + def test_ex_allocate_address(self): + ret = self.driver.ex_allocate_address() + self.assertTrue(ret) + + def test_ex_release_address(self): + ret = self.driver.ex_release_address('1.2.3.4') + self.assertTrue(ret) + def test_ex_associate_addresses(self): node = Node('i-4382922a', None, None, None, None, self.driver) ret = self.driver.ex_associate_addresses(node, '1.2.3.4') self.assertTrue(ret) + def test_ex_disassociate_address(self): + ret = self.driver.ex_disassociate_address('1.2.3.4') + self.assertTrue(ret) + def test_ex_change_node_size_same_size(self): size = NodeSize('m1.small', 'Small Instance', None, None, None, None, driver=self.driver) node = Node('i-4382922a', None, None, None, None, self.driver, @@ -777,10 +789,22 @@ class EC2MockHttp(MockHttpTestCase): body = self.fixtures.load('describe_addresses_multi.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _AllocateAddress(self, method, url, body, headers): + body = self.fixtures.load('allocate_address.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _AssociateAddress(self, method, url, body, headers): body = self.fixtures.load('associate_address.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _DisassociateAddress(self, method, url, body, headers): + body = self.fixtures.load('disassociate_address.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + + def _ReleaseAddress(self, method, url, body, headers): + body = self.fixtures.load('release_address.xml') + return (httplib.OK, body, {}, httplib.responses[httplib.OK]) + def _all_addresses_DescribeAddresses(self, method, url, body, headers): body = self.fixtures.load('describe_addresses_all.xml') return (httplib.OK, body, {}, httplib.responses[httplib.OK])
