Merge branch 'opennebula_api' of github.com:ungleich/dynamicweb into opennebula_api
This commit is contained in:
		
				commit
				
					
						03ec8ef674
					
				
			
		
					 10 changed files with 223 additions and 68 deletions
				
			
		|  | @ -231,7 +231,7 @@ | ||||||
|                       <p>2 GiB RAM, </p> |                       <p>2 GiB RAM, </p> | ||||||
|                       <p>{% trans "15 GiB storage(SSD)" %}</p> |                       <p>{% trans "15 GiB storage(SSD)" %}</p> | ||||||
|                         <p> |                         <p> | ||||||
|                         <a href="#" class="btn btn-primary btn-buynow">{% trans "Buy Now!" %}</a> <a href="#" class="btn btn-default">{% trans "More Info" %}</a> </p> |                         <a href="{% url 'hosting:login' %}" class="btn btn-primary btn-buynow">{% trans "Buy Now!" %}</a></p> | ||||||
|                   </div> |                   </div> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ from django.conf import settings | ||||||
| from hosting.views import RailsHostingView, DjangoHostingView, NodeJSHostingView | from hosting.views import RailsHostingView, DjangoHostingView, NodeJSHostingView | ||||||
| from membership import urls as membership_urls | from membership import urls as membership_urls | ||||||
| from ungleich_page.views import LandingView | from ungleich_page.views import LandingView | ||||||
|  | from django.views.generic import RedirectView | ||||||
|  | from django.core.urlresolvers import reverse_lazy | ||||||
| import debug_toolbar | import debug_toolbar | ||||||
| 
 | 
 | ||||||
