Merge pull request #418 from pcoder/task/3615/decouple_landing_page_from_opennebula
Task/3615/decouple landing page from opennebula
This commit is contained in:
commit
53fc982837
29
datacenterlight/management/commands/fetchvmtemplates.py
Normal file
29
datacenterlight/management/commands/fetchvmtemplates.py
Normal 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)))
|
|
@ -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
|
||||||
|
|
|
@ -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,10 +17,11 @@
|
||||||
</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>
|
||||||
<div class="help-block with-errors">
|
<div class="help-block with-errors">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
|
@ -34,10 +35,11 @@
|
||||||
</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>
|
||||||
<div class="help-block with-errors">
|
<div class="help-block with-errors">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
|
@ -51,10 +53,11 @@
|
||||||
</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>
|
||||||
<div class="help-block with-errors">
|
<div class="help-block with-errors">
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
|
@ -70,7 +73,7 @@
|
||||||
<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>
|
||||||
|
@ -80,31 +83,38 @@
|
||||||
</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>
|
||||||
|
|
|
@ -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):
|
||||||
|
@ -211,20 +211,11 @@ class IndexView(CreateView):
|
||||||
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):
|
||||||
|
@ -236,9 +227,8 @@ class IndexView(CreateView):
|
||||||
storage_field = forms.IntegerField(validators=[self.validate_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')
|
||||||
|
@ -350,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'
|
||||||
|
@ -499,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
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue