You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by vd...@apache.org on 2018/12/04 08:54:19 UTC
[04/23] libcloud git commit: Move floatingips to neutron api
LIBCLOUD-874
Move floatingips to neutron api LIBCLOUD-874
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/84aa986f
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/84aa986f
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/84aa986f
Branch: refs/heads/trunk
Commit: 84aa986ff8c21db2e547b22c117cbff3795204dd
Parents: 2b2e1f1
Author: micafer <mi...@upv.es>
Authored: Tue Sep 25 15:35:28 2018 +0200
Committer: Rick van de Loo <ri...@gmail.com>
Committed: Tue Dec 4 09:45:48 2018 +0100
----------------------------------------------------------------------
libcloud/common/openstack.py | 5 +-
libcloud/compute/drivers/openstack.py | 122 ++++++++++++++++++-
.../openstack_v1.1/_v2_0__floatingip.json | 23 ++++
.../openstack_v1.1/_v2_0__floatingips.json | 52 ++++++++
.../openstack_v1.1/_v2_0__networks_public.json | 64 ++++++++++
libcloud/test/compute/test_openstack.py | 70 ++++++++++-
6 files changed, 329 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/common/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/common/openstack.py b/libcloud/common/openstack.py
index b64f669..db9f43f 100644
--- a/libcloud/common/openstack.py
+++ b/libcloud/common/openstack.py
@@ -390,8 +390,9 @@ class OpenStackResponse(Response):
context = self.connection.context
driver = self.connection.driver
key_pair_name = context.get('key_pair_name', None)
-
- if len(values) > 0 and values[0]['code'] == 404 and key_pair_name:
+ print(values)
+ if len(values) > 0 and 'code' in values[0] and \
+ values[0]['code'] == 404 and key_pair_name:
raise KeyPairDoesNotExistError(name=key_pair_name,
driver=driver)
elif len(values) > 0 and 'message' in values[0]:
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/compute/drivers/openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/openstack.py b/libcloud/compute/drivers/openstack.py
index de6d445..fb92dab 100644
--- a/libcloud/compute/drivers/openstack.py
+++ b/libcloud/compute/drivers/openstack.py
@@ -59,6 +59,7 @@ __all__ = [
'OpenStack_1_1_Connection',
'OpenStack_1_1_NodeDriver',
'OpenStack_1_1_FloatingIpPool',
+ 'OpenStack_2_FloatingIpPool',
'OpenStack_1_1_FloatingIpAddress',
'OpenStack_2_PortInterfaceState',
'OpenStack_2_PortInterface',
@@ -3255,10 +3256,29 @@ class OpenStack_2_NodeDriver(OpenStack_1_1_NodeDriver):
:rtype: ``bool``
"""
- resp = self.connection.request('/v2.0/security-group-rules/%s' %
- (rule.id), method='DELETE')
+ resp = self.network_connection.request(
+ '/v2.0/security-group-rules/%s' % (rule.id), method='DELETE')
return resp.status == httplib.NO_CONTENT
+ def _to_floating_ip_pool(self, obj):
+ return OpenStack_2_FloatingIpPool(obj['id'], obj['name'],
+ self.network_connection)
+
+ def _to_floating_ip_pools(self, obj):
+ pool_elements = obj['networks']
+ return [self._to_floating_ip_pool(pool) for pool in pool_elements]
+
+ def ex_list_floating_ip_pools(self):
+ """
+ List available floating IP pools
+
+ :rtype: ``list`` of :class:`OpenStack_1_1_FloatingIpPool`
+ """
+ return self._to_floating_ip_pools(
+ self.network_connection.request('/v2.0/networks?router:external'
+ '=True&fields=id&fields='
+ 'name').object)
+
class OpenStack_1_1_FloatingIpPool(object):
"""
@@ -3365,6 +3385,104 @@ class OpenStack_1_1_FloatingIpAddress(object):
% (self.id, self.ip_address, self.pool, self.driver))
+class OpenStack_2_FloatingIpPool(OpenStack_1_1_FloatingIpPool):
+ """
+ Floating IP Pool info.
+ """
+
+ def __init__(self, id, name, connection):
+ self.id = id
+ self.name = name
+ self.connection = connection
+
+ def _to_floating_ips(self, obj):
+ ip_elements = obj['floatingips']
+ return [self._to_floating_ip(ip) for ip in ip_elements]
+
+ def _to_floating_ip(self, obj):
+ instance_id = None
+
+ # In neutron version prior to 13.0.0 port_details does not exists
+ if 'port_details' not in obj and 'port_id' in obj:
+ port = self.connection.driver.ex_get_port(obj['port_id'])
+ if port:
+ obj['port_details'] = {"device_id": port.extra["device_id"],
+ "device_owner":
+ port.extra["device_owner"],
+ "mac_address":
+ port.extra["mac_address"]}
+
+ if 'port_details' in obj and obj['port_details']:
+ if obj['port_details']['device_owner'] == 'compute:nova':
+ instance_id = obj['port_details']['device_id']
+
+ ip_address = obj['floating_ip_address']
+ return OpenStack_1_1_FloatingIpAddress(id=obj['id'],
+ ip_address=ip_address,
+ pool=self,
+ node_id=instance_id,
+ driver=self.connection.driver)
+
+ def list_floating_ips(self):
+ """
+ List floating IPs in the pool
+
+ :rtype: ``list`` of :class:`OpenStack_1_1_FloatingIpAddress`
+ """
+ return self._to_floating_ips(
+ self.connection.request('/v2.0/floatingips').object)
+
+ def get_floating_ip(self, ip):
+ """
+ Get specified floating IP from the pool
+
+ :param ip: floating IP to get
+ :type ip: ``str``
+
+ :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
+ """
+ floating_ips = self._to_floating_ips(
+ self.connection.request('/v2.0/floatingips?floating_ip_address'
+ '=%s' % ip).object)
+ return floating_ips[0]
+
+ def create_floating_ip(self):
+ """
+ Create new floating IP in the pool
+
+ :rtype: :class:`OpenStack_1_1_FloatingIpAddress`
+ """
+ resp = self.connection.request('/v2.0/floatingips',
+ method='POST',
+ data={'floatingip':
+ {'floating_network_id': self.id}}
+ )
+ data = resp.object['floatingip']
+ id = data['id']
+ ip_address = data['floating_ip_address']
+ return OpenStack_1_1_FloatingIpAddress(id=id,
+ ip_address=ip_address,
+ pool=self,
+ node_id=None,
+ driver=self.connection.driver)
+
+ def delete_floating_ip(self, ip):
+ """
+ Delete specified floating IP from the pool
+
+ :param ip: floating IP to remove
+ :type ip: :class:`OpenStack_1_1_FloatingIpAddress`
+
+ :rtype: ``bool``
+ """
+ resp = self.connection.request('/v2.0/floatingips/%s' % ip.id,
+ method='DELETE')
+ return resp.status in (httplib.NO_CONTENT, httplib.ACCEPTED)
+
+ def __repr__(self):
+ return ('<OpenStack_2_FloatingIpPool: name=%s>' % self.name)
+
+
class OpenStack_2_SubNet(object):
"""
A Virtual SubNet.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingip.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingip.json b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingip.json
new file mode 100644
index 0000000..0ef2ef5
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingip.json
@@ -0,0 +1,23 @@
+{
+ "floatingip":
+ {
+ "router_id": null,
+ "description": "for test",
+ "dns_domain": "my-domain.org.",
+ "dns_name": "myfip2",
+ "created_at": "2016-12-21T11:55:50Z",
+ "updated_at": "2016-12-21T11:55:53Z",
+ "revision_number": 2,
+ "project_id": "4969c491a3c74ee4af974e6d800c62de",
+ "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
+ "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
+ "fixed_ip_address": null,
+ "floating_ip_address": "10.3.1.42",
+ "port_id": null,
+ "id": "09ea1784-2f81-46dc-8c91-244b4df75bde",
+ "status": "DOWN",
+ "port_details": null,
+ "tags": ["tag1,tag2"],
+ "port_forwardings": []
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
new file mode 100644
index 0000000..fa71752
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__floatingips.json
@@ -0,0 +1,52 @@
+{
+ "floatingips": [
+ {
+ "router_id": null,
+ "description": "for test",
+ "dns_domain": "my-domain.org.",
+ "dns_name": "myfip2",
+ "created_at": "2016-12-21T11:55:50Z",
+ "updated_at": "2016-12-21T11:55:53Z",
+ "revision_number": 2,
+ "project_id": "4969c491a3c74ee4af974e6d800c62de",
+ "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
+ "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
+ "fixed_ip_address": null,
+ "floating_ip_address": "10.3.1.42",
+ "port_id": null,
+ "id": "09ea1784-2f81-46dc-8c91-244b4df75bde",
+ "status": "DOWN",
+ "port_details": null,
+ "tags": ["tag1,tag2"],
+ "port_forwardings": []
+ },
+ {
+ "router_id": "d23abc8d-2991-4a55-ba98-2aaea84cc72f",
+ "description": "for test",
+ "dns_domain": "my-domain.org.",
+ "dns_name": "myfip",
+ "created_at": "2016-12-21T10:55:50Z",
+ "updated_at": "2016-12-21T10:55:53Z",
+ "revision_number": 1,
+ "project_id": "4969c491a3c74ee4af974e6d800c62de",
+ "tenant_id": "4969c491a3c74ee4af974e6d800c62de",
+ "floating_network_id": "376da547-b977-4cfe-9cba-275c80debf57",
+ "fixed_ip_address": "10.0.0.3",
+ "floating_ip_address": "10.3.1.1",
+ "port_id": "ce705c24-c1ef-408a-bda3-7bbd946164ab",
+ "id": "04c5336a-0629-4694-ba30-04b0bdfa88a4",
+ "status": "ACTIVE",
+ "port_details": {
+ "status": "ACTIVE",
+ "name": "",
+ "admin_state_up": true,
+ "network_id": "02dd8479-ef26-4398-a102-d19d0a7b3a1f",
+ "device_owner": "compute:nova",
+ "mac_address": "fa:16:3e:b1:3b:30",
+ "device_id": "fcfc96da-19e2-40fd-8497-f29da1b21143"
+ },
+ "tags": ["tag1,tag2"],
+ "port_forwardings": []
+ }
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__networks_public.json
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__networks_public.json b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__networks_public.json
new file mode 100644
index 0000000..4ac5688
--- /dev/null
+++ b/libcloud/test/compute/fixtures/openstack_v1.1/_v2_0__networks_public.json
@@ -0,0 +1,64 @@
+{
+ "networks": [
+ {
+ "admin_state_up": true,
+ "availability_zone_hints": [],
+ "availability_zones": [
+ "nova"
+ ],
+ "created_at": "2016-03-08T20:19:41",
+ "dns_domain": "my-domain.org.",
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ "ipv4_address_scope": null,
+ "ipv6_address_scope": null,
+ "l2_adjacency": false,
+ "mtu": 1500,
+ "name": "public",
+ "port_security_enabled": true,
+ "project_id": "4fd44f30292945e481c7b8a0c8908869",
+ "qos_policy_id": "6a8454ade84346f59e8d40665f878b2e",
+ "revision_number": 1,
+ "router:external": true,
+ "shared": false,
+ "status": "ACTIVE",
+ "subnets": [
+ "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
+ ],
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "updated_at": "2016-03-08T20:19:41",
+ "vlan_transparent": true,
+ "description": "",
+ "is_default": false
+ },
+ {
+ "admin_state_up": true,
+ "availability_zone_hints": [],
+ "availability_zones": [
+ "nova"
+ ],
+ "created_at": "2016-03-08T20:19:41",
+ "dns_domain": "my-domain.org.",
+ "id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ "ipv4_address_scope": null,
+ "ipv6_address_scope": null,
+ "l2_adjacency": false,
+ "mtu": 1500,
+ "name": "foobar",
+ "port_security_enabled": true,
+ "project_id": "4fd44f30292945e481c7b8a0c8908869",
+ "qos_policy_id": "6a8454ade84346f59e8d40665f878b2e",
+ "revision_number": 1,
+ "router:external": true,
+ "shared": false,
+ "status": "ACTIVE",
+ "subnets": [
+ "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
+ ],
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "updated_at": "2016-03-08T20:19:41",
+ "vlan_transparent": true,
+ "description": "",
+ "is_default": false
+ }
+ ]
+}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/84aa986f/libcloud/test/compute/test_openstack.py
----------------------------------------------------------------------
diff --git a/libcloud/test/compute/test_openstack.py b/libcloud/test/compute/test_openstack.py
index 3faea2b..db7b357 100644
--- a/libcloud/test/compute/test_openstack.py
+++ b/libcloud/test/compute/test_openstack.py
@@ -45,7 +45,7 @@ from libcloud.compute.drivers.openstack import (
OpenStack_1_1_NodeDriver, OpenStackSecurityGroup,
OpenStackSecurityGroupRule, OpenStack_1_1_FloatingIpPool,
OpenStack_1_1_FloatingIpAddress, OpenStackKeyPair,
- OpenStack_1_0_Connection,
+ OpenStack_1_0_Connection, OpenStack_2_FloatingIpPool,
OpenStackNodeDriver,
OpenStack_2_NodeDriver, OpenStack_2_PortInterfaceState, OpenStackNetwork)
from libcloud.compute.base import Node, NodeImage, NodeSize
@@ -1399,6 +1399,53 @@ class OpenStack_1_1_Tests(unittest.TestCase, TestCaseMixin):
self.assertEqual(pool.delete_floating_ip.call_count, 1)
+ def test_OpenStack_2_FloatingIpPool_list_floating_ips(self):
+ pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
+ ret = pool.list_floating_ips()
+
+ self.assertEqual(ret[0].id, '09ea1784-2f81-46dc-8c91-244b4df75bde')
+ self.assertEqual(ret[0].pool, pool)
+ self.assertEqual(ret[0].ip_address, '10.3.1.42')
+ self.assertEqual(ret[0].node_id, None)
+ self.assertEqual(ret[1].id, '04c5336a-0629-4694-ba30-04b0bdfa88a4')
+ self.assertEqual(ret[1].pool, pool)
+ self.assertEqual(ret[1].ip_address, '10.3.1.1')
+ self.assertEqual(
+ ret[1].node_id, 'fcfc96da-19e2-40fd-8497-f29da1b21143')
+
+ def test_OpenStack_2_FloatingIpPool_get_floating_ip(self):
+ pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
+ ret = pool.get_floating_ip('10.3.1.42')
+
+ self.assertEqual(ret.id, '09ea1784-2f81-46dc-8c91-244b4df75bde')
+ self.assertEqual(ret.pool, pool)
+ self.assertEqual(ret.ip_address, '10.3.1.42')
+ self.assertEqual(ret.node_id, None)
+
+ def test_OpenStack_2_FloatingIpPool_create_floating_ip(self):
+ pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
+ ret = pool.create_floating_ip()
+
+ self.assertEqual(ret.id, '09ea1784-2f81-46dc-8c91-244b4df75bde')
+ self.assertEqual(ret.pool, pool)
+ self.assertEqual(ret.ip_address, '10.3.1.42')
+ self.assertEqual(ret.node_id, None)
+
+ def test_OpenStack_2_FloatingIpPool_delete_floating_ip(self):
+ pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
+ ip = OpenStack_1_1_FloatingIpAddress('foo-bar-id', '42.42.42.42', pool)
+
+ self.assertTrue(pool.delete_floating_ip(ip))
+
+ def test_OpenStack_2_FloatingIpAddress_delete(self):
+ pool = OpenStack_2_FloatingIpPool(1, 'foo', self.driver.connection)
+ pool.delete_floating_ip = Mock()
+ ip = OpenStack_1_1_FloatingIpAddress('foo-bar-id', '42.42.42.42', pool)
+
+ ip.pool.delete_floating_ip()
+
+ self.assertEqual(pool.delete_floating_ip.call_count, 1)
+
def test_ex_get_metadata_for_node(self):
image = NodeImage(id=11, name='Ubuntu 8.10 (intrepid)', driver=self.driver)
size = NodeSize(1, '256 slice', None, None, None, None, driver=self.driver)
@@ -2374,8 +2421,12 @@ class OpenStack_1_1_MockHttp(MockHttp, unittest.TestCase):
def _v2_1337_v2_0_networks(self, method, url, body, headers):
if method == 'GET':
- body = self.fixtures.load('_v2_0__networks.json')
- return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+ if "router:external=True" in url:
+ body = self.fixtures.load('_v2_0__networks_public.json')
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+ else:
+ body = self.fixtures.load('_v2_0__networks.json')
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
elif method == 'POST':
body = self.fixtures.load('_v2_0__networks_POST.json')
return (httplib.ACCEPTED, body, self.json_content_headers, httplib.responses[httplib.OK])
@@ -2453,6 +2504,19 @@ class OpenStack_1_1_MockHttp(MockHttp, unittest.TestCase):
body = ''
return (httplib.NO_CONTENT, body, self.json_content_headers, httplib.responses[httplib.OK])
+ def _v2_1337_v2_0_floatingips(self, method, url, body, headers):
+ if method == 'POST':
+ body = self.fixtures.load('_v2_0__floatingip.json')
+ return (httplib.CREATED, body, self.json_content_headers, httplib.responses[httplib.OK])
+ if method == 'GET':
+ body = self.fixtures.load('_v2_0__floatingips.json')
+ return (httplib.OK, body, self.json_content_headers, httplib.responses[httplib.OK])
+
+ def _v2_1337_v2_0_floatingips_foo_bar_id(self, method, url, body, headers):
+ if method == 'DELETE':
+ body = ''
+ return (httplib.NO_CONTENT, body, self.json_content_headers, httplib.responses[httplib.OK])
+
# This exists because the nova compute url in devstack has v2 in there but the v1.1 fixtures
# work fine.