Make neutronapi get_floating*() methods return objects

This makes the neutronapi module return NeutronFloatingIP objects from
the relevant methods, instead of bare dicts.

Note that the API is returning string floating ip identifiers when neutron
is in use, as opposed to the integer ones returned when nova-network is in
use. This patch does not address that problem, but uses the new
NeutronFloatingIP.

Needed for blueprint rm-object-dict-compat-newton

Co-Authored-By: Ryan Rossiter <rlrossit@us.ibm.com>
Change-Id: Ie60fb8661195eec9c01a57129efe8145504789e1
This commit is contained in:
Dan Smith 2014-11-20 15:19:11 -08:00 committed by Jay Pipes
parent 500f3ddf6e
commit a0bedb332c
3 changed files with 113 additions and 26 deletions

View File

@ -1362,7 +1362,7 @@ class API(base_api.NetworkAPI):
pool_dict = self._setup_net_dict(client,
fip['floating_network_id'])
port_dict = self._setup_port_dict(context, client, fip['port_id'])
return self._format_floating_ip_model(fip, pool_dict, port_dict)
return self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
def _get_floating_ip_pools(self, client, project_id=None):
search_opts = {constants.NET_EXTERNAL: True}
@ -1379,27 +1379,31 @@ class API(base_api.NetworkAPI):
# nova.network.api.get_floating_ip_pools
return [n['name'] or n['id'] for n in pools]
def _format_floating_ip_model(self, fip, pool_dict, port_dict):
def _make_floating_ip_obj(self, context, fip, pool_dict, port_dict):
pool = pool_dict[fip['floating_network_id']]
result = {'id': fip['id'],
'address': fip['floating_ip_address'],
'pool': pool['name'] or pool['id'],
'project_id': fip['tenant_id'],
# In Neutron v2, an exact fixed_ip_id does not exist.
'fixed_ip_id': fip['port_id'],
}
# NOTE(danms): Don't give these objects a context, since they're
# not lazy-loadable anyway
floating = objects.floating_ip.NeutronFloatingIP(
id=fip['id'], address=fip['floating_ip_address'],
pool=(pool['name'] or pool['id']), project_id=fip['tenant_id'],
fixed_ip_id=fip['port_id'])
# In Neutron v2 API fixed_ip_address and instance uuid
# (= device_id) are known here, so pass it as a result.
result['fixed_ip'] = {'address': fip['fixed_ip_address']}
if fip['fixed_ip_address']:
floating.fixed_ip = objects.FixedIP(
address=fip['fixed_ip_address'])
else:
floating.fixed_ip = None
if fip['port_id']:
instance_uuid = port_dict[fip['port_id']]['device_id']
result['instance'] = {'uuid': instance_uuid}
# TODO(mriedem): remove this workaround once the get_floating_ip*
# API methods are converted to use nova objects.
result['fixed_ip']['instance_uuid'] = instance_uuid
# NOTE(danms): This could be .refresh()d, so give it context
floating.instance = objects.Instance(context=context,
uuid=instance_uuid)
if floating.fixed_ip:
floating.fixed_ip.instance_uuid = instance_uuid
else:
result['instance'] = None
return result
floating.instance = None
return floating
def get_floating_ip_by_address(self, context, address):
"""Return a floating IP given an address."""
@ -1408,7 +1412,7 @@ class API(base_api.NetworkAPI):
pool_dict = self._setup_net_dict(client,
fip['floating_network_id'])
port_dict = self._setup_port_dict(context, client, fip['port_id'])
return self._format_floating_ip_model(fip, pool_dict, port_dict)
return self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
def get_floating_ips_by_project(self, context):
client = get_client(context)
@ -1418,7 +1422,7 @@ class API(base_api.NetworkAPI):
return []
pool_dict = self._setup_pools_dict(client)
port_dict = self._setup_ports_dict(client, project_id)
return [self._format_floating_ip_model(fip, pool_dict, port_dict)
return [self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
for fip in fips]
def get_instance_id_by_floating_address(self, context, address):

View File

@ -269,6 +269,15 @@ class FloatingIpTestV21(test.TestCase):
self.assertIsNone(view['floating_ip']['fixed_ip'])
self.assertIsNone(view['floating_ip']['instance_id'])
def test_translate_floating_ip_view_neutronesque(self):
uuid = 'ca469a10-fa76-11e5-86aa-5e5517507c66'
fixed_id = 'ae900cf4-fb73-11e5-86aa-5e5517507c66'
floating_ip = objects.floating_ip.NeutronFloatingIP(id=uuid,
address='1.2.3.4', pool='pool', context='ctxt',
fixed_ip_id=fixed_id)
view = self.floating_ips._translate_floating_ip_view(floating_ip)
self.assertEqual(uuid, view['floating_ip']['id'])
def test_translate_floating_ip_view_dict(self):
floating_ip = {'id': 0, 'address': '10.0.0.10', 'pool': 'nova',
'fixed_ip': None}

View File

@ -22,6 +22,7 @@ from keystoneauth1.fixture import V2Token
from keystoneauth1 import loading as ks_loading
import mock
from mox3 import mox
import netaddr
from neutronclient.common import exceptions
from neutronclient.v2_0 import client
from oslo_config import cfg
@ -2039,17 +2040,24 @@ class TestNeutronv2(TestNeutronv2Base):
'address': fip_data['floating_ip_address'],
'pool': self.fip_pool['name'],
'project_id': fip_data['tenant_id'],
'fixed_ip_id': fip_data['port_id'],
'fixed_ip':
{'address': fip_data['fixed_ip_address']},
'fixed_ip': None,
'instance': ({'uuid': self.port_data2[idx]['device_id']}
if fip_data['port_id']
else None)}
if expected['instance'] is not None:
expected['fixed_ip']['instance_uuid'] = \
expected['instance']['uuid']
if fip_data['fixed_ip_address']:
expected['fixed_ip'] = {'address': fip_data['fixed_ip_address']}
return expected
def _compare(self, obj, dic):
for key, value in dic.items():
objvalue = obj[key]
if isinstance(value, dict):
self._compare(objvalue, value)
elif isinstance(objvalue, netaddr.IPAddress):
self.assertEqual(value, str(objvalue))
else:
self.assertEqual(value, objvalue)
def _test_get_floating_ip(self, fip_data, idx=0, by_address=False):
api = neutronapi.API()
fip_id = fip_data['id']
@ -2074,7 +2082,7 @@ class TestNeutronv2(TestNeutronv2Base):
fip = api.get_floating_ip_by_address(self.context, address)
else:
fip = api.get_floating_ip(self.context, fip_id)
self.assertEqual(expected, fip)
self._compare(fip, expected)
def test_get_floating_ip_unassociated(self):
self._test_get_floating_ip(self.fip_unassociated, idx=0)
@ -2148,7 +2156,9 @@ class TestNeutronv2(TestNeutronv2Base):
expected = [self._get_expected_fip_model(self.fip_unassociated),
self._get_expected_fip_model(self.fip_associated, idx=1)]
fips = api.get_floating_ips_by_project(self.context)
self.assertEqual(expected, fips)
self.assertEqual(len(expected), len(fips))
for i, expected_value in enumerate(expected):
self._compare(fips[i], expected_value)
def _test_get_instance_id_by_floating_address(self, fip_data,
associated=False):
@ -3849,6 +3859,70 @@ class TestNeutronv2WithMock(test.TestCase):
port_client.update_port.assert_called_once_with(
uuids.port_id, port_req_body)
def test_make_floating_ip_obj(self):
self._test_make_floating_ip_obj()
def test_make_floating_ip_obj_pool_id(self):
self._test_make_floating_ip_obj(set_pool_name=False)
def test_make_floating_ip_obj_no_fixed_ip_address(self):
self._test_make_floating_ip_obj(set_fixed_ip=False)
def test_make_floating_ip_obj_no_port_id(self):
self._test_make_floating_ip_obj(set_port=False)
def _test_make_floating_ip_obj(self, set_port=True, set_fixed_ip=True,
set_pool_name=True):
net_id = '6cd58996-001a-11e6-86aa-5e5517507c66'
float_id = 'ea474936-0016-11e6-86aa-5e5517507c66'
tenant_id = '310b1db6-0017-11e6-86aa-5e5517507c66'
port_id = '40cfc710-0017-11e6-86aa-5e5517507c66' if set_port else None
device_id = '6b892334-0017-11e6-86aa-5e5517507c66'
floating_ip_address = '10.0.0.1'
fixed_ip_address = '192.168.100.100' if set_fixed_ip else None
pool_name = 'my_pool' if set_pool_name else None
pool_id = 'd7f7150e-001b-11e6-86aa-5e5517507c66'
fip = {'id': float_id,
'floating_ip_address': floating_ip_address,
'tenant_id': tenant_id,
'port_id': port_id,
'fixed_ip_address': fixed_ip_address,
'floating_network_id': net_id
}
pool_dict = {net_id: {'name': pool_name, 'id': pool_id}}
port_dict = {port_id: {'device_id': device_id}}
actual_obj = self.api._make_floating_ip_obj(self.context, fip,
pool_dict, port_dict)
expected_pool = pool_name if set_pool_name else pool_id
if set_fixed_ip:
if set_port:
expected_fixed = objects.FixedIP(address=fixed_ip_address,
instance_uuid=device_id)
else:
expected_fixed = objects.FixedIP(address=fixed_ip_address)
else:
expected_fixed = None
if set_port:
expected_instance = objects.Instance(context=context,
uuid=device_id)
else:
expected_instance = None
expected_floating = objects.floating_ip.NeutronFloatingIP(
id=float_id, address=floating_ip_address, pool=expected_pool,
project_id=tenant_id, fixed_ip_id=port_id,
fixed_ip=expected_fixed, instance=expected_instance)
self.assertEqual(expected_floating.obj_to_primitive(),
actual_obj.obj_to_primitive())
class TestNeutronv2ModuleMethods(test.NoDBTestCase):