Merge branch 'opennebula_api' of github.com:ungleich/dynamicweb into opennebula_api
This commit is contained in:
		
				commit
				
					
						e6ec14dfe7
					
				
			
		
					 10 changed files with 174 additions and 111 deletions
				
			
		| 
						 | 
				
			
			@ -4,8 +4,9 @@ from django.core.urlresolvers import reverse
 | 
			
		|||
 | 
			
		||||
from utils.mailer import BaseEmail
 | 
			
		||||
 | 
			
		||||
from .models import HostingOrder, HostingBill
 | 
			
		||||
from .models import HostingOrder, HostingBill, HostingPlan
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
admin.site.register(HostingOrder)
 | 
			
		||||
admin.site.register(HostingBill)
 | 
			
		||||
admin.site.register(HostingPlan)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										24
									
								
								hosting/migrations/0040_hostingplan.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								hosting/migrations/0040_hostingplan.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
# -*- coding: utf-8 -*-
 | 
			
		||||
# Generated by Django 1.9.4 on 2017-05-13 11:35
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('hosting', '0039_hostingorder_price'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name='HostingPlan',
 | 
			
		||||
            fields=[
 | 
			
		||||
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
			
		||||
                ('disk_size', models.FloatField(default=0.0)),
 | 
			
		||||
                ('cpu_cores', models.FloatField(default=0.0)),
 | 
			
		||||
                ('memory', models.FloatField(default=0.0)),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +21,31 @@ from .managers import VMPlansManager
 | 
			
		|||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class HostingPlan(models.Model):
 | 
			
		||||
    disk_size = models.FloatField(default=0.0)
 | 
			
		||||
    cpu_cores = models.FloatField(default=0.0)
 | 
			
		||||
    memory = models.FloatField(default=0.0)
 | 
			
		||||
 | 
			
		||||
    def serialize(self):
 | 
			
		||||
        return {
 | 
			
		||||
            'id': self.id,
 | 
			
		||||
            'cpu':self.cpu_cores,
 | 
			
		||||
            'memory': self.memory,
 | 
			
		||||
            'disk_size': self.disk_size,
 | 
			
		||||
            'price': self.price(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_serialized_configs(cls):
 | 
			
		||||
        return [cfg.serialize()
 | 
			
		||||
                for cfg in cls.objects.all()]
 | 
			
		||||
 | 
			
		||||
    def price(self):
 | 
			
		||||
        price = self.disk_size * 0.2
 | 
			
		||||
        price += self.cpu_cores * 5
 | 
			
		||||
        price += self.memory * 2
 | 
			
		||||
        return price
 | 
			
		||||
 | 
			
		||||
class HostingOrder(AssignPermissionsMixin, models.Model):
 | 
			
		||||
 | 
			
		||||
    ORDER_APPROVED_STATUS = 'Approved'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@
 | 
			
		|||
{% block content %}
 | 
			
		||||
 | 
			
		||||
<div class="container">
 | 
			
		||||
    <div class="orders-container">
 | 
			
		||||
    <div class="orders-container" style="padding-bottom: 15%">
 | 
			
		||||
        {# Adress bar  #}
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div class="invoice-title">
 | 
			
		||||
| 
						 | 
				
			
			@ -78,14 +78,14 @@
 | 
			
		|||
            </div>
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-sm-6">
 | 
			
		||||
                    {% trans "CH02 0900 0000 6071 8848 8%}
 | 
			
		||||
                    {% trans "CH02 0900 0000 6071 8848 8" %}
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-sm-6">
 | 
			
		||||
                    {% trans "POFICHBEXXX" %}
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    <div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
			
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,26 +11,22 @@
 | 
			
		|||
                <form  method="POST" action="">
 | 
			
		||||
                    {% csrf_token %}
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        Select VM:
 | 
			
		||||
                        Select VM Template:
 | 
			
		||||
                        <select name="vm_template_id">
 | 
			
		||||
                            {% for template in templates %}
 | 
			
		||||
                               
 | 
			
		||||
                                  <option value="{{template.id}}">
 | 
			
		||||
                                                CORE: {{template.cores}},
 | 
			
		||||
                                                RAM: {{template.memory}} GiB, 
 | 
			
		||||
                                                SSD: {{template.disk_size}} GiB
 | 
			
		||||
                                  </option>
 | 
			
		||||
                                
 | 
			
		||||
                                <option value="{{template.id}}">{{template.name}} </option>
 | 
			
		||||
                            {% endfor %}
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div> 
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
                        Select VM Configuration:
 | 
			
		||||
                        <select name="vm_image_id">
 | 
			
		||||
                            {% for image in images %}
 | 
			
		||||
                                
 | 
			
		||||
                                <option value="{{image.id}}">{{image.name}} </option>
 | 
			
		||||
                                
 | 
			
		||||
                        <select name="configuration">
 | 
			
		||||
                            {% for config in configuration_options %}
 | 
			
		||||
                                <option value="{{config.id}}">
 | 
			
		||||
                                    CORE: {{config.cpu|floatformat}},
 | 
			
		||||
                                    RAM: {{config.memory|floatformat}} GiB, 
 | 
			
		||||
                                    SSD: {{config.disk_size|floatformat}} GiB
 | 
			
		||||
                                </option>
 | 
			
		||||
                            {% endfor %}
 | 
			
		||||
                        </select>
 | 
			
		||||
                    </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@
 | 
			
		|||
                            <tr>
 | 
			
		||||
                                <td scope="row">{{ order.id }}</td>
 | 
			
		||||
                                <td>{{ order.created_at }}</td>
 | 
			
		||||
                                <td>{{ order.vm_plan.price }} CHF</td>
 | 
			
		||||
                                <td>{{ order.price }} CHF</td>
 | 
			
		||||
                                <td>{% if order.approved %}
 | 
			
		||||
                                    <span class="text-success strong">{% trans "Approved"%}</span>
 | 
			
		||||
                                {% else %}
 | 
			
		||||
| 
						 | 
				
			
			@ -99,4 +99,4 @@
 | 
			
		|||
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,14 +100,17 @@
 | 
			
		|||
							<div class="content">
 | 
			
		||||
								<!-- <p><b>Type</b> <span class="pull-right">{{request.session.vm_specs.location_code}}</span></p> -->
 | 
			
		||||
								<!-- <hr> -->
 | 
			
		||||
								<p><b>Cores</b> <span class="pull-right">{{request.session.template.cores}}</span></p>
 | 
			
		||||
								<p><b>Cores</b> <span
 | 
			
		||||
                                    class="pull-right">{{request.session.specs.cpu|floatformat}}</span></p>
 | 
			
		||||
								<hr>
 | 
			
		||||
								<p><b>Memory</b> <span class="pull-right">{{request.session.template.memory}} GiB</span></p>
 | 
			
		||||
								<p><b>Memory</b> <span
 | 
			
		||||
                                    class="pull-right">{{request.session.specs.memory|floatformat}} GiB</span></p>
 | 
			
		||||
								<hr>
 | 
			
		||||
								<p><b>Disk space</b> <span class="pull-right">{{request.session.template.disk_size}} GiB</span></p>
 | 
			
		||||
								<p><b>Disk space</b> <span
 | 
			
		||||
                                    class="pull-right">{{request.session.specs.disk_size|floatformat}} GiB</span></p>
 | 
			
		||||
								<hr>
 | 
			
		||||
								<h4>Total<p
 | 
			
		||||
                                    class="pull-right"><b>{{request.session.template.price }} CHF</b></p></h4>
 | 
			
		||||
                                    class="pull-right"><b>{{request.session.specs.price }} CHF</b></p></h4>
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
					</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,14 +25,13 @@ from utils.stripe_utils import StripeUtils
 | 
			
		|||
from utils.forms import BillingAddressForm, PasswordResetRequestForm, UserBillingAddressForm
 | 
			
		||||
from utils.views import PasswordResetViewMixin, PasswordResetConfirmViewMixin, LoginViewMixin
 | 
			
		||||
from utils.mailer import BaseEmail
 | 
			
		||||
from .models import HostingOrder, HostingBill, UserHostingKey
 | 
			
		||||
from .models import HostingOrder, HostingBill, HostingPlan, UserHostingKey
 | 
			
		||||
from .forms import HostingUserSignupForm, HostingUserLoginForm, UserHostingKeyForm
 | 
			
		||||
from .mixins import ProcessVMSelectionMixin
 | 
			
		||||
 | 
			
		||||
from opennebula_api.models import OpenNebulaManager
 | 
			
		||||
from opennebula_api.serializers import VirtualMachineSerializer,\
 | 
			
		||||
                                       VirtualMachineTemplateSerializer,\
 | 
			
		||||
                                       ImageSerializer
 | 
			
		||||
                                       VirtualMachineTemplateSerializer
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
from oca.exceptions import OpenNebulaException
 | 
			
		||||
| 
						 | 
				
			
			@ -407,12 +406,12 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
			
		|||
 | 
			
		||||
            context = self.get_context_data()
 | 
			
		||||
 | 
			
		||||
            specifications = request.session.get('template')
 | 
			
		||||
            template = request.session.get('template')
 | 
			
		||||
            specs = request.session.get('specs')
 | 
			
		||||
 | 
			
		||||
            vm_template_id = specifications.get('id', 1)
 | 
			
		||||
            vm_image_id = request.session.get('image').get('id', 1)
 | 
			
		||||
            vm_template_id = template.get('id', 1)
 | 
			
		||||
 | 
			
		||||
            final_price = specifications.get('price', 1)
 | 
			
		||||
            final_price = specs.get('price')
 | 
			
		||||
 | 
			
		||||
            token = form.cleaned_data.get('token')
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -455,12 +454,14 @@ class PaymentVMView(LoginRequiredMixin, FormView):
 | 
			
		|||
 | 
			
		||||
            except UserHostingKey.DoesNotExist:
 | 
			
		||||
                pass
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            # Create a vm using logged user
 | 
			
		||||
            vm_id = manager.create_vm(
 | 
			
		||||
                template_id=vm_template_id,
 | 
			
		||||
                #XXX: Confi
 | 
			
		||||
                specs=specs,
 | 
			
		||||
                ssh_key=user_key.public_key,
 | 
			
		||||
                image_id=vm_image_id, 
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            # Create a Hosting Order
 | 
			
		||||
| 
						 | 
				
			
			@ -587,11 +588,11 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
 | 
			
		|||
 | 
			
		||||
        manager = OpenNebulaManager()
 | 
			
		||||
        templates = manager.get_templates()
 | 
			
		||||
        images = manager.get_images()
 | 
			
		||||
        configuration_options = HostingPlan.get_serialized_configs()
 | 
			
		||||
 | 
			
		||||
        context = {
 | 
			
		||||
            'templates': VirtualMachineTemplateSerializer(templates, many=True).data,
 | 
			
		||||
            'images' : ImageSerializer(images, many=True).data
 | 
			
		||||
            'configuration_options' : configuration_options,
 | 
			
		||||
        }
 | 
			
		||||
        return render(request, self.template_name, context)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -599,10 +600,11 @@ class CreateVirtualMachinesView(LoginRequiredMixin, View):
 | 
			
		|||
        manager = OpenNebulaManager()
 | 
			
		||||
        template_id = request.POST.get('vm_template_id')
 | 
			
		||||
        template = manager.get_template(template_id)
 | 
			
		||||
        image_id = request.POST.get('vm_image_id')
 | 
			
		||||
        image = manager.get_image(image_id)
 | 
			
		||||
        configuration_id = int(request.POST.get('configuration'))
 | 
			
		||||
        configuration = HostingPlan.objects.get(id=configuration_id)
 | 
			
		||||
        request.session['template'] = VirtualMachineTemplateSerializer(template).data
 | 
			
		||||
        request.session['image'] = ImageSerializer(image).data
 | 
			
		||||
 | 
			
		||||
        request.session['specs'] = configuration.serialize() 
 | 
			
		||||
        return redirect(reverse('hosting:payment'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -715,6 +717,10 @@ class HostingBillDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailV
 | 
			
		|||
        # Get vms
 | 
			
		||||
        queryset = manager.get_vms()
 | 
			
		||||
        vms = VirtualMachineSerializer(queryset, many=True).data
 | 
			
		||||
        # Set total price
 | 
			
		||||
        bill = context['bill']
 | 
			
		||||
        bill.total_price = 0.0
 | 
			
		||||
        for vm in vms:
 | 
			
		||||
            bill.total_price += vm['price']
 | 
			
		||||
        context['vms'] = vms
 | 
			
		||||
 | 
			
		||||
        return context
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,37 +109,64 @@ class OpenNebulaManager():
 | 
			
		|||
        except:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
    def create_vm(self, template_id, image_id=None, ssh_key=None):
 | 
			
		||||
        extra_template_formater = """<CONTEXT>
 | 
			
		||||
                                      <SSH_PUBLIC_KEY>{ssh_key}</SSH_PUBLIC_KEY>
 | 
			
		||||
                                     </CONTEXT>
 | 
			
		||||
                                     <DISK>
 | 
			
		||||
                                      <IMAGE_ID>{image_id}</IMAGE_ID>
 | 
			
		||||
                                     </DISK>
 | 
			
		||||
                                  """
 | 
			
		||||
    def create_template(self, name, cores, memory, disk_size, core_price, memory_price,
 | 
			
		||||
                        disk_size_price, ssh='' ):
 | 
			
		||||
        """Create and add a new template to opennebula.
 | 
			
		||||
        :param name:      A string representation describing the template.
 | 
			
		||||
                          Used as label in view.
 | 
			
		||||
        :param cores:     Amount of virtual cpu cores for the VM.
 | 
			
		||||
        :param memory:  Amount of RAM for the VM (GB)
 | 
			
		||||
        :param disk_size:    Amount of disk space for VM (GB)
 | 
			
		||||
        :param core_price:     Price of virtual cpu for the VM per core.
 | 
			
		||||
        :param memory_price:  Price of RAM for the VM per GB
 | 
			
		||||
        :param disk_size_price:    Price of disk space for VM per GB
 | 
			
		||||
        :param ssh: User public ssh key
 | 
			
		||||
        """
 | 
			
		||||
        
 | 
			
		||||
        template_id = oca.VmTemplate.allocate(
 | 
			
		||||
            self.oneadmin_client,
 | 
			
		||||
            template_string_formatter.format(
 | 
			
		||||
                name=name,
 | 
			
		||||
                vcpu=cores,
 | 
			
		||||
                cpu=0.1*cores,
 | 
			
		||||
                size=1024 * disk_size,
 | 
			
		||||
                memory=1024 * memory,
 | 
			
		||||
                # * 10 because we set cpu to *0.1
 | 
			
		||||
                cpu_cost=10*core_price,
 | 
			
		||||
                memory_cost=memory_price,
 | 
			
		||||
                disk_cost=disk_size_price,
 | 
			
		||||
                ssh=ssh
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def create_vm(self, template_id, specs, ssh_key=None):
 | 
			
		||||
 | 
			
		||||
        template = self.get_template(template_id)
 | 
			
		||||
        vm_id = template.instantiate(name ='', pending=False, extra_template='')
 | 
			
		||||
        image = self.get_image(image_id)
 | 
			
		||||
        vm_specs_formatter = """<TEMPLATE>
 | 
			
		||||
                                 <MEMORY>{memory}</MEMORY>
 | 
			
		||||
                                 <VCPU>{vcpu}</VCPU>
 | 
			
		||||
                                 <CPU>{cpu}</CPU>
 | 
			
		||||
                                 <DISK>
 | 
			
		||||
                                  <TYPE>fs</TYPE>
 | 
			
		||||
                                  <SIZE>{size}</SIZE>
 | 
			
		||||
                                  <DEV_PREFIX>vd</DEV_PREFIX>
 | 
			
		||||
                                 </DISK>
 | 
			
		||||
                                 <CONTEXT>
 | 
			
		||||
                                 <SSH_PUBLIC_KEY>{ssh}</SSH_PUBLIC_KEY>
 | 
			
		||||
                                 </CONTEXT>
 | 
			
		||||
                                </TEMPLATE>
 | 
			
		||||
                           """
 | 
			
		||||
        vm_id = template.instantiate(name ='',
 | 
			
		||||
                                    pending=False,
 | 
			
		||||
                                    extra_template=vm_specs_formatter.format(
 | 
			
		||||
                                        vcpu=int(specs['cpu']),
 | 
			
		||||
                                        cpu=0.1* int(specs['cpu']),
 | 
			
		||||
                                        size=1024 * int(specs['disk_size']),
 | 
			
		||||
                                        memory=1024 * int(specs['memory']),
 | 
			
		||||
                                        ssh=ssh_key
 | 
			
		||||
                                        )
 | 
			
		||||
                                    )
 | 
			
		||||
 | 
			
		||||
        image_name = "{image_name}{template_name}{vm_id}".format(
 | 
			
		||||
                image_name=image.name,
 | 
			
		||||
                template_name=template.name,
 | 
			
		||||
                vm_id = vm_id,
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
        image_id = image.clone(name=image_name)
 | 
			
		||||
 | 
			
		||||
        self.oneadmin_client.call(
 | 
			
		||||
            oca.VmTemplate.METHODS['update'],
 | 
			
		||||
            vm_id, 
 | 
			
		||||
            extra_template_formater.format(
 | 
			
		||||
                ssh_key=ssh_key,
 | 
			
		||||
                image_id=image_id
 | 
			
		||||
                ),
 | 
			
		||||
            # 0 = Replace / 1 = Merge
 | 
			
		||||
            1,
 | 
			
		||||
        )
 | 
			
		||||
        try:
 | 
			
		||||
            self.oneadmin_client.call(
 | 
			
		||||
                oca.VirtualMachine.METHODS['chown'],
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +203,6 @@ class OpenNebulaManager():
 | 
			
		|||
        try:
 | 
			
		||||
           template_pool = oca.VmTemplatePool(self.oneadmin_client)
 | 
			
		||||
           template_pool.info()
 | 
			
		||||
        #TODO: Replace with logger
 | 
			
		||||
        except ConnectionRefusedError:
 | 
			
		||||
            logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
 | 
			
		||||
                    host=settings.OPENNEBULA_DOMAIN,
 | 
			
		||||
| 
						 | 
				
			
			@ -262,38 +288,3 @@ class OpenNebulaManager():
 | 
			
		|||
            self.opennebula_user.id,
 | 
			
		||||
            new_password
 | 
			
		||||
        ) 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def _get_image_pool(self):
 | 
			
		||||
        try:
 | 
			
		||||
           image_pool = oca.ImagePool(self.oneadmin_client)
 | 
			
		||||
           image_pool.info()
 | 
			
		||||
        #TODO: Replace with logger
 | 
			
		||||
        except ConnectionRefusedError:
 | 
			
		||||
            logger.info('Could not connect to host: {host} via protocol {protocol}'.format(
 | 
			
		||||
                    host=settings.OPENNEBULA_DOMAIN,
 | 
			
		||||
                    protocol=settings.OPENNEBULA_PROTOCOL)
 | 
			
		||||
                )
 | 
			
		||||
            raise ConnectionRefusedError
 | 
			
		||||
        return image_pool
 | 
			
		||||
 | 
			
		||||
    def get_images(self):
 | 
			
		||||
        try:
 | 
			
		||||
            public_images = [
 | 
			
		||||
                    image
 | 
			
		||||
                    for image in self._get_image_pool()
 | 
			
		||||
                    if 'public-' in image.name 
 | 
			
		||||
                    ]
 | 
			
		||||
            return public_images
 | 
			
		||||
        except ConnectionRefusedError:
 | 
			
		||||
            return []
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    def get_image(self, image_id):
 | 
			
		||||
        image_id = int(image_id)
 | 
			
		||||
        try:
 | 
			
		||||
            image_pool = self._get_image_pool()
 | 
			
		||||
            return image_pool.get_by_id(image_id)
 | 
			
		||||
        except:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,10 +10,12 @@ from .models import OpenNebulaManager
 | 
			
		|||
class VirtualMachineTemplateSerializer(serializers.Serializer):
 | 
			
		||||
    """Serializer to map the virtual machine template instance into JSON format."""
 | 
			
		||||
    id          = serializers.IntegerField(read_only=True)
 | 
			
		||||
    name        = serializers.CharField()
 | 
			
		||||
    set_name    = serializers.CharField(read_only=True, label='Name')
 | 
			
		||||
    name        = serializers.SerializerMethodField()
 | 
			
		||||
    cores       = serializers.IntegerField(source='template.vcpu') 
 | 
			
		||||
    disk        = serializers.IntegerField(write_only=True)
 | 
			
		||||
    disk_size   = serializers.SerializerMethodField()
 | 
			
		||||
    set_memory      = serializers.IntegerField(write_only=True, label='Memory')
 | 
			
		||||
    memory      = serializers.SerializerMethodField()
 | 
			
		||||
    core_price  = serializers.FloatField(source='template.cpu_cost')
 | 
			
		||||
    disk_size_price  = serializers.FloatField(source='template.disk_cost')
 | 
			
		||||
| 
						 | 
				
			
			@ -63,20 +65,28 @@ class VirtualMachineTemplateSerializer(serializers.Serializer):
 | 
			
		|||
    def get_memory(self, obj):
 | 
			
		||||
        return int(obj.template.memory)/1024
 | 
			
		||||
 | 
			
		||||
    def get_name(self, obj):
 | 
			
		||||
        # TODO: Filter public- away
 | 
			
		||||
        return obj.name
 | 
			
		||||
 | 
			
		||||
class VirtualMachineSerializer(serializers.Serializer):
 | 
			
		||||
    """Serializer to map the virtual machine instance into JSON format."""
 | 
			
		||||
 | 
			
		||||
    name        = serializers.CharField(read_only=True)
 | 
			
		||||
    cores       = serializers.IntegerField(read_only=True, source='template.vcpu') 
 | 
			
		||||
    cores       = serializers.IntegerField(source='template.vcpu') 
 | 
			
		||||
    disk        = serializers.IntegerField(write_only=True)
 | 
			
		||||
    set_memory      = serializers.IntegerField(write_only=True, label='Memory')
 | 
			
		||||
    memory      = serializers.SerializerMethodField()
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    disk_size   = serializers.SerializerMethodField()
 | 
			
		||||
    memory      = serializers.SerializerMethodField()
 | 
			
		||||
    ip          = serializers.CharField(read_only=True,
 | 
			
		||||
                                        source='user_template.ungleich_public_ip',
 | 
			
		||||
                                        default='-')
 | 
			
		||||
    vm_id       = serializers.IntegerField(read_only=True, source='id')
 | 
			
		||||
    state       = serializers.CharField(read_only=True, source='str_state')
 | 
			
		||||
    price       = serializers.SerializerMethodField()
 | 
			
		||||
    ssh_key     = serializers.CharField(write_only=True)
 | 
			
		||||
 | 
			
		||||
    template_id = serializers.ChoiceField(
 | 
			
		||||
                choices=[(key.id, key.name) for key in
 | 
			
		||||
| 
						 | 
				
			
			@ -87,13 +97,26 @@ class VirtualMachineSerializer(serializers.Serializer):
 | 
			
		|||
 | 
			
		||||
    def create(self, validated_data):
 | 
			
		||||
        owner = validated_data['owner']
 | 
			
		||||
        ssh_key = validated_data['ssh_key']
 | 
			
		||||
        cores = validated_data['template']['vcpu']
 | 
			
		||||
        memory = validated_data['set_memory']
 | 
			
		||||
        disk = validated_data['disk']
 | 
			
		||||
 | 
			
		||||
        template_id = validated_data['template']['template_id']
 | 
			
		||||
        specs = {
 | 
			
		||||
                    'cpu' : cores,
 | 
			
		||||
                    'disk_size' : disk,
 | 
			
		||||
                    'memory' : memory,
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            manager = OpenNebulaManager(email=owner.email,
 | 
			
		||||
                                        password=owner.password,
 | 
			
		||||
                                        )
 | 
			
		||||
            opennebula_id = manager.create_vm(template_id)
 | 
			
		||||
            opennebula_id = manager.create_vm(template_id=template_id,
 | 
			
		||||
                                              ssh_key=ssh_key,
 | 
			
		||||
                                              specs=specs)
 | 
			
		||||
        except OpenNebulaException as err:
 | 
			
		||||
            raise serializers.ValidationError("OpenNebulaException occured. {0}".format(err))
 | 
			
		||||
        
 | 
			
		||||
| 
						 | 
				
			
			@ -116,9 +139,3 @@ class VirtualMachineSerializer(serializers.Serializer):
 | 
			
		|||
        for disk in template.disks:
 | 
			
		||||
            price += int(disk.size)/1024 * float(template.disk_cost)
 | 
			
		||||
        return price
 | 
			
		||||
 | 
			
		||||
class ImageSerializer(serializers.Serializer):
 | 
			
		||||
    """Serializer to map the image instance into JSON format."""
 | 
			
		||||
    id          = serializers.IntegerField(read_only=True)
 | 
			
		||||
    name        = serializers.CharField()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue