Skip to content

Commit 7601efa

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "nova-net: Remove use of legacy 'FloatingIP' object"
2 parents 1d9a131 + 6b44628 commit 7601efa

File tree

9 files changed

+112
-402
lines changed

9 files changed

+112
-402
lines changed

nova/api/openstack/compute/floating_ip_pools.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
from nova.policies import floating_ip_pools as fip_policies
2020

2121

22-
def _translate_floating_ip_view(pool_name):
22+
def _translate_floating_ip_view(pool):
2323
return {
24-
'name': pool_name,
24+
'name': pool['name'] or pool['id'],
2525
}
2626

2727

2828
def _translate_floating_ip_pools_view(pools):
2929
return {
30-
'floating_ip_pools': [_translate_floating_ip_view(pool_name)
31-
for pool_name in pools]
30+
'floating_ip_pools': [_translate_floating_ip_view(pool)
31+
for pool in pools]
3232
}
3333

3434

nova/api/openstack/compute/floating_ips.py

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
from oslo_log import log as logging
1919
from oslo_utils import netutils
20-
from oslo_utils import uuidutils
2120
import webob
2221

2322
from nova.api.openstack.api_version_request \
@@ -37,45 +36,21 @@
3736

3837

3938
def _translate_floating_ip_view(floating_ip):
40-
result = {
41-
'id': floating_ip['id'],
42-
'ip': floating_ip['address'],
43-
'pool': floating_ip['pool'],
39+
instance_id = None
40+
if floating_ip['port_details']:
41+
instance_id = floating_ip['port_details']['device_id']
42+
43+
return {
44+
'floating_ip': {
45+
'id': floating_ip['id'],
46+
'ip': floating_ip['floating_ip_address'],
47+
'pool': floating_ip['network_details']['name'] or (
48+
floating_ip['network_details']['id']),
49+
'fixed_ip': floating_ip['fixed_ip_address'],
50+
'instance_id': instance_id,
51+
}
4452
}
4553

46-
# If fixed_ip is unset on floating_ip, then we can't get any of the next
47-
# stuff, so we'll just short-circuit
48-
if 'fixed_ip' not in floating_ip:
49-
result['fixed_ip'] = None
50-
result['instance_id'] = None
51-
return {'floating_ip': result}
52-
53-
# TODO(rlrossit): These look like dicts, but they're actually versioned
54-
# objects, so we need to do these contain checks because they will not be
55-
# caught by the exceptions below (it raises NotImplementedError and
56-
# OrphanedObjectError. This comment can probably be removed when
57-
# the dict syntax goes away.
58-
try:
59-
if 'address' in floating_ip['fixed_ip']:
60-
result['fixed_ip'] = floating_ip['fixed_ip']['address']
61-
else:
62-
result['fixed_ip'] = None
63-
except (TypeError, KeyError, AttributeError):
64-
result['fixed_ip'] = None
65-
try:
66-
if 'instance_uuid' in floating_ip['fixed_ip']:
67-
result['instance_id'] = floating_ip['fixed_ip']['instance_uuid']
68-
else:
69-
result['instance_id'] = None
70-
except (TypeError, KeyError, AttributeError):
71-
result['instance_id'] = None
72-
return {'floating_ip': result}
73-
74-
75-
def _translate_floating_ips_view(floating_ips):
76-
return {'floating_ips': [_translate_floating_ip_view(ip)['floating_ip']
77-
for ip in floating_ips]}
78-
7954

8055
def get_instance_by_floating_ip_addr(self, context, address):
8156
try:
@@ -136,7 +111,8 @@ def index(self, req):
136111

137112
floating_ips = self.network_api.get_floating_ips_by_project(context)
138113

139-
return _translate_floating_ips_view(floating_ips)
114+
return {'floating_ips': [_translate_floating_ip_view(ip)['floating_ip']
115+
for ip in floating_ips]}
140116

141117
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
142118
@wsgi.expected_errors((400, 403, 404))
@@ -185,7 +161,7 @@ def delete(self, req, id):
185161
except exception.InvalidID as e:
186162
raise webob.exc.HTTPBadRequest(explanation=e.format_message())
187163

188-
address = floating_ip['address']
164+
address = floating_ip['floating_ip_address']
189165

190166
# get the associated instance object (if any)
191167
instance = get_instance_by_floating_ip_addr(self, context, address)
@@ -311,11 +287,7 @@ def _remove_floating_ip(self, req, id, body):
311287
instance = get_instance_by_floating_ip_addr(self, context, address)
312288

313289
# disassociate if associated
314-
if (instance and
315-
floating_ip.get('fixed_ip_id') and
316-
(uuidutils.is_uuid_like(id) and
317-
[instance.uuid == id] or
318-
[instance.id == id])[0]):
290+
if instance and floating_ip['port_id'] and instance.uuid == id:
319291
try:
320292
disassociate_floating_ip(self, context, instance, address)
321293
except exception.FloatingIpNotAssociated:

nova/network/neutron.py

Lines changed: 53 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2578,27 +2578,6 @@ def get_fixed_ip_by_address(self, context, address):
25782578
raise exception.FixedIpAssociatedWithMultipleInstances(
25792579
address=address)
25802580

2581-
def _setup_net_dict(self, client, network_id):
2582-
if not network_id:
2583-
return {}
2584-
pool = client.show_network(network_id)['network']
2585-
return {pool['id']: pool}
2586-
2587-
def _setup_port_dict(self, context, client, port_id):
2588-
if not port_id:
2589-
return {}
2590-
port = self._show_port(context, port_id, neutron_client=client)
2591-
return {port['id']: port}
2592-
2593-
def _setup_pools_dict(self, client):
2594-
pools = self._get_floating_ip_pools(client)
2595-
return {i['id']: i for i in pools}
2596-
2597-
def _setup_ports_dict(self, client, project_id=None):
2598-
search_opts = {'tenant_id': project_id} if project_id else {}
2599-
ports = client.list_ports(**search_opts)['ports']
2600-
return {p['id']: p for p in ports}
2601-
26022581
def get_floating_ip(self, context, id):
26032582
"""Return floating IP object given the floating IP id."""
26042583
client = get_client(context)
@@ -2607,72 +2586,64 @@ def get_floating_ip(self, context, id):
26072586
except neutron_client_exc.NeutronClientException as e:
26082587
if e.status_code == 404:
26092588
raise exception.FloatingIpNotFound(id=id)
2610-
else:
2611-
with excutils.save_and_reraise_exception():
2612-
LOG.exception('Unable to access floating IP %s', id)
2613-
pool_dict = self._setup_net_dict(client,
2614-
fip['floating_network_id'])
2615-
port_dict = self._setup_port_dict(context, client, fip['port_id'])
2616-
return self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
2617-
2618-
def _get_floating_ip_pools(self, client, project_id=None):
2619-
search_opts = {constants.NET_EXTERNAL: True}
2620-
if project_id:
2621-
search_opts.update({'tenant_id': project_id})
2622-
data = client.list_networks(**search_opts)
2623-
return data['networks']
2589+
2590+
with excutils.save_and_reraise_exception():
2591+
LOG.exception('Unable to access floating IP %s', id)
2592+
2593+
# retrieve and cache the network details now since many callers need
2594+
# the network name which isn't present in the response from neutron
2595+
network_uuid = fip['floating_network_id']
2596+
try:
2597+
fip['network_details'] = client.show_network(
2598+
network_uuid)['network']
2599+
except neutron_client_exc.NetworkNotFoundClient:
2600+
raise exception.NetworkNotFound(network_id=network_uuid)
2601+
2602+
return fip
26242603

26252604
def get_floating_ip_pools(self, context):
2626-
"""Return floating IP pool names."""
2605+
"""Return floating IP pools a.k.a. external networks."""
26272606
client = get_client(context)
2628-
pools = self._get_floating_ip_pools(client)
2629-
return [n['name'] or n['id'] for n in pools]
2630-
2631-
def _make_floating_ip_obj(self, context, fip, pool_dict, port_dict):
2632-
pool = pool_dict[fip['floating_network_id']]
2633-
# NOTE(danms): Don't give these objects a context, since they're
2634-
# not lazy-loadable anyway
2635-
floating = objects.floating_ip.NeutronFloatingIP(
2636-
id=fip['id'], address=fip['floating_ip_address'],
2637-
pool=(pool['name'] or pool['id']), project_id=fip['tenant_id'],
2638-
fixed_ip_id=fip['port_id'])
2639-
# In Neutron v2 API fixed_ip_address and instance uuid
2640-
# (= device_id) are known here, so pass it as a result.
2641-
if fip['fixed_ip_address']:
2642-
floating.fixed_ip = objects.FixedIP(
2643-
address=fip['fixed_ip_address'])
2644-
else:
2645-
floating.fixed_ip = None
2646-
if fip['port_id']:
2647-
instance_uuid = port_dict[fip['port_id']]['device_id']
2648-
# NOTE(danms): This could be .refresh()d, so give it context
2649-
floating.instance = objects.Instance(context=context,
2650-
uuid=instance_uuid)
2651-
if floating.fixed_ip:
2652-
floating.fixed_ip.instance_uuid = instance_uuid
2653-
else:
2654-
floating.instance = None
2655-
return floating
2607+
data = client.list_networks(**{constants.NET_EXTERNAL: True})
2608+
return data['networks']
26562609

26572610
def get_floating_ip_by_address(self, context, address):
26582611
"""Return a floating IP given an address."""
26592612
client = get_client(context)
26602613
fip = self._get_floating_ip_by_address(client, address)
2661-
pool_dict = self._setup_net_dict(client,
2662-
fip['floating_network_id'])
2663-
port_dict = self._setup_port_dict(context, client, fip['port_id'])
2664-
return self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
2614+
2615+
# retrieve and cache the network details now since many callers need
2616+
# the network name which isn't present in the response from neutron
2617+
network_uuid = fip['floating_network_id']
2618+
try:
2619+
fip['network_details'] = client.show_network(
2620+
network_uuid)['network']
2621+
except neutron_client_exc.NetworkNotFoundClient:
2622+
raise exception.NetworkNotFound(network_id=network_uuid)
2623+
2624+
return fip
26652625

26662626
def get_floating_ips_by_project(self, context):
26672627
client = get_client(context)
26682628
project_id = context.project_id
26692629
fips = self._safe_get_floating_ips(client, tenant_id=project_id)
2670-
if not fips:
2671-
return []
2672-
pool_dict = self._setup_pools_dict(client)
2673-
port_dict = self._setup_ports_dict(client, project_id)
2674-
return [self._make_floating_ip_obj(context, fip, pool_dict, port_dict)
2675-
for fip in fips]
2630+
2631+
# retrieve and cache the network details now since many callers need
2632+
# the network name which isn't present in the response from neutron
2633+
networks = {}
2634+
for fip in fips:
2635+
network_uuid = fip['floating_network_id']
2636+
if network_uuid not in networks:
2637+
try:
2638+
network = client.show_network(network_uuid)['network']
2639+
except neutron_client_exc.NetworkNotFoundClient:
2640+
raise exception.NetworkNotFound(network_id=network_uuid)
2641+
2642+
networks[network['id']] = network
2643+
2644+
fip['network_details'] = networks[network_uuid]
2645+
2646+
return fips
26762647

26772648
def get_instance_id_by_floating_address(self, context, address):
26782649
"""Return the instance id a floating IP's fixed IP is allocated to."""
@@ -2787,7 +2758,7 @@ def release_floating_ip(self, context, address,
27872758
self._release_floating_ip(context, address)
27882759

27892760
def disassociate_and_release_floating_ip(self, context, instance,
2790-
floating_ip):
2761+
floating_ip):
27912762
"""Removes (deallocates) and deletes the floating IP.
27922763
27932764
This api call was added to allow this to be done in one operation
@@ -2797,14 +2768,17 @@ def disassociate_and_release_floating_ip(self, context, instance,
27972768
@refresh_cache
27982769
def _release_floating_ip_and_refresh_cache(self, context, instance,
27992770
floating_ip):
2800-
self._release_floating_ip(context, floating_ip['address'],
2801-
raise_if_associated=False)
2771+
self._release_floating_ip(
2772+
context, floating_ip['floating_ip_address'],
2773+
raise_if_associated=False)
2774+
28022775
if instance:
28032776
_release_floating_ip_and_refresh_cache(self, context, instance,
28042777
floating_ip)
28052778
else:
2806-
self._release_floating_ip(context, floating_ip['address'],
2807-
raise_if_associated=False)
2779+
self._release_floating_ip(
2780+
context, floating_ip['floating_ip_address'],
2781+
raise_if_associated=False)
28082782

28092783
def _release_floating_ip(self, context, address,
28102784
raise_if_associated=True):

nova/tests/functional/api_sample_tests/test_floating_ip_pools.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ class FloatingIPPoolsSampleTests(api_sample_base.ApiSampleTestBaseV21):
1919
sample_dir = "os-floating-ip-pools"
2020

2121
def test_list_floatingippools(self):
22-
pool_list = ["pool1", "pool2"]
22+
pool_list = [
23+
{'name': 'pool1'},
24+
{'name': 'pool2'},
25+
]
2326

2427
def fake_get_floating_ip_pools(self, context):
2528
return pool_list
@@ -28,7 +31,7 @@ def fake_get_floating_ip_pools(self, context):
2831
fake_get_floating_ip_pools)
2932
response = self._do_get('os-floating-ip-pools')
3033
subs = {
31-
'pool1': pool_list[0],
32-
'pool2': pool_list[1]
34+
'pool1': pool_list[0]['name'],
35+
'pool2': pool_list[1]['name'],
3336
}
3437
self._verify_response('floatingippools-list-resp', subs, response, 200)

nova/tests/functional/api_sample_tests/test_servers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ def test_server_remove_floating_ip(self):
785785
self.stub_out(
786786
'nova.network.neutron.API.get_floating_ip_by_address',
787787
lambda *a, **k: {
788-
'fixed_ip_id': 'a0c566f0-faab-406f-b77f-2b286dc6dd7e'})
788+
'port_id': 'a0c566f0-faab-406f-b77f-2b286dc6dd7e'})
789789
self.stub_out(
790790
'nova.network.neutron.API.'
791791
'get_instance_id_by_floating_address',

nova/tests/unit/api/openstack/compute/test_floating_ip_pools.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424

2525

2626
def fake_get_floating_ip_pools(*args, **kwargs):
27-
return ['nova', 'other']
27+
return [
28+
{'name': 'nova'},
29+
{'name': 'other'},
30+
]
2831

2932

3033
class FloatingIpPoolTestV21(test.NoDBTestCase):
@@ -42,9 +45,9 @@ def test_translate_floating_ip_pools_view(self):
4245
view = self.floating_ip_pools._translate_floating_ip_pools_view(pools)
4346
self.assertIn('floating_ip_pools', view)
4447
self.assertEqual(view['floating_ip_pools'][0]['name'],
45-
pools[0])
48+
pools[0]['name'])
4649
self.assertEqual(view['floating_ip_pools'][1]['name'],
47-
pools[1])
50+
pools[1]['name'])
4851

4952
def test_floating_ips_pools_list(self):
5053
with mock.patch.object(self.controller.network_api,
@@ -53,8 +56,10 @@ def test_floating_ips_pools_list(self):
5356
res_dict = self.controller.index(self.req)
5457

5558
pools = fake_get_floating_ip_pools(None, self.context)
56-
response = {'floating_ip_pools': [{'name': name} for name in pools]}
57-
self.assertEqual(res_dict, response)
59+
response = {
60+
'floating_ip_pools': [{'name': pool['name']} for pool in pools],
61+
}
62+
self.assertEqual(response, res_dict)
5863

5964

6065
class FloatingIPPoolsPolicyEnforcementV21(test.NoDBTestCase):

0 commit comments

Comments
 (0)