views.py 7.22 KB
Newer Older
1 2
from os import getenv
import json
Őry Máté committed
3
import logging
4 5 6
import re

from django.contrib.auth.models import User, Group
7
from django.contrib.messages import warning
8
from django.core import signing
9 10
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
11
from django.shortcuts import redirect
12
from django.utils.translation import ugettext_lazy as _
13 14
from django.views.generic import TemplateView, DetailView, View
from django.views.generic.detail import SingleObjectMixin
15
from django.http import HttpResponse
16

17
from django_tables2 import SingleTableView
Kálmán Viktor committed
18

19
from .tables import VmListTable
20
from vm.models import Instance, InstanceTemplate, InterfaceTemplate
21
from firewall.models import Vlan
22
from storage.models import Disk
23

Őry Máté committed
24 25
logger = logging.getLogger(__name__)

26 27

class IndexView(TemplateView):
Kálmán Viktor committed
28
    template_name = "dashboard/index.html"
29

30
    def get_context_data(self, **kwargs):
31 32 33 34 35
        if self.request.user.is_authenticated():
            user = self.request.user
        else:
            user = None

36
        instances = Instance.objects.filter(owner=user)
37 38
        context = super(IndexView, self).get_context_data(**kwargs)
        context.update({
39
            'instances': instances[:5],
40
            'more_instances': instances.count() - len(instances[:5])
41 42 43
        })

        context.update({
44 45
            'running_vms': instances.filter(state='RUNNING'),
            'running_vm_num': instances.filter(state='RUNNING').count(),
46 47
            'stopped_vm_num': instances.exclude(
                state__in=['RUNNING', 'NOSTATE']).count()
48 49 50
        })
        return context

51

52 53 54 55 56 57 58 59 60 61
def get_acl_data(obj):
    levels = obj.ACL_LEVELS
    users = obj.get_users_with_level()
    users = [{'user': u, 'level': l} for u, l in users]
    groups = obj.get_groups_with_level()
    groups = [{'group': g, 'level': l} for g, l in groups]
    return {'users': users, 'groups': groups, 'levels': levels,
            'url': reverse('dashboard.views.vm-acl', args=[obj.pk])}


62
class VmDetailView(DetailView):
Kálmán Viktor committed
63
    template_name = "dashboard/vm-detail.html"
64
    model = Instance
65 66

    def get_context_data(self, **kwargs):
67
        context = super(VmDetailView, self).get_context_data(**kwargs)
68 69 70
        instance = context['instance']
        if instance.node:
            port = instance.vnc_port
71
            host = str(instance.node.host.ipv4)
72
            value = signing.dumps({'host': host,
73 74
                                   'port': port},
                                  key=getenv("PROXY_SECRET", 'asdasd')),
75 76 77
            context.update({
                'vnc_url': '%s' % value
            })
78
        context['acl'] = get_acl_data(instance)
79
        return context
Kálmán Viktor committed
80

81 82

class AclUpdateView(View, SingleObjectMixin):
83

84
    def post(self, request, *args, **kwargs):
85
        instance = self.get_object()
86 87
        if not (instance.has_level(request.user, "owner") or
                getattr(instance, 'owner', None) == request.user):
Őry Máté committed
88 89
            logger.warning('Tried to set permissions of %s by non-owner %s.',
                           unicode(instance), unicode(request.user))
90
            raise PermissionDenied()
91 92 93 94 95
        self.set_levels(request, instance)
        self.add_levels(request, instance)
        return redirect(instance)

    def set_levels(self, request, instance):
96 97 98 99 100
        for key, value in request.POST.items():
            m = re.match('perm-([ug])-(\d+)', key)
            if m:
                type, id = m.groups()
                entity = {'u': User, 'g': Group}[type].objects.get(id=id)
101
                instance.set_level(entity, value)
Őry Máté committed
102 103 104
                logger.info("Set %s's acl level for %s to %s by %s.",
                            unicode(entity), unicode(instance),
                            value, unicode(request.user))
105

106
    def add_levels(self, request, instance):
107 108
        name = request.POST['perm-new-name']
        value = request.POST['perm-new']
109 110 111 112 113 114
        if not name:
            return
        try:
            entity = User.objects.get(username=name)
        except User.DoesNotExist:
            entity = None
115 116
            try:
                entity = Group.objects.get(name=name)
117 118 119 120
            except Group.DoesNotExist:
                warning(request, _('User or group "%s" not found.') % name)
                return

121
        instance.set_level(entity, value)
Őry Máté committed
122 123 124
        logger.info("Set %s's new acl level for %s to %s by %s.",
                    unicode(entity), unicode(instance),
                    value, unicode(request.user))
125

Kálmán Viktor committed
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
class TemplateDetail(DetailView):
    model = InstanceTemplate

    def get(self, request, *args, **kwargs):
        if request.is_ajax():
            template = InstanceTemplate.objects.get(pk=kwargs['pk'])
            template = {
                'num_cores': template.num_cores,
                'ram_size': template.ram_size,
                'priority': template.priority,
                'arch': template.arch,
                'description': template.description,
                'system': template.system,
                'name': template.name,
                'disks': [{'pk': d.pk, 'name': d.name}
                          for d in template.disks.all()],
                'network': [
                    {'vlan_pk': i.vlan.pk, 'vlan': i.vlan.name,
                     'managed': i.managed}
                    for i in InterfaceTemplate.objects.filter(
                        template=self.get_object()).all()
                ]
            }
            return HttpResponse(json.dumps(template),
                                content_type="application/json")
        else:
            # return super(TemplateDetail, self).get(request, *args, **kwargs)
            return HttpResponse('soon')


157
class VmList(SingleTableView):
Kálmán Viktor committed
158
    template_name = "dashboard/vm-list.html"
159 160
    model = Instance
    table_class = VmListTable
161
    table_pagination = False
162 163 164 165 166 167


class VmCreate(TemplateView):

    def get_template_names(self):
        if self.request.is_ajax():
168
            return ['dashboard/modal-wrapper.html']
169
        else:
170
            return ['dashboard/nojs-wrapper.html']
171 172 173

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
174 175 176 177
        context.update({
            'template': 'dashboard/vm-create.html',
            'box_title': 'Create a VM'
        })
178
        return self.render_to_response(context)
179 180 181

    def get_context_data(self, **kwargs):
        context = super(VmCreate, self).get_context_data(**kwargs)
182
        # TODO acl
183
        context.update({
184
            'templates': InstanceTemplate.objects.all(),
185
            'vlans': Vlan.objects.all(),
186
            'disks': Disk.objects.exclude(type="qcow2-snap")
187 188 189
        })

        return context
190 191

    def post(self, request, *args, **kwargs):
192 193 194 195 196
        if self.request.user.is_authenticated():
            user = self.request.user
        else:
            user = None

197 198 199 200 201
        resp = request.POST.copy()
        resp['managed-vlans'] = request.POST.getlist('managed-vlans')
        resp['unmanaged-vlans'] = request.POST.getlist('unmanaged-vlans')
        resp['disks'] = request.POST.getlist('disks')

202 203 204 205 206 207
        template = InstanceTemplate.objects.get(
            pk=request.POST.get('template-pk'))
        inst = Instance.create_from_template(template=template, owner=user)
        inst.deploy_async()

        # TODO handle response
208
        return HttpResponse(json.dumps(resp), content_type="application/json")