| urlpatterns = [   url(r'^index.html$', LandingView.as_view()), | urlpatterns = [   url(r'^index.html$', LandingView.as_view()), | ||||||
|  | @ -28,6 +30,7 @@ urlpatterns += i18n_patterns('', | ||||||
|                              url(r'^/?$', LandingView.as_view()), |                              url(r'^/?$', LandingView.as_view()), | ||||||
|                              url(r'^admin/', include(admin.site.urls)), |                              url(r'^admin/', include(admin.site.urls)), | ||||||
|                              url(r'^datacenterlight', include('datacenterlight.urls', namespace="datacenterlight")), |                              url(r'^datacenterlight', include('datacenterlight.urls', namespace="datacenterlight")), | ||||||
|  |                              url(r'^hosting/', RedirectView.as_view(url=reverse_lazy('hosting:login')), name='redirect_hosting_login'), | ||||||
|                              url(r'^alplora', include('alplora.urls', namespace="alplora")), |                              url(r'^alplora', include('alplora.urls', namespace="alplora")), | ||||||
|                              url(r'^membership/', include(membership_urls)), |                              url(r'^membership/', include(membership_urls)), | ||||||
|                              url(r'^digitalglarus/', include('digitalglarus.urls', |                              url(r'^digitalglarus/', include('digitalglarus.urls', | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ class HostingPlan(models.Model): | ||||||
|                 for cfg in cls.objects.all()] |                 for cfg in cls.objects.all()] | ||||||
| 
 | 
 | ||||||
|     def price(self): |     def price(self): | ||||||
|         price = self.disk_size * 0.2 |         price = self.disk_size * 0.6 | ||||||
|         price += self.cpu_cores * 5 |         price += self.cpu_cores * 5 | ||||||
|         price += self.memory * 2 |         price += self.memory * 2 | ||||||
|         return price |         return price | ||||||
|  |  | ||||||
|  | @ -5,9 +5,19 @@ | ||||||
|     <div class="container dashboard-container"> |     <div class="container dashboard-container"> | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|             <div class="col-md-8 col-md-offset-2"> |             <div class="col-md-8 col-md-offset-2"> | ||||||
|  |                 <div class="col-md-12"> | ||||||
|  |                     <br/> | ||||||
|  |                     {% if messages %} | ||||||
|  |                         <div class="alert alert-warning"> | ||||||
|  |                             {% for message in messages %} | ||||||
|  |                             <span>{{ message }}</span> | ||||||
|  |                             {% endfor %} | ||||||
|  |                         </div> | ||||||
|  |                     {% endif %} | ||||||
|  |                 </div> | ||||||
|  |                 {% if not error %} | ||||||
|                 <h3><i class="fa fa-server" aria-hidden="true"></i> {% trans "New Virtual Machine"%} </h3> |                 <h3><i class="fa fa-server" aria-hidden="true"></i> {% trans "New Virtual Machine"%} </h3> | ||||||
|                 <hr/> |                 <hr/> | ||||||
|                  |  | ||||||
|                 <form  method="POST" action=""> |                 <form  method="POST" action=""> | ||||||
|                     {% csrf_token %} |                     {% csrf_token %} | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|  | @ -34,6 +44,7 @@ | ||||||
|                         <button class="btn btn-success" >{% trans "Start VM"%} </button>                          |                         <button class="btn btn-success" >{% trans "Start VM"%} </button>                          | ||||||
|                     </div> |                     </div> | ||||||
|                 </form> |                 </form> | ||||||
|  |                 {% endif %} | ||||||
| 
 | 
 | ||||||
|             </div> |             </div> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -87,7 +87,7 @@ | ||||||
| 								</div><!--/row--> | 								</div><!--/row--> | ||||||
| 								<div class="row"> | 								<div class="row"> | ||||||
| 									<div class="col-md-12"> | 									<div class="col-md-12"> | ||||||
| 										{% trans "Configuration"%}: {{virtual_machine.get_configuration_display}} | 										{% trans "Configuration"%}: {{virtual_machine.configuration}} | ||||||
| 									</div> | 									</div> | ||||||
| 								</div> | 								</div> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,10 +7,6 @@ | ||||||
| 			<div class="col-md-8 col-md-offset-2" style="margin-top: 35px;"> | 			<div class="col-md-8 col-md-offset-2" style="margin-top: 35px;"> | ||||||
| 				<table class="table borderless table-hover">  | 				<table class="table borderless table-hover">  | ||||||
| 				<h3 class="pull-left"><i class="fa fa-server" aria-hidden="true"></i> {% trans "Virtual Machines"%} </h3> | 				<h3 class="pull-left"><i class="fa fa-server" aria-hidden="true"></i> {% trans "Virtual Machines"%} </h3> | ||||||
|                 <p class="pull-right"> |  | ||||||
|                     <a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>                     |  | ||||||
|                 </p> |  | ||||||
| 				<br/> |  | ||||||
|                 <div class="col-md-12"> |                 <div class="col-md-12"> | ||||||
|                     <br/> |                     <br/> | ||||||
|                     {% if messages %} |                     {% if messages %} | ||||||
|  | @ -21,6 +17,12 @@ | ||||||
|                         </div> |                         </div> | ||||||
|                     {% endif %} |                     {% endif %} | ||||||
|                 </div> |                 </div> | ||||||
|  |                 {% if not error %} | ||||||
|  |                 <p class="pull-right"> | ||||||
|  |                     <a class="btn btn-success" href="{% url 'hosting:create-virtual-machine' %}" >{% trans "Create VM"%} </a>                     | ||||||
|  |                 </p> | ||||||
|  | 				<br/> | ||||||
|  |                  | ||||||
| 				<thead>  | 				<thead>  | ||||||
| 				<tr>  | 				<tr>  | ||||||
| 					<th>{% trans "ID"%}</th> | 					<th>{% trans "ID"%}</th> | ||||||
|  | @ -53,6 +55,7 @@ | ||||||
| 					{% endfor %} | 					{% endfor %} | ||||||
| 				</tbody>  | 				</tbody>  | ||||||
| 				</table> | 				</table> | ||||||
|  |                 {% endif %} | ||||||
| 
 | 
 | ||||||
| 			    {% if is_paginated %} | 			    {% if is_paginated %} | ||||||
| 			        <div class="pagination"> | 			        <div class="pagination"> | ||||||
|  |  | ||||||
|  | @ -37,6 +37,8 @@ from opennebula_api.serializers import VirtualMachineSerializer,\ | ||||||
| from oca.exceptions import OpenNebulaException | from oca.exceptions import OpenNebulaException | ||||||
| from oca.pool import WrongNameError | from oca.pool import WrongNameError | ||||||
| 
 | 
 | ||||||
|  | CONNECTION_ERROR = "Your VMs cannot be displayed at the moment due to a backend \ | ||||||
|  |                     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" | ||||||
|  | @ -528,8 +530,13 @@ class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, Detai | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         vm = manager.get_vm(obj.vm_id) |         try: | ||||||
|         context['vm'] = VirtualMachineSerializer(vm).data |             vm = manager.get_vm(obj.vm_id) | ||||||
|  |             context['vm'] = VirtualMachineSerializer(vm).data | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             messages.error( request, | ||||||
|  |                 'In order to create a VM, you need to create/upload your SSH KEY first.' | ||||||
|  |                 ) | ||||||
|         return context |         return context | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -564,9 +571,28 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         queryset = manager.get_vms() |         try: | ||||||
|         serializer = VirtualMachineSerializer(queryset, many=True) |             queryset = manager.get_vms() | ||||||
|         return serializer.data |             serializer = VirtualMachineSerializer(queryset, many=True) | ||||||
|  |             return serializer.data | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             messages.error( self.request, | ||||||
|  |                 'We could not load your VMs due to a backend connection \ | ||||||
|  |                 error. Please try again in a few minutes' | ||||||
|  |                 ) | ||||||
|  | 
 | ||||||
|  |             self.kwargs['error'] = 'connection' | ||||||
|  |             return [] | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |     def get_context_data(self, **kwargs): | ||||||
|  |         error = self.kwargs.get('error') | ||||||
|  |         if error is not None: | ||||||
|  |             print(error) | ||||||
|  |             context = { 'error' : 'connection' } | ||||||
|  |         else: | ||||||
|  |             context = super(ListView, self).get_context_data(**kwargs) | ||||||
|  |         return context | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class CreateVirtualMachinesView(LoginRequiredMixin, View): | class CreateVirtualMachinesView(LoginRequiredMixin, View): | ||||||
|  | @ -586,14 +612,24 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View): | ||||||
|             ) |             ) | ||||||
|             return HttpResponseRedirect(reverse('hosting:key_pair')) |             return HttpResponseRedirect(reverse('hosting:key_pair')) | ||||||
| 
 | 
 | ||||||
|         manager = OpenNebulaManager() |         try: | ||||||
|         templates = manager.get_templates() |             manager = OpenNebulaManager() | ||||||
|         configuration_options = HostingPlan.get_serialized_configs() |             templates = manager.get_templates() | ||||||
|  |             configuration_options = HostingPlan.get_serialized_configs() | ||||||
|  | 
 | ||||||
|  |             context = { | ||||||
|  |                 'templates': VirtualMachineTemplateSerializer(templates, many=True).data, | ||||||
|  |                 'configuration_options' : configuration_options, | ||||||
|  |             } | ||||||
|  |         except: | ||||||
|  |             messages.error( request, | ||||||
|  |                 'We could not load the VM templates due to a backend connection \ | ||||||
|  |                 error. Please try again in a few minutes' | ||||||
|  |                 ) | ||||||
|  |             context = { | ||||||
|  |                 'error' : 'connection' | ||||||
|  |                     } | ||||||
| 
 | 
 | ||||||
|         context = { |  | ||||||
|             'templates': VirtualMachineTemplateSerializer(templates, many=True).data, |  | ||||||
|             'configuration_options' : configuration_options, |  | ||||||
|         } |  | ||||||
|         return render(request, self.template_name, context) |         return render(request, self.template_name, context) | ||||||
| 
 | 
 | ||||||
|     def post(self, request): |     def post(self, request): | ||||||
|  | @ -622,10 +658,16 @@ class VirtualMachineView(LoginRequiredMixin, View): | ||||||
|         vm_id = self.kwargs.get('pk') |         vm_id = self.kwargs.get('pk') | ||||||
|         try: |         try: | ||||||
|             vm = manager.get_vm(vm_id) |             vm = manager.get_vm(vm_id) | ||||||
|  |             return vm | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             messages.error( self.request, | ||||||
|  |                 'We could not load your VM due to a backend connection \ | ||||||
|  |                 error. Please try again in a few minutes' | ||||||
|  |                 ) | ||||||
|  |             return None | ||||||
|         except Exception as error: |         except Exception as error: | ||||||
|             print(error) |             print(error) | ||||||
|             raise Http404() |             raise Http404() | ||||||
|         return vm |  | ||||||
| 
 | 
 | ||||||
|     def get_success_url(self): |     def get_success_url(self): | ||||||
|         final_url = reverse('hosting:virtual_machines') |         final_url = reverse('hosting:virtual_machines') | ||||||
|  | @ -633,10 +675,14 @@ class VirtualMachineView(LoginRequiredMixin, View): | ||||||
| 
 | 
 | ||||||
|     def get(self, request, *args, **kwargs): |     def get(self, request, *args, **kwargs): | ||||||
|         vm = self.get_object() |         vm = self.get_object() | ||||||
|         serializer = VirtualMachineSerializer(vm) |         try:  | ||||||
|         context = { |             serializer = VirtualMachineSerializer(vm) | ||||||
|             'virtual_machine': serializer.data, |             context = { | ||||||
|         } |                 'virtual_machine': serializer.data, | ||||||
|  |             } | ||||||
|  |         except: | ||||||
|  |             pass | ||||||
|  | 
 | ||||||
|         return render(request, self.template_name, context) |         return render(request, self.template_name, context) | ||||||
| 
 | 
 | ||||||
|     def post(self, request, *args, **kwargs): |     def post(self, request, *args, **kwargs): | ||||||
|  |  | ||||||
|  | @ -84,8 +84,12 @@ class OpenNebulaManager(): | ||||||
|             vm_pool.info() |             vm_pool.info() | ||||||
|         except AttributeError: |         except AttributeError: | ||||||
|             logger.info('Could not connect via client, using oneadmin instead')  |             logger.info('Could not connect via client, using oneadmin instead')  | ||||||
|             vm_pool = oca.VirtualMachinePool(self.oneadmin_client) |             try: | ||||||
|             vm_pool.info(filter=-2) |                 vm_pool = oca.VirtualMachinePool(self.oneadmin_client) | ||||||
|  |                 vm_pool.info(filter=-2) | ||||||
|  |                 return vm_pool | ||||||
|  |             except: | ||||||
|  |                 raise ConnectionRefusedError | ||||||
| 
 | 
 | ||||||
|         except ConnectionRefusedError: |         except ConnectionRefusedError: | ||||||
|             logger.info('Could not connect to host: {host} via protocol {protocol}'.format( |             logger.info('Could not connect to host: {host} via protocol {protocol}'.format( | ||||||
|  | @ -93,13 +97,16 @@ class OpenNebulaManager(): | ||||||
|                     protocol=settings.OPENNEBULA_PROTOCOL) |                     protocol=settings.OPENNEBULA_PROTOCOL) | ||||||
|                 ) |                 ) | ||||||
|             raise ConnectionRefusedError |             raise ConnectionRefusedError | ||||||
|         return vm_pool |         # For now we'll just handle all other errors as connection errors | ||||||
|  |         except: | ||||||
|  |             raise ConnectionRefusedError | ||||||
| 
 | 
 | ||||||
|     def get_vms(self): |     def get_vms(self): | ||||||
|         try: |         try: | ||||||
|             return self._get_vm_pool() |             return self._get_vm_pool() | ||||||
|         except ConnectionRefusedError: |         except ConnectionRefusedError: | ||||||
|             return [] |             raise ConnectionRefusedError | ||||||
|  |              | ||||||
|     |     | ||||||
|     def get_vm(self, vm_id): |     def get_vm(self, vm_id): | ||||||
|         vm_id = int(vm_id) |         vm_id = int(vm_id) | ||||||
|  | @ -107,7 +114,7 @@ class OpenNebulaManager(): | ||||||
|             vm_pool = self._get_vm_pool() |             vm_pool = self._get_vm_pool() | ||||||
|             return vm_pool.get_by_id(vm_id) |             return vm_pool.get_by_id(vm_id) | ||||||
|         except: |         except: | ||||||
|             return None |             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='' ): | ||||||
|  | @ -146,26 +153,56 @@ class OpenNebulaManager(): | ||||||
|                                  <MEMORY>{memory}</MEMORY> |                                  <MEMORY>{memory}</MEMORY> | ||||||
|                                  <VCPU>{vcpu}</VCPU> |                                  <VCPU>{vcpu}</VCPU> | ||||||
|                                  <CPU>{cpu}</CPU> |                                  <CPU>{cpu}</CPU> | ||||||
|                                  <DISK> |                                  <CONTEXT> | ||||||
|  |                                   <SSH_PUBLIC_KEY>{ssh}</SSH_PUBLIC_KEY> | ||||||
|  |                                  </CONTEXT> | ||||||
|  |                            """ | ||||||
|  |         try: | ||||||
|  |             disk = template.template.disks[0] | ||||||
|  |             image_id = disk.image_id | ||||||
|  |             vm_specs = vm_specs_formatter.format( | ||||||
|  |                                         vcpu=int(specs['cpu']), | ||||||
|  |                                         cpu=0.1* int(specs['cpu']), | ||||||
|  |                                         memory=1024 * int(specs['memory']), | ||||||
|  |                                         ssh=ssh_key | ||||||
|  |                      | ||||||
|  |                     ) | ||||||
|  |             vm_specs += """<DISK> | ||||||
|                                   <TYPE>fs</TYPE> |                                   <TYPE>fs</TYPE> | ||||||
|                                   <SIZE>{size}</SIZE> |                                   <SIZE>{size}</SIZE> | ||||||
|                                   <DEV_PREFIX>vd</DEV_PREFIX> |                                   <DEV_PREFIX>vd</DEV_PREFIX> | ||||||
|                                  </DISK> |                                   <IMAGE_ID>{image_id}</IMAGE_ID> | ||||||
|                                  <CONTEXT> |                            </DISK> | ||||||
|                                  <SSH_PUBLIC_KEY>{ssh}</SSH_PUBLIC_KEY> |                           </TEMPLATE> | ||||||
|                                  </CONTEXT> |                         """.format(size=1024 * int(specs['disk_size']), | ||||||
|                                 </TEMPLATE> |                                    image_id=image_id) | ||||||
|                            """ | 
 | ||||||
|         vm_id = template.instantiate(name ='', |         except: | ||||||
|                                     pending=False, |             disk = template.template.disks[0] | ||||||
|                                     extra_template=vm_specs_formatter.format( |             image = disk.image | ||||||
|  |             image_uname = disk.image_uname | ||||||
|  | 
 | ||||||
|  |             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']), | ||||||
|                                         size=1024 * int(specs['disk_size']), |  | ||||||
|                                         memory=1024 * int(specs['memory']), |                                         memory=1024 * int(specs['memory']), | ||||||
|                                         ssh=ssh_key |                                         ssh=ssh_key | ||||||
|                                         ) |                      | ||||||
|                                     ) |                     ) | ||||||
|  |             vm_specs += """<DISK> | ||||||
|  |                                   <TYPE>fs</TYPE> | ||||||
|  |                                   <SIZE>{size}</SIZE> | ||||||
|  |                                   <DEV_PREFIX>vd</DEV_PREFIX> | ||||||
|  |                                   <IMAGE>{image}</IMAGE> | ||||||
|  |                                   <IMAGE_UNAME>{image_uname}</IMAGE_UNAME> | ||||||
|  |                            </DISK> | ||||||
|  |                           </TEMPLATE> | ||||||
|  |                         """.format(size=1024 * int(specs['disk_size']), | ||||||
|  |                                    image=image, | ||||||
|  |                                    image_uname=image_uname) | ||||||
|  |         vm_id = template.instantiate(name ='', | ||||||
|  |                                     pending=False, | ||||||
|  |                                     extra_template=vm_specs,                                    ) | ||||||
| 
 | 
 | ||||||
