Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge "Accepts UUID as an ID of Floating IP"

  • Loading branch information...
commit 025dea1866e82112a882cdbc4a715bd3d382ae36 2 parents ceea2b1 + 7ab5ace
authored November 29, 2012 openstack-gerrit committed November 29, 2012
6  openstack_dashboard/dashboards/project/access_and_security/floating_ips/tables.py
@@ -28,6 +28,8 @@
28 28
 
29 29
 from openstack_dashboard import api
30 30
 
  31
+from .utils import get_int_or_uuid
  32
+
31 33
 
32 34
 LOG = logging.getLogger(__name__)
33 35
 
@@ -83,7 +85,7 @@ def allowed(self, request, fip):
83 85
 
84 86
     def single(self, table, request, obj_id):
85 87
         try:
86  
-            fip = table.get_object_by_id(int(obj_id))
  88
+            fip = table.get_object_by_id(get_int_or_uuid(obj_id))
87 89
             api.server_remove_floating_ip(request, fip.instance_id, fip.id)
88 90
             LOG.info('Disassociating Floating IP "%s".' % obj_id)
89 91
             messages.success(request,
@@ -118,7 +120,7 @@ class FloatingIPsTable(tables.DataTable):
118 120
                          empty_value="-")
119 121
 
120 122
     def sanitize_id(self, obj_id):
121  
-        return int(obj_id)
  123
+        return get_int_or_uuid(obj_id)
122 124
 
123 125
     def get_object_display(self, datum):
124 126
         return datum.ip
39  openstack_dashboard/dashboards/project/access_and_security/floating_ips/tests.py
@@ -19,6 +19,8 @@
19 19
 #    License for the specific language governing permissions and limitations
20 20
 #    under the License.
21 21
 
  22
+import uuid
  23
+
22 24
 from django import http
23 25
 from django.core.urlresolvers import reverse
24 26
 
@@ -27,6 +29,8 @@
27 29
 from openstack_dashboard import api
28 30
 from openstack_dashboard.test import helpers as test
29 31
 
  32
+from .utils import get_int_or_uuid
  33
+
30 34
 
31 35
 INDEX_URL = reverse('horizon:project:access_and_security:index')
32 36
 NAMESPACE = "horizon:project:access_and_security:floating_ips"
@@ -49,10 +53,10 @@ def test_associate(self):
49 53
         workflow = res.context['workflow']
50 54
         choices = dict(workflow.steps[0].action.fields['ip_id'].choices)
51 55
         # Verify that our "associated" floating IP isn't in the choices list.
52  
-        self.assertTrue(self.floating_ips.get(id=1) not in choices)
  56
+        self.assertTrue(self.floating_ips.first() not in choices)
53 57
 
54 58
     def test_associate_post(self):
55  
-        floating_ip = self.floating_ips.get(id=2)
  59
+        floating_ip = self.floating_ips.list()[1]
56 60
         server = self.servers.first()
57 61
         self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
58 62
         self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
@@ -74,7 +78,7 @@ def test_associate_post(self):
74 78
         self.assertRedirectsNoFollow(res, INDEX_URL)
75 79
 
76 80
     def test_associate_post_with_redirect(self):
77  
-        floating_ip = self.floating_ips.get(id=2)
  81
+        floating_ip = self.floating_ips.list()[1]
78 82
         server = self.servers.first()
79 83
         self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
80 84
         self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
@@ -97,7 +101,7 @@ def test_associate_post_with_redirect(self):
97 101
         self.assertRedirectsNoFollow(res, next)
98 102
 
99 103
     def test_associate_post_with_exception(self):
100  
-        floating_ip = self.floating_ips.get(id=2)
  104
+        floating_ip = self.floating_ips.list()[1]
101 105
         server = self.servers.first()
102 106
         self.mox.StubOutWithMock(api.nova, 'server_add_floating_ip')
103 107
         self.mox.StubOutWithMock(api.nova, 'tenant_floating_ip_list')
@@ -175,3 +179,30 @@ def test_disassociate_post_with_exception(self):
175 179
         action = "floating_ips__disassociate__%s" % floating_ip.id
176 180
         res = self.client.post(INDEX_URL, {"action": action})
177 181
         self.assertRedirectsNoFollow(res, INDEX_URL)
  182
+
  183
+
  184
+class FloatingIpQuantumViewTests(FloatingIpViewTests):
  185
+    def setUp(self):
  186
+        super(FloatingIpViewTests, self).setUp()
  187
+        self.floating_ips = self.floating_ips_uuid
  188
+
  189
+
  190
+class FloatingIpUtilsTests(test.TestCase):
  191
+    def test_accept_valid_integer(self):
  192
+        val = 100
  193
+        ret = get_int_or_uuid(val)
  194
+        self.assertEqual(val, ret)
  195
+
  196
+    def test_accept_valid_integer_string(self):
  197
+        val = '100'
  198
+        ret = get_int_or_uuid(val)
  199
+        self.assertEqual(int(val), ret)
  200
+
  201
