Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / helpdesk / views.py @ 9ca32eaa

History | View | Annotate | Download (10.6 kB)

1 605d23bf Kostas Papadimitriou
# Copyright 2012 GRNET S.A. All rights reserved.
2 605d23bf Kostas Papadimitriou
#
3 605d23bf Kostas Papadimitriou
# Redistribution and use in source and binary forms, with or
4 605d23bf Kostas Papadimitriou
# without modification, are permitted provided that the following
5 605d23bf Kostas Papadimitriou
# conditions are met:
6 605d23bf Kostas Papadimitriou
#
7 605d23bf Kostas Papadimitriou
#   1. Redistributions of source code must retain the above
8 605d23bf Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
9 605d23bf Kostas Papadimitriou
#      disclaimer.
10 605d23bf Kostas Papadimitriou
#
11 605d23bf Kostas Papadimitriou
#   2. Redistributions in binary form must reproduce the above
12 605d23bf Kostas Papadimitriou
#      copyright notice, this list of conditions and the following
13 605d23bf Kostas Papadimitriou
#      disclaimer in the documentation and/or other materials
14 605d23bf Kostas Papadimitriou
#      provided with the distribution.
15 605d23bf Kostas Papadimitriou
#
16 605d23bf Kostas Papadimitriou
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 605d23bf Kostas Papadimitriou
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 605d23bf Kostas Papadimitriou
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 605d23bf Kostas Papadimitriou
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 605d23bf Kostas Papadimitriou
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 605d23bf Kostas Papadimitriou
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 605d23bf Kostas Papadimitriou
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 605d23bf Kostas Papadimitriou
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 605d23bf Kostas Papadimitriou
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 605d23bf Kostas Papadimitriou
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 605d23bf Kostas Papadimitriou
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 605d23bf Kostas Papadimitriou
# POSSIBILITY OF SUCH DAMAGE.
28 605d23bf Kostas Papadimitriou
#
29 605d23bf Kostas Papadimitriou
# The views and conclusions contained in the software and
30 605d23bf Kostas Papadimitriou
# documentation are those of the authors and should not be
31 605d23bf Kostas Papadimitriou
# interpreted as representing official policies, either expressed
32 605d23bf Kostas Papadimitriou
# or implied, of GRNET S.A.
33 605d23bf Kostas Papadimitriou
34 d59d86d4 Kostas Papadimitriou
import re
35 605d23bf Kostas Papadimitriou
import logging
36 d59d86d4 Kostas Papadimitriou
37 6c45fa84 Kostas Papadimitriou
from django.shortcuts import redirect
38 c3564ce9 Kostas Papadimitriou
from django.views.generic.simple import direct_to_template
39 e129e26b Kostas Papadimitriou
from django.conf import settings
40 e129e26b Kostas Papadimitriou
from django.core.exceptions import PermissionDenied
41 6c45fa84 Kostas Papadimitriou
from django.http import Http404, HttpResponseRedirect
42 605d23bf Kostas Papadimitriou
from django.core.urlresolvers import reverse
43 605d23bf Kostas Papadimitriou
44 ebda2ad4 Kostas Papadimitriou
from urllib import unquote
45 c3564ce9 Kostas Papadimitriou
46 d91de78c Christos Stavrakakis
import astakosclient
47 d91de78c Christos Stavrakakis
from snf_django.lib import astakos
48 d91de78c Christos Stavrakakis
49 6c45fa84 Kostas Papadimitriou
from synnefo.db.models import VirtualMachine, NetworkInterface, Network
50 e129e26b Kostas Papadimitriou
51 cc5c8608 Kostas Papadimitriou
# server actions specific imports
52 41a7fae7 Christos Stavrakakis
from synnefo.api import util
53 cc5c8608 Kostas Papadimitriou
from synnefo.logic import backend as servers_backend
54 27c0d6c5 Kostas Papadimitriou
from synnefo.ui.views import UI_MEDIA_URL
55 cc5c8608 Kostas Papadimitriou
56 605d23bf Kostas Papadimitriou
logger = logging.getLogger(__name__)
57 605d23bf Kostas Papadimitriou
58 7ad07359 Kostas Papadimitriou
HELPDESK_MEDIA_URL = getattr(settings, 'HELPDESK_MEDIA_URL',
59 7ad07359 Kostas Papadimitriou
                             settings.MEDIA_URL + 'helpdesk/')