|         try: |         try: | ||||||
|             self.oneadmin_client.call( |             self.oneadmin_client.call( | ||||||
|  | @ -203,13 +240,16 @@ class OpenNebulaManager(): | ||||||
|         try: |         try: | ||||||
|            template_pool = oca.VmTemplatePool(self.oneadmin_client) |            template_pool = oca.VmTemplatePool(self.oneadmin_client) | ||||||
|            template_pool.info() |            template_pool.info() | ||||||
|  |            return template_pool | ||||||
|         except ConnectionRefusedError: |         except ConnectionRefusedError: | ||||||
|             logger.info('Could not connect to host: {host} via protocol {protocol}'.format( |             logger.info('Could not connect to host: {host} via protocol {protocol}'.format( | ||||||
|                     host=settings.OPENNEBULA_DOMAIN, |                     host=settings.OPENNEBULA_DOMAIN, | ||||||
|                     protocol=settings.OPENNEBULA_PROTOCOL) |                     protocol=settings.OPENNEBULA_PROTOCOL) | ||||||
|                 ) |                 ) | ||||||
|             raise ConnectionRefusedError |             raise ConnectionRefusedError | ||||||
|         return template_pool |         except: | ||||||
|  |             raise ConnectionRefusedError | ||||||
|  |          | ||||||
| 
 | 
 | ||||||
|     def get_templates(self): |     def get_templates(self): | ||||||
|         try: |         try: | ||||||
|  | @ -220,6 +260,14 @@ class OpenNebulaManager(): | ||||||
|                     ] |                     ] | ||||||
|             return public_templates  |             return public_templates  | ||||||
|         except ConnectionRefusedError: |         except ConnectionRefusedError: | ||||||
|  |             raise ConnectionRefusedError | ||||||
|  |         except: | ||||||
|  |             raise ConnectionRefusedError | ||||||
|  | 
 | ||||||
