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…
Reference in a new issue