Merge branch 'opennebula-integration' into vm_bill
This commit is contained in:
		
				commit
				
					
						3ee075fad9
					
				
			
		
					 4 changed files with 180 additions and 84 deletions
				
			
		|  | @ -5,7 +5,7 @@ import oca | |||
| from django.db import models | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.functional import cached_property | ||||
| from django.conf import settings | ||||
| from hosting.opennebula_functions import OpenNebulaManager | ||||
| 
 | ||||
| from django.conf import settings | ||||
| 
 | ||||
|  | @ -177,79 +177,38 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | |||
|         self.status = self.CANCELED_STATUS | ||||
|         self.save(update_fields=['status']) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vm(self, email, vm_id): | ||||
|         # Get opennebula client | ||||
|         opennebula_client = OpenNebulaManager() | ||||
| 
 | ||||
|         # Get vm given the id | ||||
|         vm = opennebula_client.get_vm( | ||||
|             email, | ||||
|             vm_id | ||||
|         ) | ||||
| 
 | ||||
|         # Parse vm data | ||||
|         vm_data = OpenNebulaManager.parse_vm(vm) | ||||
| 
 | ||||
|         return vm_data | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vms(self, email): | ||||
|         # Get User | ||||
|         user_email = email | ||||
| 
 | ||||
|         # Connect to open nebula server | ||||
|         # TODO: handle potential connection error | ||||
|         oneadmin_client = oca.Client("{0}:{1}".format( | ||||
|             settings.OPENNEBULA_USERNAME, | ||||
|             settings.OPENNEBULA_PASSWORD), | ||||
|             "{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|                 domain=settings.OPENNEBULA_DOMAIN, | ||||
|                 port=settings.OPENNEBULA_PORT, | ||||
|                 endpoint=settings.OPENNEBULA_ENDPOINT | ||||
|         )) | ||||
|         # Get open nebula user id for given email | ||||
|         user_pool = oca.UserPool(oneadmin_client) | ||||
|         user_pool.info() | ||||
|         try: | ||||
|             user = user_pool.get_by_name(user_email) | ||||
|             user_id = user.id | ||||
|             logger.debug("User {user} exists.".format(user=user_email)) | ||||
|         except WrongNameError as wrong_name_err: | ||||
|             # User does not exist. So, we create this user in OpenNebula | ||||
|             password = get_user_opennebula_password() | ||||
|             # We use the core authenticator driver for the new user | ||||
|             user_id = oneadmin_client.call('user.allocate',  | ||||
|                                            user_email, password, | ||||
|                                            'core') | ||||
|             logger.debug("User {0} does not exist. Created the user. User id = {1}", user_email, user_id) | ||||
|         # Get opennebula client | ||||
|         opennebula_client = OpenNebulaManager() | ||||
| 
 | ||||
|         # We should now have an OpenNebula user corresponding to user_email | ||||
|         # It is now ok to now perform opennebula functions with this user's client | ||||
|         client = oca.Client("{0}:{1}".format( | ||||
|             user_email, | ||||
|             get_user_opennebula_password()), | ||||
|             "{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|                 domain=settings.OPENNEBULA_DOMAIN, | ||||
|                 port=settings.OPENNEBULA_PORT, | ||||
|                 endpoint=settings.OPENNEBULA_ENDPOINT | ||||
|         )) | ||||
| 
 | ||||
|         # Get vm_pool for given user_id | ||||
|         vm_pool = oca.VirtualMachinePool(client) | ||||
|         vm_pool.info(filter=user_id) | ||||
|         # Get vm pool | ||||
|         vm_pool = opennebula_client.get_vms(email) | ||||
| 
 | ||||
|         # Reset total price | ||||
|         self.total_price = 0 | ||||
|         vms = [] | ||||
|         # Add vm in vm_pool to context | ||||
|         for vm in vm_pool: | ||||
|             name = vm.name | ||||
|             cores = int(vm.template.vcpu) | ||||
|             memory = int(vm.template.memory) / 1024 | ||||
|             # Check if vm has more than one disk | ||||
|             if 'DISK' in vm.template.multiple: | ||||
|                 disk_size = 0 | ||||
|                 for disk in vm.template.disks: | ||||
|                     disk_size += int(disk.size) / 1024 | ||||
|             else: | ||||
|                 disk_size = int(vm.template.disk.size) / 1024 | ||||
| 
 | ||||