|  |     def try_get_templates(self): | ||||||
|  |         try: | ||||||
|  |             return self.get_templates() | ||||||
|  |         except: | ||||||
|             return [] |             return [] | ||||||
| 
 | 
 | ||||||
|     def get_template(self, template_id): |     def get_template(self, template_id): | ||||||
|  | @ -228,7 +276,7 @@ class OpenNebulaManager(): | ||||||
|             template_pool = self._get_template_pool() |             template_pool = self._get_template_pool() | ||||||
|             return template_pool.get_by_id(template_id) |             return template_pool.get_by_id(template_id) | ||||||
|         except: |         except: | ||||||
|             return None |             raise ConnectionRefusedError | ||||||
| 
 | 
 | ||||||
|      |      | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -17,9 +17,6 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | ||||||
|     disk_size   = serializers.SerializerMethodField() |     disk_size   = serializers.SerializerMethodField() | ||||||
|     set_memory      = serializers.IntegerField(write_only=True, label='Memory') |     set_memory      = serializers.IntegerField(write_only=True, label='Memory') | ||||||
|     memory      = serializers.SerializerMethodField() |     memory      = serializers.SerializerMethodField() | ||||||
|     core_price  = serializers.FloatField(source='template.cpu_cost') |  | ||||||
|     disk_size_price  = serializers.FloatField(source='template.disk_cost') |  | ||||||
|     memory_price  = serializers.FloatField(source='template.memory_cost') |  | ||||||
|     price       = serializers.SerializerMethodField() |     price       = serializers.SerializerMethodField() | ||||||
| 
 | 
 | ||||||
