Merge branch 'master' into task/3785/my_bills_page
This commit is contained in:
commit
7bd61f708c
39 changed files with 1141 additions and 698 deletions
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-09-23 19:00+0530\n"
|
||||
"POT-Creation-Date: 2017-09-24 12:34+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
|
@ -268,7 +268,7 @@ msgstr ""
|
|||
"Link klickst</a>.<br/>\n"
|
||||
|
||||
msgid "My VM page"
|
||||
msgstr ""
|
||||
msgstr "Meine VM page"
|
||||
|
||||
#, python-format
|
||||
msgid ""
|
||||
|
|
@ -306,6 +306,9 @@ msgstr "Registrieren"
|
|||
msgid "Forgot your password ? "
|
||||
msgstr "Passwort vergessen?"
|
||||
|
||||
msgid "Resend activation link"
|
||||
msgstr "Aktivierungslink noch einmal senden"
|
||||
|
||||
msgid "Notifications"
|
||||
msgstr "Benachrichtigungen"
|
||||
|
||||
|
|
@ -385,7 +388,7 @@ msgid "Processing..."
|
|||
msgstr "Abarbeitung..."
|
||||
|
||||
msgid "Hold tight, we are processing your request"
|
||||
msgstr "Bitte warten - wir verbeiten Deine Anfrage gerade"
|
||||
msgstr "Bitte warten - wir bearbeiten Deine Anfrage gerade"
|
||||
|
||||
msgid "Some problem encountered. Please try again later."
|
||||
msgstr "Ein Problem ist aufgetreten. Bitte versuche es später noch einmal."
|
||||
|
|
@ -620,7 +623,7 @@ msgid "View Detail"
|
|||
msgstr "Details anzeigen"
|
||||
|
||||
msgid "login"
|
||||
msgstr "Einloggen"
|
||||
msgstr "anmelden"
|
||||
|
||||
msgid ""
|
||||
"Thank you for signing up. We have sent an email to you. Please follow the "
|
||||
|
|
|
|||
34
hosting/migrations/0043_vmdetail.py
Normal file
34
hosting/migrations/0043_vmdetail.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.9.4 on 2017-09-24 18:12
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('hosting', '0042_hostingorder_subscription_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='VMDetail',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('vm_id', models.IntegerField(default=0)),
|
||||
('disk_size', models.FloatField(default=0.0)),
|
||||
('cores', models.FloatField(default=0.0)),
|
||||
('memory', models.FloatField(default=0.0)),
|
||||
('configuration', models.CharField(default='', max_length=25)),
|
||||
('ipv4', models.TextField(default='')),
|
||||
('ipv6', models.TextField(default='')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('terminated_at', models.DateTimeField(null=True)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -159,3 +159,16 @@ class HostingBill(AssignPermissionsMixin, models.Model):
|
|||
instance = cls.objects.create(customer=customer,
|
||||
billing_address=billing_address)
|
||||
return instance
|
||||
|
||||
|
||||
class VMDetail(models.Model):
|
||||
user = models.ForeignKey(CustomUser)
|
||||
vm_id = models.IntegerField(default=0)
|
||||
disk_size = models.FloatField(default=0.0)
|
||||
cores = models.FloatField(default=0.0)
|
||||
memory = models.FloatField(default=0.0)
|
||||
configuration = models.CharField(default='', max_length=25)
|
||||
ipv4 = models.TextField(default='')
|
||||
ipv6 = models.TextField(default='')
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
terminated_at = models.DateTimeField(null=True)
|
||||
|
|
|
|||
|
|
@ -857,6 +857,8 @@ a.list-group-item-danger:focus,
|
|||
background: rgba(235, 204, 209, 0.2);
|
||||
}
|
||||
.has-error .form-control,
|
||||
.has-error .form-control:focus,
|
||||
.has-error .form-control:active,
|
||||
.has-error .input-group-addon {
|
||||
color: #eb4d5c;
|
||||
border-color: #eb4d5c;
|
||||
|
|
@ -870,3 +872,48 @@ a.list-group-item-danger.active:focus {
|
|||
.panel-danger > .panel-heading .badge {
|
||||
background-color: #eb4d5c;
|
||||
}
|
||||
|
||||
/* bootstrap input box-shadom disable */
|
||||
.has-error .form-control:focus,
|
||||
.has-error .form-control:active,
|
||||
.has-success .form-control:focus,
|
||||
.has-success .form-control:active {
|
||||
box-shadow: inset 0 0 1px rgba(0,0,0,0.25);
|
||||
}
|
||||
.checkmark {
|
||||
display: inline-block;
|
||||
}
|
||||
.checkmark:after {
|
||||
/*Add another block-level blank space*/
|
||||
content: '';
|
||||
display: block;
|
||||
/*Make it a small rectangle so the border will create an L-shape*/
|
||||
width: 25px;
|
||||
height: 60px;
|
||||
/*Add a white border on the bottom and left, creating that 'L' */
|
||||
border: solid #777;
|
||||
border-width: 0 3px 3px 0;
|
||||
/*Rotate the L 45 degrees to turn it into a checkmark*/
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.closemark {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
position: relative;
|
||||
}
|
||||
.closemark:before, .closemark:after {
|
||||
position: absolute;
|
||||
left: 25px;
|
||||
content: ' ';
|
||||
height: 50px;
|
||||
width: 2px;
|
||||
background-color: #777;
|
||||
}
|
||||
.closemark:before {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.closemark:after {
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,100 @@
|
|||
}
|
||||
|
||||
.summary-box .content {
|
||||
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
/* landing page payment new style */
|
||||
.last-p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.dcl-payment-section {
|
||||
max-width: 391px;
|
||||
margin: 0 auto 30px;
|
||||
padding: 0 10px 30px;
|
||||
border-bottom: 1px solid #edebeb;
|
||||
height: 100%;
|
||||
}
|
||||
.dcl-payment-section hr{
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.dcl-payment-section .top-hr {
|
||||
margin-left: -10px;
|
||||
}
|
||||
.dcl-payment-section h3 {
|
||||
font-weight: 600;
|
||||
}
|
||||
.dcl-payment-section p {
|
||||
padding: 0 5px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.dcl-payment-section .card-warning-content {
|
||||
padding: 8px 10px;
|
||||
font-weight: 300;
|
||||
}
|
||||
.dcl-payment-order strong{
|
||||
font-size: 17px;
|
||||
}
|
||||
.dcl-payment-order p {
|
||||
font-weight: 300;
|
||||
}
|
||||
.dcl-payment-section .form-group {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.dcl-payment-section .form-control {
|
||||
box-shadow: none;
|
||||
padding: 6px 12px;
|
||||
height: 32px;
|
||||
}
|
||||
.dcl-payment-user {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dcl-payment-user h4 {
|
||||
font-weight: 600;
|
||||
padding-left: 5px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.dcl-payment-grid {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.dcl-payment-box {
|
||||
width: 50%;
|
||||
position: relative;
|
||||
padding: 0 30px;
|
||||
}
|
||||
.dcl-payment-box:nth-child(2) {
|
||||
order: 1;
|
||||
}
|
||||
.dcl-payment-box:nth-child(4) {
|
||||
order: 2;
|
||||
}
|
||||
.dcl-payment-section {
|
||||
padding: 15px 10px;
|
||||
margin-bottom: 0;
|
||||
border-bottom-width: 5px;
|
||||
}
|
||||
.dcl-payment-box:nth-child(2n) .dcl-payment-section {
|
||||
border-bottom: none;
|
||||
}
|
||||
.dcl-payment-box:nth-child(1):after,
|
||||
.dcl-payment-box:nth-child(2):after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
background: #eee;
|
||||
width: 1px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
top: 20px;
|
||||
bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,6 @@ $(document).ready(function() {
|
|||
$('html,body').scrollTop(scrollmem);
|
||||
});
|
||||
|
||||
$('.modal-text').removeClass('hide');
|
||||
var create_vm_form = $('#virtual_machine_create_form');
|
||||
create_vm_form.submit(function () {
|
||||
$('#btn-create-vm').prop('disabled', true);
|
||||
|
|
@ -90,26 +89,28 @@ $(document).ready(function() {
|
|||
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');
|
||||
fa_icon.attr('class', 'checkmark');
|
||||
// $('.modal-header > .close').removeClass('hidden');
|
||||
$('#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;
|
||||
})
|
||||
$('#createvm-modal-done-btn')
|
||||
.attr('href', data.redirect)
|
||||
.removeClass('hide');
|
||||
}
|
||||
},
|
||||
error: function (xmlhttprequest, textstatus, message) {
|
||||
fa_icon = $('.modal-icon > .fa');
|
||||
fa_icon.attr('class', 'fa fa-times');
|
||||
$('.modal-header > .close').attr('class', 'close');
|
||||
$('.modal-text').addClass('hide');
|
||||
fa_icon.attr('class', 'fa fa-close');
|
||||
if (typeof(create_vm_error_message) !== 'undefined') {
|
||||
$('#createvm-modal-title').text(create_vm_error_message);
|
||||
$('#createvm-modal-text').text(create_vm_error_message);
|
||||
}
|
||||
$('#btn-create-vm').prop('disabled', false);
|
||||
$('#createvm-modal-close-btn').removeClass('hide');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
$('#createvm-modal').on('hidden.bs.modal', function () {
|
||||
$(this).find('.modal-footer .btn').addClass('hide');
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,20 +47,5 @@
|
|||
window.location.href = '{{next_url}}';
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
window.onload = function () {
|
||||
{% for user_key in keys %}
|
||||
var locale_date = moment.utc(document.getElementById("ssh-created_at-{{user_key.id}}").textContent,'YYYY-MM-DD HH:mm').toDate();
|
||||
locale_date = moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
|
||||
document.getElementById('ssh-created_at-{{user_key.id}}').innerHTML = locale_date;
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
{%endblock%}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
<a class="unlink" href="{% url 'hosting:signup' %}">{% trans "Sign up"%}</a>
|
||||
<span class="text"> or </span>
|
||||
<a class="unlink" href="{% url 'hosting:reset_password' %}">{% trans "Forgot your password ? "%}</a>
|
||||
<span class="text"> or </span><br/>
|
||||
<a class="unlink" href="{% url 'hosting:resend_activation_link' %}">{% trans "Resend activation link"%}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@
|
|||
<p>
|
||||
<strong>{% trans "Status" %}: </strong>
|
||||
<strong>
|
||||
{% if order.status == 'Approved' %}
|
||||
{% if vm.terminated_at %}
|
||||
<span class="vm-color-failed">{% trans "Terminated" %}</span>
|
||||
{% elif order.status == 'Approved' %}
|
||||
<span class="vm-color-online">{% trans "Approved" %}</span>
|
||||
{% else %}
|
||||
<span class="vm-status-failed">{% trans "Declined" %}</span>
|
||||
|
|
@ -96,14 +98,14 @@
|
|||
</p>
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
{% comment %}
|
||||
{% if vm.created_at %}
|
||||
<p>
|
||||
<span>{% trans "Period" %}: </span>
|
||||
<span>{{ vm.created_at|date:'Y/m/d' }} - {% if vm.terminated_at %}{{ vm.terminated_at|date:'Y/m/d' }}{% else %}{% now 'Y/m/d' %}{% endif %}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>
|
||||
<span>{% trans "Period" %}</span>
|
||||
<span class="pull-right">{{}}</span>
|
||||
</p>
|
||||
{% endcomment %}
|
||||
<p>
|
||||
<span>{% trans "Cores" %}</span>
|
||||
<span>{% trans "Cores" %}: </span>
|
||||
{% if vm.cores %}
|
||||
<span class="pull-right">{{vm.cores|floatformat}}</span>
|
||||
{% else %}
|
||||
|
|
@ -111,11 +113,11 @@
|
|||
{% endif %}
|
||||
</p>
|
||||
<p>
|
||||
<span>{% trans "Memory" %}</span>
|
||||
<span>{% trans "Memory" %}: </span>
|
||||
<span class="pull-right">{{vm.memory}} GB</span>
|
||||
</p>
|
||||
<p>
|
||||
<span>{% trans "Disk space" %}</span>
|
||||
<span>{% trans "Disk space" %}: </span>
|
||||
<span class="pull-right">{{vm.disk_size}} GB</span>
|
||||
</p>
|
||||
<p>
|
||||
|
|
@ -160,22 +162,19 @@
|
|||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close hidden" data-dismiss="modal"
|
||||
aria-label="create-vm-close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="modal-icon">
|
||||
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
|
||||
<span class="sr-only">{% trans "Processing..." %}</span>
|
||||
</div>
|
||||
<h4 class="modal-title" id="createvm-modal-title">
|
||||
</h4>
|
||||
<h4 class="modal-title" id="createvm-modal-title"></h4>
|
||||
<div class="modal-text" id="createvm-modal-body">
|
||||
{% trans "Hold tight, we are processing your request" %}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a id="createvm-modal-done-btn" class="btn btn-success btn-ok btn-wide hide" href="{% url 'hosting:virtual_machines' %}">{% trans "OK" %}</a>
|
||||
<button id="createvm-modal-close-btn" type="button" class="btn btn-danger btn-ok btn-wide hide" data-dismiss="modal" aria-label="create-vm-close">{% trans "Close" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -202,4 +201,4 @@
|
|||
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
|
||||
<script src="{% static 'hosting/js/html2pdf.js' %}"></script>
|
||||
<script src="{% static 'hosting/js/order.js' %}"></script>
|
||||
{% endblock js_extra %}
|
||||
{% endblock js_extra %}
|
||||
|
|
|
|||
36
hosting/templates/hosting/resend_activation_link.html
Normal file
36
hosting/templates/hosting/resend_activation_link.html
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{% extends "hosting/base_short.html" %}
|
||||
{% load staticfiles bootstrap3%}
|
||||
{% load i18n %}
|
||||
|
||||
{% block navbar %}
|
||||
{% include 'hosting/includes/_navbar_transparent.html' %}
|
||||
{% endblock navbar %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div class="auth-container">
|
||||
<div class="auth-bg"></div>
|
||||
<div class="auth-center">
|
||||
<div class="auth-title">
|
||||
<h2>{% trans "Your VM hosted in Switzerland"%}</h2>
|
||||
</div>
|
||||
<div class="auth-content">
|
||||
<div class="intro-message auth-box sign-up">
|
||||
<h2 class="section-heading">{% trans "Resend activation link"%}</h2>
|
||||
<form action="{% url 'hosting:resend_activation_link' %}" method="post" class="form" novalidate>
|
||||
{% csrf_token %}
|
||||
{% for field in form %}
|
||||
{% bootstrap_field field show_label=False %}
|
||||
{% endfor %}
|
||||
{% buttons %}
|
||||
<button type="submit" class="btn btn-block btn-success">
|
||||
{% trans "Submit"%}
|
||||
</button>
|
||||
{% endbuttons %}
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -101,21 +101,5 @@
|
|||
window.location.href = '{{next_url}}';
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
window.onload = function () {
|
||||
{% for user_key in keys %}
|
||||
var locale_date = moment.utc(document.getElementById("ssh-created_at-{{user_key.id}}").textContent,'YYYY-MM-DD HH:mm').toDate();
|
||||
locale_date = moment(locale_date).format("YYYY-MM-DD h:mm:ss a");
|
||||
document.getElementById('ssh-created_at-{{user_key.id}}').innerHTML = locale_date;
|
||||
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
{%endblock%}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@
|
|||
<p><strong>{{virtual_machine.name}}</strong></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-danger btn-ok btn-wide">{% trans "OK" %}</a>
|
||||
<a class="btn btn-danger btn-ok btn-wide">{% trans "OK" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -123,8 +123,9 @@
|
|||
<div class="modal-header">
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="modal-icon"><i class="fa fa-check" aria-hidden="true"></i></div>
|
||||
<h4 class="modal-title" id="ModalLabel">{% blocktrans with machine_name=virtual_machine.name %}Your Virtual Machine <strong>{{machine_name}}</strong> is successfully terminated!{% endblocktrans %}</h4>
|
||||
<div class="modal-icon"><i class="checkmark" aria-hidden="true"></i></div>
|
||||
<h4 class="modal-title"></h4>
|
||||
<div class="modal-text" id="ModalLabel">{% blocktrans with machine_name=virtual_machine.name %}Your Virtual Machine <strong>{{machine_name}}</strong> is successfully terminated!{% endblocktrans %}</div>
|
||||
<div class="modal-footer">
|
||||
<a href="{% url 'hosting:virtual_machines' %}" class="btn btn-success btn-wide">{% trans "OK" %}</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@
|
|||
{% endif %}
|
||||
{% if not error %}
|
||||
<div class="dashboard-subtitle">
|
||||
<p>{% trans 'To create a new virtual machine, click "Create VM"' %}</p>
|
||||
<p>{% trans 'To create a new virtual machine, click "Create VM"' %}
|
||||
{% if show_create_ssh_key_msg %}
|
||||
{% url 'hosting:create_ssh_key' as create_ssh_url %}
|
||||
<br/>{% blocktrans %}To access your VM, add your SSH key <a href="{{create_ssh_url}}">here</a>{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
<div class="text-right">
|
||||
<a class="btn btn-vm" href="{% url 'hosting:create_virtual_machine' %}"><span class="css-plus"></span> <span>{% trans "CREATE VM" %}</span></a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ from .views import (
|
|||
MarkAsReadNotificationView, PasswordResetView, PasswordResetConfirmView,
|
||||
HostingPricingView, CreateVirtualMachinesView, HostingBillListView,
|
||||
HostingBillDetailView, SSHKeyDeleteView, SSHKeyCreateView, SSHKeyListView,
|
||||
SSHKeyChoiceView, DashboardView, SettingsView)
|
||||
|
||||
SSHKeyChoiceView, DashboardView, SettingsView, ResendActivationEmailView)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'index/?$', IndexView.as_view(), name='index'),
|
||||
|
|
@ -52,6 +51,8 @@ urlpatterns = [
|
|||
url(r'signup/?$', SignupView.as_view(), name='signup'),
|
||||
url(r'signup-validate/?$', SignupValidateView.as_view(),
|
||||
name='signup-validate'),
|
||||
url(r'resend-activation-link/?$', ResendActivationEmailView.as_view(),
|
||||
name='resend_activation_link'),
|
||||
url(r'reset-password/?$', PasswordResetView.as_view(),
|
||||
name='reset_password'),
|
||||
url(r'reset-password-confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
|
||||
|
|
|
|||
113
hosting/views.py
113
hosting/views.py
|
|
@ -1,6 +1,7 @@
|
|||
import json
|
||||
import logging
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from time import sleep
|
||||
|
||||
from django import forms
|
||||
|
|
@ -33,20 +34,25 @@ from membership.models import CustomUser, StripeCustomer
|
|||
from opennebula_api.models import OpenNebulaManager
|
||||
from opennebula_api.serializers import VirtualMachineSerializer, \
|
||||
VirtualMachineTemplateSerializer, VMTemplateSerializer
|
||||
from utils.forms import BillingAddressForm, PasswordResetRequestForm, \
|
||||
UserBillingAddressForm
|
||||
from utils.forms import (
|
||||
BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm,
|
||||
ResendActivationEmailForm
|
||||
)
|
||||
from utils.hosting_utils import get_vm_price
|
||||
from utils.mailer import BaseEmail
|
||||
from utils.stripe_utils import StripeUtils
|
||||
from utils.views import (
|
||||
PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
|
||||
PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin,
|
||||
ResendActivationLinkViewMixin
|
||||
)
|
||||
from .forms import HostingUserSignupForm, HostingUserLoginForm, \
|
||||
UserHostingKeyForm, generate_ssh_key_name
|
||||
from .mixins import ProcessVMSelectionMixin
|
||||
from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey
|
||||
from .models import (
|
||||
HostingOrder, HostingBill, HostingPlan, UserHostingKey, VMDetail
|
||||
)
|
||||
from datacenterlight.models import VMTemplate
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a \
|
||||
|
|
@ -282,6 +288,14 @@ class SignupValidatedView(SignupValidateView):
|
|||
return context
|
||||
|
||||
|
||||
class ResendActivationEmailView(ResendActivationLinkViewMixin):
|
||||
template_name = 'hosting/resend_activation_link.html'
|
||||
form_class = ResendActivationEmailForm
|
||||
success_url = reverse_lazy('hosting:login')
|
||||
email_template_path = 'datacenterlight/emails/'
|
||||
email_template_name = 'user_activation'
|
||||
|
||||
|
||||
class PasswordResetView(PasswordResetViewMixin):
|
||||
site = 'dcl'
|
||||
template_name = 'hosting/reset_password.html'
|
||||
|
|
@ -599,13 +613,6 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
|||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not UserHostingKey.objects.filter(user=self.request.user).exists():
|
||||
messages.success(
|
||||
request,
|
||||
'In order to create a VM, you create/upload your SSH KEY first.'
|
||||
)
|
||||
return HttpResponseRedirect(reverse('hosting:ssh_keys'))
|
||||
|
||||
if 'next' in request.session:
|
||||
del request.session['next']
|
||||
|
||||
|
|
@ -678,25 +685,30 @@ class OrdersHostingDetailView(LoginRequiredMixin,
|
|||
if obj is not None:
|
||||
# invoice for previous order
|
||||
try:
|
||||
manager = OpenNebulaManager(
|
||||
email=owner.email, password=owner.password
|
||||
)
|
||||
vm = manager.get_vm(obj.vm_id)
|
||||
context['vm'] = VirtualMachineSerializer(vm).data
|
||||
except WrongIdError:
|
||||
messages.error(
|
||||
self.request,
|
||||
_('The VM you are looking for is unavailable at the '
|
||||
'moment. Please contact Data Center Light support.')
|
||||
)
|
||||
self.kwargs['error'] = 'WrongIdError'
|
||||
context['error'] = 'WrongIdError'
|
||||
except ConnectionRefusedError:
|
||||
messages.error(
|
||||
self.request,
|
||||
_('In order to create a VM, you need to create/upload '
|
||||
'your SSH KEY first.')
|
||||
)
|
||||
vm_detail = VMDetail.objects.get(vm_id=obj.vm_id)
|
||||
context['vm'] = vm_detail.__dict__
|
||||
context['vm']['name'] = '{}-{}'.format(context['vm']['configuration'], context['vm']['vm_id'])
|
||||
except VMDetail.DoesNotExist:
|
||||
try:
|
||||
manager = OpenNebulaManager(
|
||||
email=owner.email, password=owner.password
|
||||
)
|
||||
vm = manager.get_vm(obj.vm_id)
|
||||
context['vm'] = VirtualMachineSerializer(vm).data
|
||||
except WrongIdError:
|
||||
messages.error(
|
||||
self.request,
|
||||
_('The VM you are looking for is unavailable at the '
|
||||
'moment. Please contact Data Center Light support.')
|
||||
)
|
||||
self.kwargs['error'] = 'WrongIdError'
|
||||
context['error'] = 'WrongIdError'
|
||||
except ConnectionRefusedError:
|
||||
messages.error(
|
||||
self.request,
|
||||
_('In order to create a VM, you need to create/upload '
|
||||
'your SSH KEY first.')
|
||||
)
|
||||
elif not card_details.get('response_object'):
|
||||
# new order, failed to get card details
|
||||
context['failed_payment'] = True
|
||||
|
|
@ -756,12 +768,11 @@ class OrdersHostingDetailView(LoginRequiredMixin,
|
|||
cpu = specs.get('cpu')
|
||||
memory = specs.get('memory')
|
||||
disk_size = specs.get('disk_size')
|
||||
amount_to_be_charged = (cpu * 5) + (memory * 2) + (disk_size * 0.6)
|
||||
plan_name = "{cpu} Cores, {memory} GB RAM, {disk_size} GB SSD".format(
|
||||
cpu=cpu,
|
||||
memory=memory,
|
||||
disk_size=disk_size)
|
||||
|
||||
amount_to_be_charged = get_vm_price(cpu=cpu, memory=memory,
|
||||
disk_size=disk_size)
|
||||
plan_name = StripeUtils.get_stripe_plan_name(cpu=cpu,
|
||||
memory=memory,
|
||||
disk_size=disk_size)
|
||||
stripe_plan_id = StripeUtils.get_stripe_plan_id(cpu=cpu,
|
||||
ram=memory,
|
||||
ssd=disk_size,
|
||||
|
|
@ -806,9 +817,10 @@ class OrdersHostingDetailView(LoginRequiredMixin,
|
|||
'status': True,
|
||||
'redirect': reverse('hosting:virtual_machines'),
|
||||
'msg_title': str(_('Thank you for the order.')),
|
||||
'msg_body': str(_('Your VM will be up and running in a few moments.'
|
||||
' We will send you a confirmation email as soon as'
|
||||
' it is ready.'))
|
||||
'msg_body': str(
|
||||
_('Your VM will be up and running in a few moments.'
|
||||
' We will send you a confirmation email as soon as'
|
||||
' it is ready.'))
|
||||
}
|
||||
|
||||
return HttpResponse(json.dumps(response),
|
||||
|
|
@ -866,6 +878,10 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
|
|||
context = {'error': 'connection'}
|
||||
else:
|
||||
context = super(ListView, self).get_context_data(**kwargs)
|
||||
if UserHostingKey.objects.filter(user=self.request.user).exists():
|
||||
context['show_create_ssh_key_msg'] = False
|
||||
else:
|
||||
context['show_create_ssh_key_msg'] = True
|
||||
return context
|
||||
|
||||
|
||||
|
|
@ -886,15 +902,6 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
|
|||
raise ValidationError(_('Invalid storage size'))
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if not UserHostingKey.objects.filter(user=self.request.user).exists():
|
||||
messages.success(
|
||||
request,
|
||||
_(
|
||||
'In order to create a VM, you need to '
|
||||
'create/upload your SSH KEY first.'
|
||||
)
|
||||
)
|
||||
return HttpResponseRedirect(reverse('hosting:ssh_keys'))
|
||||
context = {'templates': VMTemplate.objects.all()}
|
||||
return render(request, self.template_name, context)
|
||||
|
||||
|
|
@ -905,7 +912,6 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
|
|||
memory_field = forms.IntegerField(validators=[self.validate_memory])
|
||||
storage = request.POST.get('storage')
|
||||
storage_field = forms.IntegerField(validators=[self.validate_storage])
|
||||
price = request.POST.get('total')
|
||||
template_id = int(request.POST.get('config'))
|
||||
template = VMTemplate.objects.filter(
|
||||
opennebula_vm_template_id=template_id).first()
|
||||
|
|
@ -937,7 +943,8 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
|
|||
extra_tags='storage')
|
||||
return HttpResponseRedirect(
|
||||
reverse('datacenterlight:index') + "#order_form")
|
||||
|
||||
price = get_vm_price(cpu=cores, memory=memory,
|
||||
disk_size=storage)
|
||||
specs = {
|
||||
'cpu': cores,
|
||||
'memory': memory,
|
||||
|
|
@ -1043,6 +1050,10 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
|||
except WrongIdError:
|
||||
response['status'] = True
|
||||
response['text'] = ugettext('Terminated')
|
||||
vm_detail_obj = VMDetail.objects.filter(
|
||||
vm_id=opennebula_vm_id).first()
|
||||
vm_detail_obj.terminated_at = datetime.utcnow()
|
||||
vm_detail_obj.save()
|
||||
break
|
||||
except BaseException:
|
||||
break
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue