diff --git a/datacenterlight/locale/de/LC_MESSAGES/django.po b/datacenterlight/locale/de/LC_MESSAGES/django.po index 6c9d36ae..dedd3f84 100644 --- a/datacenterlight/locale/de/LC_MESSAGES/django.po +++ b/datacenterlight/locale/de/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-03 16:44+0000\n" +"POT-Creation-Date: 2017-09-16 14:09+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,6 +18,10 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#, python-format +msgid "Your New VM %(vm_name)s at Data Center Light" +msgstr "Deine neue VM %(vm_name)s bei Data Center Light" + msgid "Enter name" msgstr "Name" @@ -183,9 +187,18 @@ msgstr "Kontakt" msgid "All Rights Reserved" msgstr "Alle Rechte vorbehalten" +msgid "Toggle navigation" +msgstr "Konfiguration" + msgid "Why Data Center Light?" msgstr "Warum Data Center Light?" +msgid "Login" +msgstr "" + +msgid "Dashboard" +msgstr "" + msgid "Finally, an affordable VM hosting in Switzerland!" msgstr "Endlich: bezahlbares VM Hosting in der Schweiz" diff --git a/datacenterlight/tasks.py b/datacenterlight/tasks.py index dea4e0a6..1335869b 100644 --- a/datacenterlight/tasks.py +++ b/datacenterlight/tasks.py @@ -1,16 +1,22 @@ -from dynamicweb.celery import app +from datetime import datetime + +from celery.exceptions import MaxRetriesExceededError from celery.utils.log import get_task_logger from celery import current_task from django.conf import settings +from django.core.mail import EmailMessage +from django.utils import translation +from django.utils.translation import ugettext_lazy as _ + +from dynamicweb.celery import app +from hosting.models import HostingOrder, HostingBill +from membership.models import StripeCustomer, CustomUser from opennebula_api.models import OpenNebulaManager from opennebula_api.serializers import VirtualMachineSerializer -from hosting.models import HostingOrder, HostingBill +from utils.hosting_utils import get_all_public_keys from utils.forms import UserBillingAddressForm -from datetime import datetime -from membership.models import StripeCustomer -from django.core.mail import EmailMessage +from utils.mailer import BaseEmail from utils.models import BillingAddress -from celery.exceptions import MaxRetriesExceededError logger = get_task_logger(__name__) @@ -53,19 +59,29 @@ def create_vm_task(self, vm_template_id, user, specs, template, billing_address = BillingAddress.objects.filter( id=billing_address_id).first() customer = StripeCustomer.objects.filter(id=stripe_customer_id).first() - # Create OpenNebulaManager - manager = OpenNebulaManager(email=settings.OPENNEBULA_USERNAME, - password=settings.OPENNEBULA_PASSWORD) - # Create a vm using oneadmin, also specify the name + if 'pass' in user: + on_user = user.get('email') + on_pass = user.get('pass') + logger.debug("Using user {user} to create VM".format(user=on_user)) + vm_name = None + else: + on_user = settings.OPENNEBULA_USERNAME + on_pass = settings.OPENNEBULA_PASSWORD + logger.debug("Using OpenNebula admin user to create VM") + vm_name = "{email}-{template_name}-{date}".format( + email=user.get('email'), + template_name=template.get('name'), + date=int(datetime.now().strftime("%s"))) + + # Create OpenNebulaManager + manager = OpenNebulaManager(email=on_user, password=on_pass) + vm_id = manager.create_vm( template_id=vm_template_id, specs=specs, ssh_key=settings.ONEADMIN_USER_SSH_PUBLIC_KEY, - vm_name="{email}-{template_name}-{date}".format( - email=user.get('email'), - template_name=template.get('name'), - date=int(datetime.now().strftime("%s"))) + vm_name=vm_name ) if vm_id is None: @@ -124,6 +140,54 @@ def create_vm_task(self, vm_template_id, user, specs, template, } email = EmailMessage(**email_data) email.send() + + if 'pass' in user: + lang = 'en-us' + if user.get('language') is not None: + logger.debug("Language is set to {}".format(user.get('language'))) + lang = user.get('language') + translation.activate(lang) + # Send notification to the user as soon as VM has been booked + context = { + 'vm': vm, + 'order': order, + 'base_url': "{0}://{1}".format(user.get('request_scheme'), + user.get('request_host')), + 'page_header': _( + 'Your New VM %(vm_name)s at Data Center Light') % { + 'vm_name': vm.get('name')} + } + email_data = { + 'subject': context.get('page_header'), + 'to': user.get('email'), + 'context': context, + 'template_name': 'new_booked_vm', + 'template_path': 'hosting/emails/', + 'from_address': settings.DCL_SUPPORT_FROM_ADDRESS, + } + email = BaseEmail(**email_data) + email.send() + + # try to see if we have the IP and that if the ssh keys can + # be configured + new_host = manager.get_primary_ipv4(vm_id) + logger.debug("New VM ID is {vm_id}".format(vm_id=vm_id)) + if new_host is not None: + custom_user = CustomUser.objects.get(email=user.get('email')) + if custom_user is not None: + public_keys = get_all_public_keys(custom_user) + keys = [{'value': key, 'state': True} for key in + public_keys] + if len(keys) > 0: + logger.debug( + "Calling configure on {host} for {num_keys} keys".format( + host=new_host, num_keys=len(keys))) + # Let's delay the task by 75 seconds to be sure + # that we run the cdist configure after the host + # is up + manager.manage_public_key(keys, + hosts=[new_host], + countdown=75) except Exception as e: logger.error(str(e)) try: diff --git a/hosting/static/hosting/js/virtual_machine_detail.js b/hosting/static/hosting/js/virtual_machine_detail.js index 303f95ca..b6202e97 100644 --- a/hosting/static/hosting/js/virtual_machine_detail.js +++ b/hosting/static/hosting/js/virtual_machine_detail.js @@ -1,18 +1,48 @@ +$(document).ready(function () { + var create_vm_form = $('#virtual_machine_create_form'); + create_vm_form.submit(function () { + $('#btn-create-vm').prop('disabled', true); + $.ajax({ + url: create_vm_form.attr('action'), + type: 'POST', + data: create_vm_form.serialize(), + success: function (data) { + if (data.status === true) { + fa_icon = $('.modal-icon > .fa'); + fa_icon.attr('class', 'fa fa-check'); + $('.modal-header > .close').attr('class', 'close'); + $('#createvm-modal-title').text(data.msg_title); + $('#createvm-modal-body').text(data.msg_body); + $('#createvm-modal').on('hidden.bs.modal', function () { + window.location = data.redirect; + }) + } + }, + error: function (xmlhttprequest, textstatus, message) { + fa_icon = $('.modal-icon > .fa'); + fa_icon.attr('class', 'fa fa-times'); + $('.modal-header > .close').attr('class', 'close'); + if (typeof(create_vm_error_message) !== 'undefined') { + $('#createvm-modal-title').text(create_vm_error_message); + } + $('#btn-create-vm').prop('disabled', false); + } + }); + return false; + }); -$( document ).ready(function() { + $('#confirm-cancel').on('click', '.btn-ok', function (e) { + $('#virtual_machine_cancel_form').trigger('submit'); + }); - $('#confirm-cancel').on('click', '.btn-ok', function(e) { - $('#virtual_machine_cancel_form').trigger('submit'); - }); + var hash = window.location.hash; + hash && $('ul.nav a[href="' + hash + '"]').tab('show'); - var hash = window.location.hash; - hash && $('ul.nav a[href="' + hash + '"]').tab('show'); + $('.nav-tabs a').click(function (e) { + $(this).tab('show'); + var scrollmem = $('body').scrollTop() || $('html').scrollTop(); + window.location.hash = this.hash; + $('html,body').scrollTop(scrollmem); + }); - $('.nav-tabs a').click(function (e) { - $(this).tab('show'); - var scrollmem = $('body').scrollTop() || $('html').scrollTop(); - window.location.hash = this.hash; - $('html,body').scrollTop(scrollmem); - }); - -}); \ No newline at end of file +}); diff --git a/hosting/templates/hosting/order_detail.html b/hosting/templates/hosting/order_detail.html index 64c0b5d3..39c59808 100644 --- a/hosting/templates/hosting/order_detail.html +++ b/hosting/templates/hosting/order_detail.html @@ -1,63 +1,100 @@ {% extends "hosting/base_short.html" %} {% load staticfiles bootstrap3 %} {% load i18n %} +{% load custom_tags %} + {% block content %}
- {% if messages %} + {% if messages %}

-
- {% for message in messages %} - {{ message }} - {% endfor %} -
+
+ {% for message in messages %} + {{ message }} + {% endfor %} +
{% endif %} {% if not error %}
-
-

{{page_header_text}}

{% trans "Order #"%} {{order.id}}

-
-
-
-
+
+

{{page_header_text}}

+

+ {% if order %} + {% trans "Order #"%} {{order.id}} + {% endif %} +

+
+
+
+
{% trans "Date"%}:
- {{order.created_at|date:'Y-m-d H:i'}}

+ + {% if order %} + {{order.created_at|date:'Y-m-d H:i'}} + {% else %} + {% now "Y-m-d H:i" %} + {% endif %} +

+ {% if order %} {% trans "Status:"%}
{% if order.status == 'Approved' %} - {% trans "Approved" %} + + {% trans "Approved" %} + {% else %} - {% trans "Declined" %} + + {% trans "Declined" %} + {% endif %}

+ {% endif %}
-
-
-

{% trans "Billed To:"%}

- {{user.name}}
+
+
+

{% trans "Billed To:"%}

+ {% if order %} + {{user.name}}
{{order.billing_address.street_address}},{{order.billing_address.postal_code}}
- {{order.billing_address.city}}, {{order.billing_address.country}}. -
-
+ {{order.billing_address.city}}, + {{order.billing_address.country}}. + {% else %} + {% with request.session.billing_address_data as billing_address %} + {{billing_address|get_value_from_dict:'cardholder_name'}}
+ {{billing_address|get_value_from_dict:'street_address'}}, + {{billing_address|get_value_from_dict:'postal_code'}}
+ {{billing_address|get_value_from_dict:'city'}}, + {{billing_address|get_value_from_dict:'country'}}. + {% endwith %} + {% endif %} +
+
-
-
-
-
- {% trans "Payment Method:"%}
- {{order.cc_brand}} {% trans "ending in" %} **** {{order.last4}}
- {{user.email}} -
-
-
-
+
+
+
+
+ {% trans "Payment Method:"%}
+ {% if order %} + {{order.cc_brand}} {% trans "ending in" %} **** + {{order.last4}}
+ {{user.email}} + {% else %} + {{cc_brand}} {% trans "ending in" %} **** + {{cc_last4}}
+ {{request.session.user.email}} + {% endif %} +
+
+
+
@@ -65,33 +102,113 @@