60 7ad07359 Kostas Papadimitriou
61 d59d86d4 Kostas Papadimitriou
IP_SEARCH_REGEX = re.compile('([0-9]+)(?:\.[0-9]+){3}')
62 6c45fa84 Kostas Papadimitriou
UUID_SEARCH_REGEX = re.compile('([0-9a-z]{8}-([0-9a-z]{4}-){3}[0-9a-z]{12})')
63 ba8ff608 Kostas Papadimitriou
VM_SEARCH_REGEX = re.compile('vm(-){0,}(?P<vmid>[0-9]+)')
64 6c45fa84 Kostas Papadimitriou
65 6c45fa84 Kostas Papadimitriou
66 ebda2ad4 Kostas Papadimitriou
def get_token_from_cookie(request, cookiename):
67 ebda2ad4 Kostas Papadimitriou
    """
68 ebda2ad4 Kostas Papadimitriou
    Extract token from the cookie name provided. Cookie should be in the same
69 ebda2ad4 Kostas Papadimitriou
    form as astakos service sets its cookie contents::
70 ebda2ad4 Kostas Papadimitriou

71 ebda2ad4 Kostas Papadimitriou
        <user_uniq>|<user_token>
72 ebda2ad4 Kostas Papadimitriou
    """
73 ebda2ad4 Kostas Papadimitriou
    try:
74 ebda2ad4 Kostas Papadimitriou
        cookie_content = unquote(request.COOKIES.get(cookiename, None))
75 ebda2ad4 Kostas Papadimitriou
        return cookie_content.split("|")[1]
76 ebda2ad4 Kostas Papadimitriou
    except AttributeError:
77 ebda2ad4 Kostas Papadimitriou
        pass
78 ebda2ad4 Kostas Papadimitriou
79 ebda2ad4 Kostas Papadimitriou
    return None
80 ebda2ad4 Kostas Papadimitriou
81 9fd36718 Kostas Papadimitriou
82 6c45fa84 Kostas Papadimitriou
AUTH_COOKIE_NAME = getattr(settings, 'HELPDESK_AUTH_COOKIE_NAME',
83 6c45fa84 Kostas Papadimitriou
                           getattr(settings, 'UI_AUTH_COOKIE_NAME',
84 6c45fa84 Kostas Papadimitriou
                                   '_pithos2_a'))
85 6c45fa84 Kostas Papadimitriou
PERMITTED_GROUPS = getattr(settings, 'HELPDESK_PERMITTED_GROUPS', ['helpdesk'])
86 605d23bf Kostas Papadimitriou
SHOW_DELETED_VMS = getattr(settings, 'HELPDESK_SHOW_DELETED_VMS', False)
87 605d23bf Kostas Papadimitriou
88 605d23bf Kostas Papadimitriou
89 605d23bf Kostas Papadimitriou
def token_check(func):
90 605d23bf Kostas Papadimitriou
    """
91 605d23bf Kostas Papadimitriou
    Mimic csrf security check using user auth token.
92 605d23bf Kostas Papadimitriou
    """
93 605d23bf Kostas Papadimitriou
    def wrapper(request, *args, **kwargs):
94 605d23bf Kostas Papadimitriou
        if not hasattr(request, 'user'):
95 605d23bf Kostas Papadimitriou
            raise PermissionDenied
96 605d23bf Kostas Papadimitriou
97 605d23bf Kostas Papadimitriou
        token = request.POST.get('token', None)
98 4edee820 Kostas Papadimitriou
        if token and token == request.user.get('auth_token', None):
99 605d23bf Kostas Papadimitriou
            return func(request, *args, **kwargs)
100 605d23bf Kostas Papadimitriou
101 605d23bf Kostas Papadimitriou
        raise PermissionDenied
102 605d23bf Kostas Papadimitriou
103 605d23bf Kostas Papadimitriou
    return wrapper