|     def create(self, validated_data): |     def create(self, validated_data): | ||||||
|  | @ -30,9 +27,6 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | ||||||
|         name    = data.pop('name') |         name    = data.pop('name') | ||||||
|         disk_size = data.pop('disk')  |         disk_size = data.pop('disk')  | ||||||
|         memory  = template.pop('memory') |         memory  = template.pop('memory') | ||||||
|         core_price = template.pop('cpu_cost')  |  | ||||||
|         memory_price = template.pop('memory_cost')  |  | ||||||
|         disk_size_price = template.pop('disk_cost') |  | ||||||
|         manager = OpenNebulaManager() |         manager = OpenNebulaManager() | ||||||
|          |          | ||||||
|         try: |         try: | ||||||
|  | @ -50,16 +44,23 @@ class VirtualMachineTemplateSerializer(serializers.Serializer): | ||||||
|     def get_disk_size(self, obj): |     def get_disk_size(self, obj): | ||||||
|         template = obj.template |         template = obj.template | ||||||
|         disk_size = 0 |         disk_size = 0 | ||||||
|         for disk in template.disks: |         try: | ||||||
|             disk_size += int(disk.size) |             for disk in template.disks: | ||||||
|         return disk_size / 1024  |                 disk_size += int(disk.size) | ||||||
|  |             return disk_size / 1024  | ||||||
|  |         except: | ||||||
|  |             return 0 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|     def get_price(self, obj): |     def get_price(self, obj): | ||||||
|         template = obj.template |         template = obj.template | ||||||
|         price = float(template.cpu) * float(template.cpu_cost) |         price = float(template.cpu) * 5.0 | ||||||
|         price += (int(template.memory)/1024 * float(template.memory_cost)) |         price += (int(template.memory)/1024 * 2.0) | ||||||
|         for disk in template.disks: |         try: | ||||||
|             price += int(disk.size)/1024 * float(template.disk_cost) |             for disk in template.disks: | ||||||
|  |                 price += int(disk.size)/1024 * 0.6 | ||||||
|  |         except: | ||||||
|  |             pass | ||||||
|         return price |         return price | ||||||
| 
 | 
 | ||||||
