Merge branch 'opennebula-integration' into vm_bill
This commit is contained in:
		
				commit
				
					
						3078536bd7
					
				
			
		
					 4 changed files with 150 additions and 14 deletions
				
			
		|  | @ -7,6 +7,8 @@ from django.utils.translation import ugettext_lazy as _ | |||
| from django.utils.functional import cached_property | ||||
| from django.conf import settings | ||||
| 
 | ||||
| from django.conf import settings | ||||
| 
 | ||||
| from Crypto.PublicKey import RSA | ||||
| from stored_messages.settings import stored_messages_settings | ||||
| 
 | ||||
|  | @ -17,6 +19,8 @@ from .managers import VMPlansManager | |||
| from oca.exceptions import OpenNebulaException | ||||
| from oca.pool import WrongNameError | ||||
| 
 | ||||
| import logging | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
| class VirtualMachineType(models.Model): | ||||
| 
 | ||||
|  | @ -173,6 +177,83 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | |||
|         self.status = self.CANCELED_STATUS | ||||
|         self.save(update_fields=['status']) | ||||
| 
 | ||||
|     @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) | ||||
|              | ||||
|         # 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) | ||||
| 
 | ||||
|         # 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) | ||||
|             # self.total_price += price | ||||
|         # self.save() | ||||
|         return vms | ||||
| 
 | ||||
| 
 | ||||
| class HostingOrder(AssignPermissionsMixin, models.Model): | ||||
| 
 | ||||
|  | @ -336,3 +417,12 @@ class HostingBill(AssignPermissionsMixin, models.Model): | |||
|         return vms | ||||
| 
 | ||||
| 
 | ||||
|          | ||||
| def get_user_opennebula_password(): | ||||
|     ''' | ||||
|     TODO: Implement the way we obtain the user's opennebula password  | ||||
|     ''' | ||||
|     pw = os.environ.get('OPENNEBULA_USER_PW') | ||||
|     if pw is None: | ||||
|         raise Exception("Define OPENNEBULA_USER_PW env variable") | ||||
|     return pw | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ from django.utils.translation import ugettext_lazy as _ | |||
| from oca.exceptions import OpenNebulaException | ||||
| from oca.pool import WrongNameError | ||||
| 
 | ||||
| from django import forms | ||||
| # Get an instance of a logger | ||||
| logger = logging.getLogger(__name__) | ||||
| 
 | ||||
