Statistics
| Branch: | Tag: | Revision:

root / snf-cyclades-app / synnefo / admin / views.py @ a17a8e98

History | View | Annotate | Download (8.9 kB)

1 1081c1a0 Giorgos Verigakis
# Copyright 2011 GRNET S.A. All rights reserved.
2 1081c1a0 Giorgos Verigakis
#
3 1081c1a0 Giorgos Verigakis
# Redistribution and use in source and binary forms, with or
4 1081c1a0 Giorgos Verigakis
# without modification, are permitted provided that the following
5 1081c1a0 Giorgos Verigakis
# conditions are met:
6 1081c1a0 Giorgos Verigakis
#
7 1081c1a0 Giorgos Verigakis
#   1. Redistributions of source code must retain the above
8 1081c1a0 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
9 1081c1a0 Giorgos Verigakis
#      disclaimer.
10 1081c1a0 Giorgos Verigakis
#
11 1081c1a0 Giorgos Verigakis
#   2. Redistributions in binary form must reproduce the above
12 1081c1a0 Giorgos Verigakis
#      copyright notice, this list of conditions and the following
13 1081c1a0 Giorgos Verigakis
#      disclaimer in the documentation and/or other materials
14 1081c1a0 Giorgos Verigakis
#      provided with the distribution.
15 1081c1a0 Giorgos Verigakis
#
16 1081c1a0 Giorgos Verigakis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 1081c1a0 Giorgos Verigakis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 1081c1a0 Giorgos Verigakis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1081c1a0 Giorgos Verigakis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 1081c1a0 Giorgos Verigakis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 1081c1a0 Giorgos Verigakis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 1081c1a0 Giorgos Verigakis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 1081c1a0 Giorgos Verigakis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 1081c1a0 Giorgos Verigakis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1081c1a0 Giorgos Verigakis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 1081c1a0 Giorgos Verigakis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 1081c1a0 Giorgos Verigakis
# POSSIBILITY OF SUCH DAMAGE.
28 1081c1a0 Giorgos Verigakis
#
29 1081c1a0 Giorgos Verigakis
# The views and conclusions contained in the software and
30 1081c1a0 Giorgos Verigakis
# documentation are those of the authors and should not be
31 1081c1a0 Giorgos Verigakis
# interpreted as representing official policies, either expressed
32 1081c1a0 Giorgos Verigakis
# or implied, of GRNET S.A.
33 1081c1a0 Giorgos Verigakis
34 1f06d8ff Giorgos Verigakis
from functools import wraps
35 2035039b Giorgos Verigakis
from logging import getLogger
36 1f06d8ff Giorgos Verigakis
37 c909cbbd Giorgos Verigakis
from django.conf import settings
38 1f06d8ff Giorgos Verigakis
from django.http import HttpResponse
39 1f06d8ff Giorgos Verigakis
from django.shortcuts import redirect
40 1f06d8ff Giorgos Verigakis
from django.template.loader import render_to_string
41 1f06d8ff Giorgos Verigakis
42 1f06d8ff Giorgos Verigakis
from synnefo.db import models
43 9e98ba3c Giorgos Verigakis
from synnefo.logic import backend, users
44 e1f81736 Giorgos Verigakis
45 e1f81736 Giorgos Verigakis
46 9e98ba3c Giorgos Verigakis
log = getLogger('synnefo.admin')
47 1f06d8ff Giorgos Verigakis
48 1f06d8ff Giorgos Verigakis
49 1f06d8ff Giorgos Verigakis
def render(template, tab, **kwargs):
50 1f06d8ff Giorgos Verigakis
    kwargs.setdefault('tab', tab)
51 1f06d8ff Giorgos Verigakis
    return render_to_string(template, kwargs)
52 1f06d8ff Giorgos Verigakis
53 1f06d8ff Giorgos Verigakis
54 53155501 Giorgos Verigakis
def requires_admin(func):
55 53155501 Giorgos Verigakis
    @wraps(func)
56 53155501 Giorgos Verigakis
    def wrapper(request, *args):