|             #TODO: Replace with vm plan | ||||
|             price = 0.6 * disk_size + 2 * memory + 5 * cores | ||||
|             vm = {} | ||||
|             vm['name'] = name | ||||
|             vm['price'] = price | ||||
|             vm['disk_size'] = disk_size | ||||
|             vm['cores'] = cores | ||||
|             vm['memory'] = memory | ||||
|             vms.append(vm) | ||||
|             vm_data = OpenNebulaManager.parse_vm(vm) | ||||
|             vms.append(vm_data) | ||||
|             # self.total_price += price | ||||
|         # self.save() | ||||
|         return vms | ||||
|  |  | |||
|  | @ -19,6 +19,94 @@ from django import forms | |||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| 
 | ||||
| class OpenNebulaManager: | ||||
| 
 | ||||
|     VM_STATE = { | ||||
|         '0': 'INIT', | ||||
|         '1': 'PENDING', | ||||
|         '2': 'HOLD', | ||||
|         '3': 'ACTIVE', | ||||
|         '4': 'STOPPED', | ||||
|         '5': 'SUSPENDED', | ||||
|         '6': 'DONE', | ||||
|         '8': 'POWEROFF', | ||||
|         '9': 'UNDEPLOYED', | ||||
|         '10': 'CLONING', | ||||
|         '11': 'CLONING_FAILURE', | ||||
|     } | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         self.client = oca.Client("{0}:{1}".format( | ||||
|             settings.OPENNEBULA_USERNAME, | ||||
|             settings.OPENNEBULA_PASSWORD), | ||||
|             "{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|                 domain=settings.OPENNEBULA_DOMAIN, | ||||
|                 port=settings.OPENNEBULA_PORT, | ||||
|                 endpoint=settings.OPENNEBULA_ENDPOINT | ||||
|         )) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vm_state(self, state): | ||||
|         return self.VM_STATE.get(str(state)) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def parse_vm(self, vm): | ||||
|         name = vm.name | ||||
|         cores = int(vm.template.vcpu) | ||||
|         memory = int(vm.template.memory) / 1024 | ||||
|         # Check if vm has more than one disk | ||||
|         if 'DISK' in vm.template.multiple: | ||||
|             disk_size = 0 | ||||
|             for disk in vm.template.disks: | ||||
|                 disk_size += int(disk.size) / 1024 | ||||
|         else: | ||||
|             disk_size = int(vm.template.disk.size) / 1024 | ||||
| 
 | ||||
|         #TODO: Replace with vm plan | ||||
|         price = 0.6 * disk_size + 2 * memory + 5 * cores | ||||
|         vm_data = {} | ||||
|         vm_data['name'] = name | ||||
|         vm_data['price'] = price | ||||
|         vm_data['disk_size'] = disk_size | ||||
|         vm_data['cores'] = cores | ||||
|         vm_data['memory'] = memory | ||||
|         vm_data['deploy_id'] = vm.deploy_id | ||||
|         vm_data['id'] = vm.id | ||||
|         vm_data['state'] = self.get_vm_state(vm.state) | ||||
| 
 | ||||
|         return vm_data | ||||
| 
 | ||||
|     def get_vm(self, email, vm_id): | ||||
|         # Get vm's | ||||
|         vms = self.get_vms(email) | ||||
| 
 | ||||
|         # Filter vm by given id | ||||
|         return vms.get_by_id(int(vm_id)) | ||||
| 
 | ||||
|     def get_vms(self, email): | ||||
|         client = self.client | ||||
| 
 | ||||
|         # Get open nebula user id for given email | ||||
|         user_pool = oca.UserPool(client) | ||||
|         user_pool.info() | ||||
| 
 | ||||
|         # TODO: handle potential name error | ||||
|         user_id = user_pool.get_by_name(email).id | ||||
| 
 | ||||
|         # Get vm_pool for given user_id | ||||
|         vm_pool = oca.VirtualMachinePool(client) | ||||
|         vm_pool.info() | ||||
| 
 | ||||
|         # TODO: this is just to test with oneadmin user, remove this | ||||
|         user_id = 0 | ||||
|         vm_pool.info(filter=user_id) | ||||
| 
 | ||||
|         return vm_pool | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class HostingManageVMAdmin(admin.ModelAdmin): | ||||
|     client = None | ||||
|     oneadmin_client = None | ||||
|  |  | |||
|  | @ -20,18 +20,18 @@ | |||
| 				</tr> | ||||
| 				</thead> | ||||
| 				<tbody>  | ||||
| 					{% for vm in vms %} | ||||
| 					{% for vm in vms_opennebula %} | ||||
| 					<tr> | ||||
| 						<td scope="row">{{vm.name}}</td>  | ||||
| 						<td scope="row">{{vm.deploy_id}}</td>  | ||||
| 						<td>{{vm.price}} CHF</td>  | ||||
| 						<td> | ||||
|                             | ||||
| 							{% if vm.status == 'pending' %} | ||||
| 								<span class="h3 label label-warning"><strong>{{vm.get_status_display}}</strong></span> | ||||
| 							{% elif  vm.status == 'online' %} | ||||
| 								<span class="h3 label label-success"><strong>{{vm.get_status_display}}</strong></span> | ||||
| 							{% if vm.state == 'ACTIVE' %} | ||||
| 								<span class="h3 label label-success"><strong> {{vm.state}}</strong></span> | ||||
| 							{% elif  vm.state == 'POWEROFF' %} | ||||
| 								<span class="h3 label label-danger"><strong>{{vm.state}}</strong></span> | ||||
| 							{% else %} | ||||
| 								<span class="h3 label label-danger"><strong>{{vm.get_status_display}}</strong></span> | ||||
| 								<span class="h3 label label-warning"><strong>{{vm.state}}</strong></span> | ||||
| 							{% endif %}   | ||||
| 
 | ||||
