Bug fix on neutron's API to return the correct target ID
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. Change-Id: I02286dbbb60318b0157992622ffdeeae45a71bc1 Closes-Bug: 1265872
This commit is contained in:
parent
cf252d2252
commit
86f8794490
@ -81,6 +81,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()
|
||||
|
||||
|
@ -118,6 +118,13 @@ class FloatingIpManager(object):
|
||||
"""
|
||||
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."""
|
||||
|
@ -389,16 +389,25 @@ class FloatingIpManager(network_base.FloatingIpManager):
|
||||
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
|
||||
|
@ -354,6 +354,9 @@ class FloatingIpManager(network_base.FloatingIpManager):
|
||||
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"]
|
||||
|
||||
|
@ -522,17 +522,19 @@ class SimpleDisassociateIP(tables.Action):
|
||||
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)
|
||||
|
@ -2056,7 +2056,7 @@ class InstanceTests(test.TestCase):
|
||||
|
||||
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',),
|
||||
@ -2073,9 +2073,9 @@ class InstanceTests(test.TestCase):
|
||||
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(
|
||||
|
@ -542,3 +542,15 @@ class NetworkApiNeutronFloatingIpTests(NetworkApiNeutronTestBase):
|
||||
|
||||
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))
|
||||
|
Loading…
x
Reference in New Issue
Block a user