57 53155501 Giorgos Verigakis
        if not request.user or request.user.type != 'ADMIN':
58 9a6cab7a Giorgos Verigakis
            return HttpResponse('Forbidden', status=403)
59 53155501 Giorgos Verigakis
        return func(request, *args)
60 53155501 Giorgos Verigakis
    return wrapper
61 53155501 Giorgos Verigakis
62 53155501 Giorgos Verigakis
63 89c358a3 Giorgos Verigakis
def get_filters(request, session_key, all_filters, default=None):
64 89c358a3 Giorgos Verigakis
    if default is None:
65 89c358a3 Giorgos Verigakis
        default = all_filters
66 89c358a3 Giorgos Verigakis
    filters = request.session.get(session_key, default)
67 89c358a3 Giorgos Verigakis
    filter = request.GET.get('toggle_filter')
68 89c358a3 Giorgos Verigakis
    if filter:
69 89c358a3 Giorgos Verigakis
        if filter in filters:
70 89c358a3 Giorgos Verigakis
            filters.remove(filter)
71 89c358a3 Giorgos Verigakis
        elif filter in all_filters:
72 89c358a3 Giorgos Verigakis
            filters.add(filter)
73 89c358a3 Giorgos Verigakis
        request.session[session_key] = filters
74 89c358a3 Giorgos Verigakis
    return filters
75 89c358a3 Giorgos Verigakis
76 89c358a3 Giorgos Verigakis
77 53155501 Giorgos Verigakis
@requires_admin
78 1f06d8ff Giorgos Verigakis
def index(request):
79 60f5da1a Giorgos Verigakis
    stats = {}
80 60f5da1a Giorgos Verigakis
    stats['images'] = models.Image.objects.exclude(state='DELETED').count()
81 60f5da1a Giorgos Verigakis
    stats['flavors'] = models.Flavor.objects.count()
82 60f5da1a Giorgos Verigakis
    stats['vms'] = models.VirtualMachine.objects.filter(deleted=False).count()
83 60f5da1a Giorgos Verigakis
    stats['networks'] = models.Network.objects.exclude(state='DELETED').count()
84 60f5da1a Giorgos Verigakis
85 f5c6e3f4 Giorgos Verigakis
    stats['ganeti_instances'] = len(backend.get_ganeti_instances())
86 f5c6e3f4 Giorgos Verigakis
    stats['ganeti_nodes'] = len(backend.get_ganeti_nodes())
87 f5c6e3f4 Giorgos Verigakis
    stats['ganeti_jobs'] = len(backend.get_ganeti_jobs())
88 4416efc0 Giorgos Verigakis
89 60f5da1a Giorgos Verigakis
    images = []
90 60f5da1a Giorgos Verigakis
    for image in models.Image.objects.exclude(state='DELETED'):
91 1588c123 Giorgos Verigakis
        vms = models.VirtualMachine.objects.filter(imageid=image.id)
92 60f5da1a Giorgos Verigakis
        count = vms.filter(deleted=False).count()
93 60f5da1a Giorgos Verigakis
        images.append((count, image.name))
94 60f5da1a Giorgos Verigakis
    images.sort(reverse=True)
95 60f5da1a Giorgos Verigakis
96 60f5da1a Giorgos Verigakis
    html = render('index.html', 'home', stats=stats, images=images)
97 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)
98 1f06d8ff Giorgos Verigakis
99 1f06d8ff Giorgos Verigakis
100 53155501 Giorgos Verigakis
@requires_admin
101 1f06d8ff Giorgos Verigakis
def flavors_list(request):
102 89c358a3 Giorgos Verigakis
    all_states = set(['DELETED'])
103 89c358a3 Giorgos Verigakis
    default = set()
104 89c358a3 Giorgos Verigakis
    filters = get_filters(request, 'flavors_filters', all_states, default)
105 89c358a3 Giorgos Verigakis
    
106 89c358a3 Giorgos Verigakis
    flavors = models.Flavor.objects.all()
