views.py 7.99 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
from django.views.generic import TemplateView, DetailView
17 18
from django.core.urlresolvers import reverse_lazy
from django.shortcuts import redirect
19

20
from django_tables2 import SingleTableView
21
from tables import VmListTable
Kálmán Viktor committed
22

23
from .tables import VmListTable
24
from vm.models import Instance, InstanceTemplate, InterfaceTemplate
25
from firewall.models import Vlan
26
from storage.models import Disk
27

Őry Máté committed
28
logger = logging.getLogger(__name__)
29

30 31

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

34
    def get_context_data(self, **kwargs):
35 36 37 38 39
        if self.request.user.is_authenticated():
            user = self.request.user
        else:
            user = None

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

        context.update({
48 49
            'running_vms': instances.filter(state='RUNNING'),
            'running_vm_num': instances.filter(state='RUNNING').count(),
50 51
            'stopped_vm_num': instances.exclude(
                state__in=['RUNNING', 'NOSTATE']).count()
52 53 54
        })
        return context

55

56 57 58 59 60 61 62 63 64 65
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])}


66
class VmDetailView(DetailView):
Kálmán Viktor committed
67
    template_name = "dashboard/vm-detail.html"
68
    model = Instance
69 70

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


86
class AclUpdateView(View, SingleObjectMixin):
87

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

    def set_levels(self, request, instance):
100 101 102 103 104
        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)
105
                instance.set_level(entity, value)
Őry Máté committed
106 107 108
                logger.info("Set %s's acl level for %s to %s by %s.",
                            unicode(entity), unicode(instance),
                            value, unicode(request.user))
109

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

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

Kálmán Viktor committed
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 157 158 159 160
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')


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


class VmCreate(TemplateView):

    def get_template_names(self):
        if self.request.is_ajax():
172
            return ['dashboard/modal-wrapper.html']
173
        else:
174
            return ['dashboard/nojs-wrapper.html']
175 176 177

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

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

        return context
194

195
    # TODO handle not ajax posts
196
    def post(self, request, *args, **kwargs):
197 198 199 200 201
        if self.request.user.is_authenticated():
            user = self.request.user
        else:
            user = None

202 203 204
        resp = {}
        try:
            ikwargs = {
205 206 207
                'num_cores': int(request.POST.get('cpu-count')),
                'ram_size': int(request.POST.get('ram-size')),
                'priority': int(request.POST.get('cpu-priority')),
208 209 210 211 212 213 214 215 216
                'disks': Disk.objects.filter(
                    pk__in=request.POST.getlist('disks'))
            }

            template = InstanceTemplate.objects.get(
                pk=request.POST.get('template-pk'))
            inst = Instance.create_from_template(template=template,
                                                 owner=user, **ikwargs)
            inst.deploy_async()
217

218 219 220 221 222
            resp['pk'] = inst.pk
        except InstanceTemplate.DoesNotExist:
            resp['error'] = True
        except:
            resp['error'] = True
223

224 225 226 227 228 229
        if request.is_ajax():
            return HttpResponse(json.dumps(resp),
                                content_type="application/json",
                                status=500 if resp.get('error') else 200)
        else:
            return redirect(reverse_lazy('dashboard.views.detail', resp))