+    def test_accept_valid_uuid(self):
  202
+        val = str(uuid.uuid4())
  203
+        ret = get_int_or_uuid(val)
  204
+        self.assertEqual(val, ret)
  205
+
  206
+    def test_reject_random_string(self):
  207
+        val = '55WbJTpJDf'
  208
+        self.assertRaises(ValueError, get_int_or_uuid, val)
31  openstack_dashboard/dashboards/project/access_and_security/floating_ips/utils.py
... ...
@@ -0,0 +1,31 @@
  1
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
  2
+
  3
+# Copyright 2012 NEC Corporation All Rights Reserved.
  4
+#
  5
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
  6
+#    not use this file except in compliance with the License. You may obtain
  7
+#    a copy of the License at
  8
+#
  9
+#         http://www.apache.org/licenses/LICENSE-2.0
  10
+#
  11
+#    Unless required by applicable law or agreed to in writing, software
  12
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  13
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  14
+#    License for the specific language governing permissions and limitations
  15
+#    under the License.
  16
+
  17
+import uuid
  18
+
  19
+
  20
+def get_int_or_uuid(value):
  21
+    """Check if a value is valid as UUID or an integer.
  22
+
  23
+    This method is mainly used to convert floating IP id to the
  24
+    appropriate type. For floating IP id, integer is used in Nova's
  25
+    original implementation, but UUID is used in Quantum based one.
  26
+    """
  27
+    try:
  28
+        uuid.UUID(value)
  29
+        return value
  30
+    except (ValueError, AttributeError):
  31
+        return int(value)
4  openstack_dashboard/dashboards/project/access_and_security/floating_ips/workflows.py
@@ -24,13 +24,15 @@
24 24
 
25 25
 from openstack_dashboard import api
26 26
 
  27
+from .utils import get_int_or_uuid
  28
+
27 29
 
28 30
 ALLOCATE_URL = "horizon:project:access_and_security:floating_ips:allocate"
29 31
 
30 32
 
31 33
 class AssociateIPAction(workflows.Action):
32 34
     ip_id = forms.DynamicTypedChoiceField(label=_("IP Address"),
33  
-                                          coerce=int,
  35
+                                          coerce=get_int_or_uuid,
34 36
                                           empty_value=None,
35 37
                                           add_item_link=ALLOCATE_URL)
36 38
     instance_id = forms.ChoiceField(label=_("Instance"))
6  openstack_dashboard/dashboards/project/access_and_security/tests.py
@@ -86,3 +86,9 @@ def test_association(self):
86 86
         self.assertContains(res,
87 87
                             '<option value="101">server_1 (101)</option>')
88 88
         self.assertContains(res, '<option value="2">server_2 (2)</option>')
  89
+
  90
+
  91
+class AccessAndSecurityQuantumTests(AccessAndSecurityTests):
  92
+    def setUp(self):
  93
+        super(AccessAndSecurityTests, self).setUp()
  94
+        self.floating_ips = self.floating_ips_uuid
15  openstack_dashboard/test/test_data/nova_data.py
@@ -13,6 +13,7 @@
13 13
 #    under the License.
14 14
 
15 15
 import json
  16
+import uuid
16 17
 
17 18
 from novaclient.v1_1 import (flavors, keypairs, servers, volumes,
18 19
                              volume_types, quotas,
@@ -143,6 +144,7 @@ def data(TEST):
143 144
     TEST.quotas = TestDataContainer()
144 145
     TEST.quota_usages = TestDataContainer()
145 146
     TEST.floating_ips = TestDataContainer()
  147
+    TEST.floating_ips_uuid = TestDataContainer()
146 148
     TEST.usages = TestDataContainer()
147 149
     TEST.certs = TestDataContainer()
148 150
     TEST.volume_snapshots = TestDataContainer()
@@ -335,6 +337,19 @@ def data(TEST):
335 337
                                      'ip': '58.58.58.58'})
336 338
     TEST.floating_ips.add(fip_1, fip_2)
337 339
 
  340
+    # Floating IP with UUID id (for Floating IP with Quantum)
  341
+    fip_3 = floating_ips.FloatingIP(floating_ips.FloatingIPManager(None),
  342
+                                    {'id': str(uuid.uuid4()),
  343
+                                     'fixed_ip': '10.0.0.4',
  344
+                                     'instance_id': server_1.id,
  345
+                                     'ip': '58.58.58.58'})
  346
+    fip_4 = floating_ips.FloatingIP(floating_ips.FloatingIPManager(None),
  347
+                                    {'id': str(uuid.uuid4()),
  348
+                                     'fixed_ip': None,
  349
+                                     'instance_id': None,
  350
+                                     'ip': '58.58.58.58'})
  351
+    TEST.floating_ips_uuid.add(fip_3, fip_4)
  352
+
338 353
     # Usage
339 354
     usage_vals = {"tenant_id": TEST.tenant.id,
340 355
                   "instance_name": server_1.name,

0 notes on commit 025dea1

Please sign in to comment.
Something went wrong with that request. Please try again.