107 89c358a3 Giorgos Verigakis
    if 'DELETED' not in filters:
108 89c358a3 Giorgos Verigakis
        flavors = flavors.exclude(deleted=True)
109 89c358a3 Giorgos Verigakis
    
110 89c358a3 Giorgos Verigakis
    html = render('flavors_list.html', 'flavors',
111 89c358a3 Giorgos Verigakis
                    flavors=flavors,
112 89c358a3 Giorgos Verigakis
                    all_states=sorted(all_states),
113 89c358a3 Giorgos Verigakis
                    filters=filters)
114 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)
115 1f06d8ff Giorgos Verigakis
116 53155501 Giorgos Verigakis
117 53155501 Giorgos Verigakis
@requires_admin
118 1f06d8ff Giorgos Verigakis
def flavors_create(request):
119 1f06d8ff Giorgos Verigakis
    if request.method == 'GET':
120 1f06d8ff Giorgos Verigakis
        html = render('flavors_create.html', 'flavors')
121 1f06d8ff Giorgos Verigakis
        return HttpResponse(html)
122 1f06d8ff Giorgos Verigakis
    if request.method == 'POST':
123 1f06d8ff Giorgos Verigakis
        flavor = models.Flavor()
124 e1f81736 Giorgos Verigakis
        flavor.cpu = int(request.POST.get('cpu'))
125 e1f81736 Giorgos Verigakis
        flavor.ram = int(request.POST.get('ram'))
126 e1f81736 Giorgos Verigakis
        flavor.disk = int(request.POST.get('disk'))
127 1f06d8ff Giorgos Verigakis
        flavor.save()
128 9e98ba3c Giorgos Verigakis
        log.info('User %s created Flavor %s', request.user.name, flavor.name)
129 1f06d8ff Giorgos Verigakis
        return redirect(flavors_info, flavor.id)
130 1f06d8ff Giorgos Verigakis
131 53155501 Giorgos Verigakis
132 53155501 Giorgos Verigakis
@requires_admin
133 1f06d8ff Giorgos Verigakis
def flavors_info(request, flavor_id):
134 1f06d8ff Giorgos Verigakis
    flavor = models.Flavor.objects.get(id=flavor_id)
135 c909cbbd Giorgos Verigakis
    html = render('flavors_info.html', 'flavors',
136 c909cbbd Giorgos Verigakis
                    flavor=flavor,
137 c909cbbd Giorgos Verigakis
                    disk_templates=settings.GANETI_DISK_TEMPLATES)
138 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)
139 1f06d8ff Giorgos Verigakis
140 53155501 Giorgos Verigakis
141 53155501 Giorgos Verigakis
@requires_admin
142 1f06d8ff Giorgos Verigakis
def flavors_modify(request, flavor_id):
143 1f06d8ff Giorgos Verigakis
    flavor = models.Flavor.objects.get(id=flavor_id)
144 e1f81736 Giorgos Verigakis
    flavor.cpu = int(request.POST.get('cpu'))
145 e1f81736 Giorgos Verigakis
    flavor.ram = int(request.POST.get('ram'))
146 e1f81736 Giorgos Verigakis
    flavor.disk = int(request.POST.get('disk'))
147 c909cbbd Giorgos Verigakis
    flavor.disk_template = request.POST.get('disk_template')
148 870c24a0 Giorgos Verigakis
    flavor.deleted = True if request.POST.get('deleted') else False
149 1f06d8ff Giorgos Verigakis
    flavor.save()
150 9e98ba3c Giorgos Verigakis
    log.info('User %s modified Flavor %s', request.user.name, flavor.name)
151 1f06d8ff Giorgos Verigakis
    return redirect(flavors_info, flavor.id)
152 1f06d8ff Giorgos Verigakis
153 53155501 Giorgos Verigakis
154 53155501 Giorgos Verigakis
@requires_admin
155 1f06d8ff Giorgos Verigakis
def flavors_delete(request, flavor_id):
156 1f06d8ff Giorgos Verigakis
    flavor = models.Flavor.objects.get(id=flavor_id)
