models: Remove "cleared" and "processed" fields from Jobs.
[ganeti_webmgr.git] / ganeti_web / tests / views / virtual_machine / edit.py
blobaf364acc15189d13708089b0d8591cc84af7f126
1 from django.contrib.auth.models import User
2 from django.test import Client
3 from django.utils import simplejson as json
5 from ganeti_web import models
6 from ganeti_web.util.proxy.constants import JOB_RUNNING
7 from ganeti_web.tests.views.virtual_machine.base import TestVirtualMachineViewsBase
8 from ganeti_web.utilities import cluster_os_list
10 __all__ = ['TestVirtualMachineEditViews',
11 'TestVirtualMachineDeleteViews',
12 'TestVirtualMachineReinstallViews',
13 'TestVirtualMachineRenameViews',
14 'TestVirtualMachineReparentViews']
16 VirtualMachine = models.VirtualMachine
19 class TestVirtualMachineEditViews(TestVirtualMachineViewsBase):
21 def test_view_modify(self):
22 """
23 Test modifying an instance
24 """
26 args = (self.cluster.slug, self.vm.hostname)
27 url = '/cluster/%s/%s/edit' % args
29 user = User(id=52, username='modifier')
30 user.set_password('secret2')
31 user.save()
33 ## GET
34 # Anonymous User
35 response = self.c.get(url)
36 self.assertEqual(302, response.status_code)
38 # User with Modify Permissions
39 user.grant('modify', self.vm)
40 self.assertTrue(self.c.login(username=user.username,
41 password='secret2'))
42 self.assertFalse(user.is_superuser)
43 self.assertTrue(user.has_perm('modify', self.vm))
44 self.assertFalse(user.has_perm('admin', self.vm))
45 response = self.c.get(url)
46 self.assertEqual(200, response.status_code)
47 self.assertEqual('text/html; charset=utf-8', response['content-type'])
48 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_kvm.html')
49 user.revoke_all(self.vm)
50 self.c.logout()
52 # User with Admin Permissions
53 user.grant('admin', self.vm)
54 self.assertTrue(self.c.login(username=user.username,
55 password='secret2'))
56 self.assertFalse(user.is_superuser)
57 response = self.c.get(url)
58 self.assertEqual(200, response.status_code)
59 self.assertEqual('text/html; charset=utf-8', response['content-type'])
60 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_kvm.html')
61 user.revoke_all(self.vm)
62 self.c.logout()
64 # Superuser
65 user.is_superuser = True
66 user.save()
67 self.assertTrue(self.c.login(username=user.username,
68 password='secret2'))
69 response = self.c.get(url)
70 self.assertEqual(200, response.status_code)
71 self.assertEqual('text/html; charset=utf-8', response['content-type'])
72 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_kvm.html')
73 self.c.logout()
74 user.is_superuser = False
75 user.save()
77 ## POST
78 os_list = cluster_os_list(self.cluster)
79 data = dict(vcpus=2,
80 acpi=True,
81 disk_cache='default',
82 initrd_path='',
83 kernel_args='ro',
84 kvm_flag='',
85 mem_path='',
86 migration_downtime=30,
87 security_domain='',
88 security_model='none',
89 usb_mouse='',
90 use_chroot=False,
91 use_localtime=False,
92 vnc_bind_address='0.0.0.0',
93 vnc_tls=False,
94 vnc_x509_path='',
95 vnc_x509_verify=False,
96 memory=512,
97 os='image+debian-osgeo',
98 disk_type='paravirtual',
99 boot_order='disk',
100 nic_type='paravirtual',
101 nic_count=1,
102 nic_count_original=1,
103 nic_link_0='br0',
104 nic_mac_0='aa:bb:00:00:33:d2',
105 root_path='/dev/vda1',
106 kernel_path='/boot/vmlinuz-2.32.6-27-generic',
107 serial_console=True,
108 cdrom_image_path='',
109 cdrom2_image_path='')
111 # Required Values
112 user.grant('modify', self.vm)
113 self.assertTrue(self.c.login(username=user.username,
114 password='secret2'))
115 session = self.c.session
116 session['os_list'] = os_list
117 session.save()
118 for property in ['vcpus', 'memory', 'disk_type', 'boot_order',
119 'nic_type']:
120 data_ = data.copy()
121 del data_[property]
122 self.assertFalse(user.is_superuser)
123 response = self.c.post(url, data_)
124 # If failure then a field that is not required by the model, but
125 # should be required by the form, is not being required by
126 # the form. See the ModifyVirtualMachineForm.required field.
127 self.assertNotEqual(response.context['form'][property].errors, [], msg=property)
128 self.assertEqual(200, response.status_code) # 302 if success (BAD)
129 self.assertEqual('text/html; charset=utf-8', response['content-type'])
130 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_kvm.html')
131 self.c.logout()
132 user.revoke_all(self.vm)
135 # Anonymous User
136 response = self.c.post(url, data)
137 self.assertEqual(302, response.status_code)
139 # Superuser
140 user.is_superuser = True
141 user.save()
142 self.assertTrue(self.c.login(username=user.username,
143 password='secret2'))
144 self.assertTrue(user.is_superuser)
145 session = self.c.session
146 session['os_list'] = os_list
147 session.save()
148 response = self.c.post(url, data)
149 self.assertEqual(302, response.status_code)
150 self.assertEqual('text/html; charset=utf-8', response['content-type'])
151 self.c.logout()
152 user.is_superuser = False
153 user.save()
155 # User without Permissions
156 self.assertTrue(self.c.login(username=user.username,
157 password='secret2'))
158 self.assertFalse(user.is_superuser)
159 session = self.c.session
160 session['os_list'] = os_list
161 session.save()
162 response = self.c.post(url, data)
163 self.assertEqual(403, response.status_code)
164 self.assertTrue(response.context['message'])
165 self.assertEqual('text/html; charset=utf-8', response['content-type'])
166 self.assertTemplateUsed(response, '403.html')
167 self.c.logout()
169 # User with Modify Permissions
170 user.grant('modify', self.vm)
171 self.assertTrue(self.c.login(username=user.username,
172 password='secret2'))
173 self.assertFalse(user.is_superuser)
174 session = self.c.session
175 session['os_list'] = os_list
176 session.save()
177 response = self.c.post(url, data)
178 self.assertEqual(302, response.status_code)
179 self.assertEqual('text/html; charset=utf-8', response['content-type'])
180 user.revoke_all(self.vm)
181 self.c.logout()
183 # User with Admin Permissions
184 user.grant('admin', self.vm)
185 self.assertTrue(self.c.login(username=user.username,
186 password='secret2'))
187 self.assertFalse(user.is_superuser)
188 session = self.c.session
189 session['os_list'] = os_list
190 session.save()
191 response = self.c.post(url, data)
192 self.assertEqual(302, response.status_code)
193 self.assertEqual('text/html; charset=utf-8', response['content-type'])
194 user.revoke_all(self.vm)
195 self.c.logout()
197 def test_view_modify_confirm(self):
199 Test confirm page for modifying an instance
202 args = (self.cluster.slug, self.vm.hostname)
203 url = '/cluster/%s/%s/edit/confirm' % args
205 user = User(id=52, username='modifier')
206 user.set_password('secret2')
207 user.save()
209 self.vm.owner = user.get_profile()
210 self.vm.save()
212 os_list = cluster_os_list(self.cluster)
213 edit_form = dict(vcpus=2,
214 acpi=True,
215 disk_cache='default',
216 initrd_path='',
217 kernel_args='ro',
218 kvm_flag='',
219 mem_path='',
220 migration_downtime=30,
221 security_domain='',
222 security_model='none',
223 usb_mouse='',
224 use_chroot=False,
225 use_localtime=False,
226 vnc_bind_address='0.0.0.0',
227 vnc_tls=False,
228 vnc_x509_path='',
229 vnc_x509_verify=False,
230 memory=512,
231 os='image+debian-osgeo',
232 disk_type='paravirtual',
233 boot_order='disk',
234 nic_type='paravirtual',
235 nic_count=1,
236 nic_count_original=1,
237 nic_link_0='br0',
238 nic_mac_0='aa:bb:00:00:33:d2',
239 root_path='/dev/vda1',
240 kernel_path='/boot/vmlinuz-2.32.6-27-generic',
241 serial_console=True,
242 cdrom_image_path='')
244 ## SESSION VARIABLES
245 # Make sure session variables are set
246 user.is_superuser = True
247 user.save()
248 self.assertTrue(self.c.login(username=user.username,
249 password='secret2'))
250 session = self.c.session
251 # edit_form
252 response = self.c.get(url)
253 self.assertEqual(400, response.status_code)
254 session['edit_form'] = edit_form
255 session.save()
256 response = self.c.get(url)
257 self.assertEqual(200, response.status_code)
258 self.assertEqual('text/html; charset=utf-8', response['content-type'])
259 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_confirm.html')
261 #session['os_list'] = os_list
262 #session.save()
263 user.revoke_all(self.vm)
264 user.is_superuser = False
265 user.save()
266 self.c.logout()
268 ## GET
269 # Anonymous User
270 response = self.c.get(url)
271 self.assertEqual(302, response.status_code)
273 # User with Modify Permissions
274 user.grant('modify', self.vm)
275 self.assertFalse(user.is_superuser)
276 self.assertTrue(self.c.login(username=user.username,
277 password='secret2'))
278 session = self.c.session
279 session['edit_form'] = edit_form
280 session['os_list'] = os_list
281 session.save()
282 response = self.c.get(url)
283 self.assertEqual(200, response.status_code)
284 self.assertEqual('text/html; charset=utf-8', response['content-type'])
285 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_confirm.html')
286 user.revoke_all(self.vm)
287 self.c.logout()
289 # User with Admin Permissions
290 user.grant('admin', self.vm)
291 self.assertFalse(user.is_superuser)
292 self.assertTrue(self.c.login(username=user.username,
293 password='secret2'))
294 session = self.c.session
295 session['edit_form'] = edit_form
296 session['os_list'] = os_list
297 session.save()
298 response = self.c.get(url)
299 self.assertEqual(200, response.status_code)
300 self.assertEqual('text/html; charset=utf-8', response['content-type'])
301 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_confirm.html')
302 user.revoke_all(self.vm)
303 self.c.logout()
305 # Superuser
306 user.is_superuser = True
307 user.save()
308 self.assertTrue(self.c.login(username=user.username,
309 password='secret2'))
310 session = self.c.session
311 session['edit_form'] = edit_form
312 session['os_list'] = os_list
313 session.save()
314 response = self.c.get(url)
315 self.assertEqual(200, response.status_code)
316 self.assertEqual('text/html; charset=utf-8', response['content-type'])
317 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_confirm.html')
318 self.c.logout()
319 user.is_superuser = False
320 user.save()
322 ## POST
323 data = {'rapi_dict':json.dumps(edit_form)}
324 # Anonymous User
325 response = self.c.post(url, data)
326 self.assertEqual(302, response.status_code)
328 for i in ('cancel', 'edit', 'save', 'reboot'):
329 data[i] = True
331 # Superuser
332 user.is_superuser = True
333 user.save()
334 self.assertTrue(self.c.login(username=user.username,
335 password='secret2'))
336 session = self.c.session
337 session['edit_form'] = edit_form
338 session['os_list'] = os_list
339 session.save()
340 self.assertTrue(user.is_superuser)
341 response = self.c.post(url, data)
342 self.assertEqual(302, response.status_code)
343 self.assertEqual('text/html; charset=utf-8', response['content-type'])
344 self.c.logout()
345 user.is_superuser = False
346 user.save()
348 # User without Permissions
349 self.assertTrue(self.c.login(username=user.username,
350 password='secret2'))
351 self.assertFalse(user.is_superuser)
352 response = self.c.post(url, data)
353 self.assertEqual(403, response.status_code)
354 self.assertTrue(response.context['message'])
355 self.assertEqual('text/html; charset=utf-8', response['content-type'])
356 self.assertTemplateUsed(response, '403.html')
357 self.c.logout()
359 # User with Modify Permissions
360 user.grant('modify', self.vm)
361 user.grant('power', self.vm)
362 self.assertTrue(self.c.login(username=user.username,
363 password='secret2'))
364 session = self.c.session
365 session['edit_form'] = edit_form
366 session['os_list'] = os_list
367 session.save()
368 self.assertFalse(user.is_superuser)
369 response = self.c.post(url, data)
370 self.assertEqual(302, response.status_code)
371 self.assertEqual('text/html; charset=utf-8', response['content-type'])
372 user.revoke_all(self.vm)
373 self.c.logout()
375 # User with Admin Permissions
376 user.grant('admin', self.vm)
377 self.assertTrue(self.c.login(username=user.username,
378 password='secret2'))
379 session = self.c.session
380 session['edit_form'] = edit_form
381 session['os_list'] = os_list
382 session.save()
383 self.assertFalse(user.is_superuser)
384 response = self.c.post(url, data)
385 self.assertEqual(302, response.status_code)
386 self.assertEqual('text/html; charset=utf-8', response['content-type'])
387 user.revoke_all(self.vm)
388 self.c.logout()
390 del data[i]
392 def test_view_modify_quota_over(self):
393 args = (self.cluster.slug, self.vm.hostname)
394 url = '/cluster/%s/%s/edit' % args
396 user = User(id=52, username='modifier')
397 user.set_password('secret2')
398 user.save()
399 user.grant('modify', self.vm)
400 profile = user.get_profile()
401 self.vm.owner = profile
402 self.vm.save()
404 self.cluster.set_quota(profile, dict(ram=1000, disk=2000,
405 virtual_cpus=10))
407 ## POST
408 os_list = cluster_os_list(self.cluster)
409 data = dict(vcpus=2000,
410 acpi=True,
411 disk_cache='default',
412 initrd_path='',
413 kernel_args='ro',
414 kvm_flag='',
415 mem_path='',
416 migration_downtime=30,
417 security_domain='',
418 security_model='none',
419 usb_mouse='',
420 use_chroot=False,
421 use_localtime=False,
422 vnc_bind_address='0.0.0.0',
423 vnc_tls=False,
424 vnc_x509_path='',
425 vnc_x509_verify=False,
426 memory=512,
427 os='image+debian-osgeo',
428 disk_type='paravirtual',
429 boot_order='disk',
430 nic_type='paravirtual',
431 nic_count=1,
432 nic_count_original=1,
433 nic_link_0='br0',
434 nic_mac_0='aa:bb:00:00:33:d2',
435 root_path='/dev/vda1',
436 kernel_path='/boot/vmlinuz-2.32.6-27-generic',
437 serial_console=True,
438 cdrom_image_path='')
440 user.grant('modify', self.vm)
441 self.assertTrue(self.c.login(username=user.username,
442 password='secret2'))
443 self.assertFalse(user.is_superuser)
444 session = self.c.session
445 session['os_list'] = os_list
446 session.save()
447 response = self.c.post(url, data)
448 self.assertEqual(200, response.status_code) # 302 if success (BAD)
449 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_kvm.html')
450 user.revoke_all(self.vm)
451 self.c.logout()
453 def test_view_modify_confirm_quota_over(self):
454 args = (self.cluster.slug, self.vm.hostname)
455 url = '/cluster/%s/%s/edit/confirm' % args
457 user = User(id=52, username='modifier')
458 user.set_password('secret2')
459 user.save()
460 user.grant('modify', self.vm)
461 profile = user.get_profile()
462 self.vm.owner = profile
463 self.vm.save()
465 self.cluster.set_quota(profile, dict(ram=1000, disk=2000,
466 virtual_cpus=10))
468 os_list = cluster_os_list(self.cluster)
469 edit_form = dict(vcpus=2000,
470 acpi=True,
471 disk_cache='default',
472 initrd_path='',
473 kernel_args='ro',
474 kvm_flag='',
475 mem_path='',
476 migration_downtime=30,
477 security_domain='',
478 security_model='none',
479 usb_mouse='',
480 use_chroot=False,
481 use_localtime=False,
482 vnc_bind_address='0.0.0.0',
483 vnc_tls=False,
484 vnc_x509_path='',
485 vnc_x509_verify=False,
486 memory=512,
487 os='image+debian-osgeo',
488 disk_type='paravirtual',
489 boot_order='disk',
490 nic_type='paravirtual',
491 nic_count=1,
492 nic_count_original=1,
493 nic_link_0='br0',
494 nic_mac_0='aa:bb:00:00:33:d2',
495 root_path='/dev/vda1',
496 kernel_path='/boot/vmlinuz-2.32.6-27-generic',
497 serial_console=True,
498 cdrom_image_path='')
499 data = {'rapi_dict':json.dumps(edit_form), 'save':True}
501 # regular user
502 self.assertTrue(self.c.login(username=user.username,
503 password='secret2'))
504 session = self.c.session
505 session['edit_form'] = edit_form
506 session['os_list'] = os_list
507 session.save()
508 response = self.c.post(url, data)
509 self.assertEqual(200, response.status_code)
510 self.assertEqual('text/html; charset=utf-8', response['content-type'])
511 self.assertTemplateUsed(response, 'ganeti/virtual_machine/edit_confirm.html')
512 self.c.logout()
515 class TestVirtualMachineDeleteViews(TestVirtualMachineViewsBase):
517 Test the virtual machine deletion view in a variety of ways.
520 def setUp(self):
521 super(TestVirtualMachineDeleteViews, self).setUp()
522 self.url = '/cluster/%s/%s/delete'
523 self.args = (self.cluster.slug, self.vm.hostname)
525 def test_view_delete_anonymous(self):
526 response = self.c.get(self.url % self.args, follow=True)
527 self.assertEqual(200, response.status_code)
528 self.assertTemplateUsed(response, 'registration/login.html')
530 def test_view_delete_unauthorized(self):
531 self.assertTrue(self.c.login(username=self.user.username,
532 password='secret'))
533 response = self.c.post(self.url % self.args)
534 self.assertEqual(403, response.status_code)
536 def test_view_delete_invalid_vm(self):
537 self.assertTrue(self.c.login(username=self.user.username,
538 password='secret'))
539 response = self.c.get(self.url % (self.cluster.slug, "DoesNotExist"))
540 self.assertEqual(404, response.status_code)
542 def test_view_delete_get_authorized_remove(self):
543 self.user.grant('remove', self.vm)
544 self.assertTrue(self.c.login(username=self.user.username,
545 password='secret'))
546 response = self.c.get(self.url % self.args)
547 self.assertEqual(200, response.status_code)
548 self.assertEqual('text/html; charset=utf-8', response['content-type'])
549 self.assertTemplateUsed(response,
550 'ganeti/virtual_machine/delete.html')
551 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
553 def test_view_delete_get_authorized_admin(self):
554 self.user.grant('admin', self.vm)
555 self.assertTrue(self.c.login(username=self.user.username,
556 password='secret'))
557 response = self.c.get(self.url % self.args)
558 self.assertEqual(200, response.status_code)
559 self.assertEqual('text/html; charset=utf-8', response['content-type'])
560 self.assertTemplateUsed(response,
561 'ganeti/virtual_machine/delete.html')
562 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
564 def test_view_delete_get_authorized_cluster_admin(self):
565 self.user.grant('admin', self.cluster)
566 self.assertTrue(self.c.login(username=self.user.username,
567 password='secret'))
568 response = self.c.get(self.url % self.args)
569 self.assertEqual(200, response.status_code)
570 self.assertEqual('text/html; charset=utf-8', response['content-type'])
571 self.assertTemplateUsed(response,
572 'ganeti/virtual_machine/delete.html')
573 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
575 def test_view_delete_get_superuser(self):
576 self.assertTrue(self.c.login(username=self.superuser.username,
577 password='secret'))
578 response = self.c.get(self.url % self.args)
579 self.assertEqual(200, response.status_code)
580 self.assertEqual('text/html; charset=utf-8', response['content-type'])
581 self.assertTemplateUsed(response,
582 'ganeti/virtual_machine/delete.html')
583 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
585 def test_view_delete_post_superuser(self):
586 self.assertTrue(self.c.login(username=self.superuser.username,
587 password='secret'))
588 self.vm.rapi.GetJobStatus.response = JOB_RUNNING
589 response = self.c.post(self.url % self.args, follow=True)
590 self.assertEqual(200, response.status_code)
591 self.assertEqual('text/html; charset=utf-8', response['content-type'])
592 self.assertTemplateUsed(response,
593 'ganeti/virtual_machine/delete_status.html')
594 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
595 qs = VirtualMachine.objects.filter(id=self.vm.id)
596 pending_delete, job_id = qs.values('pending_delete', 'last_job_id')[0]
597 self.assertTrue(pending_delete)
598 self.assertTrue(job_id)
600 def test_view_delete_post_7605(self):
602 When a VM is deleted, all of its jobs should be cleared.
604 See #7605 for more information.
607 job = models.Job.objects.create(job_id=42, obj=self.vm,
608 cluster_id=self.vm.cluster_id)
610 self.assertTrue(self.c.login(username=self.superuser.username,
611 password='secret'))
612 self.vm.rapi.GetJobStatus.response = JOB_RUNNING
613 response = self.c.post(self.url % self.args, follow=True)
614 self.assertEqual(200, response.status_code)
615 self.assertEqual('text/html; charset=utf-8', response['content-type'])
616 self.assertTemplateUsed(response,
617 'ganeti/virtual_machine/delete_status.html')
618 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
619 qs = VirtualMachine.objects.filter(id=self.vm.id)
620 pending_delete, job_id = qs.values('pending_delete', 'last_job_id')[0]
621 self.assertTrue(pending_delete)
622 self.assertTrue(job_id)
624 # Refresh and make sure it's cleared.
625 qs = models.Job.objects.filter(job_id=job.job_id)
626 self.assertFalse(qs.exists())
628 def test_view_delete_post_cluster_admin(self):
629 self.user.grant('admin', self.cluster)
630 self.assertTrue(self.c.login(username=self.user.username,
631 password='secret'))
632 response = self.c.post(self.url % self.args, follow=True)
633 self.assertEqual(200, response.status_code)
634 self.assertEqual('text/html; charset=utf-8', response['content-type'])
635 self.assertTemplateUsed(response,
636 'ganeti/virtual_machine/delete_status.html')
637 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
638 qs = VirtualMachine.objects.filter(id=self.vm.id)
639 pending_delete, job_id = qs.values('pending_delete', 'last_job_id')[0]
640 self.assertTrue(pending_delete)
641 self.assertTrue(job_id)
643 def test_view_delete_post_admin(self):
644 self.user.grant('admin', self.vm)
645 self.assertTrue(self.c.login(username=self.user.username,
646 password='secret'))
647 response = self.c.post(self.url % self.args, follow=True)
648 self.assertEqual(200, response.status_code)
649 self.assertEqual('text/html; charset=utf-8', response['content-type'])
650 self.assertTemplateUsed(response, 'ganeti/virtual_machine/delete_status.html')
651 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
652 qs = VirtualMachine.objects.filter(id=self.vm.id)
653 pending_delete, job_id = qs.values('pending_delete', 'last_job_id')[0]
654 self.assertTrue(pending_delete)
655 self.assertTrue(job_id)
657 def test_view_delete_post_vm_remove(self):
658 self.user.grant('remove', self.vm)
659 self.assertTrue(self.c.login(username=self.user.username,
660 password='secret'))
661 response = self.c.post(self.url % self.args, follow=True)
662 self.assertEqual(200, response.status_code)
663 self.assertEqual('text/html; charset=utf-8', response['content-type'])
664 self.assertTemplateUsed(response, 'ganeti/virtual_machine/delete_status.html')
665 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
666 qs = VirtualMachine.objects.filter(id=self.vm.id)
667 pending_delete, job_id = qs.values('pending_delete', 'last_job_id')[0]
668 self.assertTrue(pending_delete)
669 self.assertTrue(job_id)
671 def test_view_delete_strict_csrf(self):
673 The POST method is protected by a CSRF token. Attempts to delete a VM
674 without the token will fail.
676 See #9783 for more information.
679 c = Client(enforce_csrf_checks=True)
680 self.assertTrue(c.login(username=self.superuser.username,
681 password='secret'))
682 response = c.post(self.url % self.args)
683 self.assertEqual(403, response.status_code)
684 qs = VirtualMachine.objects.filter(id=self.vm.id)
685 self.assertTrue(qs.exists())
686 self.assertFalse(qs[0].pending_delete)
688 def test_view_delete_strict_csrf_delete(self):
690 The DELETE method is protected by a CSRF token. Attempts to delete a
691 VM without the token will fail.
693 See #9783 for more information.
696 c = Client(enforce_csrf_checks=True)
697 self.assertTrue(c.login(username=self.superuser.username,
698 password='secret'))
699 response = c.delete(self.url % self.args)
700 self.assertEqual(403, response.status_code)
701 qs = VirtualMachine.objects.filter(id=self.vm.id)
702 self.assertTrue(qs.exists())
703 self.assertFalse(qs[0].pending_delete)
706 class TestVirtualMachineReinstallViews(TestVirtualMachineViewsBase):
708 def test_view_reinstall(self):
710 Tests view for reinstalling virtual machines
712 url = '/cluster/%s/%s/reinstall'
713 args = (self.cluster.slug, self.vm.hostname)
715 # anonymous user
716 response = self.c.get(url % args, follow=True)
717 self.assertEqual(200, response.status_code)
718 self.assertTemplateUsed(response, 'registration/login.html')
720 # unauthorized user
721 self.assertTrue(self.c.login(username=self.user.username,
722 password='secret'))
723 response = self.c.post(url % args)
724 self.assertEqual(403, response.status_code)
726 # invalid vm
727 response = self.c.get(url % (self.cluster.slug, "DoesNotExist"))
728 self.assertEqual(404, response.status_code)
730 # authorized GET (vm remove permissions)
731 self.user.grant('remove', self.vm)
732 response = self.c.get(url % args)
733 self.assertEqual(200, response.status_code)
734 self.assertEqual('text/html; charset=utf-8', response['content-type'])
735 self.assertTemplateUsed(response, 'ganeti/virtual_machine/reinstall.html')
736 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
737 self.user.revoke_all(self.vm)
739 # authorized GET (vm admin permissions)
740 self.user.grant('admin', self.vm)
741 response = self.c.get(url % args)
742 self.assertEqual(200, response.status_code)
743 self.assertEqual('text/html; charset=utf-8', response['content-type'])
744 self.assertTemplateUsed(response, 'ganeti/virtual_machine/reinstall.html')
745 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
746 self.user.revoke_all(self.cluster)
748 # authorized GET (cluster admin permissions)
749 self.user.grant('admin', self.cluster)
750 response = self.c.get(url % args)
751 self.assertEqual(200, response.status_code)
752 self.assertEqual('text/html; charset=utf-8', response['content-type'])
753 self.assertTemplateUsed(response, 'ganeti/virtual_machine/reinstall.html')
754 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
755 self.user.revoke_all(self.cluster)
757 # authorized GET (superuser)
758 self.user.is_superuser = True
759 self.user.save()
760 response = self.c.get(url % args)
761 self.assertEqual(200, response.status_code)
762 self.assertEqual('text/html; charset=utf-8', response['content-type'])
763 self.assertTemplateUsed(response, 'ganeti/virtual_machine/reinstall.html')
764 self.assertTrue(VirtualMachine.objects.filter(id=self.vm.id).exists())
766 #authorized POST (superuser)
767 response = self.c.post(url % args)
768 self.assertEqual(302, response.status_code)
769 self.user.is_superuser = False
770 self.user.save()
771 self.vm.save()
773 #authorized POST (cluster admin)
774 self.user.grant('admin', self.cluster)
775 response = self.c.post(url % args)
776 self.assertEqual(302, response.status_code)
777 self.user.revoke_all(self.cluster)
779 #authorized POST (vm admin)
780 self.vm.save()
781 self.user.grant('admin', self.vm)
782 response = self.c.post(url % args)
783 self.assertEqual(302, response.status_code)
784 self.vm.save()
785 self.user.revoke_all(self.vm)
787 #authorized POST (cluster admin)
788 self.vm.save()
789 self.user.grant('remove', self.vm)
790 response = self.c.post(url % args)
791 self.assertEqual(302, response.status_code)
792 self.vm.save()
793 self.user.revoke_all(self.vm)
796 class TestVirtualMachineRenameViews(TestVirtualMachineViewsBase):
798 def test_view_rename_get(self):
800 VM rename GET requests should have the standard responses.
803 url = "/cluster/%s/%s/rename/"
804 args = (self.cluster.slug, self.vm.hostname)
805 template = 'ganeti/virtual_machine/rename.html'
806 users =[self.superuser, self.cluster_admin, self.vm_admin,
807 self.vm_modify]
808 denied = [self.cluster_migrate]
810 # test GET requests
811 self.assert_standard_fails(url, args)
812 self.assert_200(url, args, users, template=template)
813 self.assert_403(url, args, denied)
815 def test_view_rename_post(self):
817 VM rename POST requests should have the standard responses.
820 url = "/cluster/%s/%s/rename/"
821 args = (self.cluster.slug, self.vm.hostname)
822 template_success = 'ganeti/virtual_machine/detail.html'
823 users = [self.superuser, self.cluster_admin, self.vm_admin,
824 self.vm_modify]
825 denied = [self.cluster_migrate]
826 data = {'hostname':'foo.arg.different', 'ip_check':False, 'name_check':False}
828 def tests(user, response):
829 updated_vm = VirtualMachine.objects.get(pk=self.vm.pk)
830 self.assertEqual('foo.arg.different', updated_vm.hostname)
831 self.vm.save()
833 self.assert_standard_fails(url, args, data, method='post')
834 self.assert_200(url, args, users, template_success, data=data,
835 follow=True, method="post", tests=tests)
836 self.assert_403(url, args, denied, data=data, method="post")
838 def test_view_rename_form(self):
840 Tests that form validation is working properly
843 url = "/cluster/%s/%s/rename/"
844 args = (self.cluster.slug, self.vm.hostname)
845 template = 'ganeti/virtual_machine/rename.html'
846 data = {'hostname':'foo.arg.different', 'ip_check':False, 'name_check':False}
847 errors = ({'hostname': self.vm.hostname},)
849 #noinspection PyUnusedLocal
850 def tests(user, response):
851 updated_vm = VirtualMachine.objects.get(pk=self.vm.pk)
852 self.assertEqual(self.vm.hostname, updated_vm.hostname)
854 self.assert_view_missing_fields(url, args, data, fields=['hostname'],
855 template=template, tests=tests)
856 self.assert_view_values(url, args, data, errors, template,
857 tests=tests)
860 class TestVirtualMachineReparentViews(TestVirtualMachineViewsBase):
862 def test_view_rename_get(self):
864 VM reparent GET requests should have the standard responses.
867 url = "/cluster/%s/%s/reparent/"
868 args = (self.cluster.slug, self.vm.hostname)
869 template = 'ganeti/virtual_machine/reparent.html'
870 users =[self.superuser, self.cluster_admin]
871 denied = [self.vm_admin, self.vm_modify, self.cluster_migrate]
873 # test GET requests
874 self.assert_standard_fails(url, args)
875 self.assert_200(url, args, users, template=template)
876 self.assert_403(url, args, denied)
878 def test_view_rename_post(self):
880 VM reparent POST requests should have the standard responses.
883 self.vm.owner = self.vm_admin.get_profile()
884 self.vm.save()
886 url = "/cluster/%s/%s/reparent/"
887 args = (self.cluster.slug, self.vm.hostname)
888 template_success = 'ganeti/virtual_machine/detail.html'
889 users = [self.superuser, self.cluster_admin]
890 denied = [self.vm_admin, self.vm_modify, self.cluster_migrate]
891 data = {'owner': self.vm_modify.get_profile().pk}
893 def tests(user, response):
894 updated_vm = VirtualMachine.objects.get(pk=self.vm.pk)
895 self.assertEqual(self.vm_modify.get_profile().clusteruser_ptr,
896 updated_vm.owner)
898 self.assert_standard_fails(url, args, data, method='post')
899 self.assert_200(url, args, users, template_success, data=data,
900 follow=True, method="post", tests=tests)
901 self.assert_403(url, args, denied, data=data, method="post")