merged from master

This commit is contained in:
Arvind Tiwari 2017-07-28 16:43:03 +05:30
commit 2724cbd375
17 changed files with 817 additions and 535 deletions

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-07-13 23:55+0530\n" "POT-Creation-Date: 2017-07-24 18:51+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -103,9 +103,8 @@ msgid "Please enter a valid email address."
msgstr "Bitte gib eine gültige E-Mailadresse ein." msgstr "Bitte gib eine gültige E-Mailadresse ein."
#: templates/datacenterlight/calculator_form.html:88 #: templates/datacenterlight/calculator_form.html:88
#: templates/datacenterlight/pricing.html:79 msgid "Continue"
msgid "Order Now!" msgstr "Weiter"
msgstr "Bestelle jetzt!"
#: templates/datacenterlight/emails/request_access_confirmation.html:99 #: templates/datacenterlight/emails/request_access_confirmation.html:99
#: templates/datacenterlight/emails/request_access_confirmation.txt:99 #: templates/datacenterlight/emails/request_access_confirmation.txt:99
@ -325,46 +324,46 @@ msgid "Confirm Order"
msgstr "Bestellung Bestätigen" msgstr "Bestellung Bestätigen"
#: templates/datacenterlight/order_detail.html:30 #: templates/datacenterlight/order_detail.html:30
msgid "Billed To:"
msgstr "Rechnungsadresse"
#: templates/datacenterlight/order_detail.html:39
msgid "Date" msgid "Date"
msgstr "Datum" msgstr "Datum"
#: templates/datacenterlight/order_detail.html:48 #: templates/datacenterlight/order_detail.html:36
msgid "Billed To:"
msgstr "Rechnungsadresse"
#: templates/datacenterlight/order_detail.html:47
msgid "Payment Method:" msgid "Payment Method:"
msgstr "Bezahlmethode" msgstr "Bezahlmethode"
#: templates/datacenterlight/order_detail.html:49 #: templates/datacenterlight/order_detail.html:48
msgid "ending" msgid "ending"
msgstr "endend in" msgstr "endend in"
#: templates/datacenterlight/order_detail.html:59 #: templates/datacenterlight/order_detail.html:58
msgid "Order summary" msgid "Order summary"
msgstr "Bestellungsübersicht" msgstr "Bestellungsübersicht"
#: templates/datacenterlight/order_detail.html:63 #: templates/datacenterlight/order_detail.html:62
msgid "Cores" msgid "Cores"
msgstr "Prozessorkerne" msgstr "Prozessorkerne"
#: templates/datacenterlight/order_detail.html:65 #: templates/datacenterlight/order_detail.html:64
msgid "Memory" msgid "Memory"
msgstr "Arbeitsspeicher" msgstr "Arbeitsspeicher"
#: templates/datacenterlight/order_detail.html:67 #: templates/datacenterlight/order_detail.html:66
msgid "Disk space" msgid "Disk space"
msgstr "Festplattenkapazität" msgstr "Festplattenkapazität"
#: templates/datacenterlight/order_detail.html:69 #: templates/datacenterlight/order_detail.html:68
msgid "Configuration" msgid "Configuration"
msgstr "Konfiguration" msgstr "Konfiguration"
#: templates/datacenterlight/order_detail.html:71 #: templates/datacenterlight/order_detail.html:70
msgid "Total" msgid "Total"
msgstr "" msgstr ""
#: templates/datacenterlight/order_detail.html:78 #: templates/datacenterlight/order_detail.html:77
msgid "Place order" msgid "Place order"
msgstr "Bestellen" msgstr "Bestellen"
@ -372,6 +371,10 @@ msgstr "Bestellen"
msgid "We are cutting down the costs significantly!" msgid "We are cutting down the costs significantly!"
msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen" msgstr "Wir sorgen dafür, dass die Kosten für Dich signifikant abnehmen"
#: templates/datacenterlight/pricing.html:79
msgid "Order Now!"
msgstr "Bestelle jetzt!"
#: templates/datacenterlight/pricing.html:89 #: templates/datacenterlight/pricing.html:89
msgid "" msgid ""
"Our VMs are hosted in Glarus, Switzerland, and our website is currently " "Our VMs are hosted in Glarus, Switzerland, and our website is currently "

View file

@ -0,0 +1,29 @@
from django.core.management.base import BaseCommand
from opennebula_api.models import OpenNebulaManager
from datacenterlight.models import VMTemplate
import logging
logger = logging.getLogger(__name__)
class Command(BaseCommand):
help = 'Fetches the VM templates from OpenNebula and populates the dcl VMTemplate model'
def handle(self, *args, **options):
try:
manager = OpenNebulaManager()
templates = manager.get_templates()
dcl_vm_templates = []
for template in templates:
template_name = template.name.strip('public-')
template_id = template.id
dcl_vm_template = VMTemplate.create(template_name, template_id)
dcl_vm_templates.append(dcl_vm_template)
old_vm_templates = VMTemplate.objects.all()
old_vm_templates.delete()
for dcl_vm_template in dcl_vm_templates:
dcl_vm_template.save()
except Exception as e:
logger.error('Error connecting to OpenNebula. Error Details: {err}'.format(err=str(e)))

View file