157 1f06d8ff Giorgos Verigakis
    flavor.delete()
158 9e98ba3c Giorgos Verigakis
    log.info('User %s deleted Flavor %s', request.user.name, flavor.name)
159 1f06d8ff Giorgos Verigakis
    return redirect(flavors_list)
160 1f06d8ff Giorgos Verigakis
161 1f06d8ff Giorgos Verigakis
162 53155501 Giorgos Verigakis
@requires_admin
163 1f06d8ff Giorgos Verigakis
def images_list(request):
164 89c358a3 Giorgos Verigakis
    all_states = set(x[0] for x in models.Image.IMAGE_STATES)
165 89c358a3 Giorgos Verigakis
    default = all_states - set(['DELETED'])
166 89c358a3 Giorgos Verigakis
    filters = get_filters(request, 'images_filters', all_states, default)
167 89c358a3 Giorgos Verigakis
    
168 89c358a3 Giorgos Verigakis
    images = models.Image.objects.all()
169 89c358a3 Giorgos Verigakis
    for state in all_states - filters:
170 89c358a3 Giorgos Verigakis
        images = images.exclude(state=state)
171 89c358a3 Giorgos Verigakis
    
172 89c358a3 Giorgos Verigakis
    html = render('images_list.html', 'images',
173 89c358a3 Giorgos Verigakis
                    images=images.order_by('id'),
174 89c358a3 Giorgos Verigakis
                    all_states=sorted(all_states),
175 89c358a3 Giorgos Verigakis
                    filters=filters)
176 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)
177 1f06d8ff Giorgos Verigakis
178 53155501 Giorgos Verigakis
179 53155501 Giorgos Verigakis
@requires_admin
180 1f06d8ff Giorgos Verigakis
def images_register(request):
181 1f06d8ff Giorgos Verigakis
    if request.method == 'GET':
182 e1f81736 Giorgos Verigakis
        formats = [x[0] for x in models.Image.FORMATS]
183 e1f81736 Giorgos Verigakis
        html = render('images_register.html', 'images', formats=formats)
184 1f06d8ff Giorgos Verigakis
        return HttpResponse(html)
185 1f06d8ff Giorgos Verigakis
    elif request.method == 'POST':
186 1f06d8ff Giorgos Verigakis
        image = models.Image()
187 1f06d8ff Giorgos Verigakis
        image.state = 'ACTIVE'
188 1f06d8ff Giorgos Verigakis
        image.name = request.POST.get('name')
189 244c552b Giorgos Verigakis
        image.userid = request.POST.get('owner')
190 1f06d8ff Giorgos Verigakis
        image.backend_id = request.POST.get('backend')
191 e1f81736 Giorgos Verigakis
        image.format = request.POST.get('format')
192 1f06d8ff Giorgos Verigakis
        image.public = True if request.POST.get('public') else False
193 1f06d8ff Giorgos Verigakis
        image.save()
194 9e98ba3c Giorgos Verigakis
        log.info('User %s registered Image %s', request.user.name, image.name)
195 1f06d8ff Giorgos Verigakis
        return redirect(images_info, image.id)
196 1f06d8ff Giorgos Verigakis
197 53155501 Giorgos Verigakis
198 53155501 Giorgos Verigakis
@requires_admin
199 1f06d8ff Giorgos Verigakis
def images_info(request, image_id):
200 1f06d8ff Giorgos Verigakis
    image = models.Image.objects.get(id=image_id)
201 1f06d8ff Giorgos Verigakis
    states = [x[0] for x in models.Image.IMAGE_STATES]
202 1f06d8ff Giorgos Verigakis
    if not image.state:
203 1f06d8ff Giorgos Verigakis
        states = [''] + states
204 1f06d8ff Giorgos Verigakis
    formats = [x[0] for x in models.Image.FORMATS]
205 1f06d8ff Giorgos Verigakis
    if not image.format:
206 1f06d8ff Giorgos Verigakis
        formats = [''] + formats
207 4416efc0 Giorgos Verigakis
    
208 7cc3c7d9 Giorgos Verigakis
    metadata = image.metadata.order_by('meta_key')
209 1f06d8ff Giorgos Verigakis
    html = render('images_info.html', 'images',
210 4416efc0 Giorgos Verigakis
                    image=image,
211 4416efc0 Giorgos Verigakis
                    states=states,
212 4416efc0 Giorgos Verigakis
                    formats=formats,
213 4416efc0 Giorgos Verigakis
                    metadata=metadata)
214 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)
215 1f06d8ff Giorgos Verigakis
216 53155501 Giorgos Verigakis
217 53155501 Giorgos Verigakis
@requires_admin
218 1f06d8ff Giorgos Verigakis
def images_modify(request, image_id):
219 1f06d8ff Giorgos Verigakis
    image = models.Image.objects.get(id=image_id)
220 1f06d8ff Giorgos Verigakis
    image.name = request.POST.get('name')
221 1f06d8ff Giorgos Verigakis
    image.state = request.POST.get('state')
222 244c552b Giorgos Verigakis
    image.userid = request.POST.get('owner')
223 244c552b Giorgos Verigakis
    vm_id = request.POST.get('sourcevm')
224 1f06d8ff Giorgos Verigakis
    image.sourcevm = vm_id and models.VirtualMachine.objects.get(id=vm_id)
225 1f06d8ff Giorgos Verigakis
    image.backend_id = request.POST.get('backend')
226 1f06d8ff Giorgos Verigakis
    image.format = request.POST.get('format')
227 1f06d8ff Giorgos Verigakis
    image.public = True if request.POST.get('public') else False
228 1f06d8ff Giorgos Verigakis
    image.save()
229 4416efc0 Giorgos Verigakis
    
230 4416efc0 Giorgos Verigakis
    keys = request.POST.getlist('key')
231 4416efc0 Giorgos Verigakis
    vals = request.POST.getlist('value')
232 4416efc0 Giorgos Verigakis
    meta = dict(zip(keys, vals))
233 7cc3c7d9 Giorgos Verigakis
    image.metadata.all().delete()
234 4416efc0 Giorgos Verigakis
    for key, val in meta.items():
235 4416efc0 Giorgos Verigakis
        if key:
236 7cc3c7d9 Giorgos Verigakis
            image.metadata.create(meta_key=key, meta_value=val)
237 4416efc0 Giorgos Verigakis
    
238 9e98ba3c Giorgos Verigakis
    log.info('User %s modified Image %s', request.user.name, image.name)
239 e1f81736 Giorgos Verigakis
240 1f06d8ff Giorgos Verigakis
    return redirect(images_info, image.id)
241 1f06d8ff Giorgos Verigakis
242 53155501 Giorgos Verigakis
243 53155501 Giorgos Verigakis
@requires_admin
244 1f06d8ff Giorgos Verigakis
def servers_list(request):
245 89c358a3 Giorgos Verigakis
    all_states = set(x[0] for x in models.VirtualMachine.OPER_STATES)
246 89c358a3 Giorgos Verigakis
    default = all_states - set(['DESTROYED'])
247 89c358a3 Giorgos Verigakis
    filters = get_filters(request, 'servers_filters', all_states, default)
248 89c358a3 Giorgos Verigakis
    
249 89c358a3 Giorgos Verigakis
    servers = models.VirtualMachine.objects.all()
250 89c358a3 Giorgos Verigakis
    for state in all_states - filters:
251 89c358a3 Giorgos Verigakis
        servers = servers.exclude(operstate=state)
252 89c358a3 Giorgos Verigakis
    
253 89c358a3 Giorgos Verigakis
    html = render('servers_list.html', 'servers',
254 89c358a3 Giorgos Verigakis
                    servers=servers.order_by('id'),
255 89c358a3 Giorgos Verigakis
                    all_states=sorted(all_states),
256 89c358a3 Giorgos Verigakis
                    filters=filters)
257 1f06d8ff Giorgos Verigakis
    return HttpResponse(html)