resolve conflicts
This commit is contained in:
		
				commit
				
					
						398b7062e0
					
				
			
		
					 18 changed files with 244 additions and 81 deletions
				
			
		|  | @ -7,7 +7,7 @@ class BetaAccessForm(forms.ModelForm): | |||
|     email = forms.CharField(widget=forms.EmailInput()) | ||||
| 
 | ||||
|     class Meta: | ||||
|         fields = ['email'] | ||||
|         fields = ['name', 'email'] | ||||
|         model = BetaAccess | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										12
									
								
								datacenterlight/static/datacenterlight/js/form.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								datacenterlight/static/datacenterlight/js/form.js
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										27
									
								
								datacenterlight/templates/datacenterlight/beta_access.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								datacenterlight/templates/datacenterlight/beta_access.html
									
										
									
									
									
										Normal 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> | ||||
							
								
								
									
										47
									
								
								datacenterlight/templates/datacenterlight/beta_success.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								datacenterlight/templates/datacenterlight/beta_success.html
									
										
									
									
									
										Normal 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">×</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> | ||||
|  | @ -227,7 +227,7 @@ | |||
|                                <h3>{% trans "VM hosting" %} </h3>  | ||||
|                             </div> | ||||
|                           <div class="price"> | ||||
|                               <span>15CHF</span> | ||||
|                               <span>15CHF/month</span> | ||||
|                           </div> | ||||
|                           <div class="descriptions"> | ||||
|                               <div class="description"> | ||||
|  | @ -243,7 +243,7 @@ | |||
|                                 <p>{% trans "15 GiB storage(SSD)" %}</p> | ||||
|                               </div> | ||||
|                           </div> | ||||
|                           <a href="{% url 'datacenterlight:pricing' %}" class="btn btn-primary">{% trans "Buy Now!" %}</a> | ||||
| 						  <a href="{% url 'datacenterlight:pricing' %}" class="btn btn-primary">{% trans "Order Now!" %}</a> | ||||
|                       </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|  | @ -261,43 +261,9 @@ | |||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="col-sm-6 col-md-6"> | ||||
|                     <div class="form"> | ||||
|                         <form class="form-beta" method="POST" action=""> | ||||
|                           {% csrf_token %} | ||||
|                           {{ form.non_field_errors }} | ||||
|                           {{ form.email.errors|striptags}} | ||||
|                           <div> | ||||
|                             {% for message in messages %} | ||||
|                                 <strong>{{ message }}</strong> | ||||
|                             {% endfor %}                   | ||||
| 					<!-- Beta access form, will be loaded via ajax --> | ||||
|                     <div class="form" id="beta_access_form"> | ||||
| 					</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">×</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> | ||||
| 
 | ||||
|  | @ -389,12 +355,12 @@ | |||
|              windowPadding: 10, | ||||
|         }); | ||||
| 
 | ||||
|         var hash = window.location.hash.substr(1); | ||||
|         console.log(hash); | ||||
|         if (hash == 'requestform'){ | ||||
|             $('#reques-success-message').modal('show'); | ||||
|         } | ||||
| 
 | ||||
|   		$.ajax({ | ||||
| 	        url: "{% url 'datacenterlight:beta_access' %}", | ||||
| 				context: document.body | ||||
| 			}).done(function(response) { | ||||
| 				$('#beta_access_form').html(response); | ||||
| 			}); | ||||
|        }; | ||||
| </script> | ||||
| 
 | ||||
|  | @ -403,6 +369,8 @@ | |||
|     <!-- Bootstrap Core JavaScript --> | ||||
|     <script src="{% static 'datacenterlight/js/bootstrap.min.js' %}"></script> | ||||
|     <script src="{% static 'datacenterlight/js/main.js' %}"></script> | ||||
|     <!-- Load form js --> | ||||
|     <script src="{% static 'datacenterlight/js/form.js' %}"></script> | ||||
| 
 | ||||
| </body> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| from django.conf.urls import url | ||||
| 
 | ||||
| from .views import IndexView, BetaProgramView, LandingProgramView, PricingView | ||||
| from .views import IndexView, BetaProgramView, LandingProgramView, BetaAccessView, PricingView | ||||
| 
 | ||||
