Merge pull request #227 from levivm/opennebula-integration
Opennebula integration
This commit is contained in:
		
				commit
				
					
						31b7b37eb9
					
				
			
		
					 3 changed files with 135 additions and 27 deletions
				
			
		|  | @ -176,13 +176,30 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | |||
|         self.save(update_fields=['status']) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vm(self, email, vm_id): | ||||
|     def create_opennebula_vm(self, user, specs): | ||||
| 
 | ||||
|         # Init opennebula manager using given user | ||||
|         opennebula_client = OpenNebulaManager( | ||||
|             user.email, | ||||
|             user.password[0:20], | ||||
|             create_user=True | ||||
|         ) | ||||
| 
 | ||||
|         # Create a vm in opennebula using given specs | ||||
|         vm = opennebula_client.create_vm(specs) | ||||
|         return vm | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vm(self, user, vm_id): | ||||
|         # Get opennebula client | ||||
|         opennebula_client = OpenNebulaManager() | ||||
|         opennebula_client = OpenNebulaManager( | ||||
|             email=user.email, | ||||
|             password=user.password[:20], | ||||
|         ) | ||||
| 
 | ||||
|         # Get vm given the id | ||||
|         vm = opennebula_client.get_vm( | ||||
|             email, | ||||
|             user.email, | ||||
|             vm_id | ||||
|         ) | ||||
| 
 | ||||
|  | @ -192,13 +209,16 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | |||
|         return vm_data | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vms(self, email): | ||||
|     def get_vms(self, user): | ||||
| 
 | ||||
|         # Get opennebula client | ||||
|         opennebula_client = OpenNebulaManager() | ||||
|         opennebula_client = OpenNebulaManager( | ||||
|             email=user.email, | ||||
|             password=user.password[:20], | ||||
|         ) | ||||
| 
 | ||||
|         # Get vm pool | ||||
|         vm_pool = opennebula_client.get_vms(email) | ||||
|         vm_pool = opennebula_client.get_vms(user.email) | ||||
| 
 | ||||
|         # Reset total price | ||||
|         self.total_price = 0 | ||||
|  |  | |||
|  | @ -35,10 +35,34 @@ class OpenNebulaManager: | |||
|         '11': 'CLONING_FAILURE', | ||||
|     } | ||||
| 
 | ||||
