Skip to content

Commit

Permalink
Bug fix on neutron's API to return the correct target ID
Browse files Browse the repository at this point in the history
In the class FloatingIpManager, the function filters the
resulting list of ports with all available floating ips.
The function now returns the target ID of a port with a
floating IP associated to it. Added a new function to get
this to pass. In the next phase is to refactor the
floating ip api to allow a finer granularity. This will
be useful later for managing floating ips.

Conflicts:
	openstack_dashboard/dashboards/project/instances/tables.py

Change-Id: I02286dbbb60318b0157992622ffdeeae45a71bc1
Closes-Bug: 1265872
(cherry picked from commit 86f8794)
  • Loading branch information
George Peristerakis authored and jpichon committed Apr 15, 2014
1 parent c5c388c commit 6ad29a1
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 12 deletions.
5 changes: 5 additions & 0 deletions openstack_dashboard/api/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ def floating_ip_target_get_by_instance(request, instance_id):
instance_id)


def floating_ip_target_list_by_instance(request, instance_id):
floating_ips = NetworkClient(request).floating_ips
return floating_ips.list_target_id_by_instance(instance_id)


def floating_ip_simple_associate_supported(request):
return NetworkClient(request).floating_ips.is_simple_associate_supported()

Expand Down
7 changes: 7 additions & 0 deletions openstack_dashboard/api/network_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ def get_target_id_by_instance(self, instance_id):
"""
pass

@abc.abstractmethod
def list_target_id_by_instance(self, instance_id):
"""Returns a list of instance's target IDs of floating IP association
based on the backend implementation
"""
pass

@abc.abstractmethod
def is_simple_associate_supported(self):
"""Returns True if the default floating IP pool is enabled."""
Expand Down
19 changes: 14 additions & 5 deletions openstack_dashboard/api/neutron.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,25 @@ def list_targets(self):
targets.append(FloatingIpTarget(target))
return targets

def get_target_id_by_instance(self, instance_id):
# In Neutron one port can have multiple ip addresses, so this method
# picks up the first one and generate target id.
def _target_ports_by_instance(self, instance_id):
if not instance_id:
return None
search_opts = {'device_id': instance_id}
ports = port_list(self.request, **search_opts)
return port_list(self.request, **search_opts)

def get_target_id_by_instance(self, instance_id):
# In Neutron one port can have multiple ip addresses, so this method
# picks up the first one and generate target id.
ports = self._target_ports_by_instance(instance_id)
if not ports:
return None
return '%s_%s' % (ports[0].id, ports[0].fixed_ips[0]['ip_address'])
return '{0}_{1}'.format(ports[0].id,
ports[0].fixed_ips[0]['ip_address'])

def list_target_id_by_instance(self, instance_id):
ports = self._target_ports_by_instance(instance_id)
return ['{0}_{1}'.format(p.id, p.fixed_ips[0]['ip_address'])
for p in ports]

def is_simple_associate_supported(self):
# NOTE: There are two reason that simple association support
Expand Down
3 changes: 3 additions & 0 deletions openstack_dashboard/api/nova.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@ def list_targets(self):
def get_target_id_by_instance(self, instance_id):
return instance_id

def list_target_id_by_instance(self, instance_id):
return [instance_id, ]

def is_simple_associate_supported(self):
return conf.HORIZON_CONFIG["simple_ip_management"]

Expand Down
10 changes: 6 additions & 4 deletions openstack_dashboard/dashboards/project/instances/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,17 +408,19 @@ def single(self, table, request, instance_id):
try:
# target_id is port_id for Neutron and instance_id for Nova Network
# (Neutron API wrapper returns a 'portid_fixedip' string)
target_id = api.network.floating_ip_target_get_by_instance(
request, instance_id).split('_')[0]
targets = api.network.floating_ip_target_list_by_instance(
request, instance_id)

target_ids = [t.split('_')[0] for t in targets]

fips = [fip for fip in api.network.tenant_floating_ip_list(request)
if fip.port_id == target_id]
if fip.port_id in target_ids]
# Removing multiple floating IPs at once doesn't work, so this pops
# off the first one.
if fips:
fip = fips.pop()
api.network.floating_ip_disassociate(request,
fip.id, target_id)
fip.id, fip.port_id)
messages.success(request,
_("Successfully disassociated "
"floating IP: %s") % fip.ip)
Expand Down
6 changes: 3 additions & 3 deletions openstack_dashboard/dashboards/project/instances/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1831,7 +1831,7 @@ def test_associate_floating_ip(self):

self.assertRedirectsNoFollow(res, INDEX_URL)

@test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
@test.create_stubs({api.network: ('floating_ip_target_list_by_instance',
'tenant_floating_ip_list',
'floating_ip_disassociate',),
api.glance: ('image_list_detailed',),
Expand All @@ -1848,9 +1848,9 @@ def test_disassociate_floating_ip(self):
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
api.glance.image_list_detailed(IgnoreArg()) \
.AndReturn((self.images.list(), False))
api.network.floating_ip_target_get_by_instance(
api.network.floating_ip_target_list_by_instance(
IsA(http.HttpRequest),
server.id).AndReturn(server.id)
server.id).AndReturn([server.id, ])
api.network.tenant_floating_ip_list(
IsA(http.HttpRequest)).AndReturn([fip])
api.network.floating_ip_disassociate(
Expand Down
12 changes: 12 additions & 0 deletions openstack_dashboard/test/api_tests/network_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,15 @@ def test_floating_ip_target_get_by_instance(self):

ret = api.network.floating_ip_target_get_by_instance(self.request, '1')
self.assertEqual(ret, self._get_target_id(candidates[0]))

def test_target_floating_ip_port_by_instance(self):
ports = self.api_ports.list()
candidates = [p for p in ports if p['device_id'] == '1']
search_opts = {'device_id': '1'}
self.qclient.list_ports(**search_opts).AndReturn({'ports': candidates})
self.mox.ReplayAll()

ret = api.network.floating_ip_target_list_by_instance(self.request,
'1')
self.assertEqual(ret[0], self._get_target_id(candidates[0]))
self.assertEqual(len(ret), len(candidates))

0 comments on commit 6ad29a1

Please sign in to comment.