104 9fd36718 Kostas Papadimitriou
105 e129e26b Kostas Papadimitriou
106 605d23bf Kostas Papadimitriou
def helpdesk_user_required(func, permitted_groups=PERMITTED_GROUPS):
107 e129e26b Kostas Papadimitriou
    """
108 e129e26b Kostas Papadimitriou
    Django view wrapper that checks if identified request user has helpdesk
109 e129e26b Kostas Papadimitriou
    permissions (exists in helpdesk group)
110 e129e26b Kostas Papadimitriou
    """
111 e129e26b Kostas Papadimitriou
    def wrapper(request, *args, **kwargs):
112 9fd36718 Kostas Papadimitriou
        HELPDESK_ENABLED = getattr(settings, 'HELPDESK_ENABLED', True)
113 9fd36718 Kostas Papadimitriou
        if not HELPDESK_ENABLED:
114 9fd36718 Kostas Papadimitriou
            raise Http404
115 9fd36718 Kostas Papadimitriou
116 605d23bf Kostas Papadimitriou
        token = get_token_from_cookie(request, AUTH_COOKIE_NAME)
117 e3ff6830 Georgios D. Tsoukalas
        astakos.get_user(request, settings.ASTAKOS_BASE_URL,
118 d91de78c Christos Stavrakakis
                         fallback_token=token, logger=logger)
119 9e3519e0 Kostas Papadimitriou
        if hasattr(request, 'user') and request.user:
120 e129e26b Kostas Papadimitriou
            groups = request.user.get('groups', [])
121 0e5c88d0 Kostas Papadimitriou
122 0e5c88d0 Kostas Papadimitriou
            if not groups:
123 d91de78c Christos Stavrakakis
                logger.error("Failed to access helpdesk view. User: %r",
124 4edee820 Kostas Papadimitriou
                             request.user_uniq)
125 0e5c88d0 Kostas Papadimitriou
                raise PermissionDenied
126 0e5c88d0 Kostas Papadimitriou
127 605d23bf Kostas Papadimitriou
            has_perm = False
128 e129e26b Kostas Papadimitriou
            for g in groups:
129 605d23bf Kostas Papadimitriou
                if g in permitted_groups:
130 605d23bf Kostas Papadimitriou
                    has_perm = True
131 605d23bf Kostas Papadimitriou
132 605d23bf Kostas Papadimitriou
            if not has_perm:
133 4edee820 Kostas Papadimitriou
                logger.error("Failed to access helpdesk view %r. No valid "
134 475e8578 Kostas Papadimitriou
                             "helpdesk group (%r) matches user groups (%r)",
135 475e8578 Kostas Papadimitriou
                             request.user_uniq, permitted_groups, groups)
136 605d23bf Kostas Papadimitriou
                raise PermissionDenied
137 e129e26b Kostas Papadimitriou
        else:
138 4edee820 Kostas Papadimitriou
            logger.error("Failed to access helpdesk view %r. No authenticated "
139 d91de78c Christos Stavrakakis
                         "user found.", request.user_uniq)
140 e129e26b Kostas Papadimitriou
            raise PermissionDenied
141 e129e26b Kostas Papadimitriou
142 4edee820 Kostas Papadimitriou
        logging.info("User %s accessed helpdesk view (%s)", request.user_uniq,
143 4edee820 Kostas Papadimitriou
                     request.path)
144 e129e26b Kostas Papadimitriou
        return func(request, *args, **kwargs)
145 e129e26b Kostas Papadimitriou
146 e129e26b Kostas Papadimitriou
    return wrapper
147 e129e26b Kostas Papadimitriou
148 e129e26b Kostas Papadimitriou
149 e129e26b Kostas Papadimitriou
@helpdesk_user_required
150 c3564ce9 Kostas Papadimitriou
def index(request):
151 c3564ce9 Kostas Papadimitriou
    """
152 c3564ce9 Kostas Papadimitriou
    Helpdesk index view.
153 c3564ce9 Kostas Papadimitriou
    """
154 c3564ce9 Kostas Papadimitriou
    # if form submitted redirect to details
155 c3564ce9 Kostas Papadimitriou
    account = request.GET.get('account', None)
156 c3564ce9 Kostas Papadimitriou
    if account:
157 6c45fa84 Kostas Papadimitriou
        return redirect('synnefo.helpdesk.views.account',
158 ba8ff608 Kostas Papadimitriou
                        search_query=account)
159 c3564ce9 Kostas Papadimitriou
160 c3564ce9 Kostas Papadimitriou
    # show index template
