Move default template for tables out of template into table base class
[ganeti_webmgr.git] / ganeti_web / views / vm_template.py
blobd10690f828417a5a1631e9613256e3574bbe1bcd
1 # Copyright (C) 2010 Oregon State University et al.
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
16 # USA.
18 from django.contrib.auth.decorators import login_required
19 from django.core.urlresolvers import reverse
20 from django.http import HttpResponse, HttpResponseRedirect
21 from django.shortcuts import get_object_or_404, render_to_response
22 from django.template import RequestContext
23 from django.views.decorators.http import require_http_methods
24 from django.views.generic.edit import FormView
26 from django_tables2 import SingleTableView
28 from ganeti_web.backend.templates import (instance_to_template,
29 template_to_instance)
30 from ganeti_web.forms.vm_template import (VirtualMachineTemplateCopyForm,
31 VMInstanceFromTemplate,
32 TemplateFromVMInstance)
33 from ganeti_web.middleware import Http403
34 from ganeti_web.models import Cluster, VirtualMachineTemplate, VirtualMachine
35 from ganeti_web.views.generic import (LoginRequiredMixin, PaginationMixin,
36 NO_PRIVS)
37 from ganeti_web.views.tables import VMTemplateTable
40 class TemplateListView(LoginRequiredMixin, PaginationMixin, SingleTableView):
41 queryset = VirtualMachineTemplate.objects.exclude(temporary=True)
42 table_class = VMTemplateTable
43 template_name = "ganeti/vm_template/list.html"
45 def get_queryset(self):
46 qs = super(TemplateListView, self).get_queryset()
47 templates = list(qs)
48 return self.sum_disks(templates)
50 def sum_disks(self, templates):
51 """
52 Helper function to sum disk templates since they're stored in the
53 database using a serialized field.
55 Note - This expects a list of templates, and does not return a queryset
57 """
58 for template in templates:
59 total_disk_size = sum([disk['size'] for disk in template.disks])
60 template.disk_space = total_disk_size
61 return templates
64 class TemplateFromVMInstanceView(LoginRequiredMixin, FormView):
65 """
66 Create a template from a virtual machine instance.
67 """
69 form_class = TemplateFromVMInstance
70 template_name = "ganeti/vm_template/to_instance.html"
72 def _get_stuff(self):
73 cluster_slug = self.kwargs["cluster_slug"]
74 hostname = self.kwargs["instance"]
76 self.cluster = get_object_or_404(Cluster, slug=cluster_slug)
77 self.vm = get_object_or_404(VirtualMachine, hostname=hostname,
78 cluster__slug=cluster_slug)
80 user = self.request.user
81 if not (user.is_superuser or
82 user.has_perm('admin', self.cluster) or
83 user.has_perm('create_vm', self.cluster)):
84 raise Http403(NO_PRIVS)
86 def form_valid(self, form):
87 """
88 Create the new VM and then redirect to the new VM's page.
89 """
91 template_name = form.cleaned_data["template_name"]
93 self._get_stuff()
95 template = instance_to_template(self.vm, template_name)
97 return HttpResponseRedirect(reverse("template-detail",
98 args=[self.cluster.slug,
99 template.template_name]))
101 def get_context_data(self, **kwargs):
102 context = super(TemplateFromVMInstanceView,
103 self).get_context_data(**kwargs)
105 self._get_stuff()
107 context["vm"] = self.vm
109 return context
112 class VMInstanceFromTemplateView(LoginRequiredMixin, FormView):
114 Create a virtual machine instance from a template.
117 form_class = VMInstanceFromTemplate
118 template_name = "ganeti/vm_template/to_vm.html"
120 def _get_stuff(self):
121 cluster_slug = self.kwargs["cluster_slug"]
122 template_name = self.kwargs["template"]
124 self.cluster = get_object_or_404(Cluster, slug=cluster_slug)
125 self.template = get_object_or_404(VirtualMachineTemplate,
126 template_name=template_name,
127 cluster__slug=cluster_slug)
129 user = self.request.user
130 if not (user.is_superuser or
131 user.has_perm('admin', self.cluster) or
132 user.has_perm('create_vm', self.cluster)):
133 raise Http403(NO_PRIVS)
135 def form_valid(self, form):
137 Create the new VM and then redirect to the new VM's page.
140 hostname = form.cleaned_data["hostname"]
141 owner = form.cleaned_data["owner"]
143 self._get_stuff()
145 vm = template_to_instance(self.template, hostname, owner)
147 return HttpResponseRedirect(reverse('instance-detail',
148 args=[self.cluster.slug,
149 vm.hostname]))
151 def get_context_data(self, **kwargs):
152 context = super(VMInstanceFromTemplateView,
153 self).get_context_data(**kwargs)
155 self._get_stuff()
157 context["template"] = self.template
159 return context
162 @login_required
163 def detail(request, cluster_slug, template):
164 user = request.user
165 if cluster_slug:
166 cluster = get_object_or_404(Cluster, slug=cluster_slug)
167 if not (user.is_superuser or
168 user.has_perm('admin', cluster) or
169 user.has_perm('create_vm', cluster)):
170 raise Http403(NO_PRIVS)
172 vm_template = get_object_or_404(VirtualMachineTemplate,
173 template_name=template,
174 cluster__slug=cluster_slug)
175 return render_to_response(
176 'ganeti/vm_template/detail.html',
177 {'template': vm_template,
178 'cluster': cluster_slug, },
179 context_instance=RequestContext(request)
183 @require_http_methods(["GET", "POST"])
184 @login_required
185 def copy(request, cluster_slug, template):
187 View used to create a copy of a VirtualMachineTemplate
189 user = request.user
190 if cluster_slug:
191 cluster = get_object_or_404(Cluster, slug=cluster_slug)
192 if not (user.is_superuser or
193 user.has_perm('admin', cluster) or
194 user.has_perm('create_vm', cluster)):
195 raise Http403(NO_PRIVS)
197 obj = get_object_or_404(VirtualMachineTemplate,
198 template_name=template,
199 cluster__slug=cluster_slug)
200 if request.method == "GET":
201 form = VirtualMachineTemplateCopyForm()
202 return render_to_response(
203 'ganeti/vm_template/copy.html',
204 {'form': form,
205 'template': obj,
206 'cluster': cluster_slug, },
207 context_instance=RequestContext(request)
209 elif request.method == "POST":
210 form = VirtualMachineTemplateCopyForm(request.POST)
211 if form.is_valid():
212 data = form.cleaned_data
213 name = data.get('template_name', 'unnamed')
214 desc = data.get('description', None)
215 # Set pk to None to create new object instead of editing
216 # current one.
217 obj.pk = None
218 obj.template_name = name
219 obj.description = desc
220 obj.save()
221 return HttpResponseRedirect(reverse('template-detail',
222 args=[cluster_slug, obj]))
225 @login_required
226 @require_http_methods(["DELETE"])
227 def delete(request, cluster_slug, template):
228 user = request.user
229 if cluster_slug:
230 cluster = get_object_or_404(Cluster, slug=cluster_slug)
231 if not (user.is_superuser or
232 user.has_perm('admin', cluster) or
233 user.has_perm('create_vm', cluster)):
234 raise Http403(NO_PRIVS)
236 try:
237 vm_template = VirtualMachineTemplate.objects \
238 .get(template_name=template,
239 cluster__slug=cluster_slug)
240 vm_template.delete()
241 except VirtualMachineTemplate.DoesNotExist:
242 return HttpResponse('-1', mimetype='application/json')
243 return HttpResponse('1', mimetype='application/json')