calling nova extensions api to enable certain nova features

Fixes: bug #1202310

Change-Id: I47365b0a89ab572f25cb71bfe17cae547261df9d
This commit is contained in:
ericpeterson-l 2013-07-17 16:03:22 -06:00
parent 9bb75cf631
commit db9c08e172
4 changed files with 118 additions and 28 deletions

View File

@ -28,6 +28,7 @@ from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from novaclient.v1_1 import client as nova_client
from novaclient.v1_1.contrib.list_extensions import ListExtManager
from novaclient.v1_1 import security_group_rules as nova_rules
from novaclient.v1_1.security_groups import SecurityGroup as NovaSecurityGroup
from novaclient.v1_1.servers import REBOOT_HARD
@ -628,3 +629,22 @@ def aggregate_list(request):
result.append(novaclient(request).aggregates.get(aggregate.id))
return result
@memoized
def list_extensions(request):
return ListExtManager(novaclient(request)).show_all()
@memoized
def extension_supported(extension_name, request):
"""
this method will determine if nova supports a given extension name.
example values for the extension_name include AdminActions, ConsoleOutput,
etc.
"""
extensions = list_extensions(request)
for extension in extensions:
if extension.name == extension_name:
return True
return False

View File

@ -27,12 +27,15 @@ from openstack_dashboard.test import helpers as test
class InstanceViewTest(test.BaseAdminViewTests):
@test.create_stubs({api.nova: ('flavor_list', 'server_list',),
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported',),
api.keystone: ('tenant_list',)})
def test_index(self):
servers = self.servers.list()
flavors = self.flavors.list()
tenants = self.tenants.list()
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.keystone.tenant_list(IsA(http.HttpRequest)).\
AndReturn([tenants, False])
search_opts = {'marker': None, 'paginate': True}
@ -48,7 +51,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertItemsEqual(instances, servers)
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list',),
'server_list', 'extension_supported',),
api.keystone: ('tenant_list',)})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
@ -60,6 +63,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndRaise(self.exceptions.nova)
api.keystone.tenant_list(IsA(http.HttpRequest)).\
@ -76,7 +81,7 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertItemsEqual(instances, servers)
@test.create_stubs({api.nova: ('flavor_list', 'flavor_get',
'server_list',),
'server_list', 'extension_supported', ),
api.keystone: ('tenant_list',)})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
@ -91,6 +96,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)). \
AndReturn(flavors)
api.keystone.tenant_list(IsA(http.HttpRequest)).\
@ -119,7 +126,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertTemplateUsed(res, 'admin/instances/index.html')
self.assertEqual(len(res.context['instances_table'].data), 0)
@test.create_stubs({api.nova: ('server_get', 'flavor_get',),
@test.create_stubs({api.nova: ('server_get', 'flavor_get',
'extension_supported', ),
api.keystone: ('tenant_get',)})
def test_ajax_loading_instances(self):
server = self.servers.first()
@ -127,6 +135,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
tenant = self.tenants.list()[0]
api.nova.server_get(IsA(http.HttpRequest), server.id).AndReturn(server)
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_get(IsA(http.HttpRequest),
server.flavor['id']).AndReturn(flavor)
api.keystone.tenant_get(IsA(http.HttpRequest),
@ -150,7 +160,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertContains(res, "Active", 1, 200)
self.assertContains(res, "Running", 1, 200)
@test.create_stubs({api.nova: ('flavor_list', 'server_list',),
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported', ),
api.keystone: ('tenant_list',)})
def test_index_options_before_migrate(self):
api.keystone.tenant_list(IsA(http.HttpRequest)).\
@ -159,6 +170,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)).\
AndReturn(self.flavors.list())
self.mox.ReplayAll()
@ -168,7 +181,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
self.assertNotContains(res, "instances__confirm")
self.assertNotContains(res, "instances__revert")
@test.create_stubs({api.nova: ('flavor_list', 'server_list',),
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'extension_supported', ),
api.keystone: ('tenant_list',)})
def test_index_options_after_migrate(self):
servers = self.servers.list()
@ -179,6 +193,8 @@ class InstanceViewTest(test.BaseAdminViewTests):
api.keystone.tenant_list(IsA(http.HttpRequest)) \
.AndReturn([self.tenants.list(), False])
search_opts = {'marker': None, 'paginate': True}
api.nova.extension_supported('AdminActions', IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.server_list(IsA(http.HttpRequest),
all_tenants=True, search_opts=search_opts) \
.AndReturn([self.servers.list(), False])

View File

@ -127,6 +127,9 @@ class TogglePause(tables.BatchAction):
classes = ("btn-pause",)
def allowed(self, request, instance=None):
if not api.nova.extension_supported('AdminActions',
request):
return False
self.paused = False
if not instance:
return self.paused
@ -156,6 +159,9 @@ class ToggleSuspend(tables.BatchAction):
classes = ("btn-suspend",)
def allowed(self, request, instance=None):
if not api.nova.extension_supported('AdminActions',
request):
return False
self.suspended = False
if not instance:
self.suspended

View File

@ -49,8 +49,12 @@ INDEX_URL = reverse('horizon:project:instances:index')
class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('flavor_list',
'server_list',
'tenant_absolute_limits')})
'tenant_absolute_limits',
'extension_supported',)})
def test_index(self):
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -61,8 +65,7 @@ class InstanceTests(test.TestCase):
self.mox.ReplayAll()
res = self.client.get(
reverse('horizon:project:instances:index'))
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res,
'project/instances/index.html')
@ -71,7 +74,7 @@ class InstanceTests(test.TestCase):
self.assertItemsEqual(instances, self.servers.list())
@test.create_stubs({api.nova: ('server_list',
'tenant_absolute_limits')})
'tenant_absolute_limits',)})
def test_index_server_list_exception(self):
search_opts = {'marker': None, 'paginate': True}
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
@ -81,7 +84,7 @@ class InstanceTests(test.TestCase):
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:instances:index'))
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, 'project/instances/index.html')
self.assertEqual(len(res.context['instances_table'].data), 0)
@ -90,12 +93,16 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('flavor_list',
'server_list',
'flavor_get',
'tenant_absolute_limits')})
'tenant_absolute_limits',
'extension_supported',)})
def test_index_flavor_list_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
full_flavors = SortedDict([(f.id, f) for f in flavors])
search_opts = {'marker': None, 'paginate': True}
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.server_list(IsA(http.HttpRequest), search_opts=search_opts) \
.AndReturn([servers, False])
api.nova.flavor_list(IsA(http.HttpRequest)) \
@ -108,7 +115,7 @@ class InstanceTests(test.TestCase):
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:instances:index'))
res = self.client.get(INDEX_URL)
self.assertTemplateUsed(res, 'project/instances/index.html')
instances = res.context['instances_table'].data
@ -118,10 +125,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('flavor_list',
'server_list',
'flavor_get',
'tenant_absolute_limits')})
'tenant_absolute_limits',
'extension_supported',)})
def test_index_flavor_get_exception(self):
servers = self.servers.list()
flavors = self.flavors.list()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
# UUIDs generated using indexes are unlikely to match
# any of existing flavor ids and are guaranteed to be deterministic.
for i, server in enumerate(servers):
@ -139,7 +150,7 @@ class InstanceTests(test.TestCase):
self.mox.ReplayAll()
res = self.client.get(reverse('horizon:project:instances:index'))
res = self.client.get(INDEX_URL)
instances = res.context['instances_table'].data
@ -188,10 +199,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_pause',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_pause_instance(self):
server = self.servers.first()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -208,10 +223,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_pause',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_pause_instance_exception(self):
server = self.servers.first()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -229,11 +248,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_unpause',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_unpause_instance(self):
server = self.servers.first()
server.status = "PAUSED"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -250,11 +272,15 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_unpause',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_unpause_instance_exception(self):
server = self.servers.first()
server.status = "PAUSED"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -275,7 +301,6 @@ class InstanceTests(test.TestCase):
'flavor_list',)})
def test_reboot_instance(self):
server = self.servers.first()
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -336,10 +361,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_suspend',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_suspend_instance(self):
server = self.servers.first()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -356,10 +385,14 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_suspend',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_suspend_instance_exception(self):
server = self.servers.first()
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -377,11 +410,15 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_resume',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_resume_instance(self):
server = self.servers.first()
server.status = "SUSPENDED"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -398,11 +435,15 @@ class InstanceTests(test.TestCase):
@test.create_stubs({api.nova: ('server_resume',
'server_list',
'flavor_list',)})
'flavor_list',
'extension_supported',)})
def test_resume_instance_exception(self):
server = self.servers.first()
server.status = "SUSPENDED"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -1429,11 +1470,15 @@ class InstanceTests(test.TestCase):
self.assertContains(res, "greater than or equal to 1")
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'tenant_absolute_limits',)})
'tenant_absolute_limits',
'extension_supported',)})
def test_launch_button_disabled_when_quota_exceeded(self):
limits = self.limits['absolute']
limits['totalInstancesUsed'] = limits['maxTotalInstances']
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}
@ -1458,11 +1503,14 @@ class InstanceTests(test.TestCase):
msg_prefix="The launch button is not disabled")
@test.create_stubs({api.nova: ('flavor_list', 'server_list',
'tenant_absolute_limits')})
'tenant_absolute_limits',
'extension_supported',)})
def test_index_options_after_migrate(self):
server = self.servers.first()
server.status = "VERIFY_RESIZE"
api.nova.extension_supported('AdminActions',
IsA(http.HttpRequest)) \
.MultipleTimes().AndReturn(True)
api.nova.flavor_list(IsA(http.HttpRequest)) \
.AndReturn(self.flavors.list())
search_opts = {'marker': None, 'paginate': True}