| 
 | ||||
| urlpatterns = [ | ||||
|  | @ -8,4 +8,5 @@ urlpatterns = [ | |||
|     url(r'^/beta-program/?$', BetaProgramView.as_view(), name='beta'), | ||||
|     url(r'^/landing/?$', LandingProgramView.as_view(), name='landing'), | ||||
|     url(r'^/pricing/?$', PricingView.as_view(), name='pricing'), | ||||
|     url(r'^/beta_access?$', BetaAccessView.as_view(), name='beta_access'), | ||||
| ] | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ from .models import BetaAccess, BetaAccessVMType, BetaAccessVM | |||
| from django.contrib import messages | ||||
| from django.core.urlresolvers import reverse_lazy, reverse | ||||
| from utils.mailer import BaseEmail | ||||
| from django.shortcuts import render | ||||
| 
 | ||||
| from opennebula_api.models import OpenNebulaManager | ||||
| from opennebula_api.serializers import VirtualMachineTemplateSerializer | ||||
|  | @ -15,6 +16,43 @@ class LandingProgramView(TemplateView): | |||
| class PricingView(TemplateView): | ||||
|     template_name = "datacenterlight/pricing.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): | ||||
|     template_name = "datacenterlight/beta.html" | ||||
|  |  | |||
|  | @ -4,15 +4,21 @@ from django.core.urlresolvers import reverse | |||
| from opennebula_api.serializers import VirtualMachineTemplateSerializer | ||||
| from opennebula_api.models import OpenNebulaManager | ||||
| 
 | ||||
| from .models import HostingPlan | ||||
| 
 | ||||
| 
 | ||||
| class ProcessVMSelectionMixin(object): | ||||
| 
 | ||||
|     def post(self, request, *args, **kwargs): | ||||
| 
 | ||||
|         template_id = int(request.POST.get('vm_template_id')) | ||||
|         configuration_id = int(request.POST.get('configuration')) | ||||
|         template = OpenNebulaManager().get_template(template_id) | ||||
|         data = VirtualMachineTemplateSerializer(template).data | ||||
|         configuration = HostingPlan.objects.get(id=configuration_id) | ||||
| 
 | ||||
|         request.session['template'] = data | ||||
|         request.session['specs'] = configuration.serialize() | ||||
| 
 | ||||
|         if not request.user.is_authenticated(): | ||||
|             request.session['next'] = reverse('hosting:payment') | ||||
|  |  | |||
|  | @ -35,7 +35,8 @@ | |||
|                                 <option value="{{config.id}}"> | ||||
|                                     CORE: {{config.cpu|floatformat}}, | ||||
|                                     RAM: {{config.memory|floatformat}} GiB,  | ||||
|                                     SSD: {{config.disk_size|floatformat}} GiB | ||||
|                                     SSD: {{config.disk_size|floatformat}} GiB, | ||||
|                                     PRICE: {{config.price|floatformat}} CHF/Month | ||||
|                                 </option> | ||||
|                             {% endfor %} | ||||
|                         </select> | ||||
|  |  | |||
|  | @ -18,13 +18,13 @@ | |||
|       <div class="row text-center"> | ||||
| 
 | ||||
|         <div class="block col-md-offset-3"> | ||||
|           {% for vm in vm_types %} | ||||
|           {% for vm in configuration_options %} | ||||
|             <div class="col-xs-12 col-sm-6 col-md-4"> | ||||
|               <form class="form-inline" method="POST" action="{{request.path}}"> | ||||
|                 {% csrf_token %} | ||||
|                 <input type="hidden" name="hosting_company" value="{{vm.hosting_company}}"> | ||||
|                 <input type="hidden" name="location_code" value="{{vm.location_code}}"> | ||||
|                 <input type="hidden" name="vm_template_id" value="{{vm.id}}"> | ||||
|                  <input type="hidden" name="configuration" value="{{vm.id}}"> | ||||
|                 | ||||
|                  | ||||
|                  | ||||
|  | @ -53,14 +53,14 @@ | |||
|                       </div> | ||||
|                     </div> | ||||
|                   </li> | ||||
| <!--                   <li> | ||||
|                   <li> | ||||
|                   <label for="configuration">Configuration: </label> | ||||
|                         <select class="form-control" name="configuration" id="{{vm.hosting_company}}-configuration" data-vm-type="{{vm.hosting_company}}"> | ||||
|                         {% for key,value in configuration_options.items   %} | ||||
|                             <option  value="{{key}}">{{ value }}</option> | ||||
|                         <select class="form-control" name="vm_template_id" id="{{vm.hosting_company}}-configuration" data-vm-type="{{vm.hosting_company}}"> | ||||
|                         {% for template in templates   %} | ||||
|                             <option  value="{{template.id}}">{{ template.name }}</option> | ||||
|                         {% endfor %} | ||||
|                         </select> | ||||
|                   </li> --> | ||||
|                   </li> | ||||
|                   <li> | ||||
|                     <input type="hidden" name="final_price" value="{{vm.final_price|floatformat}}"> | ||||
|                     <h3 id="{{vm.hosting_company}}-final-price">{{vm.price|floatformat}} CHF</h3> | ||||
|  |  | |||
|  | @ -41,11 +41,17 @@ | |||
| 									<div class="col-md-12 inline-headers"> | ||||
| 									<h3>{{virtual_machine.hosting_company_name}}</h3> | ||||
| 
 | ||||
| 										{% if virtual_machine.ip %} | ||||
| 										{% if virtual_machine.ipv6 %} | ||||
| 											<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"> | ||||
| 														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> | ||||
| 											</div> | ||||
| 										{% else %} | ||||
|  | @ -98,7 +104,7 @@ | |||
| 				            	<div class="row "> | ||||
| 									<div class="col-md-12 inline-headers"> | ||||
| 										<h3>{% trans "Current pricing"%}</h3> | ||||
| 										<span class="h3 pull-right"><strong>{{virtual_machine.price|floatformat}} CHF</strong>/mo</span>  | ||||
| 										<span class="h3 pull-right"><strong>{{virtual_machine.price|floatformat}} CHF</strong>/month</span>  | ||||
| 										<hr> | ||||
| 									</div> | ||||
| 				            	</div> | ||||
|  |  | |||
|  | @ -113,6 +113,12 @@ | |||
| {%endif%} | ||||
| 
 | ||||
| 
 | ||||
| {% if next_url %} | ||||
|     <script type="text/javascript">  | ||||
|         window.location.href = '{{next_url}}'; | ||||
|     </script> | ||||
| {% endif %} | ||||
| 
 | ||||
| {%endblock%} | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,14 +19,15 @@ | |||
|                 </div> | ||||
|                 {% if not error %} | ||||
|                 <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> | ||||
| 				<br/> | ||||
|                  | ||||
| 				<thead>  | ||||
| 				<tr>  | ||||
| 					<th>{% trans "ID"%}</th> | ||||
| 					<th>{% trans "Amount"%}</th> | ||||
|                     <th>{% trans "Ipv4"%}</th> | ||||
| 					<th>{% trans "Ipv6"%}</th> | ||||
| 					<th>{% trans "Status"%}</th> | ||||
| 					<th></th> | ||||
| 				</tr> | ||||
|  | @ -35,7 +36,12 @@ | |||
| 					{% for vm in vms %} | ||||
| 					<tr> | ||||
| 						<td scope="row">{{vm.vm_id}}</td>  | ||||
| 						<td>{{vm.price}} CHF</td>  | ||||
|                         {% if vm.ipv6  %} | ||||
| 						  <td>{{vm.ipv4}}</td>  | ||||
|                          | ||||
|                           <td>{{vm.ipv6}}</td>  | ||||
|                         {% endif %} | ||||
| 
 | ||||
| 						<td> | ||||
|                             | ||||
| 							{% if vm.state == 'ACTIVE' %} | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ urlpatterns = [ | |||
|     url(r'bills/?$', HostingBillListView.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'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/(?P<pk>\d+)/?$', VirtualMachineView.as_view(), | ||||
|         name='virtual_machines'), | ||||
|  |  | |||
|  | @ -47,6 +47,7 @@ class DjangoHostingView(ProcessVMSelectionMixin, View): | |||
|         HOSTING = 'django' | ||||
|         templates = OpenNebulaManager().get_templates() | ||||
|         data = VirtualMachineTemplateSerializer(templates, many=True).data | ||||
|         configuration_options = HostingPlan.get_serialized_configs() | ||||
| 
 | ||||
|         # configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) | ||||
|         context = { | ||||
|  | @ -57,8 +58,8 @@ class DjangoHostingView(ProcessVMSelectionMixin, View): | |||
|             'google_analytics': "UA-62285904-6", | ||||
|             'vm_types': data, | ||||
|             'email': "info@django-hosting.ch", | ||||
|             # 'vm_types': VirtualMachineType.get_serialized_vm_types(), | ||||
|             # 'configuration_options': dict(VirtualMachinePlan.VM_CONFIGURATION) | ||||
|             'configuration_options': configuration_options, | ||||
|             'templates': templates, | ||||
|         } | ||||
| 
 | ||||
|         return context | ||||
|  | @ -77,7 +78,7 @@ class RailsHostingView(ProcessVMSelectionMixin, View): | |||
|         HOSTING = 'rails' | ||||
| 
 | ||||
|         templates = OpenNebulaManager().get_templates() | ||||
|         data = VirtualMachineTemplateSerializer(templates, many=True).data | ||||
|         configuration_options = HostingPlan.get_serialized_configs() | ||||
| 
 | ||||
|         context = { | ||||
|             'hosting': HOSTING, | ||||
|  | @ -85,7 +86,8 @@ class RailsHostingView(ProcessVMSelectionMixin, View): | |||
|             'domain': "rails-hosting.ch", | ||||
|             'google_analytics': "UA-62285904-5", | ||||
|             'email': "info@rails-hosting.ch", | ||||
|             'vm_types': data, | ||||
|             'configuration_options': configuration_options, | ||||
|             'templates': templates, | ||||
|         } | ||||
|         return context | ||||
| 
 | ||||
|  | @ -102,7 +104,7 @@ class NodeJSHostingView(ProcessVMSelectionMixin, View): | |||
|         HOSTING = 'nodejs' | ||||
|         # configuration_detail = dict(VirtualMachinePlan.VM_CONFIGURATION).get(HOSTING) | ||||
|         templates = OpenNebulaManager().get_templates() | ||||
|         data = VirtualMachineTemplateSerializer(templates, many=True).data | ||||
|         configuration_options = HostingPlan.get_serialized_configs() | ||||
| 
 | ||||
|         context = { | ||||
|             'hosting': HOSTING, | ||||
|  | @ -111,7 +113,9 @@ class NodeJSHostingView(ProcessVMSelectionMixin, View): | |||
|             'domain': "node-hosting.ch", | ||||
|             'google_analytics': "UA-62285904-7", | ||||
|             'email': "info@node-hosting.ch", | ||||
|             'vm_types': data, | ||||
|             'templates': templates, | ||||
|             'configuration_options': configuration_options, | ||||
| 
 | ||||
|         } | ||||
|         return context | ||||
| 
 | ||||
|  | @ -128,12 +132,15 @@ class HostingPricingView(ProcessVMSelectionMixin, View): | |||
|     def get_context_data(self, **kwargs): | ||||
|         # configuration_options = dict(VirtualMachinePlan.VM_CONFIGURATION) | ||||
|         templates = OpenNebulaManager().get_templates() | ||||
|         data = VirtualMachineTemplateSerializer(templates, many=True).data | ||||
|         configuration_options = HostingPlan.get_serialized_configs() | ||||
| 
 | ||||
|         context = { | ||||
|             # 'configuration_options': configuration_options, | ||||
|             'email': "info@django-hosting.ch", | ||||
|             'vm_types': data, | ||||
|             'templates': templates, | ||||
|             'configuration_options': configuration_options, | ||||
| 
 | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return context | ||||
|  | @ -280,7 +287,6 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): | |||
|     form_class = UserHostingKeyForm | ||||
|     model = UserHostingKey | ||||
|     template_name = 'hosting/virtual_machine_key.html' | ||||
|     success_url = reverse_lazy('hosting:orders') | ||||
|     login_url = reverse_lazy('hosting:login') | ||||
|     context_object_name = "virtual_machine" | ||||
| 
 | ||||
|  | @ -317,7 +323,8 @@ class GenerateVMSSHKeysView(LoginRequiredMixin, FormView): | |||
|             context.update({ | ||||
|                 'private_key': form.cleaned_data.get('private_key'), | ||||
|                 'key_name': form.cleaned_data.get('name'), | ||||
|                 'form': UserHostingKeyForm(request=self.request) | ||||
|                 'form': UserHostingKeyForm(request=self.request), | ||||
|                 'next_url': reverse('hosting:create_virtual_machine') | ||||
|             }) | ||||
| 
 | ||||
|         # return HttpResponseRedirect(reverse('hosting:key_pair')) | ||||
|  | @ -384,6 +391,8 @@ class PaymentVMView(LoginRequiredMixin, FormView): | |||
|         return context | ||||
| 
 | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         if 'next' in request.session: | ||||
|             del request.session['next'] | ||||
| 
 | ||||
|         try: | ||||
|             UserHostingKey.objects.get( | ||||
|  |  | |||
|  | @ -82,6 +82,7 @@ class OpenNebulaManager(): | |||
|         try: | ||||
|             vm_pool = oca.VirtualMachinePool(self.client) | ||||
|             vm_pool.info() | ||||
|             return vm_pool | ||||
|         except AttributeError: | ||||
|             logger.info('Could not connect via client, using oneadmin instead')  | ||||
|             try: | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import oca | ||||
| import ipaddress | ||||
| 
 | ||||
| from rest_framework import serializers | ||||
| 
 | ||||
|  | @ -12,7 +13,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | |||
|     id          = serializers.IntegerField(read_only=True) | ||||
|     set_name    = serializers.CharField(read_only=True, label='Name') | ||||
|     name        = serializers.SerializerMethodField() | ||||
|     cores       = serializers.IntegerField(source='template.vcpu')  | ||||
|     cores       = serializers.SerializerMethodField()  | ||||
|     disk        = serializers.IntegerField(write_only=True) | ||||
|     disk_size   = serializers.SerializerMethodField() | ||||
|     set_memory      = serializers.IntegerField(write_only=True, label='Memory') | ||||
|  | @ -41,6 +42,12 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | |||
|          | ||||
|         return manager.get_template(template_id=opennebula_id) | ||||
| 
 | ||||
|     def get_cores(self, obj): | ||||
|         if hasattr(obj.template, 'vcpu'): | ||||
|             return obj.template.vcpu | ||||
| 
 | ||||
|         return '' | ||||
| 
 | ||||
|     def get_disk_size(self, obj): | ||||
|         template = obj.template | ||||
|         disk_size = 0 | ||||
|  | @ -67,8 +74,7 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | |||
|         return int(obj.template.memory)/1024 | ||||
| 
 | ||||
|     def get_name(self, obj): | ||||
|         # TODO: Filter public- away | ||||
|         return obj.name | ||||
|         return obj.name.strip('public-') | ||||
| 
 | ||||
| class VirtualMachineSerializer(serializers.Serializer): | ||||
|     """Serializer to map the virtual machine instance into JSON format.""" | ||||
|  | @ -81,9 +87,8 @@ class VirtualMachineSerializer(serializers.Serializer): | |||
|      | ||||
| 
 | ||||
|     disk_size   = serializers.SerializerMethodField() | ||||
|     ip          = serializers.CharField(read_only=True, | ||||
|                                         source='user_template.ungleich_public_ip', | ||||
|                                         default='-') | ||||
|     ipv4          = serializers.SerializerMethodField() | ||||
|     ipv6          = serializers.SerializerMethodField() | ||||
|     vm_id       = serializers.IntegerField(read_only=True, source='id') | ||||
|     state       = serializers.CharField(read_only=True, source='str_state') | ||||
|     price       = serializers.SerializerMethodField() | ||||
|  | @ -146,4 +151,34 @@ class VirtualMachineSerializer(serializers.Serializer): | |||
|     def get_configuration(self, obj): | ||||
|         template_id = obj.template.template_id | ||||
|         template = OpenNebulaManager().get_template(template_id) | ||||
|         return template.name | ||||
|         return template.name.strip('public-') | ||||
| 
 | ||||
|     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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue