Add support for locking and unlocking servers

Partially implements: blueprint lock-unlock-server

Change-Id: I6d261cc7fb314bda60f0732f7a7bb3b23ba7c179
This commit is contained in:
Ana Krivokapic 2014-11-12 17:12:49 +01:00
parent ff09b75886
commit 5840d041db
3 changed files with 181 additions and 1 deletions

View File

@ -656,6 +656,14 @@ def server_stop(request, instance_id):
novaclient(request).servers.stop(instance_id)
def server_lock(request, instance_id):
novaclient(request).servers.lock(instance_id)
def server_unlock(request, instance_id):
novaclient(request).servers.unlock(instance_id)
def tenant_quota_get(request, tenant_id):
return base.QuotaSet(novaclient(request).quotas.get(tenant_id))

View File

@ -709,6 +709,68 @@ class StopInstance(policy.PolicyTargetMixin, tables.BatchAction):
api.nova.server_stop(request, obj_id)
class LockInstance(policy.PolicyTargetMixin, tables.BatchAction):
name = "lock"
policy_rules = (("compute", "compute_extension:admin_actions:lock"),)
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Lock Instance",
u"Lock Instances",
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u"Locked Instance",
u"Locked Instances",
count
)
# TODO(akrivoka): When the lock status is added to nova, revisit this
# to only allow unlocked instances to be locked
def allowed(self, request, instance):
if not api.nova.extension_supported('AdminActions', request):
return False
return True
def action(self, request, obj_id):
api.nova.server_lock(request, obj_id)
class UnlockInstance(policy.PolicyTargetMixin, tables.BatchAction):
name = "unlock"
policy_rules = (("compute", "compute_extension:admin_actions:unlock"),)
@staticmethod
def action_present(count):
return ungettext_lazy(
u"Unlock Instance",
u"Unlock Instances",
count
)
@staticmethod
def action_past(count):
return ungettext_lazy(
u"Unlocked Instance",
u"Unlocked Instances",
count
)
# TODO(akrivoka): When the lock status is added to nova, revisit this
# to only allow locked instances to be unlocked
def allowed(self, request, instance):
if not api.nova.extension_supported('AdminActions', request):
return False
return True
def action(self, request, obj_id):
api.nova.server_unlock(request, obj_id)
def get_ips(instance):
template_name = 'project/instances/_instance_ips.html'
context = {"instance": instance}
@ -930,5 +992,6 @@ class InstancesTable(tables.DataTable):
SimpleDisassociateIP, EditInstance,
DecryptInstancePassword, EditInstanceSecurityGroups,
ConsoleLink, LogLink, TogglePause, ToggleSuspend,
ResizeLink, SoftRebootInstance, RebootInstance,
ResizeLink, LockInstance, UnlockInstance,
SoftRebootInstance, RebootInstance,
StopInstance, RebuildInstance, TerminateInstance)

View File

@ -653,6 +653,115 @@ class InstanceTests(helpers.TestCase):
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_lock',
'server_list',
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_lock_instance(self):
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions', IsA(
http.HttpRequest)).MultipleTimes().AndReturn(True)
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.server_lock(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
formData = {'action': 'instances__lock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_lock',
'server_list',
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_lock_instance_exception(self):
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions', IsA(
http.HttpRequest)).MultipleTimes().AndReturn(True)
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.server_lock(IsA(http.HttpRequest), server.id).AndRaise(
self.exceptions.nova)
self.mox.ReplayAll()
formData = {'action': 'instances__lock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_unlock',
'server_list',
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_unlock_instance(self):
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions', IsA(
http.HttpRequest)).MultipleTimes().AndReturn(True)
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.server_unlock(IsA(http.HttpRequest), server.id)
self.mox.ReplayAll()
formData = {'action': 'instances__unlock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({api.nova: ('server_unlock',
'server_list',
'extension_supported',),
api.glance: ('image_list_detailed',),
api.network: ('servers_update_addresses',)})
def test_unlock_instance_exception(self):
servers = self.servers.list()
server = servers[0]
api.nova.extension_supported('AdminActions', IsA(
http.HttpRequest)).MultipleTimes().AndReturn(True)
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.server_unlock(IsA(http.HttpRequest), server.id).AndRaise(
self.exceptions.nova)
self.mox.ReplayAll()
formData = {'action': 'instances__unlock__%s' % server.id}
res = self.client.post(INDEX_URL, formData)
self.assertRedirectsNoFollow(res, INDEX_URL)
@helpers.create_stubs({
api.nova: (
"server_get",