Browse Source

Correct the subnets quota check in admin networks panel

Currently when checking the subnets quota in admin networks table,
the current tenant subnets quota is checked, while the subnet is
created, using the tenant of the selected network[1], this doesn't
look the same. Similarly, in the network details subnets table,
the creation of subnets actions lacks quota checking.

[1] https://github.com/openstack/horizon/blob/master/openstack_dashboard/dashboards/admin/networks/subnets/workflows.py#L75

Change-Id: Ifb88b97168fc4f500e4bb15658f96363ddc7651f
Closes-Bug:#1719606
tags/13.0.0.0b2
wei.ying 1 year ago
parent
commit
b5bd7589e6

+ 18
- 0
openstack_dashboard/dashboards/admin/networks/subnets/tables.py View File

@@ -28,6 +28,7 @@ from openstack_dashboard.dashboards.project.networks.subnets \
28 28
     import tables as proj_tables
29 29
 from openstack_dashboard.dashboards.project.networks.subnets.tabs \
30 30
     import SubnetsTab as project_tabs_subnets_tab
31
+from openstack_dashboard.usage import quotas
31 32
 
32 33
 LOG = logging.getLogger(__name__)
33 34
 
@@ -76,6 +77,23 @@ class CreateSubnet(proj_tables.SubnetPolicyTargetMixin, tables.LinkAction):
76 77
         network_id = self.table.kwargs['network_id']
77 78
         return reverse(self.url, args=(network_id,))
78 79
 
80
+    def allowed(self, request, datum=None):
81
+        network = self.table._get_network()
82
+        usages = quotas.tenant_quota_usages(
83
+            request, tenant_id=network.tenant_id, targets=('subnets', ))
84
+
85
+        # when Settings.OPENSTACK_NEUTRON_NETWORK['enable_quotas'] = False
86
+        # usages["subnets'] is empty
87
+        if usages.get('subnets', {}).get('available', 1) <= 0:
88
+            if 'disabled' not in self.classes:
89
+                self.classes = [c for c in self.classes] + ['disabled']
90
+                self.verbose_name = _('Create Subnet (Quota exceeded)')
91
+        else:
92
+            self.verbose_name = _('Create Subnet')
93
+            self.classes = [c for c in self.classes if c != 'disabled']
94
+
95
+        return True
96
+
79 97
 
80 98
 class UpdateSubnet(proj_tables.SubnetPolicyTargetMixin, tables.LinkAction):
81 99
     name = "update"

+ 9
- 9
openstack_dashboard/dashboards/admin/networks/subnets/tests.py View File

@@ -409,18 +409,18 @@ class NetworkSubnetTests(test.BaseAdminViewTests):
409 409
 
410 410
     def _test_network_detail_ip_availability_exception(self,
411 411
                                                        mac_learning=False):
412
-        network_id = self.networks.first().id
413
-        quota_data = self.quota_usages.first()
412
+        network = self.networks.first()
413
+        quota_data = self.neutron_quota_usages.first()
414 414
         api.neutron.is_extension_supported(
415 415
             IsA(http.HttpRequest),
416 416
             'network-ip-availability').AndReturn(True)
417 417
         api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
418
-                                                 network_id).\
418
+                                                 network.id).\
419 419
             MultipleTimes().AndRaise(self.exceptions.neutron)
420
-        api.neutron.network_get(IsA(http.HttpRequest), network_id).\
421
-            AndReturn(self.networks.first())
420
+        api.neutron.network_get(IsA(http.HttpRequest), network.id).\
421
+            MultipleTimes().AndReturn(self.networks.first())
422 422
 
423
-        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
423
+        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id).\
424 424
             AndReturn([self.subnets.first()])
425 425
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
426 426
                                            'mac-learning') \
@@ -432,12 +432,12 @@ class NetworkSubnetTests(test.BaseAdminViewTests):
432 432
                                            'dhcp_agent_scheduler')\
433 433
             .MultipleTimes().AndReturn(True)
434 434
         quotas.tenant_quota_usages(
435
-            IsA(http.HttpRequest), targets=('subnets',)) \
436
-            .MultipleTimes().AndReturn(quota_data)
435
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
436
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
437 437
         self.mox.ReplayAll()
