From 387354084942a47401704a72d04588ae4416957a Mon Sep 17 00:00:00 2001 From: Levi Date: Fri, 12 May 2017 00:56:35 -0500 Subject: [PATCH] =?UTF-8?q?Force=20user=20to=20generate=20ssh=20key=20in?= =?UTF-8?q?=20order=20to=20create=20a=20VM=20#3147.=20As=20user=20I=20want?= =?UTF-8?q?=20to=20terminate=20a=20VM=20using=20web=20interface=C2=A0#3148?= =?UTF-8?q?.=20Change=20password=20in=20opennebula=20when=20user=20change?= =?UTF-8?q?=20his=20password=20on=20hosting=20app=20#3149?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hosting/forms.py | 6 +- hosting/models.py | 19 ++- hosting/opennebula_functions.py | 46 ++++-- .../hosting/virtual_machine_detail.html | 16 +- .../hosting/virtual_machine_key.html | 17 ++- .../templates/hosting/virtual_machines.html | 10 ++ hosting/views.py | 143 +++++++++++++++--- 7 files changed, 214 insertions(+), 43 deletions(-) diff --git a/hosting/forms.py b/hosting/forms.py index 7323bdf3..b143140d 100644 --- a/hosting/forms.py +++ b/hosting/forms.py @@ -101,7 +101,9 @@ class UserHostingKeyForm(forms.ModelForm): # print(self.fields) def clean_name(self): - return ''.join(random.choice(string.ascii_lowercase) for i in range(7)) + return "dcl-priv-key-%s" % ( + ''.join(random.choice(string.ascii_lowercase) for i in range(7)) + ) def clean_user(self): return self.request.user @@ -109,8 +111,6 @@ class UserHostingKeyForm(forms.ModelForm): def clean(self): cleaned_data = self.cleaned_data - print(cleaned_data) - if not cleaned_data.get('public_key'): private_key, public_key = UserHostingKey.generate_keys() cleaned_data.update({ diff --git a/hosting/models.py b/hosting/models.py index 9fa4a100..892aa45d 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -185,18 +185,31 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): instance.assign_permissions(user) return instance - def cancel_plan(self): + def cancel_plan(self, vm_id): self.status = self.CANCELED_STATUS self.save(update_fields=['status']) + @classmethod + def terminate_opennebula_vm(self, user, vm_id): + + opennebula_client = OpenNebulaManager( + user.email, + user.password, + ) + + return opennebula_client.terminate_vm(vm_id) + + @classmethod def create_opennebula_vm(self, user, specs): + # import pdb + # pdb.set_trace() + # Init opennebula manager using given user opennebula_client = OpenNebulaManager( user.email, - user.password[0:20], - create_user=True + user.password, ) # Create a vm in opennebula using given specs diff --git a/hosting/opennebula_functions.py b/hosting/opennebula_functions.py index d2796ec8..aca5424d 100644 --- a/hosting/opennebula_functions.py +++ b/hosting/opennebula_functions.py @@ -35,7 +35,7 @@ class OpenNebulaManager: '11': 'CLONING_FAILURE', } - def __init__(self, email=None, password=None, create_user=True): + def __init__(self, email=None, password=None): # Get oneadmin client self.oneadmin_client = self._get_opennebula_client( @@ -43,9 +43,6 @@ class OpenNebulaManager: 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, @@ -121,9 +118,17 @@ class OpenNebulaManager: return vm_data + def change_user_password(self, new_password): + self.oneadmin_client.call( + oca.User.METHODS['passwd'], + self.opennebula_user.id, + new_password + ) + 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 ... @@ -136,6 +141,9 @@ class OpenNebulaManager: {disk_type} {size} + + {ssh_key} + """ vm_id = oca.VirtualMachine.allocate( @@ -145,7 +153,8 @@ class OpenNebulaManager: vcpu=specs.get('cores'), cpu=0.1 * specs.get('cores'), disk_type='fs', - size=10000 * specs.get('disk_size') + size=10000 * specs.get('disk_size'), + ssh_key=specs.get('ssh_key') ) ) @@ -155,10 +164,6 @@ class OpenNebulaManager: 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)) @@ -171,6 +176,29 @@ class OpenNebulaManager: return vm_id + def terminate_vm(self, vm_id): + + TERMINATE_ACTION = 'terminate' + vm_terminated = False + + try: + self.oneadmin_client.call( + oca.VirtualMachine.METHODS['action'], + TERMINATE_ACTION, + int(vm_id), + ) + vm_terminated = True + 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_terminated + def get_vm_templates(self): template_pool = oca.VmTemplatePool(self.oneadmin_client) template_pool.info() diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index 06e5a53c..04c50279 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -170,16 +170,28 @@ {% csrf_token %} - + + +
+
+ {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} +
+