Skip to content

Commit

Permalink
Fix floating IP management from instance panel.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Roman Podolyaka committed Apr 10, 2013
1 parent 527c0a1 commit de1940c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
18 changes: 14 additions & 4 deletions openstack_dashboard/dashboards/project/instances/tables.py
Expand Up @@ -326,10 +326,15 @@ def allowed(self, request, instance):
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)
Expand All @@ -351,14 +356,19 @@ def allowed(self, 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]

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 "
Expand Down
58 changes: 58 additions & 0 deletions openstack_dashboard/dashboards/project/instances/tests.py
Expand Up @@ -1271,3 +1271,61 @@ def test_select_default_keypair_if_only_one(self):
"%(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)

0 comments on commit de1940c

Please sign in to comment.