| 						</td>  | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| from collections import namedtuple | ||||
| 
 | ||||
| from django.shortcuts import render | ||||
| from django.http import Http404 | ||||
| from django.core.urlresolvers import reverse_lazy, reverse | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.views.generic import View, CreateView, FormView, ListView, DetailView,\ | ||||
|  | @ -414,6 +415,13 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | |||
|     paginate_by = 10 | ||||
|     ordering = '-id' | ||||
| 
 | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(VirtualMachinesPlanListView, self).get_context_data(**kwargs) | ||||
|         context.update({ | ||||
|             'vms_opennebula': VirtualMachinePlan.get_vms(self.request.user.email) | ||||
|         }) | ||||
|         return context | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||
|         # print(hosting_admin.show_vms_view(self.request)) | ||||
|  | @ -458,19 +466,60 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): | |||
|     #     return super(VirtualMachinesPlanListView, self).get_queryset() | ||||
| 
 | ||||
| 
 | ||||
| class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView): | ||||
| class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, View): | ||||
|     template_name = "hosting/virtual_machine_detail.html" | ||||
|     login_url = reverse_lazy('hosting:login') | ||||
|     model = VirtualMachinePlan | ||||
|     context_object_name = "virtual_machine" | ||||
|     # model = VirtualMachinePlan | ||||
|     # context_object_name = "virtual_machine" | ||||
|     permission_required = ['view_virtualmachineplan', 'cancel_virtualmachineplan'] | ||||
|     fields = '__all__' | ||||
|     # fields = '__all__' | ||||
| 
 | ||||
|     def get_success_url(self): | ||||
|         vm = self.get_object() | ||||
|         final_url = "%s%s" % (reverse('hosting:virtual_machines', kwargs={'pk': vm.id}), | ||||
|                               '#status-v') | ||||
|         return final_url | ||||
|     # def get_context_data(self, **kwargs): | ||||
|     #     vm_plan = get_object() | ||||
|     #     context = super(VirtualMachineView, self).get_context_data(**kwargs) | ||||
|     #     context.update({ | ||||
|     #         'opennebula_vm': VirtualMachinePlan.get_vm( | ||||
|     #             self.request.user.email, | ||||
|     #             opennebula_id | ||||
|     #         ) | ||||
|     #     }) | ||||
|     #     return context | ||||
| 
 | ||||
|     # def get_object(self, queryset=None): | ||||
|     #     # if queryset is None: | ||||
|     #     #     queryset = self.get_queryset() | ||||
|     #     # Next, try looking up by primary key. | ||||
|     #     vm_id = self.kwargs.get(self.pk_url_kwarg) | ||||
|     #     try: | ||||
|     #         return VirtualMachinePlan.get_vm( | ||||
|     #             self.request.user.email, | ||||
|     #             vm_id | ||||
|     #         ) | ||||
|     #     except Exception as error: | ||||
|     #         raise Http404() | ||||
| 
 | ||||
|     # def get_success_url(self): | ||||
|     #     vm = self.get_object() | ||||
|     #     final_url = "%s%s" % (reverse('hosting:virtual_machines', kwargs={'pk': vm.id}), | ||||
|     #                           '#status-v') | ||||
|     #     return final_url | ||||
| 
 | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         vm_id = self.kwargs.get('pk', 24) | ||||
|         try: | ||||
|             opennebula_vm = VirtualMachinePlan.get_vm( | ||||
|                 self.request.user.email, | ||||
|                 vm_id | ||||
|             ) | ||||
|         except Exception as error: | ||||
|             print(error) | ||||
|             raise Http404() | ||||
| 
 | ||||
|         context = { | ||||
|             'virtual_machine': opennebula_vm, | ||||
|         } | ||||
|         # context = {} | ||||
|         return render(request, self.template_name, context) | ||||
| 
 | ||||
|     def post(self, *args, **kwargs): | ||||
|         vm = self.get_object() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue