Merge branch 'develop' of https://github.com/ungleich/dynamicweb/
This commit is contained in:
commit
1ff411e426
9 changed files with 228 additions and 135 deletions
Binary file not shown.
|
@ -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-05-20 11:12-0500\n"
|
"POT-Creation-Date: 2017-05-23 17:26-0500\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"
|
||||||
|
@ -18,6 +18,20 @@ msgstr ""
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/beta_access.html:21
|
||||||
|
msgid "Request Beta Access"
|
||||||
|
msgstr "Beantrage Beta-Zugang"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/beta_success.html:9
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Request Beta Access"
|
||||||
|
msgid "Request Sent"
|
||||||
|
msgstr "Anfrage verschickt"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/beta_success.html:12
|
||||||
|
msgid "Thank you, we will contact you as soon as possible"
|
||||||
|
msgstr "Vielen Dank, wir werden Sie sobald als möglich kontaktieren."
|
||||||
|
|
||||||
#: 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
|
||||||
msgid "Thank you for your request."
|
msgid "Thank you for your request."
|
||||||
|
@ -52,27 +66,35 @@ msgid "Thank you!"
|
||||||
msgstr "Vielen Dank!"
|
msgstr "Vielen Dank!"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:62
|
#: templates/datacenterlight/index.html:62
|
||||||
|
#: templates/datacenterlight/pricing.html:62
|
||||||
msgid "What is it"
|
msgid "What is it"
|
||||||
msgstr "Was ist es?"
|
msgstr "Was ist es?"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:65
|
#: templates/datacenterlight/index.html:65
|
||||||
#: templates/datacenterlight/index.html:171
|
#: templates/datacenterlight/index.html:171
|
||||||
#: templates/datacenterlight/index.html:362
|
#: templates/datacenterlight/index.html:331
|
||||||
|
#: templates/datacenterlight/pricing.html:65
|
||||||
|
#: templates/datacenterlight/pricing.html:188
|
||||||
msgid "Scale out"
|
msgid "Scale out"
|
||||||
msgstr "Skalierung"
|
msgstr "Skalierung"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:68
|
#: templates/datacenterlight/index.html:68
|
||||||
#: templates/datacenterlight/index.html:197
|
#: templates/datacenterlight/index.html:197
|
||||||
#: templates/datacenterlight/index.html:365
|
#: templates/datacenterlight/index.html:334
|
||||||
|
#: templates/datacenterlight/pricing.html:68
|
||||||
|
#: templates/datacenterlight/pricing.html:191
|
||||||
msgid "Reliable and light"
|
msgid "Reliable and light"
|
||||||
msgstr "Zuverlässig und leicht"
|
msgstr "Zuverlässig und leicht"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:71
|
#: templates/datacenterlight/index.html:71
|
||||||
|
#: templates/datacenterlight/pricing.html:71
|
||||||
msgid "Buy VM"
|
msgid "Buy VM"
|
||||||
msgstr "VM Kaufen"
|
msgstr "VM Kaufen"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:74
|
#: templates/datacenterlight/index.html:74
|
||||||
#: templates/datacenterlight/index.html:372
|
#: templates/datacenterlight/index.html:341
|
||||||
|
#: templates/datacenterlight/pricing.html:74
|
||||||
|
#: templates/datacenterlight/pricing.html:198
|
||||||
msgid "Contact"
|
msgid "Contact"
|
||||||
msgstr "Kontakt"
|
msgstr "Kontakt"
|
||||||
|
|
||||||
|
@ -89,7 +111,8 @@ msgid "I want it!"
|
||||||
msgstr "Das will ich haben!"
|
msgstr "Das will ich haben!"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:142
|
#: templates/datacenterlight/index.html:142
|
||||||
#: templates/datacenterlight/index.html:359
|
#: templates/datacenterlight/index.html:328
|
||||||
|
#: templates/datacenterlight/pricing.html:185
|
||||||
msgid "How it works"
|
msgid "How it works"
|
||||||
msgstr "Wie es funktioniert"
|
msgstr "Wie es funktioniert"
|
||||||
|
|
||||||
|
@ -132,6 +155,7 @@ msgstr ""
|
||||||
"Angebot ist aufgrund unserer leichten Infrastruktur überaus kostengünstig."
|
"Angebot ist aufgrund unserer leichten Infrastruktur überaus kostengünstig."
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:218
|
#: templates/datacenterlight/index.html:218
|
||||||
|
#: templates/datacenterlight/pricing.html:101
|
||||||
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 Sie signifikant abnehmen"
|
msgstr "Wir sorgen dafür, dass die Kosten für Sie signifikant abnehmen"
|
||||||
|
|
||||||
|
@ -143,60 +167,70 @@ msgstr "Bezahlbares VM Hosting in der Schweiz"
|
||||||
msgid "More Info"
|
msgid "More Info"
|
||||||
msgstr "Weitere Informationen"
|
msgstr "Weitere Informationen"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:226
|
#: templates/datacenterlight/index.html:227
|
||||||
|
#: templates/datacenterlight/pricing.html:114
|
||||||
msgid "VM hosting"
|
msgid "VM hosting"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:233
|
#: templates/datacenterlight/index.html:234
|
||||||
msgid "Based in Switzerland"
|
msgid "Based in Switzerland"
|
||||||
msgstr "Standort des Datacenters ist in der Schweiz"
|
msgstr "Standort des Datacenters ist in der Schweiz"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:242
|
#: templates/datacenterlight/index.html:243
|
||||||
msgid "15 GiB storage(SSD)"
|
msgid "15 GB Storage (SSD)"
|
||||||
msgstr ""
|
msgstr "15 GB Storage (SSD)"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:245
|
#: templates/datacenterlight/index.html:246
|
||||||
msgid "Buy Now!"
|
#: templates/datacenterlight/pricing.html:156
|
||||||
msgstr "Kaufe jetzt!"
|
msgid "Order Now!"
|
||||||
|
msgstr "Bestelle jetzt!"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:259
|
#: templates/datacenterlight/index.html:262
|
||||||
msgid "I want to try!"
|
msgid "Want to know more? Subscribe to our newsletter!"
|
||||||
msgstr "Das möchte ich haben"
|
msgstr "Willst du mehr wissen? Abonniere unseren Newsletter!"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:281
|
|
||||||
msgid "Request Beta Access"
|
|
||||||
msgstr "Beantrage Beta-Zugang"
|
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:289
|
#: templates/datacenterlight/index.html:289
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Request Beta Access"
|
|
||||||
msgid "Request Sent"
|
|
||||||
msgstr "Anfrage verschickt"
|
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:292
|
|
||||||
msgid "Thank you, we will contact you as soon as possible"
|
|
||||||
msgstr "Vielen Dank, wir werden Sie sobald als möglich kontaktieren."
|
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:320
|
|
||||||
msgid "Switzerland "
|
msgid "Switzerland "
|
||||||
msgstr "Schweiz"
|
msgstr "Schweiz"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:337
|
#: templates/datacenterlight/index.html:306
|
||||||
msgid "Questions?"
|
msgid "Questions?"
|
||||||
msgstr "Fragen?"
|
msgstr "Fragen?"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:337
|
#: templates/datacenterlight/index.html:306
|
||||||
msgid "Contact us!"
|
msgid "Contact us!"
|
||||||
msgstr "Kontaktiere uns!"
|
msgstr "Kontaktiere uns!"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:355
|
#: templates/datacenterlight/index.html:324
|
||||||
|
#: templates/datacenterlight/pricing.html:181
|
||||||
msgid "Home"
|
msgid "Home"
|
||||||
msgstr "Home"
|
msgstr "Home"
|
||||||
|
|
||||||
#: templates/datacenterlight/index.html:368
|
#: templates/datacenterlight/index.html:337
|
||||||
|
#: templates/datacenterlight/pricing.html:194
|
||||||
msgid "Pricing"
|
msgid "Pricing"
|
||||||
msgstr "Preise"
|
msgstr "Preise"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/pricing.html:122
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Based in Switzerland"
|
||||||
|
msgid "Hosted in Switzerland"
|
||||||
|
msgstr "Standort des Datacenters ist in der Schweiz"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/pricing.html:136
|
||||||
|
msgid "GB Storage (SSD)"
|
||||||
|
msgstr "GB Storage (SSD)"
|
||||||
|
|
||||||
|
#: templates/datacenterlight/pricing.html:163
|
||||||
|
msgid "Simple and affordable: Try our virtual machine with featherlight price."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#~ msgid "Buy Now!"
|
||||||
|
#~ msgstr "Kaufe jetzt!"
|
||||||
|
|
||||||
|
#~ msgid "I want to try!"
|
||||||
|
#~ msgstr "Das möchte ich haben"
|
||||||
|
|
||||||
#~ msgid "How it works:"
|
#~ msgid "How it works:"
|
||||||
#~ msgstr "Warum können wir diese Leistung so günstig anbieten:"
|
#~ msgstr "Warum können wir diese Leistung so günstig anbieten:"
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,6 @@ h6 {
|
||||||
}
|
}
|
||||||
.navbar-transparent .navbar-nav>li>a {
|
.navbar-transparent .navbar-nav>li>a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 17px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.navbar-transparent .navbar-nav>li>a:hover {
|
.navbar-transparent .navbar-nav>li>a:hover {
|
||||||
|
@ -139,6 +138,12 @@ h6 {
|
||||||
.navbar-right {
|
.navbar-right {
|
||||||
margin-right: 0px;
|
margin-right: 0px;
|
||||||
}
|
}
|
||||||
|
.navbar-default .btn-link {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.navbar-default .btn-link:hover {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
.intro-header {
|
.intro-header {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -344,6 +349,13 @@ h6 {
|
||||||
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
|
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
|
||||||
padding-bottom: 40px;
|
padding-bottom: 40px;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.pricing-section .card .img-beta{
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
width: 60px;
|
||||||
|
left: 3px;
|
||||||
}
|
}
|
||||||
.pricing-section .card .title{
|
.pricing-section .card .title{
|
||||||
padding: 15px 40px;
|
padding: 15px 40px;
|
||||||
|
@ -403,7 +415,7 @@ h6 {
|
||||||
}
|
}
|
||||||
.request-section .title h2{
|
.request-section .title h2{
|
||||||
font-family: 'Montserrat-Bold';
|
font-family: 'Montserrat-Bold';
|
||||||
font-size: 65px;
|
font-size: 45px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding-bottom: 25px;
|
padding-bottom: 25px;
|
||||||
|
@ -551,6 +563,13 @@ h6 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* margin-right: auto; */
|
/* margin-right: auto; */
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.price-calc-section .card .img-beta{
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
width: 60px;
|
||||||
|
left: 3px;
|
||||||
}
|
}
|
||||||
.price-calc-section .card .title{
|
.price-calc-section .card .title{
|
||||||
padding: 15px 40px;
|
padding: 15px 40px;
|
||||||
|
|
|
@ -9,17 +9,23 @@
|
||||||
'cpu': {
|
'cpu': {
|
||||||
'id': 'coreValue',
|
'id': 'coreValue',
|
||||||
'value': 1,
|
'value': 1,
|
||||||
'limit': 48
|
'min':1,
|
||||||
|
'max': 48,
|
||||||
|
'interval': 1
|
||||||
},
|
},
|
||||||
'ram': {
|
'ram': {
|
||||||
'id': 'ramValue',
|
'id': 'ramValue',
|
||||||
'value': 1,
|
'value': 1,
|
||||||
'limit': 200
|
'min':1,
|
||||||
|
'max': 200,
|
||||||
|
'interval': 1
|
||||||
},
|
},
|
||||||
'storage': {
|
'storage': {
|
||||||
'id': 'storageValue',
|
'id': 'storageValue',
|
||||||
'value': 1,
|
'value': 10,
|
||||||
'limit': 500
|
'min': 10,
|
||||||
|
'max': 500,
|
||||||
|
'interval': 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(window).load(function(){
|
$(window).load(function(){
|
||||||
|
@ -87,15 +93,15 @@
|
||||||
$('.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 > 1){
|
if(cardPricing[data].value > cardPricing[data].min){
|
||||||
cardPricing[data].value --;
|
cardPricing[data].value --;
|
||||||
}
|
}
|
||||||
_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].limit){
|
if(cardPricing[data].value < cardPricing[data].max){
|
||||||
cardPricing[data].value ++;
|
cardPricing[data].value = cardPricing[data].value + cardPricing[data].interval;
|
||||||
}
|
}
|
||||||
_fetchPricing();
|
_fetchPricing();
|
||||||
});
|
});
|
||||||
|
@ -110,6 +116,7 @@
|
||||||
|
|
||||||
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").text(total);
|
$("#total").text(total);
|
||||||
$('input[name=total]').val(total);
|
$('input[name=total]').val(total);
|
||||||
|
|
|
@ -227,25 +227,27 @@
|
||||||
<h3>{% trans "VM hosting" %} </h3>
|
<h3>{% trans "VM hosting" %} </h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="price">
|
<div class="price">
|
||||||
<span>15CHF/month</span>
|
<span>15 CHF/month</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="descriptions">
|
<div class="descriptions">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>{% trans "Based in Switzerland" %}</p>
|
<p>{% trans "Based in Switzerland" %}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>1 core, </p>
|
<p>1 Core, </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>2 GiB RAM, </p>
|
<p>2 GB RAM, </p>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<p>{% trans "15 GiB storage(SSD)" %}</p>
|
<p>{% trans "15 GB Storage (SSD)" %}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a href="{% url 'datacenterlight:pricing' %}" class="btn btn-primary">{% trans "Order Now!" %}</a>
|
<a href="{% url 'datacenterlight:pricing' %}" class="btn btn-primary">{% trans "Order Now!" %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
<img class="img-beta" src="{% static 'datacenterlight/img/beta.png' %}" alt="">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -257,7 +259,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6 col-md-6">
|
<div class="col-sm-6 col-md-6">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h2>{% trans "I want to try!" %}</h2>
|
<h2>{% trans "Want to know more? Subscribe to our newsletter!" %}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-6">
|
<div class="col-sm-6 col-md-6">
|
||||||
|
|
|
@ -105,6 +105,7 @@
|
||||||
|
|
||||||
<div class="price-calc-section">
|
<div class="price-calc-section">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<img class="img-beta" src="{% static 'datacenterlight/img/beta.png' %}" alt="">
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<form method="POST" action="">
|
<form method="POST" action="">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@ -122,7 +123,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<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>
|
||||||
<span id="coreValue">1</span><span> core</span>
|
<span id="coreValue">1</span><span> Core</span>
|
||||||
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i>
|
<i class="fa fa-plus-circle right" data-plus="cpu" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
|
@ -132,14 +133,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<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>
|
||||||
<span id="storageValue">15</span><span>{% trans "GiB storage(SSD)" %}</span>
|
<span id="storageValue">15</span><span>{% trans "GB Storage (SSD)" %}</span>
|
||||||
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i>
|
<i class="fa fa-plus-circle right" data-plus="storage" aria-hidden="true"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="description select-configuration">
|
<div class="description select-configuration">
|
||||||
<select name="config" id="">
|
<select name="config" id="">
|
||||||
<option value="" disabled selected>Configuration</option>
|
|
||||||
{% for template in templates %}
|
{% for template in templates %}
|
||||||
<option value="{{template.id}}">{{template.name}} </option>
|
<option value="{{template.id}}">{{template.name}} </option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -61,7 +61,7 @@
|
||||||
{% url 'hosting:payment' as payment_url %}
|
{% url 'hosting:payment' as payment_url %}
|
||||||
{% if payment_url in request.META.HTTP_REFERER %}
|
{% if payment_url in request.META.HTTP_REFERER %}
|
||||||
<div class=" content pull-right">
|
<div class=" content pull-right">
|
||||||
<a href="{% url 'hosting:key_pair'%}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a>
|
<a href="{% url 'hosting:virtual_machines'%}" ><button class="btn btn-info">{% trans "Finish Configuration"%}</button></a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -40,6 +40,7 @@ from oca.pool import WrongNameError
|
||||||
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
|
CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \
|
||||||
connection error. please try again in a few minutes."
|
connection error. please try again in a few minutes."
|
||||||
|
|
||||||
|
|
||||||
class DjangoHostingView(ProcessVMSelectionMixin, View):
|
class DjangoHostingView(ProcessVMSelectionMixin, View):
|
||||||
template_name = "hosting/django.html"
|
template_name = "hosting/django.html"
|
||||||
|
|
||||||
|
@ -187,9 +188,11 @@ class SignupView(CreateView):
|
||||||
template_name = 'hosting/signup.html'
|
template_name = 'hosting/signup.html'
|
||||||
form_class = HostingUserSignupForm
|
form_class = HostingUserSignupForm
|
||||||
model = CustomUser
|
model = CustomUser
|
||||||
|
success_url = reverse_lazy('hosting:key_pair')
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
next_url = self.request.session.get('next', reverse_lazy('hosting:virtual_machines'))
|
next_url = self.request.session.get(
|
||||||
|
'next', self.success_url)
|
||||||
return next_url
|
return next_url
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
@ -243,12 +246,14 @@ class PasswordResetConfirmView(PasswordResetConfirmViewMixin):
|
||||||
|
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'Password reset has not been successful.')
|
messages.error(
|
||||||
|
request, 'Password reset has not been successful.')
|
||||||
form.add_error(None, 'Password reset has not been successful.')
|
form.add_error(None, 'Password reset has not been successful.')
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
messages.error(request, 'The reset password link is no longer valid.')
|
messages.error(
|
||||||
|
request, 'The reset password link is no longer valid.')
|
||||||
form.add_error(None, 'The reset password link is no longer valid.')
|
form.add_error(None, 'The reset password link is no longer valid.')
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
@ -337,7 +342,20 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView):
|
||||||
'form': UserHostingKeyForm(request=self.request),
|
'form': UserHostingKeyForm(request=self.request),
|
||||||
})
|
})
|
||||||
|
|
||||||
# return HttpResponseRedirect(reverse('hosting:key_pair'))
|
owner = self.request.user
|
||||||
|
# Create OpenNebulaManager
|
||||||
|
manager = OpenNebulaManager(email=owner.email,
|
||||||
|
password=owner.password)
|
||||||
|
# Get OpenNebula user id
|
||||||
|
user_pool = manager._get_user_pool()
|
||||||
|
opennebula_user = user_pool.get_by_name(owner.email)
|
||||||
|
|
||||||
|
# Get user ssh key
|
||||||
|
user_key = UserHostingKey.objects.get(user=owner)
|
||||||
|
# Add ssh key to user
|
||||||
|
manager.oneadmin_client.call('user.update', opennebula_user.id,
|
||||||
|
'<CONTEXT><SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY></CONTEXT>'.format(ssh_key=user_key.public_key))
|
||||||
|
|
||||||
return render(self.request, self.template_name, context)
|
return render(self.request, self.template_name, context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
@ -385,9 +403,11 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
user = self.request.user
|
user = self.request.user
|
||||||
|
|
||||||
# Get user last order
|
# Get user last order
|
||||||
last_hosting_order = HostingOrder.objects.filter(customer__user=user).last()
|
last_hosting_order = HostingOrder.objects.filter(
|
||||||
|
customer__user=user).last()
|
||||||
|
|
||||||
# If user has already an hosting order, get the credit card data from it
|
# If user has already an hosting order, get the credit card data from
|
||||||
|
# it
|
||||||
if last_hosting_order:
|
if last_hosting_order:
|
||||||
credit_card_data = last_hosting_order.get_cc_data()
|
credit_card_data = last_hosting_order.get_cc_data()
|
||||||
context.update({
|
context.update({
|
||||||
|
@ -476,11 +496,10 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
except UserHostingKey.DoesNotExist:
|
except UserHostingKey.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# Create a vm using logged user
|
# Create a vm using logged user
|
||||||
vm_id = manager.create_vm(
|
vm_id = manager.create_vm(
|
||||||
template_id=vm_template_id,
|
template_id=vm_template_id,
|
||||||
#XXX: Confi
|
# XXX: Confi
|
||||||
specs=specs,
|
specs=specs,
|
||||||
ssh_key=user_key.public_key,
|
ssh_key=user_key.public_key,
|
||||||
)
|
)
|
||||||
|
@ -494,14 +513,16 @@ class PaymentVMView(LoginRequiredMixin, FormView):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a Hosting Bill
|
# Create a Hosting Bill
|
||||||
bill = HostingBill.create(customer=customer, billing_address=billing_address)
|
bill = HostingBill.create(
|
||||||
|
customer=customer, billing_address=billing_address)
|
||||||
|
|
||||||
# Create Billing Address for User if he does not have one
|
# Create Billing Address for User if he does not have one
|
||||||
if not customer.user.billing_addresses.count():
|
if not customer.user.billing_addresses.count():
|
||||||
billing_address_data.update({
|
billing_address_data.update({
|
||||||
'user': customer.user.id
|
'user': customer.user.id
|
||||||
})
|
})
|
||||||
billing_address_user_form = UserBillingAddressForm(billing_address_data)
|
billing_address_user_form = UserBillingAddressForm(
|
||||||
|
billing_address_data)
|
||||||
billing_address_user_form.is_valid()
|
billing_address_user_form.is_valid()
|
||||||
billing_address_user_form.save()
|
billing_address_user_form.save()
|
||||||
|
|
||||||
|
@ -553,7 +574,7 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai
|
||||||
vm = manager.get_vm(obj.vm_id)
|
vm = manager.get_vm(obj.vm_id)
|
||||||
context['vm'] = VirtualMachineSerializer(vm).data
|
context['vm'] = VirtualMachineSerializer(vm).data
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( request,
|
messages.error(request,
|
||||||
'In order to create a VM, you need to create/upload your SSH KEY first.'
|
'In order to create a VM, you need to create/upload your SSH KEY first.'
|
||||||
)
|
)
|
||||||
return context
|
return context
|
||||||
|
@ -595,7 +616,7 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
|
||||||
serializer = VirtualMachineSerializer(queryset, many=True)
|
serializer = VirtualMachineSerializer(queryset, many=True)
|
||||||
return serializer.data
|
return serializer.data
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( self.request,
|
messages.error(self.request,
|
||||||
'We could not load your VMs due to a backend connection \
|
'We could not load your VMs due to a backend connection \
|
||||||
error. Please try again in a few minutes'
|
error. Please try again in a few minutes'
|
||||||
)
|
)
|
||||||
|
@ -603,12 +624,11 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView):
|
||||||
self.kwargs['error'] = 'connection'
|
self.kwargs['error'] = 'connection'
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
error = self.kwargs.get('error')
|
error = self.kwargs.get('error')
|
||||||
if error is not None:
|
if error is not None:
|
||||||
print(error)
|
print(error)
|
||||||
context = { 'error' : 'connection' }
|
context = {'error': 'connection'}
|
||||||
else:
|
else:
|
||||||
context = super(ListView, self).get_context_data(**kwargs)
|
context = super(ListView, self).get_context_data(**kwargs)
|
||||||
return context
|
return context
|
||||||
|
@ -658,7 +678,8 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
|
||||||
template = manager.get_template(template_id)
|
template = manager.get_template(template_id)
|
||||||
configuration_id = int(request.POST.get('configuration'))
|
configuration_id = int(request.POST.get('configuration'))
|
||||||
configuration = HostingPlan.objects.get(id=configuration_id)
|
configuration = HostingPlan.objects.get(id=configuration_id)
|
||||||
request.session['template'] = VirtualMachineTemplateSerializer(template).data
|
request.session['template'] = VirtualMachineTemplateSerializer(
|
||||||
|
template).data
|
||||||
|
|
||||||
request.session['specs'] = configuration.serialize()
|
request.session['specs'] = configuration.serialize()
|
||||||
return redirect(reverse('hosting:payment'))
|
return redirect(reverse('hosting:payment'))
|
||||||
|
@ -680,7 +701,7 @@ class VirtualMachineView(LoginRequiredMixin, View):
|
||||||
vm = manager.get_vm(vm_id)
|
vm = manager.get_vm(vm_id)
|
||||||
return vm
|
return vm
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
messages.error( self.request,
|
messages.error(self.request,
|
||||||
'We could not load your VM due to a backend connection \
|
'We could not load your VM due to a backend connection \
|
||||||
error. Please try again in a few minutes'
|
error. Please try again in a few minutes'
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from oca.pool import WrongNameError
|
||||||
from oca.exceptions import OpenNebulaException
|
from oca.exceptions import OpenNebulaException
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class OpenNebulaManager():
|
class OpenNebulaManager():
|
||||||
"""This class represents an opennebula manager."""
|
"""This class represents an opennebula manager."""
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ class OpenNebulaManager():
|
||||||
protocol=settings.OPENNEBULA_PROTOCOL)
|
protocol=settings.OPENNEBULA_PROTOCOL)
|
||||||
)
|
)
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
def _get_user_pool(self):
|
def _get_user_pool(self):
|
||||||
try:
|
try:
|
||||||
user_pool = oca.UserPool(self.oneadmin_client)
|
user_pool = oca.UserPool(self.oneadmin_client)
|
||||||
|
@ -108,7 +110,6 @@ class OpenNebulaManager():
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
def get_vm(self, vm_id):
|
def get_vm(self, vm_id):
|
||||||
vm_id = int(vm_id)
|
vm_id = int(vm_id)
|
||||||
try:
|
try:
|
||||||
|
@ -118,7 +119,7 @@ class OpenNebulaManager():
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
||||||
disk_size_price, ssh='' ):
|
disk_size_price, ssh=''):
|
||||||
"""Create and add a new template to opennebula.
|
"""Create and add a new template to opennebula.
|
||||||
:param name: A string representation describing the template.
|
:param name: A string representation describing the template.
|
||||||
Used as label in view.
|
Used as label in view.
|
||||||
|
@ -136,11 +137,11 @@ class OpenNebulaManager():
|
||||||
template_string_formatter.format(
|
template_string_formatter.format(
|
||||||
name=name,
|
name=name,
|
||||||
vcpu=cores,
|
vcpu=cores,
|
||||||
cpu=0.1*cores,
|
cpu=0.1 * cores,
|
||||||
size=1024 * disk_size,
|
size=1024 * disk_size,
|
||||||
memory=1024 * memory,
|
memory=1024 * memory,
|
||||||
# * 10 because we set cpu to *0.1
|
# * 10 because we set cpu to *0.1
|
||||||
cpu_cost=10*core_price,
|
cpu_cost=10 * core_price,
|
||||||
memory_cost=memory_price,
|
memory_cost=memory_price,
|
||||||
disk_cost=disk_size_price,
|
disk_cost=disk_size_price,
|
||||||
ssh=ssh
|
ssh=ssh
|
||||||
|
@ -160,7 +161,7 @@ class OpenNebulaManager():
|
||||||
image_id = disk.image_id
|
image_id = disk.image_id
|
||||||
vm_specs = vm_specs_formatter.format(
|
vm_specs = vm_specs_formatter.format(
|
||||||
vcpu=int(specs['cpu']),
|
vcpu=int(specs['cpu']),
|
||||||
cpu=0.1* int(specs['cpu']),
|
cpu=0.1 * int(specs['cpu']),
|
||||||
memory=1024 * int(specs['memory']),
|
memory=1024 * int(specs['memory']),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
@ -181,7 +182,7 @@ class OpenNebulaManager():
|
||||||
|
|
||||||
vm_specs = vm_specs_formatter.format(
|
vm_specs = vm_specs_formatter.format(
|
||||||
vcpu=int(specs['cpu']),
|
vcpu=int(specs['cpu']),
|
||||||
cpu=0.1* int(specs['cpu']),
|
cpu=0.1 * int(specs['cpu']),
|
||||||
memory=1024 * int(specs['memory']),
|
memory=1024 * int(specs['memory']),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
@ -196,12 +197,15 @@ class OpenNebulaManager():
|
||||||
""".format(size=1024 * int(specs['disk_size']),
|
""".format(size=1024 * int(specs['disk_size']),
|
||||||
image=image,
|
image=image,
|
||||||
image_uname=image_uname)
|
image_uname=image_uname)
|
||||||
vm_id = template.instantiate(name ='',
|
vm_id = self.client.call(oca.VmTemplate.METHODS['instantiate'],
|
||||||
pending=False,
|
template.id,
|
||||||
extra_template=vm_specs, )
|
'',
|
||||||
|
True,
|
||||||
|
vm_specs,
|
||||||
|
False)
|
||||||
|
|
||||||
self.oneadmin_client.call(
|
self.oneadmin_client.call(
|
||||||
'vm.updateconf',
|
'vm.update',
|
||||||
vm_id,
|
vm_id,
|
||||||
"""<CONTEXT>
|
"""<CONTEXT>
|
||||||
<SSH_PUBLIC_KEY>{ssh}</SSH_PUBLIC_KEY>
|
<SSH_PUBLIC_KEY>{ssh}</SSH_PUBLIC_KEY>
|
||||||
|
@ -216,7 +220,14 @@ class OpenNebulaManager():
|
||||||
self.opennebula_user.group_ids[0]
|
self.opennebula_user.group_ids[0]
|
||||||
)
|
)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
logger.info('Could not change owner for vm with id: {}.'.format(vm_id))
|
logger.info(
|
||||||
|
'Could not change owner for vm with id: {}.'.format(vm_id))
|
||||||
|
|
||||||
|
self.oneadmin_client.call(
|
||||||
|
oca.VirtualMachine.METHODS['action'],
|
||||||
|
'release',
|
||||||
|
vm_id
|
||||||
|
)
|
||||||
return vm_id
|
return vm_id
|
||||||
|
|
||||||
def delete_vm(self, vm_id):
|
def delete_vm(self, vm_id):
|
||||||
|
@ -232,7 +243,8 @@ class OpenNebulaManager():
|
||||||
except socket.timeout as socket_err:
|
except socket.timeout as socket_err:
|
||||||
logger.info("Socket timeout error: {0}".format(socket_err))
|
logger.info("Socket timeout error: {0}".format(socket_err))
|
||||||
except OpenNebulaException as opennebula_err:
|
except OpenNebulaException as opennebula_err:
|
||||||
logger.info("OpenNebulaException error: {0}".format(opennebula_err))
|
logger.info(
|
||||||
|
"OpenNebulaException error: {0}".format(opennebula_err))
|
||||||
except OSError as os_err:
|
except OSError as os_err:
|
||||||
logger.info("OSError : {0}".format(os_err))
|
logger.info("OSError : {0}".format(os_err))
|
||||||
except ValueError as value_err:
|
except ValueError as value_err:
|
||||||
|
@ -254,7 +266,6 @@ class OpenNebulaManager():
|
||||||
except:
|
except:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
def get_templates(self):
|
def get_templates(self):
|
||||||
try:
|
try:
|
||||||
public_templates = [
|
public_templates = [
|
||||||
|
@ -282,10 +293,8 @@ class OpenNebulaManager():
|
||||||
except:
|
except:
|
||||||
raise ConnectionRefusedError
|
raise ConnectionRefusedError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
|
||||||
disk_size_price, ssh='' ):
|
disk_size_price, ssh=''):
|
||||||
"""Create and add a new template to opennebula.
|
"""Create and add a new template to opennebula.
|
||||||
:param name: A string representation describing the template.
|
:param name: A string representation describing the template.
|
||||||
Used as label in view.
|
Used as label in view.
|
||||||
|
@ -318,11 +327,11 @@ class OpenNebulaManager():
|
||||||
template_string_formatter.format(
|
template_string_formatter.format(
|
||||||
name=name,
|
name=name,
|
||||||
vcpu=cores,
|
vcpu=cores,
|
||||||
cpu=0.1*cores,
|
cpu=0.1 * cores,
|
||||||
size=1024 * disk_size,
|
size=1024 * disk_size,
|
||||||
memory=1024 * memory,
|
memory=1024 * memory,
|
||||||
# * 10 because we set cpu to *0.1
|
# * 10 because we set cpu to *0.1
|
||||||
cpu_cost=10*core_price,
|
cpu_cost=10 * core_price,
|
||||||
memory_cost=memory_price,
|
memory_cost=memory_price,
|
||||||
disk_cost=disk_size_price,
|
disk_cost=disk_size_price,
|
||||||
ssh=ssh
|
ssh=ssh
|
||||||
|
@ -332,7 +341,8 @@ class OpenNebulaManager():
|
||||||
return template_id
|
return template_id
|
||||||
|
|
||||||
def delete_template(self, template_id):
|
def delete_template(self, template_id):
|
||||||
self.oneadmin_client.call(oca.VmTemplate.METHODS['delete'], template_id, False)
|
self.oneadmin_client.call(oca.VmTemplate.METHODS[
|
||||||
|
'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(
|
||||||
|
|
Loading…
Reference in a new issue