438 438
         from django.utils.http import urlunquote
439 439
         url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
440
-                                 args=[network_id]))
440
+                                 args=[network.id]))
441 441
         res = self.client.get(url)
442 442
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')
443 443
         subnets = res.context['subnets_table'].data

+ 17
- 0
openstack_dashboard/dashboards/admin/networks/tables.py View File

@@ -27,6 +27,7 @@ from openstack_dashboard import api
27 27
 from openstack_dashboard.dashboards.project.networks \
28 28
     import tables as project_tables
29 29
 from openstack_dashboard import policy
30
+from openstack_dashboard.usage import quotas
30 31
 
31 32
 LOG = logging.getLogger(__name__)
32 33
 
@@ -82,6 +83,22 @@ class EditNetwork(policy.PolicyTargetMixin, tables.LinkAction):
82 83
 class CreateSubnet(project_tables.CreateSubnet):
83 84
     url = "horizon:admin:networks:createsubnet"
84 85
 
86
+    def allowed(self, request, datum=None):
87
+        usages = quotas.tenant_quota_usages(
88
+            request, tenant_id=datum.tenant_id, targets=('subnets', ))
89
+
90
+        # when Settings.OPENSTACK_NEUTRON_NETWORK['enable_quotas'] = False
91
+        # usages["subnets'] is empty
92
+        if usages.get('subnets', {}).get('available', 1) <= 0:
93
+            if 'disabled' not in self.classes:
94
+                self.classes = [c for c in self.classes] + ['disabled']
95
+                self.verbose_name = _('Create Subnet (Quota exceeded)')
96
+        else:
97
+            self.verbose_name = _('Create Subnet')
98
+            self.classes = [c for c in self.classes if c != 'disabled']
99
+
100
+        return True
101
+
85 102
 
86 103
 DISPLAY_CHOICES = (
87 104
     ("up", pgettext_lazy("Admin state of a Network", u"UP")),

+ 40
- 40
openstack_dashboard/dashboards/admin/networks/tests.py View File

@@ -44,6 +44,9 @@ class NetworkTests(test.BaseAdminViewTests):
44 44
         api.keystone.tenant_list(IsA(http.HttpRequest))\
45 45
             .AndReturn([tenants, False])
46 46
         for network in self.networks.list():
47
+            usage.quotas.tenant_quota_usages(
48
+                IsA(http.HttpRequest), tenant_id=network.tenant_id,
49
+                targets=('subnets', )).AndReturn(quota_data)
47 50
             api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
48 51
                                                          network.id)\
49 52
                 .AndReturn(self.agents.list())
@@ -54,9 +57,6 @@ class NetworkTests(test.BaseAdminViewTests):
54 57
         api.neutron.is_extension_supported(
55 58
             IsA(http.HttpRequest),
56 59
             'dhcp_agent_scheduler').AndReturn(True)
57
-        usage.quotas.tenant_quota_usages(
58
-            IsA(http.HttpRequest), targets=('subnets', )) \
59
-            .MultipleTimes().AndReturn(quota_data)
60 60
         self.mox.ReplayAll()
61 61
 
62 62
         res = self.client.get(INDEX_URL)
@@ -106,9 +106,9 @@ class NetworkTests(test.BaseAdminViewTests):
106 106
                                       'is_extension_supported'),
107 107
                         usage.quotas: ('tenant_quota_usages',)})
108 108
     def test_network_detail_new(self, mac_learning=False):
109
-        network_id = self.networks.first().id
109
+        network = self.networks.first()
110 110
         quota_data = self.quota_usages.first()
111
-        api.neutron.network_get(IsA(http.HttpRequest), network_id) \
111
+        api.neutron.network_get(IsA(http.HttpRequest), network.id) \
112 112
             .MultipleTimes().AndReturn(self.networks.first())
113 113
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
114 114
                                            'network-ip-availability') \
@@ -121,11 +121,11 @@ class NetworkTests(test.BaseAdminViewTests):
121 121
             IsA(http.HttpRequest),
122 122
             'dhcp_agent_scheduler').AndReturn(True)