|     def get_memory(self, obj): |     def get_memory(self, obj): | ||||||
|  | @ -87,12 +88,15 @@ class VirtualMachineSerializer(serializers.Serializer): | ||||||
|     state       = serializers.CharField(read_only=True, source='str_state') |     state       = serializers.CharField(read_only=True, source='str_state') | ||||||
|     price       = serializers.SerializerMethodField() |     price       = serializers.SerializerMethodField() | ||||||
|     ssh_key     = serializers.CharField(write_only=True) |     ssh_key     = serializers.CharField(write_only=True) | ||||||
|  |     configuration = serializers.SerializerMethodField() | ||||||
| 
 | 
 | ||||||
|     template_id = serializers.ChoiceField( |     template_id = serializers.ChoiceField( | ||||||
|                 choices=[(key.id, key.name) for key in |                 choices=[(key.id, key.name) for key in | ||||||
|                     OpenNebulaManager().get_templates()], |                         OpenNebulaManager().try_get_templates() | ||||||
|  |                         ], | ||||||
|                 source='template.template_id', |                 source='template.template_id', | ||||||
|                 write_only=True |                 write_only=True, | ||||||
|  |                 default=[] | ||||||
|             ) |             ) | ||||||
| 
 | 
 | ||||||
|     def create(self, validated_data): |     def create(self, validated_data): | ||||||
|  | @ -134,8 +138,12 @@ class VirtualMachineSerializer(serializers.Serializer): | ||||||
| 
 | 
 | ||||||
