Merge branch 'opennebula-integration' of github.com:ungleich/dynamicweb into opennebula-integration

This commit is contained in:
Levi 2017-05-08 19:06:12 -05:00
commit bd83545653
11 changed files with 189 additions and 114 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,42 @@
{% load i18n %}
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="exampleModalLabel">{% trans 'New message'%}</h4>
</div>
<form novalidate method="post" action="{% url 'alplora:contact'%}" id="contact_form">
<div class="modal-body">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form-group text-left">
<label for="recipient-name" class="control-label ">{% trans 'Name:'%}</label>
<input type="text" class="form-control" {%if form.name.errors%}
style="border-color: red" {%endif%} name="name" placeholder="{% trans 'What is your name ?'%}" id="recipient-name" required>
{{ form.name.errors|striptags }}
</div>
<div class="form-group text-left">
<label for="recipient-name" class="control-label ">{% trans 'From:'%}</label>
<input type="text" class="form-control" {%if form.email.errors%}
style="border-color: red" {%endif%}name="email" placeholder="{% trans 'You email'%}" id="recipient-name" required>
{{ form.email.errors|striptags}}
</div>
<div class="form-group text-left">
<label for="message-text" class="control-label ">{% trans 'Message:'%}</label>
<textarea class="form-control" {%if form.message.errors %} style =
"border-color: red" {%endif%} name="message" placeholder="{% trans 'Leave us your message'%}" id="message-text" required></textarea>
{{ form.message.errors|striptags}}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Close'%}</button>
<button type="submit" class="btn btn-warning">{% trans 'Send message'%}</button>
</div>
</form>
</div>
</div>
<script>
$('#contact_form').ajaxForm({
target: '#modal', success: function(response) { }
});
</script>

View file

@ -0,0 +1,21 @@
{% load i18n %}
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">{% trans "Message Sent" %}</h4>
</div>
<div class="modal-body">
<p>{% trans "Thank you, we will contact you as soon as possible" %}</p>
</div>
<div class="modal-footer text-center">
<button type="submit" class="btn btn-primary" data-dismiss="modal">Ok</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
<script>
// close the modal after 3 seconds
setTimeout(function() {
$('#modal').modal('hide');
}, 3000);
</script>

View file

