Skip to content

Commit

Permalink
Accepts UUID as an ID of Floating IP
Browse files Browse the repository at this point in the history
Fixes bug 1052561.

In Quanutm, Floating IPs are identified by UUID instead of integer ID.
After quantum-nova integration for FLoating IP has been implemented,
Horizon also needs to accept UUID style of ID for Floating IP.

Change-Id: I6ed919cbbc818c97cecef2fe3a91c8e5a7ac76e0
  • Loading branch information
amotoki committed Nov 25, 2012
1 parent 8734ea4 commit 7ab5ace
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 7 deletions.
Expand Up @@ -28,6 +28,8 @@

from openstack_dashboard import api

from .utils import get_int_or_uuid


LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -83,7 +85,7 @@ def allowed(self, request, fip):

def single(self, table, request, obj_id):
try:
fip = table.get_object_by_id(int(obj_id))
fip = table.get_object_by_id(get_int_or_uuid(obj_id))
api.server_remove_floating_ip(request, fip.instance_id, fip.id)
LOG.info('Disassociating Floating IP "%s".' % obj_id)
messages.success(request,
Expand Down Expand Up @@ -118,7 +120,7 @@ class FloatingIPsTable(tables.DataTable):
empty_value="-")

def sanitize_id(self, obj_id):
return int(obj_id)
return get_int_or_uuid(obj_id)

def get_object_display(self, datum):
return datum.ip
Expand Down
Expand Up @@ -19,6 +19,8 @@
# License for the specific language governing permissions and limitations
# under the License.

import uuid

from django import http
from django.core.urlresolvers import reverse

Expand All @@ -27,6 +29,8 @@
from openstack_dashboard import api
from openstack_dashboard.test import helpers as test

from .utils import get_int_or_uuid


INDEX_URL = reverse('horizon:project:access_and_security:index')
NAMESPACE = "horizon:project:access_and_security:floating_ips"
Expand All @@ -49,10 +53,10 @@ def test_associate(self):
workflow = res.context['workflow']
choices = dict(workflow.steps[0].action.fields['ip_id'].choices)
# Verify that our "associated" floating IP isn't in the choices list.
self.assertTrue(self.floating_ips.get(id=1) not in choices)
self.assertTrue(self.floating_ips.first() not in choices)

def test_associate_post(self):
floating_ip = self.floating_ips.get(id=2)
floating_ip = self.floating_ips.list()[1]
server = self.servers.first()
self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
Expand All @@ -74,7 +78,7 @@ def test_associate_post(self):
self.assertRedirectsNoFollow(res, INDEX_URL)

def test_associate_post_with_redirect(self):
floating_ip = self.floating_ips.get(id=2)
floating_ip = self.floating_ips.list()[1]
server = self.servers.first()
self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
Expand All @@ -97,7 +101,7 @@ def test_associate_post_with_redirect(self):
self.assertRedirectsNoFollow(res, next)

def test_associate_post_with_exception(self):
floating_ip = self.floating_ips.get(id=2)
floating_ip = self.floating_ips.list()[1]
server = self.servers.first()
self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
Expand Down Expand Up @@ -175,3 +179,30 @@ def test_disassociate_post_with_exception(self):
action = "floating_ips__disassociate__%s" % floating_ip.id
res = self.client.post(INDEX_URL, {"action": action})
self.assertRedirectsNoFollow(res, INDEX_URL)


class FloatingIpQuantumViewTests(FloatingIpViewTests):
def setUp(self):
super(FloatingIpViewTests, self).setUp()
self.floating_ips = self.floating_ips_uuid


class FloatingIpUtilsTests(test.TestCase):
def test_accept_valid_integer(self):
val = 100
ret = get_int_or_uuid(val)
self.assertEqual(val, ret)

def test_accept_valid_integer_string(self):
val = '100'
ret = get_int_or_uuid(val)
self.assertEqual(int(val), ret)

def test_accept_valid_uuid(self):
val = str(uuid.uuid4())
ret = get_int_or_uuid(val)
self.assertEqual(val, ret)

def test_reject_random_string(self):
val = '55WbJTpJDf'
self.assertRaises(ValueError, get_int_or_uuid, val)
@@ -0,0 +1,31 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 NEC Corporation All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import uuid


def get_int_or_uuid(value):
"""Check if a value is valid as UUID or an integer.
This method is mainly used to convert floating IP id to the
appropriate type. For floating IP id, integer is used in Nova's
original implementation, but UUID is used in Quantum based one.
"""
try:
uuid.UUID(value)
return value
except (ValueError, AttributeError):
return int(value)
Expand Up @@ -24,13 +24,15 @@

from openstack_dashboard import api

from .utils import get_int_or_uuid


ALLOCATE_URL = "horizon:project:access_and_security:floating_ips:allocate"


class AssociateIPAction(workflows.Action):
ip_id = forms.DynamicTypedChoiceField(label=_("IP Address"),
coerce=int,
coerce=get_int_or_uuid,
empty_value=None,
add_item_link=ALLOCATE_URL)
instance_id = forms.ChoiceField(label=_("Instance"))
Expand Down
Expand Up @@ -86,3 +86,9 @@ def test_association(self):
self.assertContains(res,
'<option value="101">server_1 (101)</option>')
self.assertContains(res, '<option value="2">server_2 (2)</option>')


class AccessAndSecurityQuantumTests(AccessAndSecurityTests):
def setUp(self):
super(AccessAndSecurityTests, self).setUp()
self.floating_ips = self.floating_ips_uuid
15 changes: 15 additions & 0 deletions openstack_dashboard/test/test_data/nova_data.py
Expand Up @@ -13,6 +13,7 @@
# under the License.

import json
import uuid

from novaclient.v1_1 import (flavors, keypairs, servers, volumes,
volume_types, quotas,
Expand Down Expand Up @@ -143,6 +144,7 @@ def data(TEST):
TEST.quotas = TestDataContainer()
TEST.quota_usages = TestDataContainer()
TEST.floating_ips = TestDataContainer()
TEST.floating_ips_uuid = TestDataContainer()
TEST.usages = TestDataContainer()
TEST.certs = TestDataContainer()
TEST.volume_snapshots = TestDataContainer()
Expand Down Expand Up @@ -335,6 +337,19 @@ def data(TEST):
'ip': '58.58.58.58'})
TEST.floating_ips.add(fip_1, fip_2)

# Floating IP with UUID id (for Floating IP with Quantum)
fip_3 = floating_ips.FloatingIP(floating_ips.FloatingIPManager(None),
{'id': str(uuid.uuid4()),
'fixed_ip': '10.0.0.4',
'instance_id': server_1.id,
'ip': '58.58.58.58'})
fip_4 = floating_ips.FloatingIP(floating_ips.FloatingIPManager(None),
{'id': str(uuid.uuid4()),
'fixed_ip': None,
'instance_id': None,
'ip': '58.58.58.58'})
TEST.floating_ips_uuid.add(fip_3, fip_4)

# Usage
usage_vals = {"tenant_id": TEST.tenant.id,
"instance_name": server_1.name,
Expand Down

0 comments on commit 7ab5ace

Please sign in to comment.