|     def get_price(self, obj): |     def get_price(self, obj): | ||||||
|         template = obj.template |         template = obj.template | ||||||
|         price = float(template.cpu) * float(template.cpu_cost) |         price = float(template.vcpu) * 5.0 | ||||||
|         price += (int(template.memory)/1024 * float(template.memory_cost)) |         price += (int(template.memory)/1024 * 2.0) | ||||||
|         for disk in template.disks: |         for disk in template.disks: | ||||||
|             price += int(disk.size)/1024 * float(template.disk_cost) |             price += int(disk.size)/1024 * 0.6 | ||||||
|         return price |         return price | ||||||
|  |     def get_configuration(self, obj): | ||||||
|  |         template_id = obj.template.template_id | ||||||
|  |         template = OpenNebulaManager().get_template(template_id) | ||||||
|  |         return template.name | ||||||
|  |  | ||||||
|  | @ -12,6 +12,12 @@ from guardian.mixins import PermissionRequiredMixin | ||||||
| from .serializers import VirtualMachineTemplateSerializer, \ | from .serializers import VirtualMachineTemplateSerializer, \ | ||||||
|                          VirtualMachineSerializer |                          VirtualMachineSerializer | ||||||
| from .models import OpenNebulaManager | from .models import OpenNebulaManager | ||||||
|  | from rest_framework.exceptions import APIException | ||||||
|  | 
 | ||||||