{% trans "Order summary"%}


-

{% trans "Cores"%} {{vm.cores}}

+ {% if request.session.specs %} + {% with request.session.specs as vm %} +

{% trans "Cores"%} + {{vm.cpu}} +


-

{% trans "Memory"%} {{vm.memory}} GB

+

{% trans "Memory"%} + {{vm.memory}} GB +


-

{% trans "Disk space"%} {{vm.disk_size}} GB

+

{% trans "Disk space"%} + {{vm.disk_size}} GB +


-

{% trans "Total"%}

{{vm.price}} CHF

+

{% trans "Configuration"%} + {{request.session.template.name}} +

+
+

{% trans "Total"%} +

+ {{vm.price}} CHF + /{% trans "Month" %} + +

+

+ {% endwith %} + {% else %} +

{% trans "Cores"%} + {{vm.cores}} +

+
+

{% trans "Memory"%} + {{vm.memory}} GB +

+
+

{% trans "Disk space"%} + {{vm.disk_size}} GB +

+
+

{% trans "Total"%}

{{vm.price}} + CHF /{% trans "Month" %} +

+ {% endif %}

- {% url 'hosting:payment' as payment_url %} - {% if payment_url in request.META.HTTP_REFERER %} - + {% if not order %} +
+ {% csrf_token %} +
+
+

{% blocktrans with vm_price=request.session.specs.price %}By clicking "Place order" this plan will charge your credit card account with the fee of {{ vm_price }}CHF/month{% endblocktrans %}.

+
+
+ +
+
+
{% endif %}
{% endif %} + + +