@ -53,7 +53,6 @@
</script> </script>
<div class="page-loader"> <div class="page-loader">
<div class="loader"> <div class="loader">
<div class="circle circle-1"></div> <div class="circle circle-1"></div>
@ -419,7 +418,9 @@
<h1>{% trans 'How do I get Alplora?'%}</h1> <h1>{% trans 'How do I get Alplora?'%}</h1>
<h3>{% trans 'Click the button below and leave us your contact.'%}<p></p>{% trans 'Team Alplora will contact you and visit you with a tracking device.'%}</h3> <h3>{% trans 'Click the button below and leave us your contact.'%}<p></p>{% trans 'Team Alplora will contact you and visit you with a tracking device.'%}</h3>
<hr class="intro-divider"> <hr class="intro-divider">
<a href="#howitworks" class="btn btn-default btn-lg"><i class="#Services"></i> <span class="network-name" data-toggle="modal" data-target="#exampleModal" >{% trans 'Contact'%}</span></a> <a href="{% url 'alplora:contact' %}" data-toggle="modal" data-target="#modal" class="btn btn-default
btn-lg"><i class="#Services"></i> <span
class="network-name" >{% trans 'Contact'%}</span></a>
</ul> </ul>
</div> </div>
@ -429,60 +430,9 @@
</div> </div>
<!-- CONTACT FORM MODAL --> <!-- CONTACT FORM MODAL -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" style="color:black;"> <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" style="color:black;">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="exampleModalLabel">{% trans 'New message'%}</h4>
</div>
<form method="POST" action="">
<div class="modal-body">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="form-group text-left">
<label for="recipient-name" class="control-label ">{% trans 'Name:'%}</label>
<input type="text" class="form-control" name="name" placeholder="{% trans 'What is your name ?'%}" id="recipient-name" required>
</div>
<div class="form-group text-left">
<label for="recipient-name" class="control-label ">{% trans 'From:'%}</label>
<input type="text" class="form-control" name="email" placeholder="{% trans 'You email'%}" id="recipient-name" required>
{{ form.email.errors|striptags}}
</div>
<div class="form-group text-left">
<label for="message-text" class="control-label ">{% trans 'Message:'%}</label>
<textarea class="form-control" name="message" placeholder="{% trans 'Leave us your message'%}" id="message-text" required></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Close'%}</button>
<button type="submit" class="btn btn-warning">{% trans 'Send message'%}</button>
</div>
</form>
</div>
</div>
</div> </div>
<!-- SUCCESS MODAL MESSAGE -->
<div class="modal fade bs-example-modal-sm" style="color:black;" id="request-success-message" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">{% trans "Message Sent" %}</h4>
</div>
<div class="modal-body">
<p>{% trans "Thank you, we will contact you as soon as possible" %}</p>
</div>
<div class="modal-footer text-center">
<button type="submit" class="btn btn-primary" data-dismiss="modal">Ok</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- /.container --> <!-- /.container -->
</div> </div>
@ -560,6 +510,7 @@
<script src="{% static 'alplora/js/main.js' %}"></script> <script src="{% static 'alplora/js/main.js' %}"></script>
<script src="{% static 'alplora/js/form.js' %}"></script>
<link rel="stylesheet" href="/static/debug_toolbar/css/print.css" type="text/css" media="print"> <link rel="stylesheet" href="/static/debug_toolbar/css/print.css" type="text/css" media="print">
<link rel="stylesheet" href="/static/debug_toolbar/css/toolbar.css" type="text/css"> <link rel="stylesheet" href="/static/debug_toolbar/css/toolbar.css" type="text/css">
@ -572,14 +523,15 @@
<script src="/static/debug_toolbar/js/toolbar.js"></script> <script src="/static/debug_toolbar/js/toolbar.js"></script>
<script type="text/javascript"> <script type="text/javascript">
window.onload=function(){ $('#modal').on('show.bs.modal', function (event) {
var hash = window.location.hash.substr(1); var modal = $(this)
if (hash == 'requestformsuccess'){ $.ajax({
$('#request-success-message').modal('show'); url: "{% url 'alplora:contact' %}",
} context: document.body
}).done(function(response) {
}; modal.html(response);
});
});
</script> </script>
</body> </body>
</html> </html>

View file

@ -1,11 +1,12 @@
from django.conf.urls import url from django.conf.urls import url
from .views import IndexView, LoginView from .views import IndexView, LoginView, ContactView
urlpatterns = [ urlpatterns = [
url(r'^/?$', IndexView.as_view(), name='index'), url(r'^/?$', IndexView.as_view(), name='index'),
url(r'/login/', LoginView.as_view(), name='login'), url(r'/login/', LoginView.as_view(), name='login'),
url(r'/contact', ContactView.as_view(), name='contact'),
# url(r'^/beta-program/?$', BetaProgramView.as_view(), name='beta'), # url(r'^/beta-program/?$', BetaProgramView.as_view(), name='beta'),
# url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), # url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'),
] ]

View file

