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.db import models | ||||||
| from django.utils.translation import ugettext_lazy as _ | from django.utils.translation import ugettext_lazy as _ | ||||||
| from django.utils.functional import cached_property | from django.utils.functional import cached_property | ||||||
| from django.conf import settings | from hosting.opennebula_functions import OpenNebulaManager | ||||||
| 
 | 
 | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| 
 | 
 | ||||||
|  | @ -177,79 +177,38 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | ||||||
|         self.status = self.CANCELED_STATUS |         self.status = self.CANCELED_STATUS | ||||||
|         self.save(update_fields=['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 |     @classmethod | ||||||
|     def get_vms(self, email): |     def get_vms(self, email): | ||||||
|         # Get User |  | ||||||
|         user_email = email |  | ||||||
| 
 | 
 | ||||||
|         # Connect to open nebula server |         # Get opennebula client | ||||||
|         # TODO: handle potential connection error |         opennebula_client = OpenNebulaManager() | ||||||
|         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) |  | ||||||
| 
 | 
 | ||||||
|         # We should now have an OpenNebula user corresponding to user_email |         # Get vm pool | ||||||
|         # It is now ok to now perform opennebula functions with this user's client |         vm_pool = opennebula_client.get_vms(email) | ||||||
|         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) |  | ||||||
| 
 | 
 | ||||||
|         # Reset total price |         # Reset total price | ||||||
|         self.total_price = 0 |         self.total_price = 0 | ||||||
|         vms = [] |         vms = [] | ||||||
|         # Add vm in vm_pool to context |         # Add vm in vm_pool to context | ||||||
|         for vm in vm_pool: |         for vm in vm_pool: | ||||||
|             name = vm.name |             vm_data = OpenNebulaManager.parse_vm(vm) | ||||||
|             cores = int(vm.template.vcpu) |             vms.append(vm_data) | ||||||
|             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) |  | ||||||
|             # self.total_price += price |             # self.total_price += price | ||||||
|         # self.save() |         # self.save() | ||||||
|         return vms |         return vms | ||||||
|  |  | ||||||
|  | @ -19,6 +19,94 @@ from django import forms | ||||||
| logger = logging.getLogger(__name__) | 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): | class HostingManageVMAdmin(admin.ModelAdmin): | ||||||
|     client = None |     client = None | ||||||
|     oneadmin_client = None |     oneadmin_client = None | ||||||
|  |  | ||||||
|  | @ -20,18 +20,18 @@ | ||||||
| 				</tr> | 				</tr> | ||||||
| 				</thead> | 				</thead> | ||||||
| 				<tbody>  | 				<tbody>  | ||||||
| 					{% for vm in vms %} | 					{% for vm in vms_opennebula %} | ||||||
| 					<tr> | 					<tr> | ||||||
| 						<td scope="row">{{vm.name}}</td>  | 						<td scope="row">{{vm.deploy_id}}</td>  | ||||||
| 						<td>{{vm.price}} CHF</td>  | 						<td>{{vm.price}} CHF</td>  | ||||||
| 						<td> | 						<td> | ||||||
|                             |                             | ||||||
| 							{% if vm.status == 'pending' %} | 							{% if vm.state == 'ACTIVE' %} | ||||||
| 								<span class="h3 label label-warning"><strong>{{vm.get_status_display}}</strong></span> | 								<span class="h3 label label-success"><strong> {{vm.state}}</strong></span> | ||||||
| 							{% elif  vm.status == 'online' %} | 							{% elif  vm.state == 'POWEROFF' %} | ||||||
| 								<span class="h3 label label-success"><strong>{{vm.get_status_display}}</strong></span> | 								<span class="h3 label label-danger"><strong>{{vm.state}}</strong></span> | ||||||
| 							{% else %} | 							{% 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 %}   | 							{% endif %}   | ||||||
| 
 | 
 | ||||||
| 						</td>  | 						</td>  | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| from collections import namedtuple | from collections import namedtuple | ||||||
| 
 | 
 | ||||||
| from django.shortcuts import render | from django.shortcuts import render | ||||||
|  | from django.http import Http404 | ||||||
| from django.core.urlresolvers import reverse_lazy, reverse | from django.core.urlresolvers import reverse_lazy, reverse | ||||||
| from django.contrib.auth.mixins import LoginRequiredMixin | from django.contrib.auth.mixins import LoginRequiredMixin | ||||||
| from django.views.generic import View, CreateView, FormView, ListView, DetailView,\ | from django.views.generic import View, CreateView, FormView, ListView, DetailView,\ | ||||||
|  | @ -414,6 +415,13 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | ||||||
|     paginate_by = 10 |     paginate_by = 10 | ||||||
|     ordering = '-id' |     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): |     def get_queryset(self): | ||||||
|         # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) |         # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||||
|         # print(hosting_admin.show_vms_view(self.request)) |         # print(hosting_admin.show_vms_view(self.request)) | ||||||
|  | @ -458,19 +466,60 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): | ||||||
|     #     return super(VirtualMachinesPlanListView, self).get_queryset() |     #     return super(VirtualMachinesPlanListView, self).get_queryset() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView): | class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, View): | ||||||
|     template_name = "hosting/virtual_machine_detail.html" |     template_name = "hosting/virtual_machine_detail.html" | ||||||
|     login_url = reverse_lazy('hosting:login') |     login_url = reverse_lazy('hosting:login') | ||||||
|     model = VirtualMachinePlan |     # model = VirtualMachinePlan | ||||||
|     context_object_name = "virtual_machine" |     # context_object_name = "virtual_machine" | ||||||
|     permission_required = ['view_virtualmachineplan', 'cancel_virtualmachineplan'] |     permission_required = ['view_virtualmachineplan', 'cancel_virtualmachineplan'] | ||||||
|     fields = '__all__' |     # fields = '__all__' | ||||||
| 
 | 
 | ||||||
|     def get_success_url(self): |     # def get_context_data(self, **kwargs): | ||||||
|         vm = self.get_object() |     #     vm_plan = get_object() | ||||||
|         final_url = "%s%s" % (reverse('hosting:virtual_machines', kwargs={'pk': vm.id}), |     #     context = super(VirtualMachineView, self).get_context_data(**kwargs) | ||||||
|                               '#status-v') |     #     context.update({ | ||||||
|         return final_url |     #         '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): |     def post(self, *args, **kwargs): | ||||||
|         vm = self.get_object() |         vm = self.get_object() | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue