Fix floating IP management from instance panel.
Quantum Floating IP API works with ports ids not instances ones (opposite to what Nova Network does). So if we want to associate (disassociate) an allocated floating IP to some instance we must use the "target_id" (which is a port_id in case of Quantum and an instance_id in case of Nova network). Fixes bug 1158596. Change-Id: Iceba4d8ee74bd58dc1cdbda7668841b0a7eb86f1
This commit is contained in:
parent
527c0a1d86
commit
de1940c922
|
@ -326,10 +326,15 @@ class SimpleAssociateIP(tables.Action):
|
|||
return False
|
||||
return not is_deleting(instance)
|
||||
|
||||
def single(self, table, request, instance):
|
||||
def single(self, table, request, instance_id):
|
||||
try:
|
||||
# target_id is port_id for Quantum and instance_id for Nova Network
|
||||
# (Quantum API wrapper returns a 'portid_fixedip' string)
|
||||
target_id = api.network.floating_ip_target_get_by_instance(
|
||||
request, instance_id).split('_')[0]
|
||||
|
||||
fip = api.network.tenant_floating_ip_allocate(request)
|
||||
api.network.floating_ip_associate(request, fip.id, instance)
|
||||
api.network.floating_ip_associate(request, fip.id, target_id)
|
||||
messages.success(request,
|
||||
_("Successfully associated floating IP: %s")
|
||||
% fip.ip)
|
||||
|
@ -351,14 +356,19 @@ class SimpleDisassociateIP(tables.Action):
|
|||
|
||||
def single(self, table, request, instance_id):
|
||||
try:
|
||||
# target_id is port_id for Quantum and instance_id for Nova Network
|
||||
# (Quantum API wrapper returns a 'portid_fixedip' string)
|
||||
target_id = api.network.floating_ip_target_get_by_instance(
|
||||
request, instance_id).split('_')[0]
|
||||
|
||||
fips = [fip for fip in api.network.tenant_floating_ip_list(request)
|
||||
if fip.port_id == instance_id]
|
||||
if fip.port_id == target_id]
|
||||
# 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, instance_id)
|
||||
fip.id, target_id)
|
||||
api.network.tenant_floating_ip_release(request, fip.id)
|
||||
messages.success(request,
|
||||
_("Successfully disassociated "
|
||||
|
|
|
@ -1271,3 +1271,61 @@ class InstanceTests(test.TestCase):
|
|||
"%(key)s</option>" % {'key': keypair.name},
|
||||
html=True,
|
||||
msg_prefix="The default keypair was not selected.")
|
||||
|
||||
@test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
|
||||
'tenant_floating_ip_allocate',
|
||||
'floating_ip_associate'),
|
||||
api.nova: ('server_list',
|
||||
'flavor_list')})
|
||||
def test_associate_floating_ip(self):
|
||||
server = self.servers.first()
|
||||
fip = self.q_floating_ips.first()
|
||||
|
||||
api.nova.server_list(
|
||||
IsA(http.HttpRequest)).AndReturn(self.servers.list())
|
||||
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
|
||||
api.network.floating_ip_target_get_by_instance(
|
||||
IsA(http.HttpRequest),
|
||||
server.id).AndReturn(server.id)
|
||||
api.network.tenant_floating_ip_allocate(
|
||||
IsA(http.HttpRequest)).AndReturn(fip)
|
||||
api.network.floating_ip_associate(
|
||||
IsA(http.HttpRequest), fip.id, server.id)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action': 'instances__associate-simple__%s' % server.id}
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.network: ('floating_ip_target_get_by_instance',
|
||||
'tenant_floating_ip_list',
|
||||
'floating_ip_disassociate',
|
||||
'tenant_floating_ip_release'),
|
||||
api.nova: ('server_list',
|
||||
'flavor_list')})
|
||||
def test_disassociate_floating_ip(self):
|
||||
server = self.servers.first()
|
||||
fip = self.q_floating_ips.first()
|
||||
fip.port_id = server.id
|
||||
|
||||
api.nova.server_list(
|
||||
IsA(http.HttpRequest)).AndReturn(self.servers.list())
|
||||
api.nova.flavor_list(IgnoreArg()).AndReturn(self.flavors.list())
|
||||
api.network.floating_ip_target_get_by_instance(
|
||||
IsA(http.HttpRequest),
|
||||
server.id).AndReturn(server.id)
|
||||
api.network.tenant_floating_ip_list(
|
||||
IsA(http.HttpRequest)).AndReturn([fip])
|
||||
api.network.floating_ip_disassociate(
|
||||
IsA(http.HttpRequest), fip.id, server.id)
|
||||
api.network.tenant_floating_ip_release(
|
||||
IsA(http.HttpRequest), fip.id)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
formData = {'action': 'instances__disassociate__%s' % server.id}
|
||||
res = self.client.post(INDEX_URL, formData)
|
||||
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
|
Loading…
Reference in New Issue