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