Merge branch 'develop' of github.com:ungleich/dynamicweb into develop

This commit is contained in:
Levi 2017-05-23 11:48:25 -05:00
commit e278ff742d
12 changed files with 186 additions and 57 deletions

View file

@ -7,7 +7,7 @@ class BetaAccessForm(forms.ModelForm):
email = forms.CharField(widget=forms.EmailInput()) email = forms.CharField(widget=forms.EmailInput())
class Meta: class Meta:
fields = ['email'] fields = ['name', 'email']
model = BetaAccess model = BetaAccess

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,27 @@
{% load i18n %}
<form novalidate id ="beta_access" class="form-beta" method="POST" action="{% url 'datacenterlight:beta_access'%}">
{% csrf_token %}
{{ form.non_field_errors }}
<div>
{% for message in messages %}
<strong>{{ message }}</strong>
{% endfor %}
</div>
<div class="inputs">
<div class="form-group">
<input type="text" name="name" class="form-control" id="name" placeholder="Enter name">
<span style="color: white">{{ form.name.errors|striptags}}</span>
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" id="email" placeholder="Enter email">
<span style="color: white">{{ form.email.errors|striptags}}</span>
</div>
</div>
<button type="submit" class="btn btn-default btn-transparent btn-lg">{% trans "Request Beta Access" %}</button>
</form>
<script>
$('#beta_access').ajaxForm({
target: '#beta_access_form', success: function(response) { }
});
</script>

View file

@ -0,0 +1,47 @@
{% load i18n %}
<div class="modal fade bs-example-modal-sm" style="color:black;" id="successModal" tabindex="-1" role="dialog">
<div class="vertical-alignment-helper">
<div class="modal-dialog vertical-align-center">
<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 "Request Sent" %}</h4>
</div>
<div class="modal-body">
<p>{% trans "Thank you, we will contact you as soon as possible" %}</p>
</div>
</div><!-- /.modal-content -->
</div>
</div>
</div><!-- /.modal -->
<script>
// Show modal
$('#successModal').modal('show');
// close the modal after 3 seconds
setTimeout(function() {
$('#successModal').modal('hide');
}, 5000);
</script>
<style>
.vertical-alignment-helper {
display:table;
height: 100%;
width: 100%;
pointer-events:none; /* This makes sure that we can still click outside of the modal to close it */
}
.vertical-align-center {
/* To center vertically */
display: table-cell;
vertical-align: middle;
pointer-events:none;
}
.modal-content {
/* Bootstrap sets the size of the modal in the modal-dialog class, we need to inherit it */
width:inherit;
height:inherit;
/* To center horizontally */
margin: 0 auto;
pointer-events: all;
}
</style>

View file

@ -243,7 +243,7 @@
<p>{% trans "15 GiB storage(SSD)" %}</p> <p>{% trans "15 GiB storage(SSD)" %}</p>
</div> </div>
</div> </div>
<a href="#" class="btn btn-primary">{% trans "Buy Now!" %}</a> <a href="{% url 'hosting:payment' %}" class="btn btn-primary">{% trans "Order Now!" %}</a>
</div> </div>
</div> </div>
</div> </div>
@ -261,43 +261,9 @@
</div> </div>
</div> </div>
<div class="col-sm-6 col-md-6"> <div class="col-sm-6 col-md-6">
<div class="form"> <!-- Beta access form, will be loaded via ajax -->
<form class="form-beta" method="POST" action=""> <div class="form" id="beta_access_form">
{% csrf_token %} </div>
{{ form.non_field_errors }}
{{ form.email.errors|striptags}}
<div>
{% for message in messages %}
<strong>{{ message }}</strong>
{% endfor %}
</div>
<div class="inputs">
<div class="form-group">
<input type="text" name="name" class="form-control" id="name" placeholder="Enter name">
</div>
<div class="form-group">
<input type="email" name="email" class="form-control" id="email" placeholder="Enter email">
</div>
</div>
<button type="submit" class="btn btn-default btn-transparent btn-lg">{% trans "Request Beta Access" %}</button>
</form>
</div>
<div class="modal fade bs-example-modal-sm" style="color:black;" id="sucessModal" 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 "Request 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 -->
</div> </div>
</div> </div>
@ -389,12 +355,12 @@
windowPadding: 10, windowPadding: 10,
}); });
var hash = window.location.hash.substr(1); $.ajax({
console.log(hash); url: "{% url 'datacenterlight:beta_access' %}",
if (hash == 'requestform'){ context: document.body
$('#reques-success-message').modal('show'); }).done(function(response) {
} $('#beta_access_form').html(response);
});
}; };
</script> </script>
@ -403,6 +369,8 @@
<!-- Bootstrap Core JavaScript --> <!-- Bootstrap Core JavaScript -->
<script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script> <script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script>
<script src="{% static 'datacenterlight/js/main.js' %}"></script> <script src="{% static 'datacenterlight/js/main.js' %}"></script>
<!-- Load form js -->
<script src="{% static 'datacenterlight/js/form.js' %}"></script>
</body> </body>

View file

@ -1,10 +1,12 @@
from django.conf.urls import url from django.conf.urls import url
from .views import IndexView, BetaProgramView, LandingProgramView from .views import IndexView, BetaProgramView, LandingProgramView, \
BetaAccessView
urlpatterns = [ urlpatterns = [
url(r'^/?$', IndexView.as_view(), name='index'), url(r'^/?$', IndexView.as_view(), name='index'),
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'),
url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'),
] ]

View file

@ -5,6 +5,7 @@ from .models import BetaAccess, BetaAccessVMType, BetaAccessVM
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 utils.mailer import BaseEmail from utils.mailer import BaseEmail
from django.shortcuts import render
from opennebula_api.models import OpenNebulaManager from opennebula_api.models import OpenNebulaManager
from opennebula_api.serializers import VirtualMachineTemplateSerializer from opennebula_api.serializers import VirtualMachineTemplateSerializer
@ -12,6 +13,43 @@ from opennebula_api.serializers import VirtualMachineTemplateSerializer
class LandingProgramView(TemplateView): class LandingProgramView(TemplateView):
template_name = "datacenterlight/landing.html" template_name = "datacenterlight/landing.html"
class BetaAccessView(FormView):
template_name = "datacenterlight/beta_access.html"
form_class = BetaAccessForm
success_message = "Thank you, we will contact you as soon as possible"
def form_valid(self, form):
context = {
'base_url': "{0}://{1}".format(self.request.scheme, self.request.get_host())
}
email_data = {
'subject': 'DatacenterLight Beta Access Request',
'to': form.cleaned_data.get('email'),
'context': context,
'template_name': 'request_access_confirmation',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
context.update({
'email': form.cleaned_data.get('email')
})
email_data = {
'subject': 'DatacenterLight Beta Access Request',
'to': 'info@ungleich.ch',
'context': context,
'template_name': 'request_access_notification',
'template_path': 'datacenterlight/emails/'
}
email = BaseEmail(**email_data)
email.send()
messages.add_message(self.request, messages.SUCCESS, self.success_message)
return render(self.request, 'datacenterlight/beta_success.html', {})
class BetaProgramView(CreateView): class BetaProgramView(CreateView):
template_name = "datacenterlight/beta.html" template_name = "datacenterlight/beta.html"

View file

@ -41,11 +41,17 @@
<div class="col-md-12 inline-headers"> <div class="col-md-12 inline-headers">
<h3>{{virtual_machine.hosting_company_name}}</h3> <h3>{{virtual_machine.hosting_company_name}}</h3>
{% if virtual_machine.ip %} {% if virtual_machine.ipv6 %}
<div class="pull-right right-place"> <div class="pull-right right-place">
<button type="link" data-clipboard-text="{{virtual_machine.ip}}" id="copy_vm_id" class="to_copy btn btn-link" <button type="link"
data-clipboard-text="{{virtual_machine.ipv4}}" id="copy_vm_id" class="to_copy btn btn-link"
data-toggle="tooltip" data-placement="bottom" title="Copied" data-trigger="click"> data-toggle="tooltip" data-placement="bottom" title="Copied" data-trigger="click">
Ip: {{virtual_machine.ip}} <i class="fa fa-files-o" aria-hidden="true"></i> Ipv4: {{virtual_machine.ipv4}} <i class="fa fa-files-o" aria-hidden="true"></i>
</button>
<button type="link"
data-clipboard-text="{{virtual_machine.ipv6}}" id="copy_vm_id" class="to_copy btn btn-link"
data-toggle="tooltip" data-placement="bottom" title="Copied" data-trigger="click">
Ipv6: {{virtual_machine.ipv6}} <i class="fa fa-files-o" aria-hidden="true"></i>
</button> </button>
</div> </div>
{% else %} {% else %}

View file

@ -19,7 +19,7 @@
</div> </div>
{% if not error %} {% if not error %}
<p class="pull-right"> <p class="pull-right">
<a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a> <a class="btn btn-success" href="{% url 'hosting:create_virtual_machine' %}" >{% trans "Create VM"%} </a>
</p> </p>
<br/> <br/>

View file

@ -19,7 +19,7 @@ urlpatterns = [
url(r'bills/?$', HostingBillListView.as_view(), name='bills'), url(r'bills/?$', HostingBillListView.as_view(), name='bills'),
url(r'bills/(?P<pk>\d+)/?$', HostingBillDetailView.as_view(), name='bills'), url(r'bills/(?P<pk>\d+)/?$', HostingBillDetailView.as_view(), name='bills'),
url(r'cancel_order/(?P<pk>\d+)/?$', OrdersHostingDeleteView.as_view(), name='delete_order'), url(r'cancel_order/(?P<pk>\d+)/?$', OrdersHostingDeleteView.as_view(), name='delete_order'),
url(r'create-virtual-machine/?$', CreateVirtualMachinesView.as_view(), name='create_virtual_machine'), url(r'create_virtual_machine/?$', CreateVirtualMachinesView.as_view(), name='create_virtual_machine'),
url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'), url(r'my-virtual-machines/?$', VirtualMachinesPlanListView.as_view(), name='virtual_machines'),
url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineView.as_view(), url(r'my-virtual-machines/(?P<pk>\d+)/?$', VirtualMachineView.as_view(),
name='virtual_machines'), name='virtual_machines'),

View file

@ -1,4 +1,5 @@
import oca import oca
import ipaddress
from rest_framework import serializers from rest_framework import serializers
@ -73,8 +74,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
return int(obj.template.memory)/1024 return int(obj.template.memory)/1024
def get_name(self, obj): def get_name(self, obj):
# TODO: Filter public- away return obj.name.strip('public-')
return obj.name
class VirtualMachineSerializer(serializers.Serializer): class VirtualMachineSerializer(serializers.Serializer):
"""Serializer to map the virtual machine instance into JSON format.""" """Serializer to map the virtual machine instance into JSON format."""
@ -87,9 +87,8 @@ class VirtualMachineSerializer(serializers.Serializer):
disk_size = serializers.SerializerMethodField() disk_size = serializers.SerializerMethodField()
ip = serializers.CharField(read_only=True, ipv4 = serializers.SerializerMethodField()
source='user_template.ungleich_public_ip', ipv6 = serializers.SerializerMethodField()
default='-')
vm_id = serializers.IntegerField(read_only=True, source='id') vm_id = serializers.IntegerField(read_only=True, source='id')
state = serializers.CharField(read_only=True, source='str_state') state = serializers.CharField(read_only=True, source='str_state')
price = serializers.SerializerMethodField() price = serializers.SerializerMethodField()
@ -153,3 +152,33 @@ class VirtualMachineSerializer(serializers.Serializer):
template_id = obj.template.template_id template_id = obj.template.template_id
template = OpenNebulaManager().get_template(template_id) template = OpenNebulaManager().get_template(template_id)
return template.name return template.name
def get_ipv4(self, obj):
nic = obj.template.nics[0]
if 'vm-ipv6-nat64-ipv4' in nic.network and is_in_v4_range(nic.mac):
return str(v4_from_mac(nic.mac))
else:
return '-'
def get_ipv6(self, obj):
nic = obj.template.nics[0]
return nic.ip6_global
def hexstr2int(string):
return int(string.replace(':', ''), 16)
FIRST_MAC = hexstr2int('02:00:b3:39:79:4d')
FIRST_V4 = ipaddress.ip_address('185.203.112.2')
COUNT = 1000
def v4_from_mac(mac):
"""Calculates the IPv4 address from a MAC address.
mac: string (the colon-separated representation)
returns: ipaddress.ip_address object with the v4 address
"""
return FIRST_V4 + (hexstr2int(mac) - FIRST_MAC)
def is_in_v4_range(mac):
return FIRST_MAC <= hexstr2int(mac) < FIRST_MAC + 1000