@ -5,13 +5,12 @@ from django.utils.translation import ugettext_lazy as _
from django.views.generic.edit import FormView from django.views.generic.edit import FormView
from django.contrib import messages from django.contrib import messages
from django.core.urlresolvers import reverse_lazy, reverse from django.core.urlresolvers import reverse_lazy, reverse
from django.shortcuts import render
from utils.forms import ContactUsForm from utils.forms import ContactUsForm
class IndexView(FormView): class IndexView(TemplateView):
template_name = "alplora/index.html" template_name = "alplora/index.html"
form_class = ContactUsForm
success_message = _('Message Successfully Sent')
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs) context = super(IndexView, self).get_context_data(**kwargs)
@ -19,17 +18,22 @@ class IndexView(FormView):
context.update(languages) context.update(languages)
return context return context
def get_success_url(self): class ContactView(FormView):
success_url = reverse('alplora:index') template_name = 'alplora/contact.html'
success_url += "#requestformsuccess" form_class = ContactUsForm
return success_url success_message = _('Message Successfully Sent')
def get_context_data(self, *args, **kwargs):
context = super(ContactView, self).get_context_data(**kwargs)
languages = getlanguages()
context.update(languages)
return context
def form_valid(self, form): def form_valid(self, form):
form.save() form.save()
form.send_email(email_to='info@alplora.ch') form.send_email(email_to='info@alplora.ch')
messages.add_message(self.request, messages.SUCCESS, self.success_message) messages.add_message(self.request, messages.SUCCESS, self.success_message)
return super(IndexView, self).form_valid(form) return render(self.request, 'alplora/contact_success.html', {})
class LoginView(TemplateView): class LoginView(TemplateView):
template_name = "alplora/login.html" template_name = "alplora/login.html"

View file

@ -17,21 +17,10 @@
{% render_model post "abstract" "" "" 'truncatewords_html:10' %} {% render_model post "abstract" "" "" 'truncatewords_html:10' %}
</h2> </h2>
<span class="meta"> <span class="meta">
Posted Posted on {{ post.date_published|date:"DATE_FORMAT" }}
{% if post.author %}
by
<a href="{% url 'djangocms_blog:posts-author' post.author.get_username %}">
{% if post.author.get_full_name %}
{{ post.author.get_full_name }}
{% else %}
{{ post.author }}
{% endif %}
</a>
{% endif %}
on {{ post.date_published|date:"DATE_FORMAT" }}
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</header> </header>

View file

@ -16,18 +16,7 @@
</h2> </h2>
</a> </a>
<p class="post-meta" style="font-size:0.9em;"> <p class="post-meta" style="font-size:0.9em;">
Posted Posted on {{ post.date_published|date:"DATE_FORMAT" }}
{% if post.author %}
by
<!-- <a href="{% url 'djangocms_blog:posts-author' post.author.get_username %}"> -->
{% if post.author.get_full_name %}
{{ post.author.get_full_name }}
{% else %}
{{ post.author }}
{% endif %}
<!-- </a> -->
{% endif %}
on {{ post.date_published|date:"DATE_FORMAT" }}
</p> </p>
<p class="post-subtitle"> <p class="post-subtitle">

View file

@ -15,7 +15,10 @@ from membership.models import StripeCustomer, CustomUser
from utils.models import BillingAddress from utils.models import BillingAddress
from utils.mixins import AssignPermissionsMixin from utils.mixins import AssignPermissionsMixin
from .managers import VMPlansManager from .managers import VMPlansManager
from oca.pool import WrongNameError
import logging
logger = logging.getLogger(__name__)
class VirtualMachineType(models.Model): class VirtualMachineType(models.Model):
@ -290,3 +293,12 @@ class ManageVM(models.Model):
class Meta: class Meta:
managed = False managed = False
def get_user_opennebula_password():
'''
TODO: Implement the way we obtain the user's opennebula password
'''
pw = os.environ.get('OPENNEBULA_USER_PW')
if pw is None:
raise Exception("Define OPENNEBULA_USER_PW env variable")
return pw

View file