|  | class ServiceUnavailable(APIException): | ||||||
|  |     status_code = 503 | ||||||
|  |     default_detail = 'Service temporarily unavailable, try again later.' | ||||||
|  |     default_code = 'service_unavailable' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class TemplateCreateView(generics.ListCreateAPIView): | class TemplateCreateView(generics.ListCreateAPIView): | ||||||
|  | @ -37,7 +43,14 @@ class TemplateDetailsView(generics.RetrieveUpdateDestroyAPIView): | ||||||
| 
 | 
 | ||||||
|     def get_queryset(self): |     def get_queryset(self): | ||||||
|         manager = OpenNebulaManager() |         manager = OpenNebulaManager() | ||||||
|         return manager.get_templates() |         # We may have ConnectionRefusedError if we don't have a  | ||||||
|  |         # connection to OpenNebula. For now, we raise ServiceUnavailable | ||||||
|  |         try: | ||||||
|  |             templates = manager.get_templates() | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             raise ServiceUnavailable             | ||||||
|  |          | ||||||
|  |         return templates | ||||||
| 
 | 
 | ||||||
| class VmCreateView(generics.ListCreateAPIView): | class VmCreateView(generics.ListCreateAPIView): | ||||||
|     """This class handles the GET and POST requests.""" |     """This class handles the GET and POST requests.""" | ||||||
|  | @ -48,7 +61,13 @@ class VmCreateView(generics.ListCreateAPIView): | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         return manager.get_vms() |         # We may have ConnectionRefusedError if we don't have a  | ||||||
|  |         # connection to OpenNebula. For now, we raise ServiceUnavailable | ||||||
|  |         try: | ||||||
|  |             vms = manager.get_vms() | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             raise ServiceUnavailable | ||||||
|  |         return vms | ||||||
| 
 | 
 | ||||||
|     def perform_create(self, serializer): |     def perform_create(self, serializer): | ||||||
|         """Save the post data when creating a new template.""" |         """Save the post data when creating a new template.""" | ||||||
|  | @ -64,17 +83,34 @@ class VmDetailsView(generics.RetrieveUpdateDestroyAPIView): | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         return manager.get_vms() |         # We may have ConnectionRefusedError if we don't have a  | ||||||
|  |         # connection to OpenNebula. For now, we raise ServiceUnavailable | ||||||
|  |         try: | ||||||
|  |             vms = manager.get_vms() | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             raise ServiceUnavailable | ||||||
|  |         return vms | ||||||
| 
 | 
 | ||||||
|     def get_object(self): |     def get_object(self): | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         return manager.get_vm(self.kwargs.get('pk')) |         # We may have ConnectionRefusedError if we don't have a  | ||||||
|  |         # connection to OpenNebula. For now, we raise ServiceUnavailable | ||||||
|  |         try: | ||||||
|  |             vm = manager.get_vm(self.kwargs.get('pk')) | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             raise ServiceUnavailable | ||||||
|  |         return vm                                     | ||||||
| 
 | 
 | ||||||
|     def perform_destroy(self, instance): |     def perform_destroy(self, instance): | ||||||
|         owner = self.request.user |         owner = self.request.user | ||||||
|         manager = OpenNebulaManager(email=owner.email, |         manager = OpenNebulaManager(email=owner.email, | ||||||
|                                     password=owner.password) |                                     password=owner.password) | ||||||
|         manager.delete_vm(instance.id) |         # We may have ConnectionRefusedError if we don't have a  | ||||||
|  |         # connection to OpenNebula. For now, we raise ServiceUnavailable | ||||||
|  |         try: | ||||||
|  |             manager.delete_vm(instance.id) | ||||||
|  |         except ConnectionRefusedError: | ||||||
|  |             raise ServiceUnavailable | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue