Merge "Revert "Remove the quota check for "Launch Instance" button""
This commit is contained in:
commit
4927f5fae4
@ -17,6 +17,7 @@ import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import urlresolvers
|
||||
from django.http import HttpResponse
|
||||
from django import shortcuts
|
||||
from django import template
|
||||
from django.template.defaultfilters import title
|
||||
@ -390,6 +391,36 @@ class LaunchLink(tables.LinkAction):
|
||||
kwargs['preempt'] = True
|
||||
super(LaunchLink, self).__init__(attrs, **kwargs)
|
||||
|
||||
def allowed(self, request, datum):
|
||||
try:
|
||||
limits = api.nova.tenant_absolute_limits(request, reserved=True)
|
||||
|
||||
instances_available = limits['maxTotalInstances'] \
|
||||
- limits['totalInstancesUsed']
|
||||
cores_available = limits['maxTotalCores'] \
|
||||
- limits['totalCoresUsed']
|
||||
ram_available = limits['maxTotalRAMSize'] - limits['totalRAMUsed']
|
||||
|
||||
if instances_available <= 0 or cores_available <= 0 \
|
||||
or ram_available <= 0:
|
||||
if "disabled" not in self.classes:
|
||||
self.classes = [c for c in self.classes] + ['disabled']
|
||||
self.verbose_name = string_concat(self.verbose_name, ' ',
|
||||
_("(Quota exceeded)"))
|
||||
else:
|
||||
self.verbose_name = _("Launch Instance")
|
||||
classes = [c for c in self.classes if c != "disabled"]
|
||||
self.classes = classes
|
||||
except Exception:
|
||||
LOG.exception("Failed to retrieve quota information")
|
||||
# If we can't get the quota information, leave it to the
|
||||
# API to check when launching
|
||||
return True # The action should always be displayed
|
||||
|
||||
def single(self, table, request, object_id=None):
|
||||
self.allowed(request, None)
|
||||
return HttpResponse(self.render(is_table_action=True))
|
||||
|
||||
|
||||
class LaunchLinkNG(LaunchLink):
|
||||
name = "launch-ng"
|
||||
|
@ -149,6 +149,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -182,6 +184,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
.AndReturn(images)
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndRaise(self.exceptions.nova)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
@ -217,6 +221,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
.AndRaise(self.exceptions.nova)
|
||||
api.glance.image_list_detailed(IgnoreArg()) \
|
||||
.AndReturn((self.images.list(), False, False))
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -261,6 +267,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -1444,6 +1452,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -3339,6 +3349,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(limits)
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -3358,6 +3370,54 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
self.assertEqual((('compute', 'os_compute_api:servers:create'),),
|
||||
launch_action.policy_rules)
|
||||
|
||||
@helpers.create_stubs({
|
||||
api.nova: ('flavor_list', 'server_list', 'tenant_absolute_limits',
|
||||
'extension_supported', 'is_feature_available',),
|
||||
api.glance: ('image_list_detailed',),
|
||||
api.neutron: ('floating_ip_simple_associate_supported',
|
||||
'floating_ip_supported',),
|
||||
api.network: ('servers_update_addresses',),
|
||||
})
|
||||
def test_launch_button_disabled_when_quota_exceeded(self):
|
||||
servers = self.servers.list()
|
||||
limits = self.limits['absolute']
|
||||
limits['totalInstancesUsed'] = limits['maxTotalInstances']
|
||||
|
||||
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.nova.is_feature_available(
|
||||
IsA(http.HttpRequest), 'locked_attribute'
|
||||
).MultipleTimes().AndReturn(True)
|
||||
api.nova.extension_supported('Shelve', IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.nova.flavor_list(IsA(http.HttpRequest)) \
|
||||
.AndReturn(self.flavors.list())
|
||||
api.glance.image_list_detailed(IgnoreArg()) \
|
||||
.AndReturn((self.images.list(), False, False))
|
||||
search_opts = {'marker': None, 'paginate': True}
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(limits)
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
IsA(http.HttpRequest)).MultipleTimes().AndReturn(True)
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
tables.LaunchLink()
|
||||
res = self.client.get(INDEX_URL)
|
||||
|
||||
launch_action = self.getAndAssertTableAction(
|
||||
res, 'instances', 'launch-ng')
|
||||
|
||||
self.assertIn('disabled', launch_action.classes,
|
||||
'The launch button should be disabled')
|
||||
self.assertEqual('Launch Instance (Quota exceeded)',
|
||||
six.text_type(launch_action.verbose_name))
|
||||
|
||||
@helpers.create_stubs({api.glance: ('image_list_detailed',),
|
||||
api.neutron: ('network_list',
|
||||
'port_list_with_trunk_types',
|
||||
@ -3492,6 +3552,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
|
||||
.AndReturn([servers, False])
|
||||
api.network.servers_update_addresses(IsA(http.HttpRequest), servers)
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
@ -3969,6 +4031,8 @@ class InstanceTests(helpers.ResetImageAPIVersionMixin, helpers.TestCase):
|
||||
api.network.servers_update_addresses(
|
||||
IsA(http.HttpRequest), servers[page_size:])
|
||||
|
||||
api.nova.tenant_absolute_limits(IsA(http.HttpRequest), reserved=True) \
|
||||
.MultipleTimes().AndReturn(self.limits['absolute'])
|
||||
api.neutron.floating_ip_supported(IsA(http.HttpRequest)) \
|
||||
.MultipleTimes().AndReturn(True)
|
||||
api.neutron.floating_ip_simple_associate_supported(
|
||||
|
Loading…
Reference in New Issue
Block a user