123 123
         usage.quotas.tenant_quota_usages(
124
-            IsA(http.HttpRequest), targets=('subnets',)) \
125
-            .MultipleTimes().AndReturn(quota_data)
124
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
125
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
126 126
         self.mox.ReplayAll()
127 127
         url = urlunquote(reverse('horizon:admin:networks:detail',
128
-                                 args=[network_id]))
128
+                                 args=[network.id]))
129 129
 
130 130
         res = self.client.get(url)
131 131
         network = res.context['network']
@@ -135,15 +135,15 @@ class NetworkTests(test.BaseAdminViewTests):
135 135
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')
136 136
 
137 137
     def _test_network_detail_subnets_tab(self, mac_learning=False):
138
-        network_id = self.networks.first().id
138
+        network = self.networks.first()
139 139
         ip_availability = self.ip_availability.get()
140 140
         quota_data = self.quota_usages.first()
141 141
         api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
142
-                                                 network_id).\
142
+                                                 network.id).\
143 143
             MultipleTimes().AndReturn(ip_availability)
144
-        api.neutron.network_get(IsA(http.HttpRequest), network_id)\
145
-            .AndReturn(self.networks.first())
146
-        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id)\
144
+        api.neutron.network_get(IsA(http.HttpRequest), network.id)\
145
+            .MultipleTimes().AndReturn(self.networks.first())
146
+        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id)\
147 147
             .AndReturn([self.subnets.first()])
148 148
         api.neutron.is_extension_supported(
149 149
             IsA(http.HttpRequest),
@@ -159,11 +159,11 @@ class NetworkTests(test.BaseAdminViewTests):
159 159
             IsA(http.HttpRequest),
160 160
             'dhcp_agent_scheduler').AndReturn(True)
161 161
         usage.quotas.tenant_quota_usages(
162
-            IsA(http.HttpRequest), targets=('subnets',)) \
163
-            .MultipleTimes().AndReturn(quota_data)
162
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
163
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
164 164
         self.mox.ReplayAll()
165 165
         url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
166
-                         args=[network_id]))
166
+                         args=[network.id]))
167 167
         res = self.client.get(url)
168 168
 
169 169
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')
@@ -196,8 +196,8 @@ class NetworkTests(test.BaseAdminViewTests):
196 196
             IsA(http.HttpRequest),
197 197
             'dhcp_agent_scheduler').AndReturn(True)
198 198
         usage.quotas.tenant_quota_usages(
199
-            IsA(http.HttpRequest), targets=('subnets',)) \
200
-            .MultipleTimes().AndReturn(quota_data)
199
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
200
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
201 201
 
202 202
         self.mox.ReplayAll()
203 203
         url = reverse('horizon:admin:networks:ports_tab',
@@ -215,7 +215,7 @@ class NetworkTests(test.BaseAdminViewTests):
215 215
                                       'list_dhcp_agent_hosting_networks',),
216 216
                         usage.quotas: ('tenant_quota_usages',)})
217 217
     def test_network_detail_agents_tab(self, mac_learning=False):
218
-        network_id = self.networks.first().id
218
+        network = self.networks.first()
219 219
         quota_data = self.quota_usages.first()
220 220
         api.neutron.is_extension_supported(IsA(http.HttpRequest),
221 221
                                            'network-ip-availability') \
@@ -225,10 +225,10 @@ class NetworkTests(test.BaseAdminViewTests):
225 225
                                            'mac-learning')\
226 226
             .AndReturn(mac_learning)
227 227
         api.neutron.list_dhcp_agent_hosting_networks(IsA(http.HttpRequest),
228
-                                                     network_id)\
228
+                                                     network.id)\
229 229
             .AndReturn(self.agents.list())
230
-        api.neutron.network_get(IsA(http.HttpRequest), network_id)\
231
-            .AndReturn(self.networks.first())
230
+        api.neutron.network_get(IsA(http.HttpRequest), network.id)\
231
+            .MultipleTimes().AndReturn(self.networks.first())
232 232
         api.neutron.is_extension_supported(
233 233
             IsA(http.HttpRequest),
234 234
             'dhcp_agent_scheduler').AndReturn(True)
@@ -236,10 +236,10 @@ class NetworkTests(test.BaseAdminViewTests):
236 236
             IsA(http.HttpRequest),
