def setUp(self): self.tearDown() self.cluster = Cluster(hostname='test.example.test', slug='OSL_TEST') self.cluster.save() self.vm = VirtualMachine(hostname='vm1.example.bak', cluster=self.cluster) self.vm.save() User(id=1, username='******').save() settings.ANONYMOUS_USER_ID = 1 self.user = User(id=2, username='******') self.user.set_password('secret') self.user.save() self.user1 = User(id=3, username='******') self.user1.set_password('secret') self.user1.grant("admin", self.cluster) self.user1.grant("admin", self.vm) self.user1.save() self.user2 = User(id=4, username="******") self.user2.set_password("secret") self.user2.is_superuser = True self.user2.save() self.c = Client()
def setUp(self): self.tearDown() self.user = User(id=2, username='******') self.user.set_password('secret') self.user.save() self.group = Group(name='testing_group') self.group.save() self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0') self.cluster0.save() self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1') self.cluster1.save() self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0) self.vm1 = VirtualMachine(hostname='vm1', cluster=self.cluster0, owner=self.user.get_profile()) # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0) self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1) self.vm4 = VirtualMachine(hostname='vm4', cluster=self.cluster1, owner=self.user.get_profile()) # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1) self.vm0.save() self.vm1.save() self.vm3.save() self.vm4.save() self.c = Client() self.owner = self.user.get_profile()
def create_virtual_machine(self, cluster=None, hostname="vm1.example.bak"): if cluster is None: cluster = Cluster(hostname="test.example.bak", slug="OSL_TEST", username="******", password="******") cluster.save() cluster.sync_nodes() vm = VirtualMachine(cluster=cluster, hostname=hostname) vm.save() return vm, cluster
def create_virtual_machine(self, cluster=None, hostname='vm1.example.bak'): if cluster is None: cluster = Cluster(hostname='test.example.bak', slug='OSL_TEST', username='******', password='******') cluster.save() cluster.sync_nodes() vm = VirtualMachine(cluster=cluster, hostname=hostname) vm.save() return vm, cluster
def test_missing_in_ganeti(self): """ Tests missing_in_ganeti property """ cluster = Cluster(hostname='ganeti.example.test') cluster.save() vm_current = VirtualMachine(cluster=cluster, hostname='gimager2.example.bak') vm_removed = VirtualMachine(cluster=cluster, hostname='does.not.exist.org') vm_current.save() vm_removed.save() self.assertEqual([u'does.not.exist.org'], cluster.missing_in_ganeti) vm_current.delete() vm_removed.delete() cluster.delete()
def test_sync_virtual_machines(self): """ Tests synchronizing cached virtuals machines (stored in db) with info the ganeti cluster is storing Verifies: * VMs no longer in ganeti are deleted * VMs missing from the database are added """ cluster = Cluster(hostname='ganeti.example.test') cluster.save() vm_missing = 'gimager.example.bak' vm_current = VirtualMachine(cluster=cluster, hostname='gimager2.example.bak') vm_removed = VirtualMachine(cluster=cluster, hostname='does.not.exist.org') vm_current.save() vm_removed.save() cluster.sync_virtual_machines() self.assertTrue(VirtualMachine.objects.get(cluster=cluster, hostname=vm_missing), 'missing vm was not created') self.assertTrue( VirtualMachine.objects.get( cluster=cluster, hostname=vm_current.hostname), 'previously existing vm was not created') self.assertTrue( VirtualMachine.objects.filter( cluster=cluster, hostname=vm_removed.hostname), "vm not in ganeti was not removed from db") cluster.sync_virtual_machines(True) self.assertFalse( VirtualMachine.objects.filter( cluster=cluster, hostname=vm_removed.hostname), 'vm not present in ganeti was not removed from db') vm_removed.delete() vm_current.delete() cluster.delete()
def test_sync_virtual_machines(self): """ Tests synchronizing cached virtuals machines (stored in db) with info the ganeti cluster is storing Verifies: * VMs no longer in ganeti are deleted * VMs missing from the database are added """ cluster = Cluster(hostname='ganeti.example.test') cluster.save() vm_missing = 'gimager.example.bak' vm_current = VirtualMachine(cluster=cluster, hostname='gimager2.example.bak') vm_removed = VirtualMachine(cluster=cluster, hostname='does.not.exist.org') vm_current.save() vm_removed.save() cluster.sync_virtual_machines() self.assertTrue( VirtualMachine.objects.get(cluster=cluster, hostname=vm_missing), 'missing vm was not created') self.assertTrue( VirtualMachine.objects.get(cluster=cluster, hostname=vm_current.hostname), 'previously existing vm was not created') self.assertTrue( VirtualMachine.objects.filter(cluster=cluster, hostname=vm_removed.hostname), "vm not in ganeti was not removed from db") cluster.sync_virtual_machines(True) self.assertFalse( VirtualMachine.objects.filter(cluster=cluster, hostname=vm_removed.hostname), 'vm not present in ganeti was not removed from db') vm_removed.delete() vm_current.delete() cluster.delete()
class ImportViews(TestCase): def setUp(self): self.tearDown() self.user = User(id=2, username='******') self.user.set_password('secret') self.user.save() self.group = Group(name='testing_group') self.group.save() self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0') self.cluster0.save() self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1') self.cluster1.save() self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0) self.vm1 = VirtualMachine(hostname='vm1', cluster=self.cluster0, owner=self.user.get_profile()) # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0) self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1) self.vm4 = VirtualMachine(hostname='vm4', cluster=self.cluster1, owner=self.user.get_profile()) # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1) self.vm0.save() self.vm1.save() self.vm3.save() self.vm4.save() self.c = Client() self.owner = self.user.get_profile() def tearDown(self): VirtualMachine.objects.all().delete() Cluster.objects.all().delete() Organization.objects.all().delete() Profile.objects.all().delete() User.objects.all().delete() Group.objects.all().delete() def test_orphans_view(self): """ Test orphans view """ url = '/import/orphans/' # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertEqual([(self.vm0.id, 'test0', 'vm0')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertEqual([(self.vm0.id, 'test0', 'vm0'), (self.vm3.id, 'test1', 'vm3')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - invalid owner data = {'virtual_machines': [self.vm0.id], 'owner': -1} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = {'virtual_machines': [self.vm3.id], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': [self.vm0.id], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) def test_missing_ganeti(self): """ Tests view for Virtual Machines missing from ganeti """ url = '/import/missing/' self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2'] self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5'] # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertEqual([('vm1', 'test0', 'vm1')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertEqual([('vm1', 'test0', 'vm1'), ('vm4', 'test1', 'vm4')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = {'virtual_machines': [self.vm3.hostname]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': ['vm1']} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) def test_missing_db(self): """ Tests view for Virtual Machines missing from database """ url = '/import/missing_db/' self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2'] self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5'] # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') cid_vm_hostname = Template('$cid:$hostname') c_vm2 = cid_vm_hostname.substitute( cid=self.cluster0.id, hostname='vm2') self.assertEqual([(c_vm2, u'test0', u'vm2')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') c_vm5 = cid_vm_hostname.substitute( cid=self.cluster1.id, hostname='vm5') self.assertEqual([(c_vm2, u'test0', u'vm2'), (c_vm5, u'test1', u'vm5')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - invalid owner data = {'virtual_machines': [self.vm0.id], 'owner': -1} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = {'virtual_machines': [self.vm3.hostname], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': [c_vm2], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) self.assertTrue(VirtualMachine.objects.filter(hostname='vm2').exists())
def missing_db(request): """ View for displaying VirtualMachines missing from the database """ user = request.user if user.is_superuser: clusters = Cluster.objects.all() else: clusters = user.get_objects_any_perms(Cluster, ['admin']) if not clusters: raise PermissionDenied(NO_PRIVS) vms = [] for cluster in clusters: for hostname in cluster.missing_in_db: vms.append(('%s:%s' % (cluster.id, hostname), hostname)) if request.method == 'POST': # process updates if this was a form submission form = ImportForm(vms, request.POST) if form.is_valid(): # update all selected VirtualMachines data = form.cleaned_data owner = data['owner'] vm_ids = data['virtual_machines'] import_ready = defaultdict(lambda: 0) orphaned = defaultdict(lambda: 0) # create missing VMs for vm in vm_ids: cluster_id, host = vm.split(':') cluster = Cluster.objects.get(id=cluster_id) VirtualMachine(hostname=host, cluster=cluster, owner=owner).save() import_ready[cluster.pk] -= 1 if owner is None: orphaned[cluster.pk] += 1 # remove created vms from the list vms = filter(lambda x: unicode(x[0]) not in vm_ids, vms) else: form = ImportForm(vms) vms = {} for cluster in clusters: for hostname in cluster.missing_in_db: vms[hostname] = (u'%s:%s' % (cluster.id, hostname), unicode(cluster.hostname), unicode(hostname)) vmhostnames = vms.keys() vmhostnames.sort() vms_tuplelist = [] for i in vmhostnames: vms_tuplelist.append(vms[i]) vms = vms_tuplelist return render_to_response("ganeti/importing/missing_db.html", {'vms': vms, 'form': form, }, context_instance=RequestContext(request), )
def template_to_instance(template, hostname, owner): """ Instantiate a VM template with a given hostname and owner. """ cluster = template.cluster beparams = { "vcpus": template.vcpus, } hvparams = {} hv = template.hypervisor or cluster.info["default_hypervisor"] kvm = hv == 'kvm' pvm = hv == 'xen-pvm' hvm = hv == 'xen-hvm' kvm_or_hvm = kvm or hvm kvm_or_pvm = kvm or pvm if kvm_or_hvm: hvparams.update(boot_order=template.boot_order) hvparams.update(cdrom_image_path=template.cdrom_image_path) hvparams.update(nic_type=template.nic_type) hvparams.update(disk_type=template.disk_type) if kvm_or_pvm: hvparams.update(kernel_path=template.kernel_path) hvparams.update(root_path=template.root_path) if kvm: hvparams.update(cdrom2_image_path=template.cdrom2_image_path) hvparams.update(serial_console=template.serial_console) memory = template.memory if has_balloonmem(cluster): minram = template.minmem beparams['minmem'] = minram beparams['maxmem'] = memory else: beparams['memory'] = memory vcpus = template.vcpus disk_size = template.disks[0]["size"] kwargs = { "os": template.os, "hypervisor": hv, "ip_check": template.ip_check, "name_check": template.name_check, "beparams": beparams, "no_install": template.no_install, "start": template.start, "hvparams": hvparams, } # Using auto allocator if template.iallocator: default_iallocator = cluster.info['default_iallocator'] kwargs.update(iallocator=default_iallocator) # Not using allocator, pass pnode else: kwargs.update(pnode=template.pnode) # Also pass in snode if it exists (drdb) if template.snode: kwargs.update(snode=template.snode) # secondary node isn't set but we're using drdb, so programming error # (this shouldn't happen if form validation is done correctly) elif template.disk_template == 'drdb': msg = 'Disk template set to drdb, but no secondary node set' raise RuntimeError(msg) job_id = cluster.rapi.CreateInstance('create', hostname, template.disk_template, template.disks, template.nics, **kwargs) vm = VirtualMachine() vm.cluster = cluster vm.hostname = hostname vm.ram = memory if has_balloonmem(cluster): vm.minram = minram vm.virtual_cpus = vcpus vm.disk_size = disk_size vm.owner = owner vm.ignore_cache = True # Do a dance to get the VM and the job referencing each other. vm.save() job = Job.objects.create(job_id=job_id, obj=vm, cluster=cluster) job.save() vm.last_job = job vm.save() # Grant admin permissions to the owner. owner.permissable.grant('admin', vm) return vm
def test_used_resources(self): """ Tests retrieving dictionary of resources used by a cluster user """ c1 = Cluster(hostname="testing1", slug="test1") c2 = Cluster(hostname="testing2", slug="test2") c3 = Cluster(hostname="testing3", slug="test3") user = User(username="******") quota = {"disk": 26, "ram": 6, "virtual_cpus": 14} for i in (c1, c2, c3, user): i.save() owner = user.get_profile() c1.set_quota(owner, quota) c3.set_quota(owner, quota) # test used_resources returns zeros for no values result = owner.used_resources(cluster=c1) self.assertEqual(0, result['ram']) self.assertEqual(0, result['disk']) self.assertEqual(0, result['virtual_cpus']) vm11 = VirtualMachine(hostname="1one", owner=owner, cluster=c1, status="running") vm21 = VirtualMachine(hostname="2one", owner=owner, cluster=c2, status="running") vm31 = VirtualMachine(hostname="3one", owner=owner, cluster=c2, status="running") vm12 = VirtualMachine(hostname="1two", owner=owner, cluster=c1, status="running", ram=1, virtual_cpus=3, disk_size=6) vm22 = VirtualMachine(hostname="2two", owner=owner, cluster=c2, status="running", ram=1, virtual_cpus=3, disk_size=6) vm32 = VirtualMachine(hostname="3two", owner=owner, cluster=c3, status="running", ram=1, virtual_cpus=3, disk_size=6) vm13 = VirtualMachine(hostname="1three", owner=owner, cluster=c1, status="stopped", ram=1, virtual_cpus=3, disk_size=6) vm23 = VirtualMachine(hostname="2three", owner=owner, cluster=c2, status="stopped", ram=1, virtual_cpus=3, disk_size=6) vm33 = VirtualMachine(hostname="3three", owner=owner, cluster=c3, status="stopped", ram=1, virtual_cpus=3, disk_size=6) for i in (vm11, vm12, vm13, vm21, vm22, vm23, vm31, vm32, vm33): i.save() # multiple clusters - every VM result = owner.used_resources(cluster=None, only_running=False) self.assertTrue(c1.id in result.keys()) self.assertTrue(c2.id in result.keys()) self.assertTrue(c3.id in result.keys()) self.assertEqual(result[c1.id]["disk"], 12) self.assertEqual(result[c1.id]["ram"], 2) self.assertEqual(result[c1.id]["virtual_cpus"], 6) self.assertEqual(result[c1.id], result[c3.id]) # multiple clusters - only running VMs result = owner.used_resources(cluster=None, only_running=True) self.assertTrue(c1.id in result.keys()) self.assertTrue(c2.id in result.keys()) self.assertTrue(c3.id in result.keys()) self.assertEqual(result[c1.id]["disk"], 12) self.assertEqual(result[c1.id]["ram"], 1) self.assertEqual(result[c1.id]["virtual_cpus"], 3) self.assertEqual(result[c1.id], result[c3.id]) # single cluster - every VM result = owner.used_resources(cluster=c1, only_running=False) self.assertEqual(result["disk"], 12) self.assertEqual(result["ram"], 2) self.assertEqual(result["virtual_cpus"], 6) # single cluster - only running VMs result = owner.used_resources(cluster=c1, only_running=True) self.assertEqual(result["disk"], 12) self.assertEqual(result["ram"], 1) self.assertEqual(result["virtual_cpus"], 3)
def test_view_overview(self): """ Tests overview (status) page """ # TODO: in future, add Ganeti errors checking cluster1 = Cluster(hostname='cluster1', slug='cluster1') cluster1.save() vm1 = VirtualMachine(hostname='vm2.example.bak', cluster=cluster1) vm1.save() job = Job(job_id=233, obj=self.vm, cluster=self.cluster, finished="2011-01-07 21:59", status="error") job.save() job1 = Job(job_id=1234, obj=vm1, cluster=cluster1, finished="2011-01-05 21:59", status="error") job1.save() job.rapi.GetJobStatus.response = JOB_ERROR url = "/" args = [] template = "ganeti/overview.html" mimetype = "text/html; charset=utf-8" status = 200 # anonymous user response = self.c.get(url % args, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # authorized user (non-admin) self.user.grant("admin", self.vm) self.user.save() self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster not in clusters) self.assertEqual(0, len(clusters)) self.assertEqual(0, response.context["orphaned"]) self.assertEqual(0, response.context["missing"]) self.assertEqual(0, response.context["import_ready"]) # authorized user (admin on one cluster) self.assertTrue(self.c.login(username=self.user1.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster in clusters) self.assertEqual(1, len(clusters)) self.assertEqual(1, response.context["orphaned"]) self.assertEqual(1, response.context["missing"]) self.assertEqual(2, response.context["import_ready"]) # authorized user (superuser) self.assertTrue(self.c.login(username=self.user2.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster in clusters) self.assertTrue(cluster1 in clusters) self.assertEqual(2, len(clusters)) self.assertEqual(2, response.context["orphaned"]) self.assertEqual(2, response.context["missing"]) self.assertEqual(4, response.context["import_ready"])
class ImportViews(TestCase): def setUp(self): self.tearDown() self.user = User(id=2, username='******') self.user.set_password('secret') self.user.save() self.group = Group(name='testing_group') self.group.save() self.cluster0 = Cluster(hostname='test0', slug='OSL_TEST0') self.cluster0.save() self.cluster1 = Cluster(hostname='test1', slug='OSL_TEST1') self.cluster1.save() self.vm0 = VirtualMachine(hostname='vm0', cluster=self.cluster0) self.vm1 = VirtualMachine(hostname='vm1', cluster=self.cluster0, owner=self.user.get_profile()) # self.vm2 = VirtualMachine(hostname='vm2', cluster=cluster0) self.vm3 = VirtualMachine(hostname='vm3', cluster=self.cluster1) self.vm4 = VirtualMachine(hostname='vm4', cluster=self.cluster1, owner=self.user.get_profile()) # self.vm5 = VirtualMachine(hostname='vm5', cluster=cluster1) self.vm0.save() self.vm1.save() self.vm3.save() self.vm4.save() self.c = Client() self.owner = self.user.get_profile() def tearDown(self): VirtualMachine.objects.all().delete() Cluster.objects.all().delete() Organization.objects.all().delete() Profile.objects.all().delete() User.objects.all().delete() Group.objects.all().delete() def test_orphans_view(self): """ Test orphans view """ url = '/import/orphans/' # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue( self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertEqual([(self.vm0.id, 'test0', 'vm0')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertEqual([(self.vm0.id, 'test0', 'vm0'), (self.vm3.id, 'test1', 'vm3')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - invalid owner data = {'virtual_machines': [self.vm0.id], 'owner': -1} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = {'virtual_machines': [self.vm3.id], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': [self.vm0.id], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/orphans.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) def test_missing_ganeti(self): """ Tests view for Virtual Machines missing from ganeti """ url = '/import/missing/' self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2'] self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5'] # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue( self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertEqual([('vm1', 'test0', 'vm1')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertEqual([('vm1', 'test0', 'vm1'), ('vm4', 'test1', 'vm4')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = {'virtual_machines': [self.vm3.hostname]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': ['vm1']} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) def test_missing_db(self): """ Tests view for Virtual Machines missing from database """ url = '/import/missing_db/' self.cluster0.rapi.GetInstances.response = ['vm0', 'vm2'] self.cluster1.rapi.GetInstances.response = ['vm3', 'vm5'] # anonymous user response = self.c.get(url, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # unauthorized user self.assertTrue( self.c.login(username=self.user.username, password='******')) response = self.c.get(url) self.assertEqual(403, response.status_code) # authorized get (cluster admin perm) self.user.grant('admin', self.cluster0) response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') cid_vm_hostname = Template('$cid:$hostname') c_vm2 = cid_vm_hostname.substitute(cid=self.cluster0.id, hostname='vm2') self.assertEqual([(c_vm2, u'test0', u'vm2')], response.context['vms']) self.user.revoke_all(self.cluster0) # authorized get (superuser) self.user.is_superuser = True self.user.save() response = self.c.get(url) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') c_vm5 = cid_vm_hostname.substitute(cid=self.cluster1.id, hostname='vm5') self.assertEqual([(c_vm2, u'test0', u'vm2'), (c_vm5, u'test1', u'vm5')], response.context['vms']) self.user.is_superuser = False self.user.save() # POST - invalid vm self.user.grant('admin', self.cluster0) data = {'virtual_machines': [-1]} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - invalid owner data = {'virtual_machines': [self.vm0.id], 'owner': -1} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - user does not have perms for cluster data = { 'virtual_machines': [self.vm3.hostname], 'owner': self.owner.id } response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertTrue(response.context['form'].errors) # POST - success data = {'virtual_machines': [c_vm2], 'owner': self.owner.id} response = self.c.post(url, data) self.assertEqual(200, response.status_code) self.assertEqual('text/html; charset=utf-8', response['content-type']) self.assertTemplateUsed(response, 'ganeti/importing/missing_db.html') self.assertFalse(response.context['form'].errors) self.assertEqual([], response.context['vms']) self.assertTrue(VirtualMachine.objects.filter(hostname='vm2').exists())
class TestGeneralViews(TestCase, ViewTestMixin): def setUp(self): self.tearDown() self.cluster = Cluster(hostname='test.example.test', slug='OSL_TEST') self.cluster.save() self.vm = VirtualMachine(hostname='vm1.example.bak', cluster=self.cluster) self.vm.save() User(id=1, username='******').save() settings.ANONYMOUS_USER_ID = 1 self.user = User(id=2, username='******') self.user.set_password('secret') self.user.save() self.user1 = User(id=3, username='******') self.user1.set_password('secret') self.user1.grant("admin", self.cluster) self.user1.grant("admin", self.vm) self.user1.save() self.user2 = User(id=4, username="******") self.user2.set_password("secret") self.user2.is_superuser = True self.user2.save() self.c = Client() def tearDown(self): SSHKey.objects.all().delete() Cluster.objects.all().delete() User.objects.all().delete() Group.objects.all().delete() Job.objects.all().delete() def test_view_overview(self): """ Tests overview (status) page """ # TODO: in future, add Ganeti errors checking cluster1 = Cluster(hostname='cluster1', slug='cluster1') cluster1.save() vm1 = VirtualMachine(hostname='vm2.example.bak', cluster=cluster1) vm1.save() job = Job(job_id=233, obj=self.vm, cluster=self.cluster, finished="2011-01-07 21:59", status="error") job.save() job1 = Job(job_id=1234, obj=vm1, cluster=cluster1, finished="2011-01-05 21:59", status="error") job1.save() job.rapi.GetJobStatus.response = JOB_ERROR url = "/" args = [] template = "ganeti/overview.html" mimetype = "text/html; charset=utf-8" status = 200 # anonymous user response = self.c.get(url % args, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # authorized user (non-admin) self.user.grant("admin", self.vm) self.user.save() self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster not in clusters) self.assertEqual(0, len(clusters)) self.assertEqual(0, response.context["orphaned"]) self.assertEqual(0, response.context["missing"]) self.assertEqual(0, response.context["import_ready"]) # authorized user (admin on one cluster) self.assertTrue(self.c.login(username=self.user1.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster in clusters) self.assertEqual(1, len(clusters)) self.assertEqual(1, response.context["orphaned"]) self.assertEqual(1, response.context["missing"]) self.assertEqual(2, response.context["import_ready"]) # authorized user (superuser) self.assertTrue(self.c.login(username=self.user2.username, password='******')) response = self.c.get(url % args) self.assertEqual(status, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) clusters = response.context['cluster_list'] self.assertTrue(self.cluster in clusters) self.assertTrue(cluster1 in clusters) self.assertEqual(2, len(clusters)) self.assertEqual(2, response.context["orphaned"]) self.assertEqual(2, response.context["missing"]) self.assertEqual(4, response.context["import_ready"]) def test_used_resources(self): """ tests the used_resources view """ group0 = Group.objects.create(name='group0') group1 = Group.objects.create(name='group1') self.user.groups.add(group0) self.user1.groups.add(group1) url = "/used_resources/" args = {} template = "ganeti/overview/used_resources_data.html" mimetype = "text/html; charset=utf-8" # anonymous user response = self.c.get(url, args, follow=True) self.assertEqual(200, response.status_code) self.assertTemplateUsed(response, 'registration/login.html') # 404 - no id self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url, {}) self.assertEqual(404, response.status_code) # 404 - invalid id response = self.c.get(url, {'id': 1234567}) self.assertEqual(404, response.status_code) # unauthorized user (different user) response = self.c.get(url, {'id': self.user2.get_profile().pk}) self.assertEqual(403, response.status_code) # unauthorized user (in different group) self.assertTrue(self.c.login(username=self.user.username, password='******')) response = self.c.get(url, {'id': group1.organization.pk}) self.assertEqual(403, response.status_code) # authorized user (same user) response = self.c.get(url, {'id': self.user.get_profile().pk}) self.assertEqual(200, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) # authorized user (in group) response = self.c.get(url, {'id': group0.organization.pk}) self.assertEqual(200, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) # authorized user (superuser) self.assertTrue(self.c.login(username=self.user2.username, password='******')) response = self.c.get(url, {'id': self.user.get_profile().pk}) self.assertEqual(200, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) # authorized user (superuser) self.assertTrue(self.c.login(username=self.user2.username, password='******')) response = self.c.get(url, {'id': group1.organization.pk}) self.assertEqual(200, response.status_code) self.assertEqual(mimetype, response['content-type']) self.assertTemplateUsed(response, template) def test_view_ssh_keys(self): """ tests retrieving all sshkeys from the gwm instance """ # add some keys SSHKey.objects.create(key="ssh-rsa test test@test", user=self.user) SSHKey.objects.create(key="ssh-dsa test asd@asd", user=self.user) SSHKey.objects.create(key="ssh-dsa test foo@bar", user=self.user1) self.user.revoke_all(self.vm) self.user.revoke_all(self.cluster) self.user1.revoke_all(self.vm) self.user1.revoke_all(self.cluster) self.user2.revoke_all(self.vm) self.user2.revoke_all(self.cluster) # get API key # import settings key = settings.WEB_MGR_API_KEY url = '/keys/%s/' args = (key,) # cluster without users who have admin perms response = self.c.get(url % args) self.assertEqual(200, response.status_code) self.assertEquals("application/json", response["content-type"]) self.assertEqual(len(json.loads(response.content)), 0) self.assertNotContains(response, "test@test") self.assertNotContains(response, "asd@asd") # vm with users who have admin perms # grant admin permission to first user self.user.grant("admin", self.vm) self.user1.grant("admin", self.cluster) response = self.c.get(url % args) self.assertEqual(200, response.status_code) self.assertEquals("application/json", response["content-type"]) self.assertEqual(len(json.loads(response.content)), 3) self.assertContains(response, "test@test", count=1) self.assertContains(response, "asd@asd", count=1) self.assertContains(response, "foo@bar", count=1)