added create vm feature from a normal user in opennebula

This commit is contained in:
Levi 2017-05-08 21:49:40 -05:00
parent bd83545653
commit abf6dbddce
3 changed files with 139 additions and 20 deletions

View file

@ -176,13 +176,27 @@ 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):
opennebula_client = OpenNebulaManager(
user.email,
user.password[0:20],
create_user=True
)
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
) )
@ -192,13 +206,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

View file

@ -35,10 +35,31 @@ 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(
self.oneadmin_client = self._get_opennebula_client(
settings.OPENNEBULA_USERNAME, settings.OPENNEBULA_USERNAME,
settings.OPENNEBULA_PASSWORD), settings.OPENNEBULA_PASSWORD
)
if not create_user:
return
self.opennebula_user = self._get_or_create_user(
email,
password
)
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 +67,27 @@ class OpenNebulaManager:
endpoint=settings.OPENNEBULA_ENDPOINT endpoint=settings.OPENNEBULA_ENDPOINT
)) ))
def _get_or_create_user(self, email, password):
# import pdb
# pdb.set_trace()
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 +119,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 +177,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 +191,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

View file

@ -27,7 +27,7 @@ from utils.mailer import BaseEmail
from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, UserHostingKey from .models import VirtualMachineType, VirtualMachinePlan, HostingOrder, 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
class DjangoHostingView(ProcessVMSelectionMixin, View): class DjangoHostingView(ProcessVMSelectionMixin, View):
@ -349,10 +349,20 @@ class PaymentVMView(LoginRequiredMixin, FormView):
# 'vm_template': vm_template # 'vm_template': vm_template
# } # }
hosting_admin = HostingManageVMAdmin.__new__(HostingManageVMAdmin) open_vm = VirtualMachinePlan.create_opennebula_vm(
hosting_admin.init_opennebula_client(request) self.request.user,
oppennebula_vm_id = hosting_admin.create_vm_view(vm_type.get_specs()) specs
plan.oppenebula_id = oppennebula_vm_id )
print(open_vm)
print(open_vm)
print(open_vm)
# 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
# Send notification to ungleich as soon as VM has been booked # Send notification to ungleich as soon as VM has been booked
context = { context = {
@ -415,14 +425,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()
@ -502,10 +512,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: