Merge branch 'opennebula-integration' into vm_bill
This commit is contained in:
		
				commit
				
					
						d0fc0144e5
					
				
			
		
					 3 changed files with 135 additions and 27 deletions
				
			
		|  | @ -178,13 +178,30 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | ||||||
|         self.save(update_fields=['status']) |         self.save(update_fields=['status']) | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @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 |         # Get opennebula client | ||||||
|         opennebula_client = OpenNebulaManager() |         opennebula_client = OpenNebulaManager( | ||||||
|  |             email=user.email, | ||||||
|  |             password=user.password[:20], | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         # Get vm given the id |         # Get vm given the id | ||||||
|         vm = opennebula_client.get_vm( |         vm = opennebula_client.get_vm( | ||||||
|             email, |             user.email, | ||||||
|             vm_id |             vm_id | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  | @ -194,13 +211,16 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): | ||||||
|         return vm_data |         return vm_data | ||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def get_vms(self, email): |     def get_vms(self, user): | ||||||
| 
 | 
 | ||||||
|         # Get opennebula client |         # Get opennebula client | ||||||
|         opennebula_client = OpenNebulaManager() |         opennebula_client = OpenNebulaManager( | ||||||
|  |             email=user.email, | ||||||
|  |             password=user.password[:20], | ||||||
|  |         ) | ||||||
| 
 | 
 | ||||||
|         # Get vm pool |         # Get vm pool | ||||||
|         vm_pool = opennebula_client.get_vms(email) |         vm_pool = opennebula_client.get_vms(user.email) | ||||||
| 
 | 
 | ||||||
|         # Reset total price |         # Reset total price | ||||||
|         self.total_price = 0 |         self.total_price = 0 | ||||||
|  |  | ||||||
|  | @ -35,10 +35,34 @@ class OpenNebulaManager: | ||||||
|         '11': 'CLONING_FAILURE', |         '11': 'CLONING_FAILURE', | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     def __init__(self): |     def __init__(self, email=None, password=None, create_user=True): | ||||||
|         self.client = oca.Client("{0}:{1}".format( | 
 | ||||||
|  |         # Get oneadmin client | ||||||
|  |         self.oneadmin_client = self._get_opennebula_client( | ||||||
|             settings.OPENNEBULA_USERNAME, |             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}://{domain}:{port}{endpoint}".format( | ||||||
|                 protocol=settings.OPENNEBULA_PROTOCOL, |                 protocol=settings.OPENNEBULA_PROTOCOL, | ||||||
|                 domain=settings.OPENNEBULA_DOMAIN, |                 domain=settings.OPENNEBULA_DOMAIN, | ||||||
|  | @ -46,6 +70,25 @@ class OpenNebulaManager: | ||||||
|                 endpoint=settings.OPENNEBULA_ENDPOINT |                 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 |     @classmethod | ||||||
|     def get_vm_state(self, state): |     def get_vm_state(self, state): | ||||||
|         return self.VM_STATE.get(str(state)) |         return self.VM_STATE.get(str(state)) | ||||||
|  | @ -77,6 +120,56 @@ class OpenNebulaManager: | ||||||
| 
 | 
 | ||||||
|         return vm_data |         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): |     def get_vm(self, email, vm_id): | ||||||
|         # Get vm's |         # Get vm's | ||||||
|         vms = self.get_vms(email) |         vms = self.get_vms(email) | ||||||
|  | @ -85,7 +178,7 @@ class OpenNebulaManager: | ||||||
|         return vms.get_by_id(int(vm_id)) |         return vms.get_by_id(int(vm_id)) | ||||||
| 
 | 
 | ||||||
|     def get_vms(self, email): |     def get_vms(self, email): | ||||||
|         client = self.client |         client = self.oneadmin_client | ||||||
| 
 | 
 | ||||||
|         # Get open nebula user id for given email |         # Get open nebula user id for given email | ||||||
|         user_pool = oca.UserPool(client) |         user_pool = oca.UserPool(client) | ||||||
|  | @ -99,7 +192,7 @@ class OpenNebulaManager: | ||||||
|         vm_pool.info() |         vm_pool.info() | ||||||
| 
 | 
 | ||||||
|         # TODO: this is just to test with oneadmin user, remove this |         # TODO: this is just to test with oneadmin user, remove this | ||||||
|         user_id = 0 |         # user_id = 0 | ||||||
|         vm_pool.info(filter=user_id) |         vm_pool.info(filter=user_id) | ||||||
| 
 | 
 | ||||||
|         return vm_pool |         return vm_pool | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ from utils.mailer import BaseEmail | ||||||
| from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, HostingBill, UserHostingKey | from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, HostingBill, UserHostingKey | ||||||
| from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm | from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm | ||||||
| from .mixins import ProcessVMSelectionMixin | from .mixins import ProcessVMSelectionMixin | ||||||
| from .opennebula_functions import HostingManageVMAdmin | from .opennebula_functions import HostingManageVMAdmin, OpenNebulaManager | ||||||
| 
 | 
 | ||||||
| from oca.exceptions import OpenNebulaException | from oca.exceptions import OpenNebulaException | ||||||
| from oca.pool import WrongNameError | from oca.pool import WrongNameError | ||||||
|  | @ -346,19 +346,14 @@ class PaymentVMView(LoginRequiredMixin, FormView): | ||||||
|             # If the Stripe payment was successed, set order status approved |             # If the Stripe payment was successed, set order status approved | ||||||
|             order.set_approved() |             order.set_approved() | ||||||
| 
 | 
 | ||||||
|             # Create VM using oppenebula functions  |             # Create a vm using logged user | ||||||
|             # _request = namedtuple('request', 'POST user') |             oppennebula_vm_id = VirtualMachinePlan.create_opennebula_vm( | ||||||
|             # _request.user = request.user |                 self.request.user, | ||||||
|             # user = namedtuple('user', 'email') |                 specs | ||||||
|             # email  |             ) | ||||||
|             # _request.POST = { |  | ||||||
|                 # 'vm_template': vm_template |  | ||||||
|             # } |  | ||||||
| 
 | 
 | ||||||
|             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.oppenebula_id = oppennebula_vm_id | ||||||
|  |             plan.save() | ||||||
| 
 | 
 | ||||||
|             # Send notification to ungleich as soon as VM has been booked |             # Send notification to ungleich as soon as VM has been booked | ||||||
|             context = { |             context = { | ||||||
|  | @ -420,14 +415,14 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
|         context = super(VirtualMachinesPlanListView, self).get_context_data(**kwargs) |         context = super(VirtualMachinesPlanListView, self).get_context_data(**kwargs) | ||||||
|         context.update({ |         context.update({ | ||||||
|             'vms_opennebula': VirtualMachinePlan.get_vms(self.request.user.email) |             'vms_opennebula': VirtualMachinePlan.get_vms(self.request.user) | ||||||
|         }) |         }) | ||||||
|         return context |         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)) | ||||||
|         print(VirtualMachinePlan.get_vms(self.request.user.email)) |         # print(VirtualMachinePlan.get_vms(self.request.user.)) | ||||||
|         user = self.request.user |         user = self.request.user | ||||||
|         self.queryset = VirtualMachinePlan.objects.active(user) |         self.queryset = VirtualMachinePlan.objects.active(user) | ||||||
|         return super(VirtualMachinesPlanListView, self).get_queryset() |         return super(VirtualMachinesPlanListView, self).get_queryset() | ||||||
|  | @ -507,10 +502,10 @@ class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, View): | ||||||
|     #     return final_url |     #     return final_url | ||||||
| 
 | 
 | ||||||
|     def get(self, request, *args, **kwargs): |     def get(self, request, *args, **kwargs): | ||||||
|         vm_id = self.kwargs.get('pk', 24) |         vm_id = self.kwargs.get('pk') | ||||||
|         try: |         try: | ||||||
|             opennebula_vm = VirtualMachinePlan.get_vm( |             opennebula_vm = VirtualMachinePlan.get_vm( | ||||||
|                 self.request.user.email, |                 self.request.user, | ||||||
|                 vm_id |                 vm_id | ||||||
|             ) |             ) | ||||||
|         except Exception as error: |         except Exception as error: | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue