diff --git a/hosting/forms.py b/hosting/forms.py index a8a60678..c94c4822 100644 --- a/hosting/forms.py +++ b/hosting/forms.py @@ -69,7 +69,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 @@ -77,8 +79,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/migrations/0039_hostingorder_price.py b/hosting/migrations/0039_hostingorder_price.py new file mode 100644 index 00000000..0d4945fa --- /dev/null +++ b/hosting/migrations/0039_hostingorder_price.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2017-05-12 16:37 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('hosting', '0038_auto_20170512_1006'), + ] + + operations = [ + migrations.AddField( + model_name='hostingorder', + name='price', + field=models.FloatField(default=0), + preserve_default=False, + ), + ] diff --git a/hosting/models.py b/hosting/models.py index 6eb0aa24..188f1733 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -1,5 +1,7 @@ import os import socket +import logging + import oca from django.db import models @@ -19,9 +21,9 @@ from .managers import VMPlansManager from oca.exceptions import OpenNebulaException from oca.pool import WrongNameError -import logging logger = logging.getLogger(__name__) + class HostingOrder(AssignPermissionsMixin, models.Model): ORDER_APPROVED_STATUS = 'Approved' @@ -35,6 +37,7 @@ class HostingOrder(AssignPermissionsMixin, models.Model): last4 = models.CharField(max_length=4) cc_brand = models.CharField(max_length=10) stripe_charge_id = models.CharField(max_length=100, null=True) + price = models.FloatField() permissions = ('view_hostingorder',) @@ -51,9 +54,13 @@ class HostingOrder(AssignPermissionsMixin, models.Model): return self.ORDER_APPROVED_STATUS if self.approved else self.ORDER_DECLINED_STATUS @classmethod - def create(cls, vm_plan=None, customer=None, billing_address=None): - instance = cls.objects.create(vm_plan=vm_plan, customer=customer, - billing_address=billing_address) + def create(cls, price=None, vm_id=None, customer=None, billing_address=None): + instance = cls.objects.create( + price=price, + vm_id=vm_id, + customer=customer, + billing_address=billing_address + ) instance.assign_permissions(customer.user) return instance @@ -67,6 +74,12 @@ class HostingOrder(AssignPermissionsMixin, models.Model): self.cc_brand = stripe_charge.source.brand self.save() + def get_cc_data(self): + return { + 'last4': self.last4, + 'cc_brand': self.cc_brand, + } if self.last4 and self.cc_brand else None + class UserHostingKey(models.Model): user = models.ForeignKey(CustomUser) diff --git a/hosting/opennebula_functions.py b/hosting/opennebula_functions.py index a00bb037..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,34 @@ 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() + return template_pool + def get_vm(self, email, vm_id): # Get vm's vms = self.get_vms(email) @@ -198,9 +231,6 @@ class OpenNebulaManager: return vm_pool - - - class HostingManageVMAdmin(admin.ModelAdmin): client = None oneadmin_client = None diff --git a/hosting/static/hosting/js/payment.js b/hosting/static/hosting/js/payment.js index c75e3d48..d06a5a3d 100644 --- a/hosting/static/hosting/js/payment.js +++ b/hosting/static/hosting/js/payment.js @@ -25,6 +25,27 @@ $( document ).ready(function() { }); + var hasCreditcard = window.hasCreditcard || false; + console.log("has creditcard", hasCreditcard); + // hasCreditcard= true; + + var submit_form_btn = $('#payment_button_with_creditcard'); + submit_form_btn.on('click', submit_payment); + + + function submit_payment(e){ + e.preventDefault(); + console.log("creditcard sdasd"); + // if (hasCreditcard) { + $('#billing-form').submit(); + console.log("has creditcard2"); + // } + + // $form.submit(); + } + + + var $form = $('#payment-form'); $form.submit(payWithStripe); diff --git a/hosting/templates/hosting/create_virtual_machine.html b/hosting/templates/hosting/create_virtual_machine.html index 33c792e4..3a68421e 100644 --- a/hosting/templates/hosting/create_virtual_machine.html +++ b/hosting/templates/hosting/create_virtual_machine.html @@ -17,14 +17,14 @@ {% endfor %} -
+
diff --git a/hosting/templates/hosting/payment.html b/hosting/templates/hosting/payment.html index c30fe3f1..bb80d566 100644 --- a/hosting/templates/hosting/payment.html +++ b/hosting/templates/hosting/payment.html @@ -8,7 +8,7 @@

Billing Address


-
+ {% for field in form %} {% csrf_token %} {% bootstrap_field field show_label=False type='fields'%} @@ -23,6 +23,17 @@
+ {% if credit_card_data.last4 %} + +
Credit Card
+
Last 4: *****{{credit_card_data.last4}}
+
Type: {{credit_card_data.cc_brand}}
+ + + + {% else %} + +
@@ -76,6 +87,7 @@ + {% endif %}
@@ -109,6 +121,7 @@
+ {% if stripe_key %} {%endif%} +{% if credit_card_data.last4 and credit_card_data.cc_brand %} + + +{%endif%} + {%endblock%} diff --git a/hosting/templates/hosting/virtual_machine_detail.html b/hosting/templates/hosting/virtual_machine_detail.html index a4ad37d4..e2f38d60 100644 --- a/hosting/templates/hosting/virtual_machine_detail.html +++ b/hosting/templates/hosting/virtual_machine_detail.html @@ -79,7 +79,7 @@
{% trans "Disk"%}
- {{virtual_machine.disk_size}} GiB + {{virtual_machine.disk_size|floatformat:2}} GiB
@@ -107,6 +107,7 @@

{% trans "Current status"%}

+
{% if virtual_machine.state == 'PENDING' %} {% trans "Cancel Virtual Machine"%} +
+
+
+
+ {% if messages %} +
+ {% for message in messages %} + {{ message }} + {% endfor %} +
+ {% endif %} +
+