161 7ad07359 Kostas Papadimitriou
    return direct_to_template(request, "helpdesk/index.html",
162 7ad07359 Kostas Papadimitriou
                              extra_context={'HELPDESK_MEDIA_URL':
163 7ad07359 Kostas Papadimitriou
                                             HELPDESK_MEDIA_URL})
164 c3564ce9 Kostas Papadimitriou
165 c3564ce9 Kostas Papadimitriou
166 e129e26b Kostas Papadimitriou
@helpdesk_user_required
167 ba8ff608 Kostas Papadimitriou
def account(request, search_query):
168 c3564ce9 Kostas Papadimitriou
    """
169 e129e26b Kostas Papadimitriou
    Account details view.
170 c3564ce9 Kostas Papadimitriou
    """
171 e129e26b Kostas Papadimitriou
172 4edee820 Kostas Papadimitriou
    logging.info("Helpdesk search by %s: %s", request.user_uniq, search_query)
173 605d23bf Kostas Papadimitriou
    show_deleted = bool(int(request.GET.get('deleted', SHOW_DELETED_VMS)))
174 605d23bf Kostas Papadimitriou
175 9e3519e0 Kostas Papadimitriou
    account_exists = True
176 5a8a6df2 Kostas Papadimitriou
    # flag to indicate successfull astakos calls
177 5a8a6df2 Kostas Papadimitriou
    account_resolved = False
178 d59d86d4 Kostas Papadimitriou
    vms = []
179 d59d86d4 Kostas Papadimitriou
    networks = []
180 ba8ff608 Kostas Papadimitriou
    is_ip = IP_SEARCH_REGEX.match(search_query)
181 ba8ff608 Kostas Papadimitriou
    is_uuid = UUID_SEARCH_REGEX.match(search_query)
182 ba8ff608 Kostas Papadimitriou
    is_vm = VM_SEARCH_REGEX.match(search_query)
183 ba8ff608 Kostas Papadimitriou
    account_name = search_query
184 6c45fa84 Kostas Papadimitriou
    auth_token = request.user.get('auth_token')
185 d59d86d4 Kostas Papadimitriou
186 d59d86d4 Kostas Papadimitriou
    if is_ip:
187 d59d86d4 Kostas Papadimitriou
        try:
188 ba8ff608 Kostas Papadimitriou
            nic = NetworkInterface.objects.get(ipv4=search_query)
189 ba8ff608 Kostas Papadimitriou
            search_query = nic.machine.userid
190 6c45fa84 Kostas Papadimitriou
            is_uuid = True
191 d59d86d4 Kostas Papadimitriou
        except NetworkInterface.DoesNotExist:
192 d59d86d4 Kostas Papadimitriou
            account_exists = False
193 ba8ff608 Kostas Papadimitriou
            account = None
194 ba8ff608 Kostas Papadimitriou
195 ba8ff608 Kostas Papadimitriou
    if is_vm:
196 ba8ff608 Kostas Papadimitriou
        vmid = is_vm.groupdict().get('vmid')
197 ba8ff608 Kostas Papadimitriou
        try:
198 ba8ff608 Kostas Papadimitriou
            vm = VirtualMachine.objects.get(pk=int(vmid))
199 ba8ff608 Kostas Papadimitriou
            search_query = vm.userid
200 ba8ff608 Kostas Papadimitriou
            is_uuid = True
201 ba8ff608 Kostas Papadimitriou
        except VirtualMachine.DoesNotExist:
202 ba8ff608 Kostas Papadimitriou
            account_exists = False
203 ba8ff608 Kostas Papadimitriou
            account = None
204 ba8ff608 Kostas Papadimitriou
            search_query = vmid
205 6c45fa84 Kostas Papadimitriou
206 e3ff6830 Georgios D. Tsoukalas
    astakos_client = astakosclient.AstakosClient(settings.ASTAKOS_BASE_URL,
207 e3ff6830 Georgios D. Tsoukalas
                                                 retry=2, use_pool=True,
208 e3ff6830 Georgios D. Tsoukalas
                                                 logger=logger)
209 468ba00b Ilias Tsitsimpis
210 5a8a6df2 Kostas Papadimitriou
    account = None
211 6c45fa84 Kostas Papadimitriou
    if is_uuid:
212 ba8ff608 Kostas Papadimitriou
        account = search_query
213 5a8a6df2 Kostas Papadimitriou
        try:
214 5a8a6df2 Kostas Papadimitriou
            account_name = astakos_client.get_username(auth_token, account)
215 5a8a6df2 Kostas Papadimitriou
        except:
216 5a8a6df2 Kostas Papadimitriou
            logger.info("Failed to resolve '%s' into account" % account)
217 ba8ff608 Kostas Papadimitriou
218 ba8ff608 Kostas Papadimitriou
    if account_exists and not is_uuid:
219 ba8ff608 Kostas Papadimitriou
        account_name = search_query
220 5a8a6df2 Kostas Papadimitriou
        try:
221 5a8a6df2 Kostas Papadimitriou
            account = astakos_client.get_uuid(auth_token, account_name)
222 5a8a6df2 Kostas Papadimitriou
        except:
223 5a8a6df2 Kostas Papadimitriou
            logger.info("Failed to resolve '%s' into account" % account_name)
224 6c45fa84 Kostas Papadimitriou
225 ba8ff608 Kostas Papadimitriou
    if not account:
226 ba8ff608 Kostas Papadimitriou
        account_exists = False
227 5a8a6df2 Kostas Papadimitriou
    else:
228 5a8a6df2 Kostas Papadimitriou
        account_resolved = True
229 ba8ff608 Kostas Papadimitriou
230 6c45fa84 Kostas Papadimitriou
    filter_extra = {}
231 6c45fa84 Kostas Papadimitriou
    if not show_deleted:
232 0c0498c8 Kostas Papadimitriou
        filter_extra['deleted'] = False
233 6c45fa84 Kostas Papadimitriou
234 6c45fa84 Kostas Papadimitriou
    # all user vms
235 6c45fa84 Kostas Papadimitriou
    vms = VirtualMachine.objects.filter(userid=account,
236 6c45fa84 Kostas Papadimitriou
                                        **filter_extra).order_by('deleted')
237 6c45fa84 Kostas Papadimitriou
    # return all user private and public networks
238 6c45fa84 Kostas Papadimitriou
    public_networks = Network.objects.filter(public=True,
239 6c45fa84 Kostas Papadimitriou
                                             nics__machine__userid=account,
240 6c45fa84 Kostas Papadimitriou
                                             **filter_extra
241 6c45fa84 Kostas Papadimitriou
                                             ).order_by('state').distinct()
242 6c45fa84 Kostas Papadimitriou
    private_networks = Network.objects.filter(userid=account,
243 6c45fa84 Kostas Papadimitriou
                                              **filter_extra).order_by('state')
244 6c45fa84 Kostas Papadimitriou
    networks = list(public_networks) + list(private_networks)
245 6c45fa84 Kostas Papadimitriou
246 5a8a6df2 Kostas Papadimitriou
    if vms.count() == 0 and private_networks.count() == 0 and not \
247 5a8a6df2 Kostas Papadimitriou
            account_resolved:
248 6c45fa84 Kostas Papadimitriou
        account_exists = False
249 e129e26b Kostas Papadimitriou
250 c3564ce9 Kostas Papadimitriou
    user_context = {
251 9e3519e0 Kostas Papadimitriou
        'account_exists': account_exists,
252 d59d86d4 Kostas Papadimitriou
        'is_ip': is_ip,
253 ba8ff608 Kostas Papadimitriou
        'is_vm': is_vm,
254 ba8ff608 Kostas Papadimitriou
        'is_uuid': is_uuid,
255 c3564ce9 Kostas Papadimitriou
        'account': account,
256 ba8ff608 Kostas Papadimitriou
        'search_query': search_query,
257 9e3519e0 Kostas Papadimitriou
        'vms': vms,
258 6c45fa84 Kostas Papadimitriou
        'show_deleted': show_deleted,
259 6c45fa84 Kostas Papadimitriou
        'account_name': account_name,
260 cc5c8608 Kostas Papadimitriou
        'token': request.user['auth_token'],
261 c3564ce9 Kostas Papadimitriou
        'networks': networks,
262 27c0d6c5 Kostas Papadimitriou
        'HELPDESK_MEDIA_URL': HELPDESK_MEDIA_URL,
263 27c0d6c5 Kostas Papadimitriou
        'UI_MEDIA_URL': UI_MEDIA_URL
264 c3564ce9 Kostas Papadimitriou
    }
265 d59d86d4 Kostas Papadimitriou
266 c3564ce9 Kostas Papadimitriou
    return direct_to_template(request, "helpdesk/account.html",
267 6c45fa84 Kostas Papadimitriou
                              extra_context=user_context)
268 c3564ce9 Kostas Papadimitriou
269 ebda2ad4 Kostas Papadimitriou
270 9e3519e0 Kostas Papadimitriou
@helpdesk_user_required
271 605d23bf Kostas Papadimitriou
@token_check
272 cc5c8608 Kostas Papadimitriou
def vm_suspend(request, vm_id):
273 605d23bf Kostas Papadimitriou
    vm = VirtualMachine.objects.get(pk=vm_id)
274 605d23bf Kostas Papadimitriou
    vm.suspended = True
275 605d23bf Kostas Papadimitriou
    vm.save()
276 4edee820 Kostas Papadimitriou
    logging.info("VM %s suspended by %s", vm_id, request.user_uniq)
277 605d23bf Kostas Papadimitriou
    account = vm.userid
278 605d23bf Kostas Papadimitriou
    return HttpResponseRedirect(reverse('helpdesk-details', args=(account,)))
279 605d23bf Kostas Papadimitriou
280 605d23bf Kostas Papadimitriou
281 605d23bf Kostas Papadimitriou
@helpdesk_user_required
282 605d23bf Kostas Papadimitriou
@token_check
283 cc5c8608 Kostas Papadimitriou
def vm_suspend_release(request, vm_id):
284 605d23bf Kostas Papadimitriou
    vm = VirtualMachine.objects.get(pk=vm_id)
285 605d23bf Kostas Papadimitriou
    vm.suspended = False
286 605d23bf Kostas Papadimitriou
    vm.save()
287 4edee820 Kostas Papadimitriou
    logging.info("VM %s unsuspended by %s", vm_id, request.user_uniq)
288 605d23bf Kostas Papadimitriou
    account = vm.userid
289 605d23bf Kostas Papadimitriou
    return HttpResponseRedirect(reverse('helpdesk-details', args=(account,)))
290 cc5c8608 Kostas Papadimitriou
291 cc5c8608 Kostas Papadimitriou
292 cc5c8608 Kostas Papadimitriou
@helpdesk_user_required
293 cc5c8608 Kostas Papadimitriou
@token_check
294 cc5c8608 Kostas Papadimitriou
def vm_shutdown(request, vm_id):
295 cc5c8608 Kostas Papadimitriou
    logging.info("VM %s shutdown by %s", vm_id, request.user_uniq)
296 cc5c8608 Kostas Papadimitriou
    vm = VirtualMachine.objects.get(pk=vm_id)
297 41a7fae7 Christos Stavrakakis
    jobId = servers_backend.shutdown_instance(vm)
298 41a7fae7 Christos Stavrakakis
    util.start_action(vm, 'STOP', jobId)
299 cc5c8608 Kostas Papadimitriou
    account = vm.userid
300 cc5c8608 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('helpdesk-details', args=(account,)))
301 cc5c8608 Kostas Papadimitriou
302 cc5c8608 Kostas Papadimitriou
303 cc5c8608 Kostas Papadimitriou
@helpdesk_user_required
304 cc5c8608 Kostas Papadimitriou
@token_check
305 cc5c8608 Kostas Papadimitriou
def vm_start(request, vm_id):
306 cc5c8608 Kostas Papadimitriou
    logging.info("VM %s start by %s", vm_id, request.user_uniq)
307 cc5c8608 Kostas Papadimitriou
    vm = VirtualMachine.objects.get(pk=vm_id)
308 41a7fae7 Christos Stavrakakis
    jobId = servers_backend.startup_instance(vm)
309 41a7fae7 Christos Stavrakakis
    util.start_action(vm, 'START', jobId)
310 cc5c8608 Kostas Papadimitriou
    account = vm.userid
311 cc5c8608 Kostas Papadimitriou
    return HttpResponseRedirect(reverse('helpdesk-details', args=(account,)))