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,
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
,
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
37 def templates(request
):
38 # Get a queryset of templates. Exclude templates that have been marked as
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
):
53 Create a template from a virtual machine instance.
56 form_class
= TemplateFromVMInstance
57 template_name
= "ganeti/vm_template/to_instance.html"
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
):
75 Create the new VM and then redirect to the new VM's page.
78 template_name
= form
.cleaned_data
["template_name"]
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
)
94 context
["vm"] = self
.vm
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"]
132 vm
= template_to_instance(self
.template
, hostname
, owner
)
134 return HttpResponseRedirect(reverse('instance-detail',
135 args
=[self
.cluster
.slug
,
138 def get_context_data(self
, **kwargs
):
139 context
= super(VMInstanceFromTemplateView
,
140 self
).get_context_data(**kwargs
)
144 context
["template"] = self
.template
150 def detail(request
, cluster_slug
, template
):
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"])
172 def copy(request
, cluster_slug
, template
):
174 View used to create a copy of a VirtualMachineTemplate
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',
193 'cluster': cluster_slug
, },
194 context_instance
=RequestContext(request
)
196 elif request
.method
== "POST":
197 form
= VirtualMachineTemplateCopyForm(request
.POST
)
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
205 obj
.template_name
= name
206 obj
.description
= desc
208 return HttpResponseRedirect(reverse('template-detail',
209 args
=[cluster_slug
, obj
]))
213 @require_http_methods(["DELETE"])
214 def delete(request
, cluster_slug
, template
):
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
)
224 vm_template
= VirtualMachineTemplate
.objects \
225 .get(template_name
=template
,
226 cluster__slug
=cluster_slug
)
228 except VirtualMachineTemplate
.DoesNotExist
:
229 return HttpResponse('-1', mimetype
='application/json')
230 return HttpResponse('1', mimetype
='application/json')