237 237
             'dhcp_agent_scheduler').AndReturn(True)
238 238
         usage.quotas.tenant_quota_usages(
239
-            IsA(http.HttpRequest), targets=('subnets', )) \
240
-            .MultipleTimes().AndReturn(quota_data)
239
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
240
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
241 241
         self.mox.ReplayAll()
242
-        url = reverse('horizon:admin:networks:agents_tab', args=[network_id])
242
+        url = reverse('horizon:admin:networks:agents_tab', args=[network.id])
243 243
         res = self.client.get(urlunquote(url))
244 244
 
245 245
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')
@@ -318,11 +318,11 @@ class NetworkTests(test.BaseAdminViewTests):
318 318
 
319 319
     def _test_network_detail_subnets_tab_subnet_exception(self,
320 320
                                                           mac_learning=False):
321
-        network_id = self.networks.first().id
321
+        network = self.networks.first()
322 322
         quota_data = self.quota_usages.first()
323
-        api.neutron.network_get(IsA(http.HttpRequest), network_id).\
324
-            AndReturn(self.networks.first())
325
-        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
323
+        api.neutron.network_get(IsA(http.HttpRequest), network.id)\
324
+            .MultipleTimes().AndReturn(self.networks.first())
325
+        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id).\
326 326
             AndRaise(self.exceptions.neutron)
327 327
         api.neutron.is_extension_supported(
328 328
             IsA(http.HttpRequest),
@@ -337,11 +337,11 @@ class NetworkTests(test.BaseAdminViewTests):
337 337
             IsA(http.HttpRequest),
338 338
             'dhcp_agent_scheduler').AndReturn(True)
339 339
         usage.quotas.tenant_quota_usages(
340
-            IsA(http.HttpRequest), targets=('subnets',)) \
341
-            .MultipleTimes().AndReturn(quota_data)
340
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
341
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
342 342
         self.mox.ReplayAll()
343 343
         url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
344
-                         args=[network_id]))
344
+                         args=[network.id]))
345 345
         res = self.client.get(url)
346 346
 
347 347
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')
@@ -370,15 +370,15 @@ class NetworkTests(test.BaseAdminViewTests):
370 370
 
371 371
     def _test_network_detail_subnets_tab_port_exception(self,
372 372
                                                         mac_learning=False):
373
-        network_id = self.networks.first().id
373
+        network = self.networks.first()
374 374
         ip_availability = self.ip_availability.get()
375 375
         quota_data = self.quota_usages.first()
376 376
         api.neutron.show_network_ip_availability(IsA(http.HttpRequest),
377
-                                                 network_id). \
377
+                                                 network.id). \
378 378
             MultipleTimes().AndReturn(ip_availability)
379
-        api.neutron.network_get(IsA(http.HttpRequest), network_id).\
380
-            AndReturn(self.networks.first())
381
-        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network_id).\
379
+        api.neutron.network_get(IsA(http.HttpRequest), network.id)\
380
+            .MultipleTimes().AndReturn(self.networks.first())
381
+        api.neutron.subnet_list(IsA(http.HttpRequest), network_id=network.id).\
382 382
             AndReturn([self.subnets.first()])
383 383
         api.neutron.is_extension_supported(
384 384
             IsA(http.HttpRequest),
@@ -393,11 +393,11 @@ class NetworkTests(test.BaseAdminViewTests):
393 393
                                            'dhcp_agent_scheduler')\
394 394
             .AndReturn(True)
395 395
         usage.quotas.tenant_quota_usages(
396
-            IsA(http.HttpRequest), targets=('subnets',)) \
397
-            .MultipleTimes().AndReturn(quota_data)
396
+            IsA(http.HttpRequest), tenant_id=network.tenant_id,
397
+            targets=('subnets',)).MultipleTimes().AndReturn(quota_data)
398 398
         self.mox.ReplayAll()
399 399
         url = urlunquote(reverse('horizon:admin:networks:subnets_tab',
400
-                         args=[network_id]))
400
+                         args=[network.id]))
401 401
         res = self.client.get(url)
402 402
 
403 403
         self.assertTemplateUsed(res, 'horizon/common/_detail.html')

Loading…
Cancel
Save