diff --git a/hosting/models.py b/hosting/models.py index 35a95331..fe40ff3f 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -4,6 +4,7 @@ import oca from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.functional import cached_property +from hosting.opennebula_functions import OpenNebulaManager from django.conf import settings @@ -174,79 +175,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) - - # 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 opennebula client + opennebula_client = OpenNebulaManager() - # 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 diff --git a/hosting/opennebula_functions.py b/hosting/opennebula_functions.py index 7bac64b5..b0d0e13b 100644 --- a/hosting/opennebula_functions.py +++ b/hosting/opennebula_functions.py @@ -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 diff --git a/hosting/templates/hosting/virtual_machines.html b/hosting/templates/hosting/virtual_machines.html index f566be44..2de8aa48 100644 --- a/hosting/templates/hosting/virtual_machines.html +++ b/hosting/templates/hosting/virtual_machines.html @@ -20,24 +20,24 @@
- {% for vm in vms %} -