@ -9,12 +9,13 @@ class BetaAccessVMType(models.Model):
def __str__(self): def __str__(self):
return "ID: %s - SSD %s - RAM %s - CPU %s - Price %s " % \ return "ID: %s - SSD %s - RAM %s - CPU %s - Price %s " % \
(self.id, str(self.ssd), self.ram, self.cpu, self.price) (self.id, str(self.ssd), self.ram, self.cpu, self.price)
class BetaAccess(models.Model): class BetaAccess(models.Model):
email = models.CharField(max_length=250) email = models.CharField(max_length=250)
name = models.CharField(max_length=250) name = models.CharField(max_length=250)
# vm = models.ForeignKey(BetaAccessVM) # vm = models.ForeignKey(BetaAccessVM)
def __str__(self): def __str__(self):
@ -48,3 +49,13 @@ class BetaAccessVM(models.Model):
amount=vm[VM_AMOUNT], type=vm_type)) amount=vm[VM_AMOUNT], type=vm_type))
return created_vms return created_vms
class VMTemplate(models.Model):
name = models.CharField(max_length=50)
opennebula_vm_template_id = models.IntegerField()
@classmethod
def create(cls, name, opennebula_vm_template_id):
vm_template = cls(name=name, opennebula_vm_template_id=opennebula_vm_template_id)
return vm_template

File diff suppressed because it is too large Load diff

View file