@ -14,6 +14,7 @@ from django.utils.translation import ugettext_lazy as _
from oca.exceptions import OpenNebulaException from oca.exceptions import OpenNebulaException
from oca.pool import WrongNameError from oca.pool import WrongNameError
from django import forms
# Get an instance of a logger # Get an instance of a logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -135,9 +136,9 @@ class HostingManageVMAdmin(admin.ModelAdmin):
port=settings.OPENNEBULA_PORT, port=settings.OPENNEBULA_PORT,
endpoint=settings.OPENNEBULA_ENDPOINT endpoint=settings.OPENNEBULA_ENDPOINT
)) ))
print("{0}:{1}".format(settings.OPENNEBULA_USERNAME, logger.debug("{0}:{1}".format(settings.OPENNEBULA_USERNAME,
settings.OPENNEBULA_PASSWORD)) settings.OPENNEBULA_PASSWORD))
print("{protocol}://{domain}:{port}{endpoint}".format( logger.debug("{protocol}://{domain}:{port}{endpoint}".format(
protocol=settings.OPENNEBULA_PROTOCOL, protocol=settings.OPENNEBULA_PROTOCOL,
domain=settings.OPENNEBULA_DOMAIN, domain=settings.OPENNEBULA_DOMAIN,
port=settings.OPENNEBULA_PORT, port=settings.OPENNEBULA_PORT,
@ -146,6 +147,7 @@ class HostingManageVMAdmin(admin.ModelAdmin):
self.create_opennebula_user(request) self.create_opennebula_user(request)
if self.client is None: if self.client is None:
opennebula_user = request.user.email opennebula_user = request.user.email
# TODO: get the password stored in django
opennebula_user_password ='19737450' opennebula_user_password ='19737450'
self.client = oca.Client("{0}:{1}".format(opennebula_user, opennebula_user_password), self.client = oca.Client("{0}:{1}".format(opennebula_user, opennebula_user_password),
"{protocol}://{domain}:{port}{endpoint}".format( "{protocol}://{domain}:{port}{endpoint}".format(
@ -172,6 +174,7 @@ class HostingManageVMAdmin(admin.ModelAdmin):
# Include common variables for rendering the admin template. # Include common variables for rendering the admin template.
self.admin_site.each_context(request), self.admin_site.each_context(request),
vms=vm_pool, vms=vm_pool,
form=HostingManageVMForm
) )
return TemplateResponse(request, "hosting/managevms.html", context) return TemplateResponse(request, "hosting/managevms.html", context)
@ -259,22 +262,30 @@ class HostingManageVMAdmin(admin.ModelAdmin):
vm_template_int = int(vm_template) vm_template_int = int(vm_template)
if 1 <= vm_template_int <= 8: if 1 <= vm_template_int <= 8:
vm_string_formatter = """<VM> vm_string_formatter = """<VM>
<CONTEXT>
<SSH_PUBLIC_KEY>
{ssh_key}
</SSH_PUBLIC_KEY>
</CONTEXT>
<MEMORY>{memory}</MEMORY> <MEMORY>{memory}</MEMORY>
<VCPU>{vcpu}</VCPU> <VCPU>{vcpu}</VCPU>
<CPU>{cpu}</CPU> <CPU>{cpu}</CPU>
<DISK> <DISK>
<TYPE>{disk_type}</TYPE> <TYPE>{disk_type}</TYPE>
<SIZE>{size}</SIZE> <SIZE>{size}</SIZE>
<DEV_PREFIX>{dev_prefix}</DEV_PREFIX>
</DISK> </DISK>
</VM> </VM>
""" """
vm_id = oca.VirtualMachine.allocate(self.client, vm_id = oca.VirtualMachine.allocate(self.client,
vm_string_formatter.format( vm_string_formatter.format(
memory=1024 * vm_template_int, ssh_key='', # public key of the user
vcpu=vm_template_int, memory=1024 * vm_template_int, # memory in MB
cpu=0.1 * vm_template_int, vcpu=vm_template_int, # vpcu
disk_type='fs', cpu=0.1 * vm_template_int, # cpu
size=10000 * vm_template_int)) disk_type='fs',
size=10000 * vm_template_int,
dev_prefix='vd')) # We need KVM virtual disk
message = _("Created with id = " + str(vm_id)) message = _("Created with id = " + str(vm_id))
messages.add_message(request, messages.SUCCESS, message) messages.add_message(request, messages.SUCCESS, message)
else: else:
@ -372,14 +383,60 @@ class HostingManageVMAdmin(admin.ModelAdmin):
opennebula_user = user_pool.get_by_name(request.user.email) opennebula_user = user_pool.get_by_name(request.user.email)
logger.debug("User {0} exists. User id = {1}".format(request.user.email, opennebula_user.id)) logger.debug("User {0} exists. User id = {1}".format(request.user.email, opennebula_user.id))
except WrongNameError as wrong_name_err: except WrongNameError as wrong_name_err:
user_id = self.oneadmin_client.call('user.allocate', request.user.email, get_random_password(), # TODO: Store this password so that we can use it later to
'dummy') # connect to opennebula
password = get_random_password()
oca.User.allocate(self.oneadmin_client, request.user.email, password)
logger.debug("User {0} does not exist. Created the user. User id = {1}", request.user.email, user_id) logger.debug("User {0} does not exist. Created the user. User id = {1}", request.user.email, user_id)
except OpenNebulaException as err: except OpenNebulaException as err:
messages.add_message(request, messages.ERROR, messages.add_message(request, messages.ERROR,
"Error : {0}".format(err)) "Error : {0}".format(err))
logger.error("Error : {0}".format(err)) logger.error("Error : {0}".format(err))
def set_field_html_name(cls, new_name):
"""
This creates wrapper around the normal widget rendering,
allowing for a custom field name (new_name).
"""
old_render = cls.widget.render
def _widget_render_wrapper(name, value, attrs=None):
return old_render(new_name, value, attrs)
cls.widget.render = _widget_render_wrapper
class HostingManageVMForm(forms.Form):
vm_templates = []
VM_CHOICES = (('1', 'disk = 10GB, vcpu=1, ram=1GB'),
('2', 'disk = 20GB, vcpu=2, ram=2GB'),
('3', 'disk = 40GB, vcpu=4, ram=4GB'),
('4', 'disk = 80GB, vcpu=8, ram=8GB'),
('5', 'disk = 160GB, vcpu=16, ram=16GB'),
('6', 'disk = 320GB, vcpu=32, ram=32GB'),
('7', 'disk = 640GB, vcpu=64, ram=64GB'),
('8', 'disk = 1280GB, vcpu=128, ram=128GB'))
#for i in range(0,8):
# factor = pow(2, i)
# vm_templates.append(VMTemplate(i, VM_CHOICES[i], 10000 * factor, factor , 0.1 * factor, 1024 * factor))
field = forms.ChoiceField(label="Choose a VM Template ", choices=VM_CHOICES, widget=forms.Select(attrs={"id": "vm_template"}))
set_field_html_name(field, 'vm_template')
class VMTemplate:
"""A simple representation of a VM template.
:param template_id: The id of the template
:param label: A string representation describing the template. Used as the label in view
:param disk: VM disk space in MB
:param vcpu: Virtual cpu for the VM
:param cpu: CPU for the VM
:param ram: The RAM for the VM
"""
def __init__(self, template_id, label, disk, vcpu, cpu, ram):
self.template_id = template_id
self.label = label
self.disk = disk
self.vcpu = vcpu
self.cpu = cpu
# Returns random password that is needed by OpenNebula # Returns random password that is needed by OpenNebula
def get_random_password(): def get_random_password():

View file

@ -2,13 +2,9 @@
{% block content %} {% block content %}
<form action="{% url 'admin:createvm' %}" method="post"> <form action="{% url 'admin:createvm' %}" method="post">
{% csrf_token %} {% csrf_token %}
<select id="vm_template" name="vm_template"> {{ form }}
<option value="select">Select a template</option> <input type="submit" name="create_vm" value="Create VM" />
<option value="1">disk = 10GB, vcpu=1, ram=2GB</option>
<option value="2">disk = 20GB, vcpu=2, ram=4GB</option>
</select>
<input type="submit" name="create_vm" value="Create VM" />
</form> </form>
{% if vms %} {% if vms %}
<section> <section>