cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
vm.py
Go to the documentation of this file.
1  # -*- coding: utf-8 -*-
2 # @COPYRIGHT_begin
3 #
4 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 # @COPYRIGHT_end
19 
20 ##
21 # @package src.wi.views.user.vm
22 #
23 # @author Krzysztof Danielowski
24 # @author Piotr Wójcik
25 # @date 26.11.2010
26 #
27 
28 from colorsys import hsv_to_rgb
29 
30 from django.contrib import messages
31 from django.shortcuts import render_to_response, redirect
32 from django.template import RequestContext
33 from django.template.loader import render_to_string
34 from django.utils.decorators import method_decorator
35 from django.utils.translation import ugettext as _
36 from django.views.decorators.csrf import csrf_protect
37 
38 from common.states import vm_states
39 from wi.commontags.templatetags.templatetags import filesizeformatmb
40 from wi.forms.vm import AssignIPForm, RevokeIPForm, RevokeDiskForm, AssignDiskForm
41 from wi.utils import messages_ajax, parsing, get_dict_from_list, get_dicts_from_list
42 from wi.utils.decorators import django_view, user_permission
43 from wi.utils.exceptions import RestErrorException
44 from wi.utils.formatters import time_from_sec
45 from wi.utils.messages_ajax import ajax_request
46 from wi.utils.states import vm_states_reversed, ec2names_reversed
47 from wi.utils.views import prep_data, CustomWizardView
48 
49 
50 ##
51 #
52 # Wizard handling virtual machine creation views.
53 #
54 class CreateVMWizard(CustomWizardView):
55  url_done = 'vms_show_vm'
56  url_start = 'vms_create_vm'
57 
58  wizard_name = 'create_vm_wizard'
59  template_dir_name = 'vms'
60 
61  def done(self, form_list, **kwargs):
62  form_data = self.get_all_cleaned_data()
63  try:
64  prep_data(('user/vm/create/', form_data), self.request.session)
65  except RestErrorException as ex:
66  messages.error(self.request, ex.value)
67  else:
68  messages.success(self.request, _('Virtual machine is being created.'))
69 
70  return redirect(self.url_done)
71 
72  def get_form_kwargs(self, step=None):
73  step = int(step)
74  initial_data = {}
75 
76  if step == 2:
77  rest_data = prep_data({'ips': 'user/public_ip/get_list/',
78  'disks': 'user/storage_image/get_list/',
79  'iso': 'user/iso_image/get_list/'},
80  self.request.session)
81 
82  initial_data = {'rest_data': rest_data}
83 
84  return initial_data
85 
86  def get_context_data(self, form, **kwargs):
87  context = super(CreateVMWizard, self).get_context_data(form=form, **kwargs)
88 
89  context.update({'steps_desc': [_('Image'), _('Hardware'), _('Optional resources'), _('Summary')]})
90 
91  if self.steps.current == '0':
92  rest_data = prep_data({'groups': 'user/group/list_groups/'}, self.request.session)
93  categories = [
94  ['all', _('All images')],
95  ['private', _('My images')],
96  ['public', _('Public images')],
97  ]
98  for item in parsing.parse_groups(rest_data):
99  categories.append([item[0], _('Group images: ') + item[1]])
100 
101  context.update({'image_categories': categories})
102 
103  elif self.steps.current == '1':
104  form_cleaned_data = self.get_all_cleaned_data()
105  rest_data = prep_data({'image': ('user/system_image/get_by_id/', {'system_image_id': form_cleaned_data['image_id']})},
106  self.request.session)
107 
108  context.update({'steps_desc': [rest_data['image']['name'] if len(rest_data['image']['name']) <= 15 else rest_data['image']['name'][:15] + '...',
109  _('Hardware'),
110  _('Optional resources'),
111  _('Summary')]})
112 
113  elif self.steps.current == '2':
114  form_cleaned_data = self.get_all_cleaned_data()
115  rest_data = prep_data({'image': ('user/system_image/get_by_id/', {'system_image_id': form_cleaned_data['image_id']}),
116  'templates': 'user/template/get_list/'},
117  self.request.session)
118  template = get_dict_from_list(rest_data['templates'], form_cleaned_data['template_id'], key='template_id')
119  context.update({'steps_desc': [rest_data['image']['name'] if len(rest_data['image']['name']) <= 15 else rest_data['image']['name'][:15] + '...',
120  str(template['cpu']) + ' CPU/' + str(filesizeformatmb(template['memory'])),
121  _('Optional resources'),
122  _('Summary')]})
123 
124  elif self.steps.current == '3':
125  form_cleaned_data = self.get_all_cleaned_data()
126  rest_data = prep_data({'image': ('user/system_image/get_by_id/', {'system_image_id': form_cleaned_data['image_id']}),
127  'templates': 'user/template/get_list/',
128  'ips': 'user/public_ip/get_list/',
129  'disks': 'user/storage_image/get_list/',
130  'iso': 'user/iso_image/get_list/'},
131  self.request.session)
132 
133  summary_data = {'summary_image': rest_data['image'],
134  'summary_template': get_dict_from_list(rest_data['templates'], form_cleaned_data['template_id'], key='template_id'),
135  'summary_ip': get_dict_from_list(rest_data['ips'], form_cleaned_data['public_ip_id'], key='public_ip_id'),
136  'summary_disks': get_dicts_from_list(rest_data['disks'], form_cleaned_data['disk_list'], key='storage_image_id'),
137  'summary_iso': get_dicts_from_list(rest_data['iso'], form_cleaned_data['iso_list'], key='iso_image_id'),
138  'summary_vnc': form_cleaned_data['vnc']}
139 
140  template = get_dict_from_list(rest_data['templates'], form_cleaned_data['template_id'], key='template_id')
141  context.update({'steps_desc': [rest_data['image']['name'] if len(rest_data['image']['name']) <= 15 else rest_data['image']['name'][:15] + '...',
142  str(template['cpu']) + ' CPU/' + str(filesizeformatmb(template['memory'])),
143  _('Optional resources'),
144  _('Summary')]})
145 
146  context.update(summary_data)
147 
148  return context
149 
150 CreateVMWizard.dispatch = method_decorator(user_permission)(
151  method_decorator(django_view)(
152  CreateVMWizard.dispatch))
153 
154 
155 @django_view
156 @ajax_request
157 @user_permission
158 ##
159 #
160 # Ajax view for fetching virtual machines list.
161 #
162 def vms_ajax_get_table(request):
163  if request.method == 'GET':
164  rest_data = prep_data('user/vm/get_list/', request.session)
165 
166  for item in rest_data:
167  item['stateName'] = vm_states_reversed[item['state']]
168  item['cpuLoadPercent'] = int(min(float(item['cpu_load'].get('60') or 0) * 100, 100))
169  item['cpuLoadColor'] = "#%02x%02x%02x" % tuple(i * 255 for i in hsv_to_rgb(float(item['cpuLoadPercent']) / 300, 1.0, 0.8))
170  item['pub_ip'] = []
171  for i in item['leases']:
172  if i['public_ip'] != "":
173  item['pub_ip'].append(i['public_ip']['address'])
174  item['stringIP'] = ', '.join(item['pub_ip'])
175  item['stringISO'] = ', '.join([iso['name'] for iso in item['iso_images']])
176  item['stringDisk'] = ', '.join([disk['name'] for disk in item['storage_images']])
177 
178  return messages_ajax.success(rest_data)
179 
180 
181 @django_view
182 @ajax_request
183 @user_permission
184 ##
185 #
186 # Ajax view fetching virtual machine details.
187 #
188 def vms_ajax_vm_details(request, vm_id, template_name='vms/ajax/vm_details.html'):
189  if request.method == 'POST':
190  vm = prep_data(('user/vm/get_by_id/', {'vm_id': vm_id}), request.session)
191 
192  if vm['state'] == vm_states['closed']:
193  return messages_ajax.success('', status=1)
194 
195  vm['uptime'] = time_from_sec(vm['uptime'])
196 
197  return messages_ajax.success(
198  render_to_string(template_name,
199  {'vm_id': vm_id,
200  'item': vm,
201  'states_reversed': vm_states_reversed,
202  'states': vm_states},
203  context_instance=RequestContext(request)))
204 
205 
206 @django_view
207 @user_permission
208 ##
209 #
210 # VNC applet view.
211 #
212 def vms_vnc(request, vm_id, template_name='vms/novnc.html'):
213  if request.POST is None or request.POST.get('vnc_endpoint') is None or request.POST.get('vnc_passwd') is None:
214  vnc_host, vnc_port, vnc_pass = 'undefined', 'undefined', 'undefined'
215  else:
216  vnc_endpoint = request.POST['vnc_endpoint'].split(':')
217  vnc_host, vnc_port, vnc_pass = vnc_endpoint[0], vnc_endpoint[1], request.POST['vnc_passwd']
218 
219  return render_to_response(template_name, {'vnc_host': vnc_host,
220  'vnc_port': vnc_port,
221  'vnc_passwd': vnc_pass,
222  'vmid': vm_id},
223  context_instance=RequestContext(request))
224 
225 
226 @django_view
227 @ajax_request
228 @user_permission
229 ##
230 #
231 # Ajax view fetching template list.
232 #
234  if request.method == 'GET':
235  rest_data = prep_data('user/template/get_list/', request.session)
236 
237  for item in rest_data:
238  item['memory'] = filesizeformatmb(item['memory'])
239  if item['ec2name'] != 0:
240  item['ec2fullname'] = ec2names_reversed[item['ec2name']]
241 
242  return messages_ajax.success(rest_data)
243 
244 
245 @django_view
246 @ajax_request
247 @user_permission
248 @csrf_protect
249 ##
250 #
251 # Ajax view for detaching elastip IP from a virtual machine.
252 #
253 def vms_ajax_revoke_ip(request, vm_id, template_name='generic/form.html', form_class=RevokeIPForm):
254  rest_data = prep_data({'vm': ('user/vm/get_by_id/', {'vm_id': vm_id})}, request.session)
255 
256  if request.method == 'POST':
257  form = form_class(data=request.POST, rest_data=rest_data)
258  if form.is_valid():
259  prep_data(('user/public_ip/unassign/', {'public_ip_id': form.cleaned_data['public_ip_id']}), request.session)
260  return messages_ajax.success(_('You have successfully revoked IP address.'))
261  else:
262  form = form_class(rest_data=rest_data)
263 
264  return messages_ajax.success(render_to_string(template_name,
265  {'form': form,
266  'text': _('Select an IP address to revoke:'),
267  'confirmation': _('Revoke')},
268  context_instance=RequestContext(request)),
269  status=1)
270 
271 
272 @django_view
273 @ajax_request
274 @user_permission
275 @csrf_protect
276 ##
277 #
278 # Ajax view for attaching IP address to a virtual machine.
279 #
280 def vms_ajax_assign_ip(request, vm_id, template_name='vms/ajax/assign_ip.html', form_class=AssignIPForm):
281  rest_data = prep_data({'ips': 'user/public_ip/get_list/',
282  'vm': ('user/vm/get_by_id/', {'vm_id': vm_id})}, request.session)
283 
284  if request.method == 'POST':
285  form = form_class(data=request.POST, rest_data=rest_data)
286  if form.is_valid():
287  prep_data(('user/public_ip/assign/', form.cleaned_data), request.session)
288  return messages_ajax.success(_('You have successfully assigned selected IP address.'))
289  else:
290  form = form_class(rest_data=rest_data)
291 
292  return messages_ajax.success(render_to_string(template_name,
293  {'form': form,
294  'text': _('Select an IP address and lease to assign:'),
295  'confirmation': _('Assign')},
296  context_instance=RequestContext(request)),
297  status=1)
298 
299 
300 @django_view
301 @ajax_request
302 @user_permission
303 @csrf_protect
304 ##
305 #
306 # Ajax view for detaching a disk from a virtual machine.
307 #
308 def vms_ajax_revoke_disk(request, vm_id, template_name='vms/ajax/revoke_disk.html', form_class=RevokeDiskForm):
309  rest_data = prep_data({'vm': ('user/vm/get_by_id/', {'vm_id': vm_id}),
310  'disk_controllers': 'user/storage_image/get_disk_controllers/'}, request.session)
311 
312  if request.method == 'POST':
313  form = form_class(data=request.POST, rest_data=rest_data)
314  if form.is_valid():
315  form.cleaned_data['vm_id'] = int(vm_id)
316  prep_data(('user/storage_image/detach/', form.cleaned_data), request.session)
317 
318  return messages_ajax.success(_('Disk has been revoked.'))
319  else:
320  form = form_class(rest_data=rest_data)
321 
322  return messages_ajax.success(render_to_string(template_name,
323  {'form': form,
324  'text': '',
325  'confirmation': _('Revoke disk')},
326  context_instance=RequestContext(request)),
327  status=1)
328 
329 
330 @django_view
331 @ajax_request
332 @user_permission
333 @csrf_protect
334 ##
335 #
336 # Ajax view for assigning Disk to a virtual machine.
337 #
338 def vms_ajax_assign_disk(request, vm_id, template_name='vms/ajax/assign_disk.html', form_class=AssignDiskForm):
339  rest_data = prep_data({'disks': 'user/storage_image/get_list/',
340  'disk_controllers': 'user/storage_image/get_disk_controllers/'},
341  request.session)
342 
343  live_attach = []
344  for item in rest_data['disk_controllers']:
345  if item['live_attach'] == True:
346  live_attach.append(item['id'])
347 
348  disks_list = []
349  for item in rest_data['disks']:
350  if item['disk_controller'] in live_attach:
351  disks_list.append(item)
352 
353  rest_data['disks'] = disks_list
354 
355  if request.method == 'POST':
356  form = form_class(data=request.POST, rest_data=rest_data)
357  if form.is_valid():
358  dictionary = form.cleaned_data
359  dictionary.update({'vm_id': vm_id})
360  prep_data(('user/storage_image/attach/', dictionary), request.session)
361  return messages_ajax.success(_('Disk has been assigned.'))
362  else:
363  form = form_class(rest_data=rest_data)
364 
365  return messages_ajax.success(render_to_string(template_name,
366  {'form': form,
367  'confirmation': _('Assign')},
368  context_instance=RequestContext(request)),
369  status=1)
370