|  | @ -47,9 +48,9 @@ class HostingManageVMAdmin(admin.ModelAdmin): | |||
|                                                   port=settings.OPENNEBULA_PORT, | ||||
|                                                   endpoint=settings.OPENNEBULA_ENDPOINT | ||||
|                                               )) | ||||
|             print("{0}:{1}".format(settings.OPENNEBULA_USERNAME, | ||||
|             logger.debug("{0}:{1}".format(settings.OPENNEBULA_USERNAME, | ||||
|                                    settings.OPENNEBULA_PASSWORD)) | ||||
|             print("{protocol}://{domain}:{port}{endpoint}".format( | ||||
|             logger.debug("{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|                 domain=settings.OPENNEBULA_DOMAIN, | ||||
|                 port=settings.OPENNEBULA_PORT, | ||||
|  | @ -58,7 +59,8 @@ class HostingManageVMAdmin(admin.ModelAdmin): | |||
|             self.create_opennebula_user(request) | ||||
|         if self.client is None: | ||||
|             opennebula_user = request.user.email | ||||
|             opennebula_user_password = get_random_password() | ||||
|             # TODO: get the password stored in django | ||||
|             opennebula_user_password ='19737450' | ||||
|             self.client = oca.Client("{0}:{1}".format(opennebula_user, opennebula_user_password), | ||||
|                                      "{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                                          protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|  | @ -84,6 +86,7 @@ class HostingManageVMAdmin(admin.ModelAdmin): | |||
|             # Include common variables for rendering the admin template. | ||||
|             self.admin_site.each_context(request), | ||||
|             vms=vm_pool, | ||||
|             form=HostingManageVMForm | ||||
|         ) | ||||
|         return TemplateResponse(request, "hosting/managevms.html", context) | ||||
| 
 | ||||
|  | @ -292,14 +295,60 @@ class HostingManageVMAdmin(admin.ModelAdmin): | |||
|             opennebula_user = user_pool.get_by_name(request.user.email) | ||||
|             logger.debug("User {0} exists. User id = {1}".format(request.user.email, opennebula_user.id)) | ||||
|         except WrongNameError as wrong_name_err: | ||||
|             user_id = self.oneadmin_client.call('user.allocate', request.user.email, get_random_password(), | ||||
|                                                 'dummy') | ||||
|             # TODO: Store this password so that we can use it later to  | ||||
|             # connect to opennebula | ||||
|             password = get_random_password() | ||||
|             oca.User.allocate(self.oneadmin_client, request.user.email, password) | ||||
|             logger.debug("User {0} does not exist. Created the user. User id = {1}", request.user.email, user_id) | ||||
|         except OpenNebulaException as err: | ||||
|             messages.add_message(request, messages.ERROR, | ||||
|                                  "Error : {0}".format(err)) | ||||
|             logger.error("Error : {0}".format(err)) | ||||
| 
 | ||||
| def set_field_html_name(cls, new_name): | ||||
|     """ | ||||
|     This creates wrapper around the normal widget rendering,  | ||||
|     allowing for a custom field name (new_name). | ||||
|     """ | ||||
|     old_render = cls.widget.render | ||||
|     def _widget_render_wrapper(name, value, attrs=None): | ||||
|         return old_render(new_name, value, attrs) | ||||
|     cls.widget.render = _widget_render_wrapper | ||||
|              | ||||
| class HostingManageVMForm(forms.Form): | ||||
|     vm_templates = [] | ||||
|     VM_CHOICES = (('1', 'disk = 10GB, vcpu=1, ram=1GB'), | ||||
|                   ('2', 'disk = 20GB, vcpu=2, ram=2GB'), | ||||
|                   ('3', 'disk = 40GB, vcpu=4, ram=4GB'), | ||||
|                   ('4', 'disk = 80GB, vcpu=8, ram=8GB'), | ||||
|                   ('5', 'disk = 160GB, vcpu=16, ram=16GB'), | ||||
|                   ('6', 'disk = 320GB, vcpu=32, ram=32GB'), | ||||
|                   ('7', 'disk = 640GB, vcpu=64, ram=64GB'), | ||||
|                   ('8', 'disk = 1280GB, vcpu=128, ram=128GB'))     | ||||
|     #for i in range(0,8): | ||||
|     #    factor = pow(2, i) | ||||
|     #    vm_templates.append(VMTemplate(i, VM_CHOICES[i], 10000 * factor, factor , 0.1 * factor, 1024 * factor)) | ||||
|     field = forms.ChoiceField(label="Choose a VM Template ", choices=VM_CHOICES, widget=forms.Select(attrs={"id": "vm_template"})) | ||||
|     set_field_html_name(field, 'vm_template') | ||||
|          | ||||
|          | ||||
| 
 | ||||
| class VMTemplate: | ||||
|     """A simple representation of a VM template. | ||||
| 
 | ||||
|     :param template_id: The id of the template | ||||
|     :param label: A string representation describing the template. Used as the label in view | ||||
|     :param disk: VM disk space in MB | ||||
|     :param vcpu: Virtual cpu for the VM | ||||
|     :param cpu: CPU for the VM | ||||
|     :param ram: The RAM for the VM | ||||
|     """ | ||||
|     def __init__(self, template_id, label, disk, vcpu, cpu, ram): | ||||
|         self.template_id = template_id | ||||
|         self.label = label | ||||
|         self.disk = disk | ||||
|         self.vcpu = vcpu | ||||
|         self.cpu = cpu | ||||
| 
 | ||||
| # Returns random password that is needed by OpenNebula | ||||
| def get_random_password(): | ||||
|  |  | |||
|  | @ -2,13 +2,9 @@ | |||
| {% block content %} | ||||
| 
 | ||||
| <form action="{% url 'admin:createvm' %}" method="post"> | ||||
| 	{% csrf_token %} | ||||
| 	<select id="vm_template" name="vm_template"> | ||||
| 		<option value="select">Select a template</option> | ||||
| 		<option value="1">disk = 10GB, vcpu=0.1, ram=1GB</option> | ||||
| 		<option value="2">disk = 20GB, vcpu=0.2, ram=2GB</option> | ||||
| 	</select> | ||||
| 	<input type="submit" name="create_vm" value="Create VM" /> | ||||
|     {% csrf_token %} | ||||
|     {{ form }} | ||||
|     <input type="submit" name="create_vm" value="Create VM" /> | ||||
| </form> | ||||
| {% if vms %} | ||||
| <section> | ||||
|  |  | |||
|  | @ -415,8 +415,9 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | |||
|     ordering = '-id' | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||
|         print(hosting_admin.show_vms_view(self.request)) | ||||
|         # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||
|         # print(hosting_admin.show_vms_view(self.request)) | ||||
|         print(VirtualMachinePlan.get_vms(self.request.user.email)) | ||||
|         user = self.request.user | ||||
|         self.queryset = VirtualMachinePlan.objects.active(user) | ||||
|         return super(VirtualMachinesPlanListView, self).get_queryset() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue