Add more information on deploying; fix format.
[ganeti_webmgr.git] / ganeti_web / views / vm_template.py
blob78e1cd40b7882883d54dc01695f6923aa91d8508
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 ganeti_web.backend.templates import (instance_to_template,
27 template_to_instance)
28 from ganeti_web.forms.vm_template import (VirtualMachineTemplateCopyForm,
29 VMInstanceFromTemplate,
30 TemplateFromVMInstance)
31 from ganeti_web.middleware import Http403
32 from ganeti_web.models import Cluster, VirtualMachineTemplate, VirtualMachine
33 from ganeti_web.views.generic import NO_PRIVS, LoginRequiredMixin
36 @login_required
37 def templates(request):
38 # Get a queryset of templates. Exclude templates that have been marked as
39 # temporary.
40 templates = VirtualMachineTemplate.objects.exclude(temporary=True)
41 # Because templates do not have 'disk_size' this value
42 # is computed here to be easily displayed.
43 for template in templates:
44 template.disk_size = sum([disk['size'] for disk in template.disks])
45 return render_to_response(
46 'ganeti/vm_template/list.html',
47 {'templates': templates, },
48 context_instance=RequestContext(request))
51 class TemplateFromVMInstanceView(LoginRequiredMixin, FormView):
52 """
53 Create a template from a virtual machine instance.
54 """
56 form_class = TemplateFromVMInstance
57 template_name = "ganeti/vm_template/to_instance.html"
59 def _get_stuff(self):
60 cluster_slug = self.kwargs["cluster_slug"]
61 hostname = self.kwargs["instance"]
63 self.cluster = get_object_or_404(Cluster, slug=cluster_slug)
64 self.vm = get_object_or_404(VirtualMachine, hostname=hostname,
65 cluster__slug=cluster_slug)
67 user = self.request.user
68 if not (user.is_superuser or
69 user.has_perm('admin', self.cluster) or
70 user.has_perm('create_vm', self.cluster)):
71 raise Http403(NO_PRIVS)
73 def form_valid(self, form):
74 """
75 Create the new VM and then redirect to the new VM's page.
76 """
78 template_name = form.cleaned_data["template_name"]
80 self._get_stuff()
82 template = instance_to_template(self.vm, template_name)
84 return HttpResponseRedirect(reverse("template-detail",
85 args=[self.cluster.slug,
86 template.template_name]))
88 def get_context_data(self, **kwargs):
89 context = super(TemplateFromVMInstanceView,
90 self).get_context_data(**kwargs)
92 self._get_stuff()
94 context["vm"] = self.vm
96 return context
99 class VMInstanceFromTemplateView(LoginRequiredMixin, FormView):
101 Create a virtual machine instance from a template.
104 form_class = VMInstanceFromTemplate
105 template_name = "ganeti/vm_template/to_vm.html"
107 def _get_stuff(self):
108 cluster_slug = self.kwargs["cluster_slug"]
109 template_name = self.kwargs["template"]
111 self.cluster = get_object_or_404(Cluster, slug=cluster_slug)
112 self.template = get_object_or_404(VirtualMachineTemplate,
113 template_name=template_name,
114 cluster__slug=cluster_slug)
116 user = self.request.user
117 if not (user.is_superuser or
118 user.has_perm('admin', self.cluster) or
119 user.has_perm('create_vm', self.cluster)):
120 raise Http403(NO_PRIVS)
122 def form_valid(self, form):
124 Create the new VM and then redirect to the new VM's page.
127 hostname = form.cleaned_data["hostname"]
128 owner = form.cleaned_data["owner"]
130 self._get_stuff()
132 vm = template_to_instance(self.template, hostname, owner)
134 return HttpResponseRedirect(reverse('instance-detail',
135 args=[self.cluster.slug,
136 vm.hostname]))
138 def get_context_data(self, **kwargs):
139 context = super(VMInstanceFromTemplateView,
140 self).get_context_data(**kwargs)
142 self._get_stuff()
144 context["template"] = self.template
146 return context
149 @login_required
150 def detail(request, cluster_slug, template):
151 user = request.user
152 if cluster_slug:
153 cluster = get_object_or_404(Cluster, slug=cluster_slug)
154 if not (user.is_superuser or
155 user.has_perm('admin', cluster) or
156 user.has_perm('create_vm', cluster)):
157 raise Http403(NO_PRIVS)
159 vm_template = get_object_or_404(VirtualMachineTemplate,
160 template_name=template,
161 cluster__slug=cluster_slug)
162 return render_to_response(
163 'ganeti/vm_template/detail.html',
164 {'template': vm_template,
165 'cluster': cluster_slug, },
166 context_instance=RequestContext(request)
170 @require_http_methods(["GET", "POST"])
171 @login_required
172 def copy(request, cluster_slug, template):
174 View used to create a copy of a VirtualMachineTemplate
176 user = request.user
177 if cluster_slug:
178 cluster = get_object_or_404(Cluster, slug=cluster_slug)
179 if not (user.is_superuser or
180 user.has_perm('admin', cluster) or
181 user.has_perm('create_vm', cluster)):
182 raise Http403(NO_PRIVS)
184 obj = get_object_or_404(VirtualMachineTemplate,
185 template_name=template,
186 cluster__slug=cluster_slug)
187 if request.method == "GET":
188 form = VirtualMachineTemplateCopyForm()
189 return render_to_response(
190 'ganeti/vm_template/copy.html',
191 {'form': form,
192 'template': obj,
193 'cluster': cluster_slug, },
194 context_instance=RequestContext(request)
196 elif request.method == "POST":
197 form = VirtualMachineTemplateCopyForm(request.POST)
198 if form.is_valid():
199 data = form.cleaned_data
200 name = data.get('template_name', 'unnamed')
201 desc = data.get('description', None)
202 # Set pk to None to create new object instead of editing
203 # current one.
204 obj.pk = None
205 obj.template_name = name
206 obj.description = desc
207 obj.save()
208 return HttpResponseRedirect(reverse('template-detail',
209 args=[cluster_slug, obj]))
212 @login_required
213 @require_http_methods(["DELETE"])
214 def delete(request, cluster_slug, template):
215 user = request.user
216 if cluster_slug:
217 cluster = get_object_or_404(Cluster, slug=cluster_slug)
218 if not (user.is_superuser or
219 user.has_perm('admin', cluster) or
220 user.has_perm('create_vm', cluster)):
221 raise Http403(NO_PRIVS)
223 try:
224 vm_template = VirtualMachineTemplate.objects \
225 .get(template_name=template,
226 cluster__slug=cluster_slug)
227 vm_template.delete()
228 except VirtualMachineTemplate.DoesNotExist:
229 return HttpResponse('-1', mimetype='application/json')
230 return HttpResponse('1', mimetype='application/json')