@ -1,22 +1,22 @@
(function($){ (function($) {
"use strict"; // Start of use strict "use strict"; // Start of use strict
/* --------------------------------------------- /* ---------------------------------------------
Scripts initialization Scripts initialization
--------------------------------------------- */ --------------------------------------------- */
var cardPricing ={ var cardPricing = {
'cpu': { 'cpu': {
'id': 'coreValue', 'id': 'coreValue',
'value': 1, 'value': 1,
'min':1, 'min': 1,
'max': 48, 'max': 48,
'interval': 1 'interval': 1
}, },
'ram': { 'ram': {
'id': 'ramValue', 'id': 'ramValue',
'value': 2, 'value': 2,
'min':2, 'min': 2,
'max': 200, 'max': 200,
'interval': 1 'interval': 1
}, },
@ -28,21 +28,21 @@
'interval': 10 'interval': 10
} }
}; };
$(window).load(function(){ $(window).load(function() {
}); });
$(document).ready(function(){ $(document).ready(function() {
verifiedUrl(); verifiedUrl();
_navScroll(); _navScroll();
_initScroll(); _initScroll();
_initNavUrl(); _initNavUrl();
_initPricing(); _initPricing();
}); });
$(window).resize(function(){ $(window).resize(function() {
@ -53,102 +53,112 @@
/* --------------------------------------------- /* ---------------------------------------------
Nav panel classic Nav panel classic
--------------------------------------------- */ --------------------------------------------- */
if (window.matchMedia("(min-width: 767px)").matches) { if (window.matchMedia("(min-width: 767px)").matches) {
$('ul.nav li.dropdown').hover(function() { $('ul.nav li.dropdown').hover(function() {
$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500); $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeIn(500);
}, function() { }, function() {
$(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500); $(this).find('.dropdown-menu').stop(true, true).delay(200).fadeOut(500);
});
} else {
/* the viewport is less than 400 pixels wide */
}
function _initScroll(){
$(window).scroll(function(){
_navScroll();
}); });
} else {
/* the viewport is less than 400 pixels wide */
} }
function _navScroll(){
if($(window).scrollTop() > 10 ){
function _initScroll() {
$(window).scroll(function() {
_navScroll();
});
}
function _navScroll() {
if ($(window).scrollTop() > 10) {
$(".navbar").removeClass("navbar-transparent"); $(".navbar").removeClass("navbar-transparent");
$(".navbar-default .btn-link").css("color", "#777"); $(".navbar-default .btn-link").css("color", "#777");
$(".dropdown-menu").removeClass("navbar-transparent"); $(".dropdown-menu").removeClass("navbar-transparent");
$(".dropdown-menu > li > a").css("color", "#777"); $(".dropdown-menu > li > a").css("color", "#777");
}else{ } else {
$(".navbar").addClass("navbar-transparent"); $(".navbar").addClass("navbar-transparent");
$(".navbar-default .btn-link").css("color", "#fff"); $(".navbar-default .btn-link").css("color", "#fff");
$(".dropdown-menu").addClass("navbar-transparent"); $(".dropdown-menu").addClass("navbar-transparent");
$(".dropdown-menu > li > a").css("color", "#fff"); $(".dropdown-menu > li > a").css("color", "#fff");
} }
} }
function _initNavUrl(){
$('.url').click(function(){ function _initNavUrl() {
var href = $(this).attr('data-url'); $('.url').click(function(event) {
$('.navbar-collapse').removeClass('in'); event.preventDefault();
$('.navbar-collapse').addClass('collapsing'); var href = $(this).attr('data-url');
$('html, body').animate({ $('.navbar-collapse').removeClass('in');
scrollTop: $(href).offset().top $('.navbar-collapse').addClass('collapsing');
}, 1000); var url = window.location.pathname;
var urlSplit = url.split('/');
if (urlSplit.length === 3 && urlSplit[2] === 'datacenterlight') {
$('html, body').animate({
scrollTop: $(href).offset().top
}, 1000);
} else {
var allUrl = window.location.href;
var redirect = allUrl.split('whydatacenterlight')
window.location.href = '/en-us/datacenterlight' + href;
}
}); });
} }
function verifiedUrl(){
if(window.location.href.indexOf('#success') > -1){ function verifiedUrl() {
if (window.location.href.indexOf('#success') > -1) {
form_success(); form_success();
console.log('epa');
} }
} }
function _initPricing(){ function _initPricing() {
_fetchPricing(); _fetchPricing();
$('.fa-minus-circle.left').click(function(event){ $('.fa-minus-circle.left').click(function(event) {
var data = $(this).data('minus'); var data = $(this).data('minus');
if(cardPricing[data].value > cardPricing[data].min){ if (cardPricing[data].value > cardPricing[data].min) {
cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval; cardPricing[data].value = Number(cardPricing[data].value) - cardPricing[data].interval;
} }
_fetchPricing(); _fetchPricing();
}); });
$('.fa-plus-circle.right').click(function(event){ $('.fa-plus-circle.right').click(function(event) {
var data = $(this).data('plus'); var data = $(this).data('plus');
if(cardPricing[data].value < cardPricing[data].max){ if (cardPricing[data].value < cardPricing[data].max) {
cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval; cardPricing[data].value = Number(cardPricing[data].value) + cardPricing[data].interval;
} }
_fetchPricing(); _fetchPricing();
}); });
$('.input-price').change(function(){ $('.input-price').change(function() {
var data = $(this).attr("name"); var data = $(this).attr("name");
cardPricing[data].value = $('input[name='+data+']').val(); cardPricing[data].value = $('input[name=' + data + ']').val();
_fetchPricing(); _fetchPricing();
}); });
} }
function _fetchPricing(){
Object.keys(cardPricing).map(function(element){ function _fetchPricing() {
Object.keys(cardPricing).map(function(element) {
//$('#'+cardPricing[element].id).val(cardPricing[element].value); //$('#'+cardPricing[element].id).val(cardPricing[element].value);
$('input[name='+element+']').val(cardPricing[element].value); $('input[name=' + element + ']').val(cardPricing[element].value);
}); });
_calcPricing(); _calcPricing();
} }
function _calcPricing(){ function _calcPricing() {
var total = (cardPricing['cpu'].value * 5) + (2* cardPricing['ram'].value) + (0.6* cardPricing['storage'].value); var total = (cardPricing['cpu'].value * 5) + (2 * cardPricing['ram'].value) + (0.6 * cardPricing['storage'].value);
total = parseFloat(total.toFixed(2)); total = parseFloat(total.toFixed(2));
$("#total").text(total); $("#total").text(total);
$('input[name=total]').val(total); $('input[name=total]').val(total);
} }
function form_success(){
function form_success() {
$('#sucessModal').modal('show'); $('#sucessModal').modal('show');
} }
function _calculate(numbers, price){
$('#valueTotal').text(numbers*price*31); function _calculate(numbers, price) {
$('#valueTotal').text(numbers * price * 31);
} }
})(jQuery); })(jQuery);

View file

@ -2,7 +2,7 @@
<form id="order_form" method="POST" action="" data-toggle="validator" role="form"> <form id="order_form" method="POST" action="" data-toggle="validator" role="form">
{% csrf_token %} {% csrf_token %}
<div class="title"> <div class="title">
<h3>{% trans "VM hosting" %} </h3> <h3>{% trans "VM hosting" %} </h3>
</div> </div>
<div class="price"> <div class="price">
<span id="total">15</span> <span id="total">15</span>
@ -17,36 +17,63 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="description input"> <div class="description input">
<i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i> <i class="fa fa-minus-circle left" data-minus="cpu" aria-hidden="true"></i>
<input class="input-price select-number" type="number" min="1" max="48" id="coreValue" name="cpu" data-error="{% trans 'Please enter a value in range 1 - 48.' %}" required> <input class="input-price select-number" type="number" min="1" max="48" id="coreValue" name="cpu"
<span> Core</span> data-error="{% trans 'Please enter a value in range 1 - 48.' %}" required>
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i> <span> Core</span>
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i>
</div>
<div class="help-block with-errors">
{% for message in messages %}
{% if 'cores' in message.tags %}
<ul class="list-unstyled"><li>
{{ message|safe }}
</li></ul>
{% endif %}
{% endfor %}
</div> </div>
<div class="help-block with-errors"></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="description input"> <div class="description input">
<i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i> <i class="fa fa-minus-circle left" data-minus="ram" aria-hidden="true"></i>
<input id="ramValue" class="input-price select-number" type="number" min="2" max="200" name="ram" data-error="{% trans 'Please enter a value in range 2 - 200.' %}" required> <input id="ramValue" class="input-price select-number" type="number" min="2" max="200" name="ram"
<span> GB RAM</span> data-error="{% trans 'Please enter a value in range 2 - 200.' %}" required>
<i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i> <span> GB RAM</span>
<i class="fa fa-plus-circle right" data-plus="ram" aria-hidden="true"></i>
</div>
<div class="help-block with-errors">
{% for message in messages %}
{% if 'memory' in message.tags %}
<ul class="list-unstyled"><li>
{{ message|safe }}
</li></ul>
{% endif %}
{% endfor %}
</div> </div>
<div class="help-block with-errors"></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="description input"> <div class="description input">
<i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i> <i class="fa fa-minus-circle left" data-minus="storage" aria-hidden="true"></i>
<input id="storageValue" class="input-price select-number" type="number" min="10" max="2000" step="10" name="storage" data-error="{% trans 'Please enter a value in range 10 - 2000.' %}" required> <input id="storageValue" class="input-price select-number" type="number" min="10" max="2000" step="10"
<span>{% trans "GB Storage (SSD)" %}</span> name="storage" data-error="{% trans 'Please enter a value in range 10 - 2000.' %}" required>
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i> <span>{% trans "GB Storage (SSD)" %}</span>
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i>
</div>
<div class="help-block with-errors">
{% for message in messages %}
{% if 'storage' in message.tags %}
<ul class="list-unstyled"><li>
{{ message|safe }}
</li></ul>
{% endif %}
{% endfor %}
</div> </div>
<div class="help-block with-errors"></div>
</div> </div>
<div class="description select-configuration input form-group justify-center"> <div class="description select-configuration input form-group justify-center">
<label for="config">OS</label> <label for="config">OS</label>
<select name="config" id=""> <select name="config" id="">
{% for template in templates %} {% for template in templates %}
<option value="{{template.id}}">{{template.name}} </option> <option value="{{template.opennebula_vm_template_id}}">{{template.name}}</option>
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
@ -56,34 +83,41 @@
</div>--> </div>-->
<div class="form-group"> <div class="form-group">
<div class="description input justify-center"> <div class="description input justify-center">
<label for="name" class="control-label">{% trans "Name"%}</label> <label for="name" class="control-label">{% trans "Name"%}</label>
<input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}" data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required> <input type="text" name="name" class="form-control" placeholder="{% trans 'Your Name'%}"
data-minlength="3" data-error="{% trans 'Please enter your name.' %}" required>
</div> </div>
<div class="help-block with-errors"> <div class="help-block with-errors">
{% for message in messages %} {% for message in messages %}
{% if 'name' in message.tags %} {% if 'name' in message.tags %}
<ul class="list-unstyled"><li> <ul class="list-unstyled">
<li>
{{ message|safe }} {{ message|safe }}
</li></ul> </li>
{% endif %} </ul>
{% endif %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="description input justify-center"> <div class="description input justify-center">
<label for="email" class="control-label">{% trans "Email"%}</label> <label for="email" class="control-label">{% trans "Email"%}</label>
<input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control" placeholder="{% trans 'Your Email' %}" data-error="{% trans 'Please enter a valid email address.' %}" required> <input name="email" type="email" pattern="^[^@\s]+@([^@\s]+\.)+[^@\s]+$" class="form-control"
placeholder="{% trans 'Your Email' %}"
data-error="{% trans 'Please enter a valid email address.' %}" required>
</div> </div>
<div class="help-block with-errors"> <div class="help-block with-errors">
{% for message in messages %} {% for message in messages %}
{% if 'email' in message.tags %} {% if 'email' in message.tags %}
<ul class="list-unstyled"><li> <ul class="list-unstyled">
<li>
{{ message|safe }} {{ message|safe }}
</li></ul> </li>
{% endif %} </ul>
{% endif %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div> </div>
<input type="submit" class="btn btn-primary disabled" value="{% trans 'Order Now!' %}"></input> <input type="submit" class="btn btn-primary disabled" value="{% trans 'Continue' %}"></input>
</form> </form>

View file

@ -12,28 +12,28 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
{% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %}
<a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav url" data-url="#home"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav url" data-url="#home"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav" data-url="#home"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
{% else %} {% else %}
<a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav url"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> <a href="{% url 'datacenterlight:index' %}" id="logoBlack" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav url"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a> <a href="{% url 'datacenterlight:index' %}" id="logoWhite" class="navbar-brand topnav"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
{% endif %} {% endif %}
</div> </div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><!-- Start Navbar collapse--> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><!-- Start Navbar collapse-->
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
{% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %} {% if request.resolver_match.url_name == "index" or request.resolver_match.url_name == "whydatacenterlight" %}
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> <a class="dropdown-toggle visible-mobile" href="#" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a>
<a class="dropdown-toggle url disabled visible-desktop" href="{% url 'datacenterlight:index' %}#how" data-url="#how" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a> <a class="dropdown-toggle url disabled visible-desktop menu-url" data-url="#how" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% trans "Highlights" %}<span class="caret"></span></a>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li><a class="url" href="{% url 'datacenterlight:index' %}#your" data-url="#your" >{% trans "Scale out" %}</a></li> <li><a class="url menu-url" data-url="#your" href="#your">{% trans "Scale out" %}</a></li>
<li><a class="url" href="{% url 'datacenterlight:index' %}#our" data-url="#our">{% trans "Reliable and light" %}</a></li> <li><a class="url menu-url" data-url="#our" href="#our">{% trans "Reliable and light" %}</a></li>
<li> <a class="url" href="{% url 'datacenterlight:index' %}#price" data-url="#price" >{% trans "Order VM" %}</a></li> <li> <a class="url menu-url" data-url="#price" href="#price">{% trans "Order VM" %}</a></li>
</ul> </ul>
</li> </li>
<li> <li>
<a class="url" href="{% url 'datacenterlight:index' %}/whydatacenterlight" >{% trans "Why Data Center Light?" %}</a> <a href="{% url 'datacenterlight:index' %}/whydatacenterlight" >{% trans "Why Data Center Light?" %}</a>
</li> </li>
<li> <li>
<a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact" >{% trans "Contact" %}</a> <a class="url" href="{% url 'datacenterlight:index' %}#contact" data-url="#contact" >{% trans "Contact" %}</a>
@ -41,18 +41,19 @@
{% endif %} {% endif %}
<li class="nav-language"> <li class="nav-language">
<div class="select-language"> <div class="select-language">
{% if LANGUAGE_CODE == 'en-us'%} {% if LANGUAGE_CODE == 'en-us'%}
<span>English</span> <span>English</span>
{% else %} {% else %}
<span>Deutsch</span> <span>Deutsch</span>
{% endif %} {% endif %}
<i class="fa fa-globe" aria-hidden="true"></i> <i class="fa fa-globe" aria-hidden="true"></i>
</div> </div>
<div onclick="return true" class="drop-language">
{% if LANGUAGE_CODE == 'en-us'%} <div class="drop-language">
<a class="url" href="{% change_lang 'de' %}">Deutsch</a> {% if LANGUAGE_CODE == 'en-us'%}
<a href="{% change_lang 'de' %}">Deutsch</a>
{% else %} {% else %}
<a class="url" href="{% change_lang 'en-us' %}" >English</a> <a href="{% change_lang 'en-us' %}" >English</a>
{% endif %} {% endif %}
</div> </div>

View file

@ -9,7 +9,7 @@
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="intro-message"> <div class="intro-message">
<h1>Data Center Light</h1> <h1>Data Center Light</h1>
<h3>{% trans "Finally, an affordable VM hosting in Switzerland!" %}</h3> <h3>{% trans "Finally, an affordable VM hosting in Switzerland!" %}</h3>
@ -59,13 +59,13 @@
<li> <li>
<i class="fa-li fa fa-check-square-o fa-lg"></i> <i class="fa-li fa fa-check-square-o fa-lg"></i>
<p class="lead">{% trans "Is creative, using a modern and alternative design for a data center in order to make it more sustainable and affordable at the same time." %}</p> <p class="lead">{% trans "Is creative, using a modern and alternative design for a data center in order to make it more sustainable and affordable at the same time." %}</p>
</li> </li>
<li> <li>
<i class="fa-li fa fa-check-square-o fa-lg"></i> <i class="fa-li fa fa-check-square-o fa-lg"></i>
<p class="lead">{% trans "Cuts down the costs for you by using FOSS (Free Open Source Software) exclusively, wherefore we can save money from paying licenses." %}</p> <p class="lead">{% trans "Cuts down the costs for you by using FOSS (Free Open Source Software) exclusively, wherefore we can save money from paying licenses." %}</p>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
@ -86,7 +86,7 @@
</div> </div>
<div class="split-description"> <div class="split-description">
<p class="lead">{% trans "We don't use special hardware. We use commodity hardware: we buy computers that you buy. Just many more and put them in a cozy home for computers called data center." %}</p> <p class="lead">{% trans "We don't use special hardware. We use commodity hardware: we buy computers that you buy. Just many more and put them in a cozy home for computers called data center." %}</p>
</div> </div>
</div> </div>
</div> </div>
@ -112,7 +112,7 @@
</div> </div>
<div class="split-description"> <div class="split-description">
<p class="lead">{% trans "Our VMs are located in Switzerland, with reliable power supply and fast internet connection. Our VM costs less thanks to our featherlight infrastructure." %}</p> <p class="lead">{% trans "Our VMs are located in Switzerland, with reliable power supply and fast internet connection. Our VM costs less thanks to our featherlight infrastructure." %}</p>
</div> </div>
</div> </div>
</div> </div>
@ -121,7 +121,7 @@
<!-- /.container --> <!-- /.container -->
<!-- /.option 1 --> <!-- /.option 1 -->
</div> </div>
<!-- /.content-section-b --> <!-- /.content-section-b -->
<div class="content-section-a pricing-section" id="price"> <div class="content-section-a pricing-section" id="price">
@ -154,7 +154,7 @@
<div class="intro-header-2 contact-section" id="contact"> <div class="intro-header-2 contact-section" id="contact">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-6 col-md-6"> <div class="col-sm-6 col-md-6">
<div class="card"> <div class="card">
<div class="subtitle"> <div class="subtitle">
@ -166,15 +166,9 @@
<p>{% trans "Switzerland " %}</p> <p>{% trans "Switzerland " %}</p>
</div> </div>
<div class="social"> <div class="social">
<a target="_blank" class="" href="https://twitter.com/datacenterlight"> <a target="_blank" class="" href="https://twitter.com/datacenterlight"><i class="fa fa-twitter fa-fw"></i></a>
<i class="fa fa-twitter fa-fw"></i> <a target="_blank" class="" href="https://github.com/ungleich"><i class="fa fa-github fa-fw"></i></a>
</a> <a target="_blank" class="" href="https://www.facebook.com/ungleich.ch/"><i class="fa fa-facebook fa-fw"></i></a>
<a target="_blank" class="" href="https://github.com/ungleich">
<i class="fa fa-github fa-fw"></i>
</a>
<a target="_blank" class="" href="https://www.facebook.com/ungleich.ch/">
<i class="fa fa-facebook fa-fw"></i>
</a>
</div> </div>
</div> </div>
</div> </div>
@ -187,7 +181,7 @@
</div> </div>
</div> </div>
</div> </div>
<!-- /.banner --> <!-- /.banner -->
{% endblock %} {% endblock %}

View file

@ -1,7 +1,7 @@
from django.views.generic import FormView, CreateView, TemplateView, DetailView from django.views.generic import FormView, CreateView, TemplateView, DetailView
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from .forms import BetaAccessForm from .forms import BetaAccessForm
from .models import BetaAccess, BetaAccessVMType, BetaAccessVM from .models import BetaAccess, BetaAccessVMType, BetaAccessVM, VMTemplate
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
@ -21,7 +21,7 @@ from datetime import datetime
from membership.models import CustomUser, StripeCustomer from membership.models import CustomUser, StripeCustomer
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer from opennebula_api.serializers import VirtualMachineTemplateSerializer, VirtualMachineSerializer, VMTemplateSerializer
class LandingProgramView(TemplateView): class LandingProgramView(TemplateView):
@ -194,41 +194,68 @@ class IndexView(CreateView):
success_url = "/datacenterlight#requestform" success_url = "/datacenterlight#requestform"
success_message = "Thank you, we will contact you as soon as possible" success_message = "Thank you, we will contact you as soon as possible"
def validate_cores(self, value):
if (value > 48) or (value < 1):
raise ValidationError(_('Not a proper cores number'))
def validate_memory(self, value):
if (value > 200) or (value < 2):
raise ValidationError(_('Not a proper ram number'))
def validate_storage(self, value):
if (value > 2000) or (value < 10):
raise ValidationError(_('Not a proper storage number'))
@cache_control(no_cache=True, must_revalidate=True, no_store=True) @cache_control(no_cache=True, must_revalidate=True, no_store=True)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
for session_var in ['specs', 'user', 'billing_address_data']: for session_var in ['specs', 'user', 'billing_address_data']:
if session_var in request.session: if session_var in request.session:
del request.session[session_var] del request.session[session_var]
try:
manager = OpenNebulaManager() vm_templates = VMTemplate.objects.all()
templates = manager.get_templates() context = {
context = { 'templates': vm_templates
'templates': VirtualMachineTemplateSerializer(templates, many=True).data }
}
except:
messages.error(request,
'We have a temporary problem to connect to our backend. \
Please try again in a few minutes'
)
context = {
'error': 'connection'
}
return render(request, self.template_name, context) return render(request, self.template_name, context)
def post(self, request): def post(self, request):
cores = request.POST.get('cpu') cores = request.POST.get('cpu')
cores_field = forms.IntegerField(validators=[self.validate_cores])
memory = request.POST.get('ram') memory = request.POST.get('ram')
memory_field = forms.IntegerField(validators=[self.validate_memory])
storage = request.POST.get('storage') storage = request.POST.get('storage')
storage_field = forms.IntegerField(validators=[self.validate_storage])
price = request.POST.get('total') price = request.POST.get('total')
template_id = int(request.POST.get('config')) template_id = int(request.POST.get('config'))
manager = OpenNebulaManager() template = VMTemplate.objects.filter(opennebula_vm_template_id=template_id).first()
template = manager.get_template(template_id) template_data = VMTemplateSerializer(template).data
template_data = VirtualMachineTemplateSerializer(template).data
name = request.POST.get('name') name = request.POST.get('name')
email = request.POST.get('email') email = request.POST.get('email')
name_field = forms.CharField() name_field = forms.CharField()
email_field = forms.EmailField() email_field = forms.EmailField()
try:
cores = cores_field.clean(cores)
except ValidationError as err:
msg = '{} : {}.'.format(cores, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='cores')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try:
memory = memory_field.clean(memory)
except ValidationError as err:
msg = '{} : {}.'.format(memory, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='memory')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try:
storage = storage_field.clean(storage)
except ValidationError as err:
msg = '{} : {}.'.format(storage, str(err))
messages.add_message(self.request, messages.ERROR, msg, extra_tags='storage')
return HttpResponseRedirect(reverse('datacenterlight:index') + "#order_form")
try: try:
name = name_field.clean(name) name = name_field.clean(name)
except ValidationError as err: except ValidationError as err:
@ -313,25 +340,6 @@ class WhyDataCenterLightView(IndexView):
template_name = "datacenterlight/whydatacenterlight.html" template_name = "datacenterlight/whydatacenterlight.html"
model = BetaAccess model = BetaAccess
@cache_control(no_cache=True, must_revalidate=True, no_store=True)
def get(self, request, *args, **kwargs):
try:
manager = OpenNebulaManager()
templates = manager.get_templates()
context = {
'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
}
except:
messages.error(
request,
'We have a temporary problem to connect to our backend. \
Please try again in a few minutes'
)
context = {
'error': 'connection'
}
return render(request, self.template_name, context)
class PaymentOrderView(FormView): class PaymentOrderView(FormView):
template_name = 'hosting/payment.html' template_name = 'hosting/payment.html'
@ -462,9 +470,9 @@ class OrderConfirmationView(DetailView):
template_id=vm_template_id, template_id=vm_template_id,
specs=specs, specs=specs,
vm_name="{email}-{template_name}-{date}".format( vm_name="{email}-{template_name}-{date}".format(
email=user.get('email'), email=user.get('email'),
template_name=template.get('name'), template_name=template.get('name'),
date=int(datetime.now().strftime("%s"))) date=int(datetime.now().strftime("%s")))
) )
# Create a Hosting Order # Create a Hosting Order

View file

@ -39,6 +39,30 @@ h6 {
font-size: 14px; font-size: 14px;
} }
.navbar-transparent {
background: transparent;
border: none;
padding: 20px;
}
.navbar-transparent .navbar-nav>li>a {
color: #fff;
cursor: pointer;
font-family: 'Lato-Regular', sans-serif;
}
.navbar-transparent .navbar-nav>li>a:hover {
color: #fff;
}
.navbar-transparent .navbar-nav>li>a:focus, .navbar-transparent .navbar-nav>li>a:hover {
color: #fff;
background-color: transparent;
}
.navbar-transparent #logoWhite{
display: block;
width: 220px;
}
.lead { .lead {
font-size: 18px; font-size: 18px;
font-weight: 400; font-weight: 400;
@ -634,11 +658,11 @@ a.unlink:hover {
.card-cvc-element { .card-cvc-element {
padding-left: 10px; padding-left: 10px;
} }
.hide-mobile{ .hide-mobile{
display:none; display:none;
} }
#billing-form .form-control { #billing-form .form-control {
box-shadow: none !important; box-shadow: none !important;
font-weight: 400; font-weight: 400;

View file

@ -48,24 +48,26 @@
<body> <body>
<!-- Navigation --> {% block navbar %}
<nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation"> <!-- Navigation -->
<div class="container topnav">
<!-- Brand and toggle get grouped for better mobile display --> <nav class="navbar navbar-default navbar-fixed-top topnav" role="navigation">
<div class="navbar-header"> <div class="container topnav">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <!-- Brand and toggle get grouped for better mobile display -->
<span class="sr-only">Toggle navigation</span> <div class="navbar-header">
<span class="icon-bar"></span> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="icon-bar"></span> <span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> <span class="icon-bar"></span>
<a class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a> <span class="icon-bar"></span>
</div> </button>
{% if request.user.is_authenticated %} <a class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_black.svg' %}"></a>
<!-- Collect the nav links, forms, and other content for toggling --> </div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> {% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right"> <!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li> <li>
<a href="{% url 'hosting:virtual_machines' %}"> <a href="{% url 'hosting:virtual_machines' %}">
<i class="fa fa-server" aria-hidden="true"></i> {% trans "My Virtual Machines"%} <i class="fa fa-server" aria-hidden="true"></i> {% trans "My Virtual Machines"%}
@ -93,33 +95,14 @@
<li><a href="{% url 'hosting:logout' %}"><i class="glyphicon glyphicon-lock"></i>{% trans "Logout"%} </a></li> <li><a href="{% url 'hosting:logout' %}"><i class="glyphicon glyphicon-lock"></i>{% trans "Logout"%} </a></li>
</ul> </ul>
</li> </li>
<!-- </ul>
<li> </div>
<a href="{{ request.session.hosting_url}}#how">{% trans "How it works"%}</a> {% endif %}
</li> <!-- /.navbar-collapse -->
<li>
<a href="{{ request.session.hosting_url }}#your">{% trans "Your infrastructure"%}</a>
</li>
<li>
<a href="{{ request.session.hosting_url }}#our">{% trans "Our inftrastructure"%}</a>
</li>
<li>
<a href="{{ request.session.hosting_url }}#price">{% trans "Pricing" %}</a>
</li>
<li>
<a href="{{ request.session.hosting_url }}#contact">{% trans "Contact"%}</a>
</li>
<li>
<a href="{% url 'hosting:login' %}?next={{request.current_path}}">{% trans "Login"%}</a>
</li> -->
</ul>
</div> </div>
{% endif %} <!-- /.container -->
<!-- /.navbar-collapse --> </nav>
</div> {% endblock navbar %}
<!-- /.container -->
</nav>
<div class="content-dashboard"> <div class="content-dashboard">

View file

@ -0,0 +1,11 @@
{% load static i18n %}
<nav class="navbar navbar-default navbar-fixed-top topnav navbar-transparent" role="navigation">
<div class="container topnav">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a id="logoWhite" class="navbar-brand topnav" href="{% if site_url %}{{site_url}}{% else %}{{ request.session.hosting_url}}{% endif %}"><img src="{% static 'datacenterlight/img/logo_white.svg' %}"></a>
</div>
</div>
<!-- /.container -->
</nav>

View file

@ -1,18 +1,23 @@
{% extends "hosting/base_short.html" %} {% extends "hosting/base_short.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles bootstrap3%} {% load staticfiles bootstrap3%}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %} {% block content %}
<div class="auth-container"> <div class="auth-container">
<div class="auth-bg"></div> <div class="auth-bg"></div>
<div class="auth-center"> <div class="auth-center">
<div class="auth-title"> <div class="auth-title">
<h2>{% trans "Your VM hosted in Switzerland"%}</h2> <h2>{% trans "Your VM hosted in Switzerland"%}</h2>
</div> </div>
<div class="auth-content"> <div class="auth-content">
<div class="intro-message auth-box"> <div class="intro-message auth-box">
<h2 class="section-heading">{% trans "Login"%}</h2> <h2 class="section-heading">{% trans "Login"%}</h2>
<form action="{% url 'hosting:login' %}" method="post" class="form" novalidated> <form action="{% url 'hosting:login' %}" method="post" class="form" novalidated>
@ -26,8 +31,8 @@
{% trans "Login"%} {% trans "Login"%}
</button> </button>
{% endbuttons %} {% endbuttons %}
<input type='hidden' name='next' value='{{request.GET.next}}'/> <input type='hidden' name='next' value='{{request.GET.next}}'/>
</form> </form>
<div class="auth-footer"> <div class="auth-footer">
<div class="text"> <div class="text">

View file

@ -2,6 +2,11 @@
{% load staticfiles bootstrap3%} {% load staticfiles bootstrap3%}
{% load i18n %} {% load i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %} {% block content %}
<div class="auth-container"> <div class="auth-container">
<div class="auth-bg"></div> <div class="auth-bg"></div>
@ -10,7 +15,7 @@
<h2>{% trans "Your VM hosted in Switzerland"%}</h2> <h2>{% trans "Your VM hosted in Switzerland"%}</h2>
</div> </div>
<div class="auth-content"> <div class="auth-content">
<div class="intro-message auth-box sign-up"> <div class="intro-message auth-box sign-up">
<h2 class="section-heading">{% trans "Reset your password"%}</h2> <h2 class="section-heading">{% trans "Reset your password"%}</h2>
<form action="{% url 'hosting:reset_password' %}" method="post" class="form" novalidate> <form action="{% url 'hosting:reset_password' %}" method="post" class="form" novalidate>

View file

@ -1,6 +1,10 @@
{% extends "hosting/base_short.html" %} {% extends "hosting/base_short.html" %}
{% load staticfiles bootstrap3 i18n %} {% load staticfiles bootstrap3 i18n %}
{% block navbar %}
{% include 'hosting/includes/_navbar_transparent.html' %}
{% endblock navbar %}
{% block content %} {% block content %}
<div class="auth-container auth-signup"> <div class="auth-container auth-signup">
<div class="auth-bg"></div> <div class="auth-bg"></div>
@ -32,7 +36,7 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -59,7 +59,7 @@ class OpenNebulaManager():
domain=settings.OPENNEBULA_DOMAIN, domain=settings.OPENNEBULA_DOMAIN,
port=settings.OPENNEBULA_PORT, port=settings.OPENNEBULA_PORT,
endpoint=settings.OPENNEBULA_ENDPOINT endpoint=settings.OPENNEBULA_ENDPOINT
)) ))
def _get_opennebula_client(self, username, password): def _get_opennebula_client(self, username, password):
return oca.Client("{0}:{1}".format( return oca.Client("{0}:{1}".format(
@ -71,7 +71,7 @@ class OpenNebulaManager():
domain=settings.OPENNEBULA_DOMAIN, domain=settings.OPENNEBULA_DOMAIN,
port=settings.OPENNEBULA_PORT, port=settings.OPENNEBULA_PORT,
endpoint=settings.OPENNEBULA_ENDPOINT endpoint=settings.OPENNEBULA_ENDPOINT
)) ))
def _get_user(self, user): def _get_user(self, user):
"""Get the corresponding opennebula user for a CustomUser object """Get the corresponding opennebula user for a CustomUser object
@ -325,7 +325,7 @@ class OpenNebulaManager():
public_templates = [ public_templates = [
template template
for template in self._get_template_pool() for template in self._get_template_pool()
if 'public-' in template.name if template.name.startswith('public-')
] ]
return public_templates return public_templates
except ConnectionRefusedError: except ConnectionRefusedError:
@ -396,7 +396,7 @@ class OpenNebulaManager():
def delete_template(self, template_id): def delete_template(self, template_id):
self.oneadmin_client.call(oca.VmTemplate.METHODS[ self.oneadmin_client.call(oca.VmTemplate.METHODS[
'delete'], template_id, False) 'delete'], template_id, False)
def change_user_password(self, new_password): def change_user_password(self, new_password):
self.oneadmin_client.call( self.oneadmin_client.call(

View file

@ -129,6 +129,12 @@ class VirtualMachineSerializer(serializers.Serializer):
return obj.name.strip('public-') return obj.name.strip('public-')
class VMTemplateSerializer(serializers.Serializer):
"""Serializer to map the VMTemplate instance into JSON format."""
id = serializers.IntegerField(read_only=True, source='opennebula_vm_template_id')
name = serializers.CharField(read_only=True)
def hexstr2int(string): def hexstr2int(string):
return int(string.replace(':', ''), 16) return int(string.replace(':', ''), 16)