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
):
23 Test modifying an instance
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')
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
,
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
)
52 # User with Admin Permissions
53 user
.grant('admin', self
.vm
)
54 self
.assertTrue(self
.c
.login(username
=user
.username
,
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
)
65 user
.is_superuser
= True
67 self
.assertTrue(self
.c
.login(username
=user
.username
,
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')
74 user
.is_superuser
= False
78 os_list
= cluster_os_list(self
.cluster
)
86 migration_downtime
=30,
88 security_model
='none',
92 vnc_bind_address
='0.0.0.0',
95 vnc_x509_verify
=False,
97 os
='image+debian-osgeo',
98 disk_type
='paravirtual',
100 nic_type
='paravirtual',
102 nic_count_original
=1,
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',
109 cdrom2_image_path
='')
112 user
.grant('modify', self
.vm
)
113 self
.assertTrue(self
.c
.login(username
=user
.username
,
115 session
= self
.c
.session
116 session
['os_list'] = os_list
118 for property in ['vcpus', 'memory', 'disk_type', 'boot_order',
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')
132 user
.revoke_all(self
.vm
)
136 response
= self
.c
.post(url
, data
)
137 self
.assertEqual(302, response
.status_code
)
140 user
.is_superuser
= True
142 self
.assertTrue(self
.c
.login(username
=user
.username
,
144 self
.assertTrue(user
.is_superuser
)
145 session
= self
.c
.session
146 session
['os_list'] = os_list
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'])
152 user
.is_superuser
= False
155 # User without Permissions
156 self
.assertTrue(self
.c
.login(username
=user
.username
,
158 self
.assertFalse(user
.is_superuser
)
159 session
= self
.c
.session
160 session
['os_list'] = os_list
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')
169 # User with Modify Permissions
170 user
.grant('modify', self
.vm
)
171 self
.assertTrue(self
.c
.login(username
=user
.username
,
173 self
.assertFalse(user
.is_superuser
)
174 session
= self
.c
.session
175 session
['os_list'] = os_list
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
)
183 # User with Admin Permissions
184 user
.grant('admin', self
.vm
)
185 self
.assertTrue(self
.c
.login(username
=user
.username
,
187 self
.assertFalse(user
.is_superuser
)
188 session
= self
.c
.session
189 session
['os_list'] = os_list
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
)
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')
209 self
.vm
.owner
= user
.get_profile()
212 os_list
= cluster_os_list(self
.cluster
)
213 edit_form
= dict(vcpus
=2,
215 disk_cache
='default',
220 migration_downtime
=30,
222 security_model
='none',
226 vnc_bind_address
='0.0.0.0',
229 vnc_x509_verify
=False,
231 os
='image+debian-osgeo',
232 disk_type
='paravirtual',
234 nic_type
='paravirtual',
236 nic_count_original
=1,
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',
245 # Make sure session variables are set
246 user
.is_superuser
= True
248 self
.assertTrue(self
.c
.login(username
=user
.username
,
250 session
= self
.c
.session
252 response
= self
.c
.get(url
)
253 self
.assertEqual(400, response
.status_code
)
254 session
['edit_form'] = edit_form
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
263 user
.revoke_all(self
.vm
)
264 user
.is_superuser
= False
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
,
278 session
= self
.c
.session
279 session
['edit_form'] = edit_form
280 session
['os_list'] = os_list
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
)
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
,
294 session
= self
.c
.session
295 session
['edit_form'] = edit_form
296 session
['os_list'] = os_list
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
)
306 user
.is_superuser
= True
308 self
.assertTrue(self
.c
.login(username
=user
.username
,
310 session
= self
.c
.session
311 session
['edit_form'] = edit_form
312 session
['os_list'] = os_list
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')
319 user
.is_superuser
= False
323 data
= {'rapi_dict':json
.dumps(edit_form
)}
325 response
= self
.c
.post(url
, data
)
326 self
.assertEqual(302, response
.status_code
)
328 for i
in ('cancel', 'edit', 'save', 'reboot'):
332 user
.is_superuser
= True
334 self
.assertTrue(self
.c
.login(username
=user
.username
,
336 session
= self
.c
.session
337 session
['edit_form'] = edit_form
338 session
['os_list'] = os_list
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'])
345 user
.is_superuser
= False
348 # User without Permissions
349 self
.assertTrue(self
.c
.login(username
=user
.username
,
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')
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
,
364 session
= self
.c
.session
365 session
['edit_form'] = edit_form
366 session
['os_list'] = os_list
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
)
375 # User with Admin Permissions
376 user
.grant('admin', self
.vm
)
377 self
.assertTrue(self
.c
.login(username
=user
.username
,
379 session
= self
.c
.session
380 session
['edit_form'] = edit_form
381 session
['os_list'] = os_list
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
)
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')
399 user
.grant('modify', self
.vm
)
400 profile
= user
.get_profile()
401 self
.vm
.owner
= profile
404 self
.cluster
.set_quota(profile
, dict(ram
=1000, disk
=2000,
408 os_list
= cluster_os_list(self
.cluster
)
409 data
= dict(vcpus
=2000,
411 disk_cache
='default',
416 migration_downtime
=30,
418 security_model
='none',
422 vnc_bind_address
='0.0.0.0',
425 vnc_x509_verify
=False,
427 os
='image+debian-osgeo',
428 disk_type
='paravirtual',
430 nic_type
='paravirtual',
432 nic_count_original
=1,
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',
440 user
.grant('modify', self
.vm
)
441 self
.assertTrue(self
.c
.login(username
=user
.username
,
443 self
.assertFalse(user
.is_superuser
)
444 session
= self
.c
.session
445 session
['os_list'] = os_list
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
)
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')
460 user
.grant('modify', self
.vm
)
461 profile
= user
.get_profile()
462 self
.vm
.owner
= profile
465 self
.cluster
.set_quota(profile
, dict(ram
=1000, disk
=2000,
468 os_list
= cluster_os_list(self
.cluster
)
469 edit_form
= dict(vcpus
=2000,
471 disk_cache
='default',
476 migration_downtime
=30,
478 security_model
='none',
482 vnc_bind_address
='0.0.0.0',
485 vnc_x509_verify
=False,
487 os
='image+debian-osgeo',
488 disk_type
='paravirtual',
490 nic_type
='paravirtual',
492 nic_count_original
=1,
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',
499 data
= {'rapi_dict':json
.dumps(edit_form
), 'save':True}
502 self
.assertTrue(self
.c
.login(username
=user
.username
,
504 session
= self
.c
.session
505 session
['edit_form'] = edit_form
506 session
['os_list'] = os_list
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')
515 class TestVirtualMachineDeleteViews(TestVirtualMachineViewsBase
):
517 Test the virtual machine deletion view in a variety of ways.
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
)
716 response
= self
.c
.get(url
% args
, follow
=True)
717 self
.assertEqual(200, response
.status_code
)
718 self
.assertTemplateUsed(response
, 'registration/login.html')
721 self
.assertTrue(self
.c
.login(username
=self
.user
.username
,
723 response
= self
.c
.post(url
% args
)
724 self
.assertEqual(403, response
.status_code
)
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
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
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)
781 self
.user
.grant('admin', self
.vm
)
782 response
= self
.c
.post(url
% args
)
783 self
.assertEqual(302, response
.status_code
)
785 self
.user
.revoke_all(self
.vm
)
787 #authorized POST (cluster admin)
789 self
.user
.grant('remove', self
.vm
)
790 response
= self
.c
.post(url
% args
)
791 self
.assertEqual(302, response
.status_code
)
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
,
808 denied
= [self
.cluster_migrate
]
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
,
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
)
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
,
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
]
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()
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
,
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")