def ptr_form(request, hostname, nic_id): """ Ajax page for PTR form validation. """ vm = get_vm(request, hostname) try: nic_ip = vm.json_get_nics()[int(nic_id) - 1]['ip'] ptr = RecordView.Record.get_record_PTR(nic_ip) if not ptr: raise Exception('PTR Record not found') except Exception: raise Http404 ptrform = PTRForm(request.POST, prefix='ptr') if ptrform.is_valid(): if ptrform.cleaned_data['content'] == ptr.content: return HttpResponse(None, status=204) else: res = RecordView.internal_response(request, 'PUT', ptr, ptrform.cleaned_data, related_obj=vm) if res.status_code in (200, 201): return HttpResponse(None, status=201) else: ptrform.set_api_errors(res.data) return render(request, 'gui/vm/ptr_form.html', {'ptrform': ptrform})
def replication_form(request, hostname): """ Ajax page for managing server replication. """ if not request.user.is_admin(request): # can_edit permission raise PermissionDenied vm = get_vm(request, hostname) if vm.slave_vms: slave_vm = vm.slave_vm.select_related( 'master_vm', 'vm', 'vm__node').exclude(name='').first() else: slave_vm = None form = ServerReplicaForm(request, vm, slave_vm, request.POST, prefix='rep') if form.is_valid(): status = form.save(args=(vm.hostname, form.cleaned_data['repname'])) if status == 205: # The replica configuration has changed in DB, but does not affect the VM on compute node return redirect('vm_details', hostname=vm.hostname) elif 200 <= status < 400: return HttpResponse( None, status=204 ) # Just hide the modal (socket.io callbacks will do the job) return render(request, 'replication/vm_details_replica_form.html', { 'form': form, 'vm': vm })
def nic_settings_form(request, hostname): """ Ajax page for changing server nic settings. """ vm = get_vm(request, hostname) if request.user.is_admin(request): # can_edit permission action = None form = AdminServerNicSettingsForm(request, vm, request.POST, prefix='opt-nic') else: action = 'update' form = ServerNicSettingsForm(request, vm, request.POST, prefix='opt-nic') # noinspection PyUnresolvedReferences if form.is_valid(): # noinspection PyUnresolvedReferences status = form.save(action=action, args=(vm.hostname, form.cleaned_data['nic_id'])) if status == 204: return HttpResponse(None, status=status) elif status in (200, 201): return redirect('vm_details', hostname=vm.hostname) return render(request, 'gui/vm/nic_settings_form.html', { 'nic_settingsform': form, 'vm': vm })
def settings_form(request, hostname): """ Ajax page for changing server settings. """ if hostname is None: vm = None else: vm = get_vm(request, hostname) if request.user.is_admin(request): # can_edit permission action = None form = AdminServerSettingsForm(request, vm, request.POST, prefix='opt') else: action = 'update' form = ServerSettingsForm(request, vm, request.POST, prefix='opt') # noinspection PyUnresolvedReferences if form.is_valid(): # noinspection PyUnresolvedReferences status = form.save(action=action, args=(form.current_hostname, )) if status == 204: # Nothing changed return HttpResponse(None, status=status) elif status in (200, 201): # noinspection PyUnresolvedReferences if form.action == 'delete': return redirect('vm_list') else: return redirect('vm_details', hostname=form.saved_hostname) return render(request, 'gui/vm/settings_form.html', { 'settingsform': form, 'vm': vm, 'mb_addon': SIZE_FIELD_MB_ADDON, })
def snapshot_form(request, hostname): """ Ajax page for snapshot form validation when creating or updating snapshot. """ vm = get_vm(request, hostname) status = 200 if request.POST.get('update', None): snapform = UpdateSnapshotForm(vm, request.POST, prefix='snap_update') if snapform.is_valid(): snap = snapform.get_snapshot() if not snap: raise Http404 if snapform.save(snap): status = 201 else: return HttpResponse(None, status=204) # Nothing changed else: snapform = CreateSnapshotForm(vm, request.POST, prefix='snap_create') if snapform.is_valid(): status = 201 context = {'snapform': snapform, 'vm': vm} return render(request, 'gui/vm/snapshot_form.html', context, status=status)
def backup_form(request, hostname): """ Ajax page for backup form validation when creating or updating backup. """ vm = get_vm(request, hostname) status = 200 if request.POST.get('update', None): template = 'backup_form_update.html' bkpform = UpdateBackupForm(vm, request.POST, prefix='snap_update') if bkpform.is_valid(): bkp = bkpform.get_backup() if not bkp: raise Http404 if bkpform.save(bkp): status = 201 else: return HttpResponse(None, status=204) # Nothing changed else: template = 'backup_form.html' bkpform = CreateBackupForm(vm, get_vm_bkpdefs(vm), request.POST, prefix='snap_create') if bkpform.is_valid(): status = 201 context = {'bkpform': bkpform, 'vm': vm} return render(request, 'gui/vm/' + template, context, status=status)
def backup_define_form(request, hostname): """ Ajax page for backup define settings. """ vm = get_vm(request, hostname) if request.POST.get('action', None) == 'create': form = CreateBackupDefineForm(request, vm, request.POST, prefix='bkpdef_create') else: form = UpdateBackupDefineForm(request, vm, request.POST) if form.is_valid(): # noinspection PyUnresolvedReferences status = form.save(args=(vm.hostname, form.cleaned_data['name'])) if status == 204: return HttpResponse(None, status=status) elif status in (200, 201): return redirect('vm_backup', hostname=vm.hostname) return render(request, 'gui/vm/backup_define_form.html', { 'form': form, 'vm': vm })
def backup(request, hostname): """ Backup list and backup definitions. """ dc_settings = request.dc.settings context = collect_view_data(request, 'vm_list') context['vm'] = vm = get_vm(request, hostname, sr=('dc', 'owner', 'template', 'slavevm')) context['vms'] = vms = get_vms(request) context['vms_tags'] = get_vms_tags(vms) context['can_edit'] = request.user.is_admin(request) context['bkpdefs'] = bkpdefs = get_vm_bkpdefs(vm) context['lastbkp'] = [] context.update(get_vm_backups(request, vm)) # Add paginator if context['can_edit']: context['bkpform_create'] = CreateBackupForm(vm, bkpdefs, prefix='snap_create') context['bkpform_restore'] = RestoreBackupForm(vms) context['bkpform_update'] = UpdateBackupForm(vm, prefix='snap_update') context['bkpdeform_update'] = UpdateBackupDefineForm(request, vm) bkpdef_initial = { 'zpool': dc_settings.VMS_STORAGE_DEFAULT, 'type': BackupDefine.DATASET, 'disk_id': 1, 'active': True, 'compression': dc_settings.VMS_VM_BACKUP_COMPRESSION_DEFAULT } context['bkpdeform_create'] = CreateBackupDefineForm(request, vm, prefix='bkpdef_create', initial=bkpdef_initial) view_vm_backup.send(sender='gui.vm.views.backup', request=request, context=context) return render(request, 'gui/vm/backup.html', context)
def snapshot(request, hostname): """ Snapshot list and snapshot definitions. """ context = collect_view_data(request, 'vm_list') context['vm'] = vm = get_vm(request, hostname, sr=('dc', 'owner', 'template', 'slavevm')) context['vms'] = vms = get_vms(request) context['vms_tags'] = get_vms_tags(vms) context['can_edit'] = request.user.is_admin(request) context['can_image'] = request.user.is_staff or request.user.has_permission(request, ImageAdminPermission.name) context['cannot_snapshot'] = not (request.user.is_admin(request) or vm.is_installed()) context['snapform_create'] = CreateSnapshotForm(vm, prefix='snap_create', initial={'disk_id': 1}) context['snapform_update'] = UpdateSnapshotForm(vm, prefix='snap_update') context['lastsnap'] = [] context['snapdefs'] = get_vm_snapdefs(vm) context.update(get_vm_snapshots(request, vm)) # Add snapshots and count attributes + paginator if context['can_edit']: context['snapdeform_update'] = UpdateSnapshotDefineForm(request, vm) context['snapdeform_create'] = CreateSnapshotDefineForm(request, vm, prefix='snapdef_create', initial={'disk_id': 1, 'active': True}) if context['can_image']: context['imgform'] = SnapshotImageForm(vm, request, None, prefix='img', initial={'owner': request.user.username, 'access': Image.PRIVATE, 'version': '1.0'}) view_vm_snapshot.send(sender='gui.vm.views.snapshot', request=request, context=context) return render(request, 'gui/vm/snapshot.html', context)
def vnc(request, hostname): """ Guacamole remote console view. """ # get VM object or raise 404 vm = get_vm(request, hostname, sr=('dc', 'owner', 'node')) # basic view data context = {'vm': vm, 'gc': {}} # First check if VNC is available for this vm and vm is running if not (vm.status in (vm.RUNNING, vm.STOPPING) and vm.node and vm.node.address and vm.vnc_port and vm.node.status in Node.STATUS_OPERATIONAL and vm.vnc_port == vm.json_active.get('vnc_port', None)): # VNC settings not found or VM is not running return render(request, 'gui/vm/vnc.html', context) # Test if VNC port is open (e.g. when the VM was just started, but the vnc is not yet initialized) if not GuacamoleAuth.test_vnc(vm): # VNC port is not open yet, but maybe it will be in few seconds (see the JS in vnc.html) context['gc']['ready'] = False return render(request, 'gui/vm/vnc.html', context) # set Guacamole tunnel setting context['gc'] = { 'ready': True, 'tunnel': settings.GUACAMOLE_HTU, 'wss': settings.GUACAMOLE_WSS, 'vnc_zoom': bool(request.GET.get('zoom', settings.GUACAMOLE_DEFAULT_ZOOM)), } # return vnc window without login (we already have a JSESSIONID cookie) if request.GET.get('nologin', False): context['gc']['token'] = request.session.get(settings.GUACAMOLE_TOKEN, '') return render(request, 'gui/vm/vnc.html', context) # Create guacamole object attached to request.user.username and VM # A password for the user will be generated automatically g = GuacamoleAuth(request, vm) # Create a VM usermap for this request.user and VM and set guacamole configuration into cache g.set_auth() # Perform a login to guacamole, which will give you a JSESSIONID cookie. gcookie = g.login() context['gc']['token'] = gcookie.get('token', '') # Get a response object response = render(request, 'gui/vm/vnc.html', context) # Set the guacamole cookie into the response object if 'cookie' in gcookie: response.set_cookie(**gcookie['cookie']) # Delete usermap (it is cached in guacamole) g.del_auth() # Give it to the user return response
def undo_settings(request, hostname): """ Ajax page for reverting server definition by calling vm_define_revert. """ vm = get_vm(request, hostname) res = UndoSettingsForm.api_call('update', vm, request, args=(hostname, )) if res.status_code == 200: return redirect('vm_details', hostname=vm.hostname) return JSONResponse(res.data, status=res.status_code)
def console(request, hostname): """ Page with remote VNC console of the server. """ context = collect_view_data(request, 'vm_list') context['vm'] = get_vm(request, hostname) context['vms'] = vms = get_vms(request) context['vms_tags'] = get_vms_tags(vms) context['can_edit'] = request.user.is_admin(request) view_vm_console.send(sender='gui.vm.views.console', request=request, context=context) return render(request, 'gui/vm/console.html', context)
def snapshot_list(request, hostname): """ Ajax page with list of snapshots. """ vm = get_vm(request, hostname) context = { 'vm': vm, 'can_edit': request.user.is_admin(request), 'lastsnap': [], 'last_snapid': request.GET.get('last_snapid', None), } context.update(get_vm_snapshots(request, vm)) # Add snapshots and count attributes + paginator return render(request, 'gui/vm/snapshot_list.html', context)
def backup_list(request, hostname): """ Ajax page with list of backups. """ vm = get_vm(request, hostname) context = { 'vm': vm, 'can_edit': request.user.is_admin(request), 'lastbkp': [], 'last_bkpid': request.GET.get('last_snapid', None), 'bkpdefs': True, # Always enable "backup now" button } context.update(get_vm_backups(request, vm)) # Add paginator return render(request, 'gui/vm/backup_list.html', context)
def tasklog(request, hostname): """ Page with server related tasklog. """ context = collect_view_data(request, 'vm_list') context['vm'] = vm = get_vm(request, hostname) context['vms'] = (vm,) context['submenu_auto'] = '' context['vms_tag_filter_disabled'] = True log_query = Q(content_type=ContentType.objects.get_for_model(vm)) & Q(object_pk=vm.pk) log = get_tasklog(request, context, base_query=log_query) context['tasklog'] = context['pager'] = get_pager(request, log, per_page=100) context['can_edit'] = request.user.is_admin(request) view_vm_tasklog.send(sender='gui.vm.views.tasklog', request=request, context=context) return render(request, 'gui/vm/tasklog.html', context)
def set_installed(request, hostname): """ Ajax page for marking the server as installed. """ vm = get_vm(request, hostname) if request.POST.get('installed'): # PUT vm_define res = ServerSettingsForm.api_call('update', vm, request, args=(hostname,), data={'installed': True}) if res.status_code == 200: messages.success(request, _('Server was marked as installed.')) return redirect('vm_details', hostname=hostname) else: return JSONResponse(res.data, status=res.status_code) raise PermissionDenied
def snapshot_image_form(request, hostname): """ Ajax page for creating new image from server snapshot. """ vm = get_vm(request, hostname) form = SnapshotImageForm(vm, request, None, request.POST, prefix='img') if form.is_valid(): status = form.save(args=(vm.hostname, form.cleaned_data['snapname'], form.cleaned_data['name'])) if status == 204: return HttpResponse(None, status=status) elif status in (200, 201): return redirect('vm_snapshot', hostname=vm.hostname) return render(request, 'gui/vm/image_snapshot_form.html', {'form': form, 'vm': vm})
def multi_settings_form(request): """ Ajax page for changing settings of multiple servers. """ if not request.user.is_admin(request): # can_edit permission raise PermissionDenied if request.POST['action'] == 'delete': # delete only for now for hostname in request.POST.getlist('hostname'): # DELETE vm_define vm = get_vm(request, hostname, auto_dc_switch=False) res = AdminServerSettingsForm.api_call('delete', vm, request, args=(hostname,)) if res.status_code != 200: return JSONResponse(res.data, status=res.status_code) node = request.GET.get('node', None) if node: return redirect('node_vms', node) else: return redirect('vm_list')
def disk_settings_form(request, hostname): """ Ajax page for changing server disk settings. """ vm = get_vm(request, hostname) if request.user.is_admin(request): # can_edit permission action = None form = AdminServerDiskSettingsForm(request, vm, request.POST, prefix='opt-disk') else: action = 'update' form = ServerDiskSettingsForm(request, vm, request.POST, prefix='opt-disk') # noinspection PyUnresolvedReferences if form.is_valid(): # noinspection PyUnresolvedReferences status = form.save(action=action, args=(vm.hostname, form.cleaned_data['disk_id'])) if status == 204: return HttpResponse(None, status=status) elif status in (200, 201): return redirect('vm_details', hostname=vm.hostname) return render( request, 'gui/vm/disk_settings_form.html', { 'disk_settingsform': form, 'vm': vm, 'mb_addon': SIZE_FIELD_MB_ADDON, 'percent_addon': SIZE_FIELD_PERCENT_ADDON, })
def monitoring(request, hostname, graph_type='cpu'): """ Page with monitoring graphs. """ context = collect_view_data(request, 'vm_list') context['vm'] = vm = get_vm(request, hostname) context['vms'] = vms = get_vms(request) context['vms_tags'] = get_vms_tags(vms) context['can_edit'] = request.user.is_admin(request) if vm.is_notcreated(): zabbix_sync_enabled = vm.zabbix_sync else: zabbix_sync_enabled = vm.is_zabbix_sync_active() if not zabbix_sync_enabled: return render(request, 'gui/vm/monitoring_disabled.html', context) from api.mon.vm.graphs import GRAPH_ITEMS context['graph_items'] = GRAPH_ITEMS context['obj_lifetime'] = vm.lifetime context['obj_operational'] = vm.status in vm.STATUS_OPERATIONAL if graph_type == 'memory': graphs = ( Graph('mem-usage'), Graph('swap-usage'), ) elif graph_type == 'network': context['vm_nics'] = nics = range(1, len(vm.json_get_nics()) + 1) graphs = list( chain(*[(Graph('net-bandwidth', nic_id=i), Graph('net-packets', nic_id=i)) for i in nics])) elif graph_type == 'disk': if vm.is_kvm(): prefix = 'disk' else: prefix = 'fs' context['desc_throughput'] = GRAPH_ITEMS.get(prefix + '-throughput').get('desc') context['desc_io'] = GRAPH_ITEMS.get(prefix + '-io').get('desc') context['graph_prefix'] = prefix context['vm_disks'] = disks = range(1, len(vm.json_get_disks()) + 1) graphs = list( chain(*[(Graph(prefix + '-throughput', disk_id=i), Graph(prefix + '-io', disk_id=i)) for i in disks])) elif graph_type == 'vm-disk': graphs = ( Graph('vm-disk-logical-throughput'), Graph('vm-disk-logical-io'), Graph('vm-disk-physical-throughput'), Graph('vm-disk-physical-io'), Graph('vm-disk-io-operations'), ) else: graph_type = 'cpu' graphs = ( Graph('cpu-usage'), Graph('cpu-waittime'), Graph('cpu-load'), ) context['graphs'] = graphs context['graph_type'] = graph_type view_vm_monitoring.send(sender='gui.vm.views.monitoring', request=request, context=context) return render(request, 'gui/vm/monitoring_%s.html' % graph_type, context)
def details(request, hostname): """ Page with details of server. """ dc_settings = request.dc.settings context = collect_view_data(request, 'vm_list', mb_addon=SIZE_FIELD_MB_ADDON) context['vm'] = vm = get_vm(request, hostname, sr=('dc', 'owner', 'node', 'template', 'slavevm')) context['vms'] = vms = get_vms(request) context['vms_tags'] = get_vms_tags(vms) context['vm_disks'] = vm_disks = get_vm_define_disk(request, vm) context['vm_nics'] = vm_nics = get_vm_define_nic(request, vm) context['ptrform'] = PTRForm(prefix='ptr') context['iso_rescuecd'] = dc_settings.VMS_ISO_RESCUECD context['mon_sla_enabled'] = (settings.MON_ZABBIX_ENABLED and DefaultDc().settings.MON_ZABBIX_ENABLED and dc_settings.MON_ZABBIX_VM_SLA) context['can_edit'] = request.user.is_admin(request) if vm.slave_vms: context['slave_vm'] = vm.slave_vm.select_related( 'master_vm', 'vm', 'vm__node').exclude(name='').first() else: context['slave_vm'] = None if vm.is_kvm(): context['iso_images'] = get_iso_images(request, vm.ostype) if vm.ostype == Vm.WINDOWS: context[ 'stop_timeout_period'] = dc_settings.VMS_VM_STOP_WIN_TIMEOUT_DEFAULT else: context[ 'stop_timeout_period'] = dc_settings.VMS_VM_STOP_TIMEOUT_DEFAULT if context['can_edit']: context['settingsform'] = AdminServerSettingsForm(request, vm, prefix='opt') initial_disk = { 'disk_id': len(vm_disks) + 1, 'zpool': vm.zpool, 'model': dc_settings.VMS_DISK_MODEL_DEFAULT, 'compression': dc_settings.VMS_DISK_COMPRESSION_DEFAULT, 'image': dc_settings.VMS_DISK_IMAGE_DEFAULT, } if initial_disk['disk_id'] == 1: initial_disk['boot'] = True initial_nic = { 'nic_id': len(vm_nics) + 1, 'model': dc_settings.VMS_NIC_MODEL_DEFAULT, 'net': dc_settings.VMS_NET_DEFAULT, } if initial_nic['nic_id'] == 1: initial_nic['dns'] = True initial_nic['primary'] = True if initial_nic['nic_id'] == dc_settings.VMS_NIC_MONITORING_DEFAULT: initial_nic['monitoring'] = True if vm.template: initial_disk.update( vm.template.get_vm_define_disk(initial_disk['disk_id'])) initial_nic.update( vm.template.get_vm_define_nic(initial_nic['nic_id'])) context['disk_settingsform'] = AdminServerDiskSettingsForm( request, vm, prefix='opt-disk', initial=initial_disk) context['nic_settingsform'] = AdminServerNicSettingsForm( request, vm, prefix='opt-nic', initial=initial_nic) else: context['settingsform'] = ServerSettingsForm(request, vm, prefix='opt') context['disk_settingsform'] = ServerDiskSettingsForm( request, vm, prefix='opt-disk') context['nic_settingsform'] = ServerNicSettingsForm(request, vm, prefix='opt-nic') view_vm_details.send(sender='gui.vm.views.details', request=request, context=context) return render(request, 'gui/vm/details.html', context)