|     def __init__(self): | ||||
|         self.client = oca.Client("{0}:{1}".format( | ||||
|     def __init__(self, email=None, password=None, create_user=True): | ||||
| 
 | ||||
|         # Get oneadmin client | ||||
|         self.oneadmin_client = self._get_opennebula_client( | ||||
|             settings.OPENNEBULA_USERNAME, | ||||
|             settings.OPENNEBULA_PASSWORD), | ||||
|             settings.OPENNEBULA_PASSWORD | ||||
|         ) | ||||
| 
 | ||||
|         if not create_user: | ||||
|             return | ||||
| 
 | ||||
|         # Get or create oppenebula user using given credentials | ||||
|         self.opennebula_user = self._get_or_create_user( | ||||
|             email, | ||||
|             password | ||||
|         ) | ||||
| 
 | ||||
|         # If opennebula user was created/obtained, get his client | ||||
|         if self.opennebula_user: | ||||
|             self.client = self._get_opennebula_client( | ||||
|                 email, | ||||
|                 password | ||||
|             ) | ||||
| 
 | ||||
|     def _get_opennebula_client(self, username, password): | ||||
|         return oca.Client("{0}:{1}".format( | ||||
|             username, | ||||
|             password), | ||||
|             "{protocol}://{domain}:{port}{endpoint}".format( | ||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||
|                 domain=settings.OPENNEBULA_DOMAIN, | ||||
|  | @ -46,6 +70,25 @@ class OpenNebulaManager: | |||
|                 endpoint=settings.OPENNEBULA_ENDPOINT | ||||
|         )) | ||||
| 
 | ||||
|     def _get_or_create_user(self, email, password): | ||||
|         try: | ||||
| 
 | ||||
|             user_pool = oca.UserPool(self.oneadmin_client) | ||||
|             user_pool.info() | ||||
|             opennebula_user = user_pool.get_by_name(email) | ||||
|             return opennebula_user | ||||
|         except WrongNameError as wrong_name_err: | ||||
|             # TODO: Store this password so that we can use it later to  | ||||
|             # connect to opennebula | ||||
|             return oca.User.allocate(self.oneadmin_client, email, password) | ||||
|             logger.debug( | ||||
|                 "User {0} does not exist. Created the user. User id = {1}", | ||||
|                 email, | ||||
|                 opennebula_user | ||||
|             ) | ||||
|         except OpenNebulaException as err: | ||||
|             logger.error("Error : {0}".format(err)) | ||||
| 
 | ||||
|     @classmethod | ||||
|     def get_vm_state(self, state): | ||||
|         return self.VM_STATE.get(str(state)) | ||||
|  | @ -77,6 +120,56 @@ class OpenNebulaManager: | |||
| 
 | ||||
|         return vm_data | ||||
| 
 | ||||
|     def create_vm(self, specs): | ||||
|         vm_id = None | ||||
|         try: | ||||
|             # We do have the vm_template param set. Get and parse it | ||||
|             # and check it to be in the desired range. | ||||
|             # We have 8 possible VM templates for the moment which are 1x, 2x, 4x ... | ||||
|             # the basic template of 10GB disk, 1GB ram, 1 vcpu, 0.1 cpu | ||||
|             vm_string_formatter = """<VM> | ||||
|                                       <MEMORY>{memory}</MEMORY> | ||||
|                                       <VCPU>{vcpu}</VCPU> | ||||
|                                       <CPU>{cpu}</CPU> | ||||
|                                       <DISK> | ||||
|                                         <TYPE>{disk_type}</TYPE> | ||||
|                                         <SIZE>{size}</SIZE> | ||||
|                                       </DISK> | ||||
|                                     </VM> | ||||
|                                     """ | ||||
|             vm_id = oca.VirtualMachine.allocate( | ||||
|                 self.oneadmin_client, | ||||
|                 vm_string_formatter.format( | ||||
|                     memory=1024 * specs.get('memory'), | ||||
|                     vcpu=specs.get('cores'), | ||||
|                     cpu=0.1 * specs.get('cores'), | ||||
|                     disk_type='fs', | ||||
|                     size=10000 * specs.get('disk_size') | ||||
|                 ) | ||||
|             ) | ||||
| 
 | ||||
|             self.oneadmin_client.call( | ||||
|                 oca.VirtualMachine.METHODS['chown'], | ||||
|                 vm_id, | ||||
|                 self.opennebula_user.id, | ||||
|                 self.opennebula_user.group_ids[0] | ||||
|             ) | ||||
|             # oca.VirtualMachine.chown( | ||||
|             #     vm_id, | ||||
|                 | ||||
|             # ) | ||||
| 
 | ||||
|         except socket.timeout as socket_err: | ||||
|             logger.error("Socket timeout error: {0}".format(socket_err)) | ||||
|         except OpenNebulaException as opennebula_err: | ||||
|             logger.error("OpenNebulaException error: {0}".format(opennebula_err)) | ||||
|         except OSError as os_err: | ||||
|             logger.error("OSError : {0}".format(os_err)) | ||||
|         except ValueError as value_err: | ||||
|             logger.error("ValueError : {0}".format(value_err)) | ||||
| 
 | ||||
|         return vm_id | ||||
| 
 | ||||
|     def get_vm(self, email, vm_id): | ||||
|         # Get vm's | ||||
|         vms = self.get_vms(email) | ||||
|  | @ -85,7 +178,7 @@ class OpenNebulaManager: | |||
|         return vms.get_by_id(int(vm_id)) | ||||
| 
 | ||||
|     def get_vms(self, email): | ||||
|         client = self.client | ||||
|         client = self.oneadmin_client | ||||
| 
 | ||||
|         # Get open nebula user id for given email | ||||
|         user_pool = oca.UserPool(client) | ||||
|  | @ -99,7 +192,7 @@ class OpenNebulaManager: | |||
|         vm_pool.info() | ||||
| 
 | ||||
|         # TODO: this is just to test with oneadmin user, remove this | ||||
|         user_id = 0 | ||||
|         # user_id = 0 | ||||
|         vm_pool.info(filter=user_id) | ||||
| 
 | ||||
|         return vm_pool | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ from utils.mailer import BaseEmail | |||
| from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, UserHostingKey | ||||
| from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm | ||||
| from .mixins import ProcessVMSelectionMixin | ||||
| from .opennebula_functions import HostingManageVMAdmin | ||||
| from .opennebula_functions import HostingManageVMAdmin, OpenNebulaManager | ||||
| 
 | ||||
| 
 | ||||
| class DjangoHostingView(ProcessVMSelectionMixin, View): | ||||
|  | @ -340,19 +340,14 @@ class PaymentVMView(LoginRequiredMixin, FormView): | |||
|             # If the Stripe payment was successed, set order status approved | ||||
|             order.set_approved() | ||||
| 
 | ||||
|             # Create VM using oppenebula functions  | ||||
|             # _request = namedtuple('request', 'POST user') | ||||
|             # _request.user = request.user | ||||
|             # user = namedtuple('user', 'email') | ||||
|             # email  | ||||
|             # _request.POST = { | ||||
|                 # 'vm_template': vm_template | ||||
|             # } | ||||
|             # Create a vm using logged user | ||||
|             oppennebula_vm_id = VirtualMachinePlan.create_opennebula_vm( | ||||
|                 self.request.user, | ||||
|                 specs | ||||
|             ) | ||||
| 
 | ||||
|             hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||
|             hosting_admin.init_opennebula_client(request) | ||||
|             oppennebula_vm_id = hosting_admin.create_vm_view(vm_type.get_specs()) | ||||
|             plan.oppenebula_id = oppennebula_vm_id | ||||
|             plan.save() | ||||
| 
 | ||||
|             # Send notification to ungleich as soon as VM has been booked | ||||
|             context = { | ||||
|  | @ -415,14 +410,14 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | |||
|     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) | ||||
|             'vms_opennebula': VirtualMachinePlan.get_vms(self.request.user) | ||||
|         }) | ||||
|         return context | ||||
| 
 | ||||
|     def get_queryset(self): | ||||
|         # hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) | ||||
|         # print(hosting_admin.show_vms_view(self.request)) | ||||
|         print(VirtualMachinePlan.get_vms(self.request.user.email)) | ||||
|         # print(VirtualMachinePlan.get_vms(self.request.user.)) | ||||
|         user = self.request.user | ||||
|         self.queryset = VirtualMachinePlan.objects.active(user) | ||||
|         return super(VirtualMachinesPlanListView, self).get_queryset() | ||||
|  | @ -502,10 +497,10 @@ class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, View): | |||
|     #     return final_url | ||||
| 
 | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         vm_id = self.kwargs.get('pk', 24) | ||||
|         vm_id = self.kwargs.get('pk') | ||||
|         try: | ||||
|             opennebula_vm = VirtualMachinePlan.get_vm( | ||||
|                 self.request.user.email, | ||||
|                 self.request.user, | ||||
|                 vm_id | ||||
|             ) | ||||
|         except Exception as error: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue